diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-bbb-bone-buses.dtsi b/arch/arm/boot/dts/ti/omap/am335x-bbb-bone-buses.dtsi
--- a/arch/arm/boot/dts/ti/omap/am335x-bbb-bone-buses.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/am335x-bbb-bone-buses.dtsi	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 Deepak Khatri <deepaklorkhatri7@gmail.com>
+ * Copyright (C) 2021 Robert Nelson <robertcnelson@gmail.com>
+ * See Cape Interface Spec page for more info on Bone Buses
+ * https://elinux.org/Beagleboard:BeagleBone_cape_interface_spec
+ * https://docs.beagleboard.io/latest/boards/capes/cape-interface-spec.html
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+// For dummy refrence when peripheral is not available.
+&{/} {
+	not_available: not_available {
+		// Use &not_available when required.
+		// This node is responsible to create these entries,
+		// /sys/firmware/devicetree/base/__symbols__/not_available
+		// /sys/firmware/devicetree/base/not_available
+	};
+};
+
+// For compatible bone pinmuxing
+bone_pinmux: &am33xx_pinmux {
+	bborg_comms_can_pins: pinmux_comms_can_pins {
+		pinctrl-single,pins = <
+			0x184 (PIN_INPUT_PULLUP | MUX_MODE2)	/* P9_24: uart1_txd.d_can1_rx */
+			0x180 (PIN_OUTPUT_PULLUP | MUX_MODE2)	/* P9_26: uart1_rxd.d_can1_tx */
+		>;
+	};
+
+	bborg_comms_rs485_pins: pinmux_comms_rs485_pins {
+		pinctrl-single,pins = <
+			0x074 (PIN_OUTPUT | MUX_MODE6)	/* P9_13: gpmc_wpn.uart4_txd_mux2 */
+			0x070 (PIN_INPUT  | MUX_MODE6)	/* P9_11: gpmc_wait0.uart4_rxd_mux2 */
+		>;
+	};
+};
+
+// ADC
+bone_adc: &tscadc {
+
+};
+
+// UART
+// https://docs.beagleboard.io/latest/boards/capes/cape-interface-spec.html#uart
+bone_uart_4: &uart4 {
+	symlink = "bone/uart/4";
+	status = "disabled";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bborg_comms_rs485_pins>;
+	//rs485-rts-delay = <0 0>;
+	//rts-gpio = <&gpio3 19 1>; /*  GPIO_ACTIVE_HIGH>; */
+	//rs485-rts-active-high;
+	//linux,rs485-enabled-at-boot-time;
+};
+
+// CAN
+// https://docs.beagleboard.io/latest/boards/capes/cape-interface-spec.html#can
+bone_can_1: &dcan1 {
+	symlink = "bone/can/1";
+	status = "disabled";
+	pinctrl-names = "default";
+//	pinctrl-0 = <
+//		&P9_26_can_pin /* tx */
+//		&P9_24_can_pin /* rx */
+//	>;
+	pinctrl-0 = <&bborg_comms_can_pins>;
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-boneblack.dts b/arch/arm/boot/dts/ti/omap/am335x-boneblack.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-boneblack.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-boneblack.dts	2025-10-23 09:30:40.281462084 -0400
@@ -12,6 +12,11 @@
 / {
 	model = "TI AM335x BeagleBone Black";
 	compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+
+	chosen {
+		base_dtb = "am335x-boneblack.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
 };
 
 &cpu0_opp_table {
@@ -35,7 +40,7 @@
 		"P9_18 [spi0_d1]",
 		"P9_17 [spi0_cs0]",
 		"[mmc0_cd]",
-		"P8_42A [ecappwm0]",
+		"P9_42A [ecappwm0]",
 		"P8_35 [lcd d12]",
 		"P8_33 [lcd d13]",
 		"P8_31 [lcd d14]",
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-boneblack-ite-hdmi.dtsi b/arch/arm/boot/dts/ti/omap/am335x-boneblack-ite-hdmi.dtsi
--- a/arch/arm/boot/dts/ti/omap/am335x-boneblack-ite-hdmi.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/am335x-boneblack-ite-hdmi.dtsi	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	connector-hdmi {
+		compatible = "hdmi-connector";
+		label = "hdmi";
+		type = "a";
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&it66122_out>;
+			};
+		};
+	};
+
+	it66122_vcn18_fixed: fixedregulator1 {
+		compatible = "regulator-fixed";
+		regulator-name = "it66122_vcn18_fixed";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+};
+
+&am33xx_pinmux {
+	nxp_hdmi_bonelt_pins: nxp-hdmi-bonelt-pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR0, PIN_OUTPUT_PULLDOWN, MUX_MODE3)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA0, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA1, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA2, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA3, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA4, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA5, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA6, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA7, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA10, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA11, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA14, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA15, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_HSYNC, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+		>;
+	};
+
+	hdmi_gpio_pins_default: hdmi-gpio-default-pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A9, PIN_INPUT_PULLUP, MUX_MODE7)	/* HDMI_INT gpmc_a9.GPIO1_25 */
+			AM33XX_PADCONF(AM335X_PIN_UART0_RTSN, PIN_OUTPUT_PULLUP, MUX_MODE7) /* HDMI_RESET uart0_rtsn.GPIO1_9 */
+		>;
+	};
+
+	mcasp0_pins: mcasp0-pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKX, PIN_INPUT_PULLUP, MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKR, PIN_OUTPUT_PULLDOWN, MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_FSX, PIN_OUTPUT_PULLUP, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKX, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A11, PIN_OUTPUT_PULLDOWN, MUX_MODE7) /* gpmc_a11.GPIO1_27 */
+		>;
+	};
+};
+
+&lcdc {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+
+	/* If you want to get 24 bit RGB and 16 BGR mode instead of
+	 * current 16 bit RGB and 24 BGR modes, set the propety
+	 * below to "crossed" and uncomment the video-ports -property
+	 * in tda19988 node.
+	 */
+	blue-and-red-wiring = "straight";
+
+	port {
+		lcdc_0: endpoint@0 {
+			remote-endpoint = <&it66122_in>;
+		};
+	};
+};
+
+&i2c0 {
+	it66122: bridge-hdmi@4c {
+		compatible = "ite,it66122";
+		reg = <0x4c>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&hdmi_gpio_pins_default>;
+
+		vcn33-supply = <&vmmcsd_fixed>;
+		vcn18-supply = <&it66122_vcn18_fixed>;
+		//vrf12-supply = <&mt6358_vrf12_reg>;
+		reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+		#sound-dai-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				it66122_in: endpoint {
+					bus-width = <24>;
+					remote-endpoint = <&lcdc_0>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				it66122_out: endpoint {
+					remote-endpoint = <&hdmi_connector_in>;
+				};
+			};
+		};
+	};
+};
+
+&mcasp0	{
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcasp0_pins>;
+	status = "okay";
+	op-mode = <0>;	/* MCASP_IIS_MODE */
+	tdm-slots = <2>;
+	serial-dir = <	/* 0: INACTIVE, 1: TX, 2: RX */
+			0 0 1 0
+		>;
+	tx-num-evt = <32>;
+	rx-num-evt = <32>;
+};
+
+/ {
+	clk_mcasp0_fixed: clk_mcasp0_fixed {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <24576000>;
+	};
+
+	clk_mcasp0: clk_mcasp0 {
+		#clock-cells = <0>;
+		compatible = "gpio-gate-clock";
+		clocks = <&clk_mcasp0_fixed>;
+		enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */
+	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "TI BeagleBone Black";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&dailink0_master>;
+		simple-audio-card,frame-master = <&dailink0_master>;
+
+		dailink0_master: simple-audio-card,cpu {
+			sound-dai = <&mcasp0>;
+			clocks = <&clk_mcasp0>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&it66122>;
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-boneblack-revd.dts b/arch/arm/boot/dts/ti/omap/am335x-boneblack-revd.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-boneblack-revd.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/am335x-boneblack-revd.dts	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-bone-common.dtsi"
+#include "am335x-boneblack-common.dtsi"
+#include "am335x-boneblack-ite-hdmi.dtsi"
+
+/ {
+	model = "TI AM335x BeagleBone Black rev D";
+	compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+
+	chosen {
+		base_dtb = "am335x-boneblack-revd.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
+};
+
+&cpu0_opp_table {
+	/*
+	 * All PG 2.0 silicon may not support 1GHz but some of the early
+	 * BeagleBone Blacks have PG 2.0 silicon which is guaranteed
+	 * to support 1GHz OPP so enable it for PG 2.0 on this board.
+	 */
+	opp-1000000000 {
+		/* OPP Nitro */
+		opp-supported-hw = <0x06 0x0100>;
+	};
+};
+
+&gpio0 {
+	gpio-line-names =
+		"[mdio_data]",
+		"[mdio_clk]",
+		"P9_22 [spi0_sclk]",
+		"P9_21 [spi0_d0]",
+		"P9_18 [spi0_d1]",
+		"P9_17 [spi0_cs0]",
+		"[mmc0_cd]",
+		"P9_42A [ecappwm0]",
+		"P8_35 [lcd d12]",
+		"P8_33 [lcd d13]",
+		"P8_31 [lcd d14]",
+		"P8_32 [lcd d15]",
+		"P9_20 [i2c2_sda]",
+		"P9_19 [i2c2_scl]",
+		"P9_26 [uart1_rxd]",
+		"P9_24 [uart1_txd]",
+		"[rmii1_txd3]",
+		"[rmii1_txd2]",
+		"[usb0_drvvbus]",
+		"[hdmi cec]",
+		"P9_41B",
+		"[rmii1_txd1]",
+		"P8_19 [ehrpwm2a]",
+		"P8_13 [ehrpwm2b]",
+		"NC",
+		"NC",
+		"P8_14",
+		"P8_17",
+		"[rmii1_txd0]",
+		"[rmii1_refclk]",
+		"P9_11 [uart4_rxd]",
+		"P9_13 [uart4_txd]";
+};
+
+&gpio1 {
+	gpio-line-names =
+		"P8_25 [mmc1_dat0]",
+		"[mmc1_dat1]",
+		"P8_5 [mmc1_dat2]",
+		"P8_6 [mmc1_dat3]",
+		"P8_23 [mmc1_dat4]",
+		"P8_22 [mmc1_dat5]",
+		"P8_3 [mmc1_dat6]",
+		"P8_4 [mmc1_dat7]",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"P8_12",
+		"P8_11",
+		"P8_16",
+		"P8_15",
+		"P9_15A",
+		"P9_23",
+		"P9_14 [ehrpwm1a]",
+		"P9_16 [ehrpwm1b]",
+		"[emmc rst]",
+		"[usr0 led]",
+		"[usr1 led]",
+		"[usr2 led]",
+		"[usr3 led]",
+		"[hdmi irq]",
+		"[usb vbus oc]",
+		"[hdmi audio]",
+		"P9_12",
+		"P8_26",
+		"P8_21 [emmc]",
+		"P8_20 [emmc]";
+};
+
+&gpio2 {
+	gpio-line-names =
+		"P9_15B",
+		"P8_18",
+		"P8_7",
+		"P8_8",
+		"P8_10",
+		"P8_9",
+		"P8_45 [hdmi]",
+		"P8_46 [hdmi]",
+		"P8_43 [hdmi]",
+		"P8_44 [hdmi]",
+		"P8_41 [hdmi]",
+		"P8_42 [hdmi]",
+		"P8_39 [hdmi]",
+		"P8_40 [hdmi]",
+		"P8_37 [hdmi]",
+		"P8_38 [hdmi]",
+		"P8_36 [hdmi]",
+		"P8_34 [hdmi]",
+		"[rmii1_rxd3]",
+		"[rmii1_rxd2]",
+		"[rmii1_rxd1]",
+		"[rmii1_rxd0]",
+		"P8_27 [hdmi]",
+		"P8_29 [hdmi]",
+		"P8_28 [hdmi]",
+		"P8_30 [hdmi]",
+		"[mmc0_dat3]",
+		"[mmc0_dat2]",
+		"[mmc0_dat1]",
+		"[mmc0_dat0]",
+		"[mmc0_clk]",
+		"[mmc0_cmd]";
+};
+
+&gpio3 {
+	gpio-line-names =
+		"[mii col]",
+		"[mii crs]",
+		"[mii rx err]",
+		"[mii tx en]",
+		"[mii rx dv]",
+		"[i2c0 sda]",
+		"[i2c0 scl]",
+		"[jtag emu0]",
+		"[jtag emu1]",
+		"[mii tx clk]",
+		"[mii rx clk]",
+		"NC",
+		"NC",
+		"[usb vbus en]",
+		"P9_31 [spi1_sclk]",
+		"P9_29 [spi1_d0]",
+		"P9_30 [spi1_d1]",
+		"P9_28 [spi1_cs0]",
+		"P9_42B [ecappwm0]",
+		"P9_27",
+		"P9_41A",
+		"P9_25",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC";
+};
+
+&baseboard_eeprom {
+	vcc-supply = <&ldo4_reg>;
+};
+
+&tscadc {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-boneblack-uboot.dts b/arch/arm/boot/dts/ti/omap/am335x-boneblack-uboot.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-boneblack-uboot.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/am335x-boneblack-uboot.dts	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-bone-common.dtsi"
+#include "am335x-bbb-bone-buses.dtsi"
+
+/ {
+	model = "TI AM335x BeagleBone Black";
+	compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+
+	chosen {
+		base_dtb = "am335x-boneblack-uboot.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>; /* 512 MB */
+	};
+};
+
+&cpu0_opp_table {
+	/*
+	 * All PG 2.0 silicon may not support 1GHz but some of the early
+	 * BeagleBone Blacks have PG 2.0 silicon which is guaranteed
+	 * to support 1GHz OPP so enable it for PG 2.0 on this board.
+	 */
+	opp-1000000000 {
+		/* OPP Nitro */
+		opp-supported-hw = <0x06 0x0100>;
+	};
+};
+
+&ldo3_reg {
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-always-on;
+};
+
+&mmc1 {
+	vmmc-supply = <&vmmcsd_fixed>;
+};
+
+&gpio0 {
+	gpio-line-names =
+		"[mdio_data]",
+		"[mdio_clk]",
+		"P9_22 [spi0_sclk]",
+		"P9_21 [spi0_d0]",
+		"P9_18 [spi0_d1]",
+		"P9_17 [spi0_cs0]",
+		"[mmc0_cd]",
+		"P9_42A [ecappwm0]",
+		"P8_35 [lcd d12]",
+		"P8_33 [lcd d13]",
+		"P8_31 [lcd d14]",
+		"P8_32 [lcd d15]",
+		"P9_20 [i2c2_sda]",
+		"P9_19 [i2c2_scl]",
+		"P9_26 [uart1_rxd]",
+		"P9_24 [uart1_txd]",
+		"[rmii1_txd3]",
+		"[rmii1_txd2]",
+		"[usb0_drvvbus]",
+		"[hdmi cec]",
+		"P9_41B",
+		"[rmii1_txd1]",
+		"P8_19 [ehrpwm2a]",
+		"P8_13 [ehrpwm2b]",
+		"NC",
+		"NC",
+		"P8_14",
+		"P8_17",
+		"[rmii1_txd0]",
+		"[rmii1_refclk]",
+		"P9_11 [uart4_rxd]",
+		"P9_13 [uart4_txd]";
+};
+
+&gpio1 {
+	gpio-line-names =
+		"P8_25 [mmc1_dat0]",
+		"[mmc1_dat1]",
+		"P8_5 [mmc1_dat2]",
+		"P8_6 [mmc1_dat3]",
+		"P8_23 [mmc1_dat4]",
+		"P8_22 [mmc1_dat5]",
+		"P8_3 [mmc1_dat6]",
+		"P8_4 [mmc1_dat7]",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"P8_12",
+		"P8_11",
+		"P8_16",
+		"P8_15",
+		"P9_15A",
+		"P9_23",
+		"P9_14 [ehrpwm1a]",
+		"P9_16 [ehrpwm1b]",
+		"[emmc rst]",
+		"[usr0 led]",
+		"[usr1 led]",
+		"[usr2 led]",
+		"[usr3 led]",
+		"[hdmi irq]",
+		"[usb vbus oc]",
+		"[hdmi audio]",
+		"P9_12",
+		"P8_26",
+		"P8_21 [emmc]",
+		"P8_20 [emmc]";
+};
+
+&gpio2 {
+	gpio-line-names =
+		"P9_15B",
+		"P8_18",
+		"P8_7",
+		"P8_8",
+		"P8_10",
+		"P8_9",
+		"P8_45 [hdmi]",
+		"P8_46 [hdmi]",
+		"P8_43 [hdmi]",
+		"P8_44 [hdmi]",
+		"P8_41 [hdmi]",
+		"P8_42 [hdmi]",
+		"P8_39 [hdmi]",
+		"P8_40 [hdmi]",
+		"P8_37 [hdmi]",
+		"P8_38 [hdmi]",
+		"P8_36 [hdmi]",
+		"P8_34 [hdmi]",
+		"[rmii1_rxd3]",
+		"[rmii1_rxd2]",
+		"[rmii1_rxd1]",
+		"[rmii1_rxd0]",
+		"P8_27 [hdmi]",
+		"P8_29 [hdmi]",
+		"P8_28 [hdmi]",
+		"P8_30 [hdmi]",
+		"[mmc0_dat3]",
+		"[mmc0_dat2]",
+		"[mmc0_dat1]",
+		"[mmc0_dat0]",
+		"[mmc0_clk]",
+		"[mmc0_cmd]";
+};
+
+&gpio3 {
+	gpio-line-names =
+		"[mii col]",
+		"[mii crs]",
+		"[mii rx err]",
+		"[mii tx en]",
+		"[mii rx dv]",
+		"[i2c0 sda]",
+		"[i2c0 scl]",
+		"[jtag emu0]",
+		"[jtag emu1]",
+		"[mii tx clk]",
+		"[mii rx clk]",
+		"NC",
+		"NC",
+		"[usb vbus en]",
+		"P9_31 [spi1_sclk]",
+		"P9_29 [spi1_d0]",
+		"P9_30 [spi1_d1]",
+		"P9_28 [spi1_cs0]",
+		"P9_42B [ecappwm0]",
+		"P9_27",
+		"P9_41A",
+		"P9_25",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC";
+};
+
+&baseboard_eeprom {
+	vcc-supply = <&ldo4_reg>;
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-boneblack-uboot-univ.dts b/arch/arm/boot/dts/ti/omap/am335x-boneblack-uboot-univ.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-boneblack-uboot-univ.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/am335x-boneblack-uboot-univ.dts	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-bone-common.dtsi"
+#include "am335x-bone-common-univ.dtsi"
+
+/ {
+	model = "TI AM335x BeagleBone Black";
+	compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+
+	chosen {
+		base_dtb = "am335x-boneblack-uboot-univ.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>; /* 512 MB */
+	};
+};
+
+&cpu0_opp_table {
+	/*
+	 * All PG 2.0 silicon may not support 1GHz but some of the early
+	 * BeagleBone Blacks have PG 2.0 silicon which is guaranteed
+	 * to support 1GHz OPP so enable it for PG 2.0 on this board.
+	 */
+	oppnitro-1000000000 {
+		opp-supported-hw = <0x06 0x0100>;
+	};
+};
+
+&ldo3_reg {
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-always-on;
+};
+
+&mmc1 {
+	vmmc-supply = <&vmmcsd_fixed>;
+};
+
+&gpio0 {
+	gpio-line-names =
+		"[mdio_data]",
+		"[mdio_clk]",
+		"P9_22 [spi0_sclk]",
+		"P9_21 [spi0_d0]",
+		"P9_18 [spi0_d1]",
+		"P9_17 [spi0_cs0]",
+		"[mmc0_cd]",
+		"P8_42A [ecappwm0]",
+		"P8_35 [lcd d12]",
+		"P8_33 [lcd d13]",
+		"P8_31 [lcd d14]",
+		"P8_32 [lcd d15]",
+		"P9_20 [i2c2_sda]",
+		"P9_19 [i2c2_scl]",
+		"P9_26 [uart1_rxd]",
+		"P9_24 [uart1_txd]",
+		"[rmii1_txd3]",
+		"[rmii1_txd2]",
+		"[usb0_drvvbus]",
+		"[hdmi cec]",
+		"P9_41B",
+		"[rmii1_txd1]",
+		"P8_19 [ehrpwm2a]",
+		"P8_13 [ehrpwm2b]",
+		"NC",
+		"NC",
+		"P8_14",
+		"P8_17",
+		"[rmii1_txd0]",
+		"[rmii1_refclk]",
+		"P9_11 [uart4_rxd]",
+		"P9_13 [uart4_txd]";
+};
+
+&gpio1 {
+	gpio-line-names =
+		"P8_25 [mmc1_dat0]",
+		"[mmc1_dat1]",
+		"P8_5 [mmc1_dat2]",
+		"P8_6 [mmc1_dat3]",
+		"P8_23 [mmc1_dat4]",
+		"P8_22 [mmc1_dat5]",
+		"P8_3 [mmc1_dat6]",
+		"P8_4 [mmc1_dat7]",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"P8_12",
+		"P8_11",
+		"P8_16",
+		"P8_15",
+		"P9_15A",
+		"P9_23",
+		"P9_14 [ehrpwm1a]",
+		"P9_16 [ehrpwm1b]",
+		"[emmc rst]",
+		"[usr0 led]",
+		"[usr1 led]",
+		"[usr2 led]",
+		"[usr3 led]",
+		"[hdmi irq]",
+		"[usb vbus oc]",
+		"[hdmi audio]",
+		"P9_12",
+		"P8_26",
+		"P8_21 [emmc]",
+		"P8_20 [emmc]";
+};
+
+&gpio2 {
+	gpio-line-names =
+		"P9_15B",
+		"P8_18",
+		"P8_7",
+		"P8_8",
+		"P8_10",
+		"P8_9",
+		"P8_45 [hdmi]",
+		"P8_46 [hdmi]",
+		"P8_43 [hdmi]",
+		"P8_44 [hdmi]",
+		"P8_41 [hdmi]",
+		"P8_42 [hdmi]",
+		"P8_39 [hdmi]",
+		"P8_40 [hdmi]",
+		"P8_37 [hdmi]",
+		"P8_38 [hdmi]",
+		"P8_36 [hdmi]",
+		"P8_34 [hdmi]",
+		"[rmii1_rxd3]",
+		"[rmii1_rxd2]",
+		"[rmii1_rxd1]",
+		"[rmii1_rxd0]",
+		"P8_27 [hdmi]",
+		"P8_29 [hdmi]",
+		"P8_28 [hdmi]",
+		"P8_30 [hdmi]",
+		"[mmc0_dat3]",
+		"[mmc0_dat2]",
+		"[mmc0_dat1]",
+		"[mmc0_dat0]",
+		"[mmc0_clk]",
+		"[mmc0_cmd]";
+};
+
+&gpio3 {
+	gpio-line-names =
+		"[mii col]",
+		"[mii crs]",
+		"[mii rx err]",
+		"[mii tx en]",
+		"[mii rx dv]",
+		"[i2c0 sda]",
+		"[i2c0 scl]",
+		"[jtag emu0]",
+		"[jtag emu1]",
+		"[mii tx clk]",
+		"[mii rx clk]",
+		"NC",
+		"NC",
+		"[usb vbus en]",
+		"P9_31 [spi1_sclk]",
+		"P9_29 [spi1_d0]",
+		"P9_30 [spi1_d1]",
+		"P9_28 [spi1_cs0]",
+		"P9_42B [ecappwm0]",
+		"P9_27",
+		"P9_41A",
+		"P9_25",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC";
+};
+
+&baseboard_eeprom {
+	vcc-supply = <&ldo4_reg>;
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-boneblack-wireless.dts b/arch/arm/boot/dts/ti/omap/am335x-boneblack-wireless.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-boneblack-wireless.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-boneblack-wireless.dts	2025-10-23 09:30:40.281462084 -0400
@@ -14,6 +14,11 @@
 	model = "TI AM335x BeagleBone Black Wireless";
 	compatible = "ti,am335x-bone-black-wireless", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
 
+	chosen {
+		base_dtb = "am335x-boneblack-wireless.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
+
 	wlan_en_reg: fixedregulator@2 {
 		compatible = "regulator-fixed";
 		regulator-name = "wlan-en-regulator";
@@ -64,6 +69,9 @@
 };
 
 &mac_sw {
+	/delete-property/pinctrl-names;
+	/delete-property/pinctrl-0;
+	/delete-property/pinctrl-1;
 	status = "disabled";
 };
 
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-boneblue.dts b/arch/arm/boot/dts/ti/omap/am335x-boneblue.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-boneblue.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-boneblue.dts	2025-10-23 09:30:40.281462084 -0400
@@ -14,6 +14,8 @@
 
 	chosen {
 		stdout-path = &uart0;
+		base_dtb = "am335x-boneblue.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
 	};
 
 	leds {
@@ -313,7 +315,7 @@
 };
 
 &i2c0 {
-	baseboard_eeprom: baseboard_eeprom@50 {
+	baseboard_eeprom: eeprom@50 {
 		compatible = "atmel,24c256";
 		reg = <0x50>;
 
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi
--- a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi	2025-10-23 09:30:40.281462084 -0400
@@ -3,6 +3,8 @@
  * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
  */
 
+#include "am335x-bbb-bone-buses.dtsi"
+
 / {
 	cpus {
 		cpu@0 {
@@ -26,14 +28,14 @@
 		compatible = "gpio-leds";
 
 		led2 {
-			label = "beaglebone:green:heartbeat";
+			label = "beaglebone:green:usr0";
 			gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 			default-state = "off";
 		};
 
 		led3 {
-			label = "beaglebone:green:mmc0";
+			label = "beaglebone:green:usr1";
 			gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "mmc0";
 			default-state = "off";
@@ -63,9 +65,6 @@
 };
 
 &am33xx_pinmux {
-	pinctrl-names = "default";
-	pinctrl-0 = <&clkout2_pin>;
-
 	user_leds_s0: user-leds-s0-pins {
 		pinctrl-single,pins = <
 			AM33XX_PADCONF(AM335X_PIN_GPMC_A5, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gpmc_a5.gpio1_21 */
@@ -96,12 +95,6 @@
 		>;
 	};
 
-	clkout2_pin: clkout2-pins {
-		pinctrl-single,pins = <
-			AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR1, PIN_OUTPUT_PULLDOWN, MUX_MODE3)	/* xdma_event_intr1.clkout2 */
-		>;
-	};
-
 	cpsw_default: cpsw-default-pins {
 		pinctrl-single,pins = <
 			/* Slave 1 */
@@ -193,6 +186,7 @@
 	pinctrl-0 = <&uart0_pins>;
 
 	status = "okay";
+	symlink = "bone/uart/0";
 };
 
 &usb0 {
@@ -211,12 +205,13 @@
 
 	status = "okay";
 	clock-frequency = <400000>;
+	symlink = "bone/i2c/0";
 
-	tps: tps@24 {
+	tps: pmic@24 {
 		reg = <0x24>;
 	};
 
-	baseboard_eeprom: baseboard_eeprom@50 {
+	baseboard_eeprom: eeprom@50 {
 		compatible = "atmel,24c256";
 		reg = <0x50>;
 		vcc-supply = <&ldo4_reg>;
@@ -239,8 +234,9 @@
 
 	status = "okay";
 	clock-frequency = <100000>;
+	symlink = "bone/i2c/2";
 
-	cape_eeprom0: cape_eeprom0@54 {
+	cape_eeprom0: eeprom@54 {
 		compatible = "atmel,24c256";
 		reg = <0x54>;
 
@@ -255,7 +251,7 @@
 		};
 	};
 
-	cape_eeprom1: cape_eeprom1@55 {
+	cape_eeprom1: eeprom@55 {
 		compatible = "atmel,24c256";
 		reg = <0x55>;
 
@@ -270,7 +266,7 @@
 		};
 	};
 
-	cape_eeprom2: cape_eeprom2@56 {
+	cape_eeprom2: eeprom@56 {
 		compatible = "atmel,24c256";
 		reg = <0x56>;
 
@@ -285,7 +281,7 @@
 		};
 	};
 
-	cape_eeprom3: cape_eeprom3@57 {
+	cape_eeprom3: eeprom@57 {
 		compatible = "atmel,24c256";
 		reg = <0x57>;
 
@@ -409,7 +405,7 @@
 		/* Support GPIO reset on revision C3 boards */
 		reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
 		reset-assert-us = <300>;
-		reset-deassert-us = <13000>;
+		reset-deassert-us = <50000>;
 	};
 };
 
@@ -442,3 +438,12 @@
 &wkup_m3_ipc {
 	firmware-name = "am335x-bone-scale-data.bin";
 };
+
+&tscadc {
+	adc {
+		ti,adc-channels = <0 1 2 3 4 5 6 7>;
+		ti,chan-step-avg = <16 16 16 16 16 16 16 16>;
+		ti,chan-step-opendelay = <0x98 0x98 0x98 0x98 0x98 0x98 0x98 0x98>;
+		ti,chan-step-sampledelay = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>;
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-bone-common-univ.dtsi b/arch/arm/boot/dts/ti/omap/am335x-bone-common-univ.dtsi
--- a/arch/arm/boot/dts/ti/omap/am335x-bone-common-univ.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/am335x-bone-common-univ.dtsi	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,2289 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <dt-bindings/board/am335x-bone-pins.h>
+
+&am33xx_pinmux {
+
+/* macro: BONE_PIN( <pin>, <mode_name>, <register_value_macro(s)> */
+#define BONE_PIN(XX,ZZ,QQ) \
+	XX##_##ZZ##_pin: pinmux_##XX##_##ZZ##_pin { pinctrl-single,pins = < QQ >; };
+
+	/************************/
+	/* P8 Header */
+	/************************/
+
+	/* P8_01                GND */
+
+	/* P8_02                GND */
+
+
+	/* P8_03 (ZCZ ball R9) gpmc_ad6 (emmc) */
+	BONE_PIN(P8_03, default, P8_03(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_03, gpio, P8_03(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_03, gpio_pu, P8_03(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_03, gpio_pd, P8_03(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_04 (ZCZ ball T9) gpmc_ad7 (emmc) */
+	BONE_PIN(P8_04, default, P8_04(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_04, gpio, P8_04(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_04, gpio_pu, P8_04(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_04, gpio_pd, P8_04(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_05 (ZCZ ball R8) gpmc_ad2 (emmc) */
+	BONE_PIN(P8_05, default, P8_05(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_05, gpio, P8_05(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_05, gpio_pu, P8_05(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_05, gpio_pd, P8_05(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_06 (ZCZ ball T8) gpmc_ad3 (emmc) */
+	BONE_PIN(P8_06, default, P8_06(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_06, gpio, P8_06(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_06, gpio_pu, P8_06(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_06, gpio_pd, P8_06(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_07 (ZCZ ball R7) gpmc_advn_ale (gpio2_2) */
+	BONE_PIN(P8_07, default, P8_07(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_07, gpio, P8_07(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_07, gpio_pu, P8_07(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_07, gpio_pd, P8_07(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_07, timer, P8_07(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_08 (ZCZ ball T7) gpmc_oen_ren (gpio2_3) */
+	BONE_PIN(P8_08, default, P8_08(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_08, gpio, P8_08(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_08, gpio_pu, P8_08(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_08, gpio_pd, P8_08(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_08, timer, P8_08(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_09 (ZCZ ball T6) gpmc_be0n_cle (gpio2_5) */
+	BONE_PIN(P8_09, default, P8_09(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_09, gpio, P8_09(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_09, gpio_pu, P8_09(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_09, gpio_pd, P8_09(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_09, timer, P8_09(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_10 (ZCZ ball U6) gpmc_wen (gpio2_4) */
+	BONE_PIN(P8_10, default, P8_10(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_10, gpio, P8_10(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_10, gpio_pu, P8_10(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_10, gpio_pd, P8_10(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_10, timer, P8_10(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_11 (ZCZ ball R12) gpmc_ad13 (gpio1_13) */
+	BONE_PIN(P8_11, default, P8_11(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_11, gpio, P8_11(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_11, gpio_pu, P8_11(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_11, gpio_pd, P8_11(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_11, eqep, P8_11(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P8_11, pruout, P8_11(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE6))
+
+	/* P8_12 (ZCZ ball T12) gpmc_ad12 (gpio1_12) */
+	BONE_PIN(P8_12, default, P8_12(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_12, gpio, P8_12(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_12, gpio_pu, P8_12(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_12, gpio_pd, P8_12(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_12, eqep, P8_12(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P8_12, pruout, P8_12(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE6))
+
+	/* P8_13 (ZCZ ball T10) gpmc_ad9 (gpio0_23) */
+	BONE_PIN(P8_13, default, P8_13(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_13, gpio, P8_13(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_13, gpio_pu, P8_13(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_13, gpio_pd, P8_13(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_13, pwm, P8_13(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE4))
+
+	/* P8_14 (ZCZ ball T11) gpmc_ad10 (gpio0_26) */
+	BONE_PIN(P8_14, default, P8_14(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_14, gpio, P8_14(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_14, gpio_pu, P8_14(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_14, gpio_pd, P8_14(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_14, pwm, P8_14(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE4))
+
+	/* P8_15 (ZCZ ball U13) gpmc_ad15 (gpio1_15) */
+	BONE_PIN(P8_15, default, P8_15(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_15, gpio, P8_15(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_15, gpio_pu, P8_15(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_15, gpio_pd, P8_15(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_15, eqep, P8_15(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P8_15, pru_ecap_pwm, P8_15(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_15, pruin, P8_15(PIN_INPUT | MUX_MODE6))
+
+	/* P8_16 (ZCZ ball V13) gpmc_ad14 (gpio1_14) */
+	BONE_PIN(P8_16, default, P8_16(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_16, gpio, P8_16(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_16, gpio_pu, P8_16(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_16, gpio_pd, P8_16(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_16, eqep, P8_16(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P8_16, pruin, P8_16(PIN_INPUT | MUX_MODE6))
+
+	/* P8_17 (ZCZ ball U12) gpmc_ad11 (gpio0_27) */
+	BONE_PIN(P8_17, default, P8_17(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_17, gpio, P8_17(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_17, gpio_pu, P8_17(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_17, gpio_pd, P8_17(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_17, pwm, P8_17(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE4))
+
+	/* P8_18 (ZCZ ball V12) gpmc_clk (gpio2_1) */
+	BONE_PIN(P8_18, default, P8_18(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_18, gpio, P8_18(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_18, gpio_pu, P8_18(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_18, gpio_pd, P8_18(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_19 (ZCZ ball U10) gpmc_ad8 (gpio0_22) */
+	BONE_PIN(P8_19, default, P8_19(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_19, gpio, P8_19(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_19, gpio_pu, P8_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_19, gpio_pd, P8_19(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_19, pwm, P8_19(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE4))
+
+	/* P8_20 (ZCZ ball V9) gpmc_csn2 (emmc) */
+	BONE_PIN(P8_20, default, P8_20(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_20, gpio, P8_20(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_20, gpio_pu, P8_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_20, gpio_pd, P8_20(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_20, pruout, P8_20(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_20, pruin, P8_20(PIN_INPUT | MUX_MODE6))
+
+	/* P8_21 (ZCZ ball U9) gpmc_csn1 (emmc) */
+	BONE_PIN(P8_21, default, P8_21(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_21, gpio, P8_21(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_21, gpio_pu, P8_21(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_21, gpio_pd, P8_21(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_21, pruout, P8_21(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_21, pruin, P8_21(PIN_INPUT | MUX_MODE6))
+
+	/* P8_22 (ZCZ ball V8) gpmc_ad5 (emmc) */
+	BONE_PIN(P8_22, default, P8_22(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_22, gpio, P8_22(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_22, gpio_pu, P8_22(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_22, gpio_pd, P8_22(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_23 (ZCZ ball U8) gpmc_ad4 (emmc) */
+	BONE_PIN(P8_23, default, P8_23(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_23, gpio, P8_23(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_23, gpio_pu, P8_23(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_23, gpio_pd, P8_23(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_24 (ZCZ ball V7) gpmc_ad1 (emmc) */
+	BONE_PIN(P8_24, default, P8_24(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_24, gpio, P8_24(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_24, gpio_pu, P8_24(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_24, gpio_pd, P8_24(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_25 (ZCZ ball U7) gpmc_ad0 (emmc) */
+	BONE_PIN(P8_25, default, P8_25(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_25, gpio, P8_25(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_25, gpio_pu, P8_25(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_25, gpio_pd, P8_25(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_26 (ZCZ ball V6) gpmc_csn0 (gpio1_29) */
+	BONE_PIN(P8_26, default, P8_26(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_26, gpio, P8_26(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_26, gpio_pu, P8_26(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_26, gpio_pd, P8_26(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_27 (ZCZ ball U5) lcd_vsync (hdmi) */
+	BONE_PIN(P8_27, default, P8_27(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_27, gpio, P8_27(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_27, gpio_pu, P8_27(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_27, gpio_pd, P8_27(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_27, pruout, P8_27(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_27, pruin, P8_27(PIN_INPUT | MUX_MODE6))
+
+	/* P8_28 (ZCZ ball V5) lcd_pclk (hdmi) */
+	BONE_PIN(P8_28, default, P8_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_28, gpio, P8_28(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_28, gpio_pu, P8_28(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_28, gpio_pd, P8_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_28, pruout, P8_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_28, pruin, P8_28(PIN_INPUT | MUX_MODE6))
+
+	/* P8_29 (ZCZ ball R5) lcd_hsync (hdmi) */
+	BONE_PIN(P8_29, default, P8_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_29, gpio, P8_29(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_29, gpio_pu, P8_29(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_29, gpio_pd, P8_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_29, pruout, P8_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_29, pruin, P8_29(PIN_INPUT | MUX_MODE6))
+
+	/* P8_30 (ZCZ ball R6) lcd_ac_bias_en (hdmi) */
+	BONE_PIN(P8_30, default, P8_30(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_30, gpio, P8_30(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_30, gpio_pu, P8_30(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_30, gpio_pd, P8_30(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_30, pruout, P8_30(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_30, pruin, P8_30(PIN_INPUT | MUX_MODE6))
+
+	/* P8_31 (ZCZ ball V4) lcd_data14 (hdmi) */
+	BONE_PIN(P8_31, default, P8_31(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_31, gpio, P8_31(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_31, gpio_pu, P8_31(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_31, gpio_pd, P8_31(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_31, eqep, P8_31(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P8_31, uart, P8_31(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P8_32 (ZCZ ball T5) lcd_data15 (hdmi) */
+	BONE_PIN(P8_32, default, P8_32(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_32, gpio, P8_32(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_32, gpio_pu, P8_32(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_32, gpio_pd, P8_32(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_32, eqep, P8_32(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_33 (ZCZ ball V3) lcd_data13 (hdmi) */
+	BONE_PIN(P8_33, default, P8_33(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_33, gpio, P8_33(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_33, gpio_pu, P8_33(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_33, gpio_pd, P8_33(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_33, eqep, P8_33(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_34 (ZCZ ball U4) lcd_data11 (hdmi) */
+	BONE_PIN(P8_34, default, P8_34(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_34, gpio, P8_34(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_34, gpio_pu, P8_34(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_34, gpio_pd, P8_34(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_34, pwm, P8_34(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE2))
+
+	/* P8_35 (ZCZ ball V2) lcd_data12 (hdmi) */
+	BONE_PIN(P8_35, default, P8_35(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_35, gpio, P8_35(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_35, gpio_pu, P8_35(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_35, gpio_pd, P8_35(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_35, eqep, P8_35(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_36 (ZCZ ball U3) lcd_data10 (hdmi) */
+	BONE_PIN(P8_36, default, P8_36(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_36, gpio, P8_36(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_36, gpio_pu, P8_36(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_36, gpio_pd, P8_36(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_36, pwm, P8_36(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE2))
+
+	/* P8_37 (ZCZ ball U1) lcd_data8 (hdmi) */
+	BONE_PIN(P8_37, default, P8_37(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_37, gpio, P8_37(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_37, gpio_pu, P8_37(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_37, gpio_pd, P8_37(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_37, pwm, P8_37(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P8_37, uart, P8_37(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P8_38 (ZCZ ball U2) lcd_data9 (hdmi) */
+	BONE_PIN(P8_38, default, P8_38(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_38, gpio, P8_38(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_38, gpio_pu, P8_38(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_38, gpio_pd, P8_38(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_38, pwm, P8_38(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P8_38, uart, P8_38(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P8_39 (ZCZ ball T3) lcd_data6 (hdmi) */
+	BONE_PIN(P8_39, default, P8_39(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_39, gpio, P8_39(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_39, gpio_pu, P8_39(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_39, gpio_pd, P8_39(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_39, eqep, P8_39(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_39, pruout, P8_39(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_39, pruin, P8_39(PIN_INPUT | MUX_MODE6))
+
+	/* P8_40 (ZCZ ball T4) lcd_data7 (hdmi) */
+	BONE_PIN(P8_40, default, P8_40(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_40, gpio, P8_40(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_40, gpio_pu, P8_40(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_40, gpio_pd, P8_40(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_40, eqep, P8_40(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_40, pruout, P8_40(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_40, pruin, P8_40(PIN_INPUT | MUX_MODE6))
+
+	/* P8_41 (ZCZ ball T1) lcd_data4 (hdmi) */
+	BONE_PIN(P8_41, default, P8_41(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_41, gpio, P8_41(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_41, gpio_pu, P8_41(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_41, gpio_pd, P8_41(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_41, eqep, P8_41(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_41, pruout, P8_41(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_41, pruin, P8_41(PIN_INPUT | MUX_MODE6))
+
+	/* P8_42 (ZCZ ball T2) lcd_data5 (hdmi) */
+	BONE_PIN(P8_42, default, P8_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_42, gpio, P8_42(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_42, gpio_pu, P8_42(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_42, gpio_pd, P8_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_42, eqep, P8_42(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_42, pruout, P8_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_42, pruin, P8_42(PIN_INPUT | MUX_MODE6))
+
+	/* P8_43 (ZCZ ball R3) lcd_data2 (hdmi) */
+	BONE_PIN(P8_43, default, P8_43(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_43, gpio, P8_43(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_43, gpio_pu, P8_43(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_43, gpio_pd, P8_43(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_43, pwm, P8_43(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_43, pruout, P8_43(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_43, pruin, P8_43(PIN_INPUT | MUX_MODE6))
+
+	/* P8_44 (ZCZ ball R4) lcd_data3 (hdmi) */
+	BONE_PIN(P8_44, default, P8_44(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_44, gpio, P8_44(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_44, gpio_pu, P8_44(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_44, gpio_pd, P8_44(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_44, pwm, P8_44(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_44, pruout, P8_44(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_44, pruin, P8_44(PIN_INPUT | MUX_MODE6))
+
+	/* P8_45 (ZCZ ball R1) lcd_data0 (hdmi) */
+	BONE_PIN(P8_45, default, P8_45(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_45, gpio, P8_45(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_45, gpio_pu, P8_45(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_45, gpio_pd, P8_45(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_45, pwm, P8_45(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_45, pruout, P8_45(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_45, pruin, P8_45(PIN_INPUT | MUX_MODE6))
+
+	/* P8_46 (ZCZ ball R2) lcd_data1 (hdmi) */
+	BONE_PIN(P8_46, default, P8_46(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_46, gpio, P8_46(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_46, gpio_pu, P8_46(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_46, gpio_pd, P8_46(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_46, pwm, P8_46(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_46, pruout, P8_46(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_46, pruin, P8_46(PIN_INPUT | MUX_MODE6))
+
+	/************************/
+	/* P9 Header */
+	/************************/
+
+	/* P9_01                GND */
+
+	/* P9_02                GND */
+
+	/* P9_03                3V3 */
+
+	/* P9_04                3V3 */
+
+	/* P9_05                VDD_5V */
+
+	/* P9_06                VDD_5V */
+
+	/* P9_07                SYS_5V */
+
+	/* P9_08                SYS_5V */
+
+	/* P9_09                PWR_BUT */
+
+	/* P9_10                RSTn */
+
+	/* P9_11 (ZCZ ball T17) gpmc_wait0 (gpio0_30) */
+	BONE_PIN(P9_11, default, P9_11(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_11, gpio, P9_11(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_11, gpio_pu, P9_11(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_11, gpio_pd, P9_11(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_11, uart, P9_11(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE6))
+
+	/* P9_12 (ZCZ ball U18) gpmc_be1n (gpio1_28) */
+	BONE_PIN(P9_12, default, P9_12(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_12, gpio, P9_12(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_12, gpio_pu, P9_12(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_12, gpio_pd, P9_12(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P9_13 (ZCZ ball U17) gpmc_wpn (gpio0_31) */
+	BONE_PIN(P9_13, default, P9_13(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_13, gpio, P9_13(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_13, gpio_pu, P9_13(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_13, gpio_pd, P9_13(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_13, uart, P9_13(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE6))
+
+	/* P9_14 (ZCZ ball U14) gpmc_a2 (gpio1_18) */
+	BONE_PIN(P9_14, default, P9_14(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_14, gpio, P9_14(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_14, gpio_pu, P9_14(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_14, gpio_pd, P9_14(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_14, pwm, P9_14(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE6))
+
+	/* P9_15 (ZCZ ball R13) gpmc_a0 (gpio1_16) */
+	BONE_PIN(P9_15, default, P9_15(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_15, gpio, P9_15(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_15, gpio_pu, P9_15(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_15, gpio_pd, P9_15(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_15, pwm, P9_15(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE6))
+
+	/* P9_16 (ZCZ ball T14) gpmc_a3 (gpio1_19) */
+	BONE_PIN(P9_16, default, P9_16(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_16, gpio, P9_16(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_16, gpio_pu, P9_16(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_16, gpio_pd, P9_16(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_16, pwm, P9_16(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE6))
+
+	/* P9_17 (ZCZ ball A16) spi0_cs0 (gpio0_5) */
+	BONE_PIN(P9_17, default, P9_17(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_17, gpio, P9_17(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_17, gpio_pu, P9_17(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_17, gpio_pd, P9_17(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_17, spi_cs, P9_17(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE0))
+	BONE_PIN(P9_17, i2c, P9_17(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P9_17, pwm, P9_17(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_17, pru_uart, P9_17(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P9_18 (ZCZ ball B16) spi0_d1 (gpio0_4) */
+	BONE_PIN(P9_18, default, P9_18(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_18, gpio, P9_18(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_18, gpio_pu, P9_18(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_18, gpio_pd, P9_18(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_18, spi, P9_18(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE0))
+	BONE_PIN(P9_18, i2c, P9_18(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P9_18, pwm, P9_18(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_18, pru_uart, P9_18(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P9_19 (ZCZ ball D17) uart1_rtsn (i2c2_scl) */
+	BONE_PIN(P9_19, default, P9_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_19, gpio, P9_19(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_19, gpio_pu, P9_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_19, gpio_pd, P9_19(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_19, timer, P9_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_19, can, P9_19(PIN_INPUT_PULLUP | MUX_MODE2))
+	BONE_PIN(P9_19, i2c, P9_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_19, spi_cs, P9_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P9_19, pru_uart, P9_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE5))
+
+	/* P9_20 (ZCZ ball D18) uart1_ctsn (i2c2_sda) */
+	BONE_PIN(P9_20, default, P9_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_20, gpio, P9_20(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_20, gpio_pu, P9_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_20, gpio_pd, P9_20(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_20, timer, P9_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_20, can, P9_20(PIN_OUTPUT_PULLUP | MUX_MODE2))
+	BONE_PIN(P9_20, i2c, P9_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_20, spi_cs, P9_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P9_20, pru_uart, P9_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE5))
+
+	/* P9_21 (ZCZ ball B17) spi0_d0 (gpio0_3) */
+	BONE_PIN(P9_21, default, P9_21(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_21, gpio, P9_21(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_21, gpio_pu, P9_21(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_21, gpio_pd, P9_21(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_21, spi, P9_21(PIN_INPUT_PULLUP | MUX_MODE0))
+	BONE_PIN(P9_21, uart, P9_21(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_21, i2c, P9_21(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P9_21, pwm, P9_21(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_21, pru_uart, P9_21(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P9_22 (ZCZ ball A17) spi0_sclk (gpio0_2) */
+	BONE_PIN(P9_22, default, P9_22(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_22, gpio, P9_22(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_22, gpio_pu, P9_22(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_22, gpio_pd, P9_22(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_22, spi_sclk, P9_22(PIN_INPUT_PULLUP | MUX_MODE0))
+	BONE_PIN(P9_22, uart, P9_22(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_22, i2c, P9_22(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P9_22, pwm, P9_22(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_22, pru_uart, P9_22(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P9_23 (ZCZ ball V14) gpmc_a1 (gpio1_17) */
+	BONE_PIN(P9_23, default, P9_23(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_23, gpio, P9_23(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_23, gpio_pu, P9_23(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_23, gpio_pd, P9_23(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_23, pwm, P9_23(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE6))
+
+	/* P9_24 (ZCZ ball D15) uart1_txd (gpio0_15) */
+	BONE_PIN(P9_24, default, P9_24(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_24, gpio, P9_24(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_24, gpio_pu, P9_24(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_24, gpio_pd, P9_24(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_24, uart, P9_24(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE0))
+	BONE_PIN(P9_24, can, P9_24(PIN_INPUT_PULLUP | MUX_MODE2))
+	BONE_PIN(P9_24, i2c, P9_24(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_24, pru_uart, P9_24(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_24, pruin, P9_24(PIN_INPUT | MUX_MODE6))
+
+	/* P9_25 (ZCZ ball A14) mcasp0_ahclkx (audio) */
+	BONE_PIN(P9_25, default, P9_25(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_25, gpio, P9_25(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_25, gpio_pu, P9_25(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_25, gpio_pd, P9_25(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_25, eqep, P9_25(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_25, pruout, P9_25(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_25, pruin, P9_25(PIN_INPUT | MUX_MODE6))
+
+	/* P9_26 (ZCZ ball D16) uart1_rxd (gpio0_14) */
+	BONE_PIN(P9_26, default, P9_26(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_26, gpio, P9_26(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_26, gpio_pu, P9_26(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_26, gpio_pd, P9_26(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_26, uart, P9_26(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE0))
+	BONE_PIN(P9_26, can, P9_26(PIN_OUTPUT_PULLUP | MUX_MODE2))
+	BONE_PIN(P9_26, i2c, P9_26(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_26, pru_uart, P9_26(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_26, pruin, P9_26(PIN_INPUT | MUX_MODE6))
+
+	/* P9_27 (ZCZ ball C13) mcasp0_fsr (gpio3_19) */
+	BONE_PIN(P9_27, default, P9_27(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_27, gpio, P9_27(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_27, gpio_pu, P9_27(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_27, gpio_pd, P9_27(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_27, eqep, P9_27(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_27, pruout, P9_27(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_27, pruin, P9_27(PIN_INPUT | MUX_MODE6))
+
+	/* P9_28 (ZCZ ball C12) mcasp0_ahclkr (audio) */
+	BONE_PIN(P9_28, default, P9_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_28, gpio, P9_28(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_28, gpio_pu, P9_28(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_28, gpio_pd, P9_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_28, pwm, P9_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_28, spi_cs, P9_28(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_28, pwm2, P9_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P9_28, pruout, P9_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_28, pruin, P9_28(PIN_INPUT | MUX_MODE6))
+
+	/* P9_29 (ZCZ ball B13) mcasp0_fsx (audio) */
+	BONE_PIN(P9_29, default, P9_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_29, gpio, P9_29(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_29, gpio_pu, P9_29(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_29, gpio_pd, P9_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_29, pwm, P9_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_29, spi, P9_29(PIN_INPUT_PULLUP | MUX_MODE3))
+	BONE_PIN(P9_29, pruout, P9_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_29, pruin, P9_29(PIN_INPUT | MUX_MODE6))
+
+	/* P9_30 (ZCZ ball D12) mcasp0_axr0 (gpio3_16) */
+	BONE_PIN(P9_30, default, P9_30(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_30, gpio, P9_30(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_30, gpio_pu, P9_30(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_30, gpio_pd, P9_30(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_30, pwm, P9_30(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_30, spi, P9_30(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_30, pruout, P9_30(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_30, pruin, P9_30(PIN_INPUT | MUX_MODE6))
+
+	/* P9_31 (ZCZ ball A13) mcasp0_aclkx (audio) */
+	BONE_PIN(P9_31, default, P9_31(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_31, gpio, P9_31(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_31, gpio_pu, P9_31(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_31, gpio_pd, P9_31(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_31, pwm, P9_31(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_31, spi_sclk, P9_31(PIN_INPUT_PULLUP | MUX_MODE3))
+	BONE_PIN(P9_31, pruout, P9_31(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_31, pruin, P9_31(PIN_INPUT | MUX_MODE6))
+
+	/* P9_32                VADC */
+
+	/* P9_33 (ZCZ ball C8)  AIN4 */
+
+	/* P9_34                AGND */
+
+	/* P9_35 (ZCZ ball A8)  AIN6 */
+
+	/* P9_36 (ZCZ ball B8)  AIN5 */
+
+	/* P9_37 (ZCZ ball B7)  AIN2 */
+
+	/* P9_38 (ZCZ ball A7)  AIN3 */
+
+	/* P9_39 (ZCZ ball B6)  AIN0 */
+
+	/* P9_40 (ZCZ ball C7)  AIN1 */
+
+	/* P9_41 (ZCZ ball D14) xdma_event_intr1 (gpio0_20) */
+	BONE_PIN(P9_41, default, P9_41(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_41, gpio, P9_41(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_41, gpio_pu, P9_41(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_41, gpio_pd, P9_41(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_41, timer, P9_41(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P9_41, pruin, P9_41(PIN_INPUT | MUX_MODE5))
+
+	/* P9_41.1 */
+	/* P9_91 (ZCZ ball D13) mcasp0_axr1 (gpio3_20) */
+	BONE_PIN(P9_91, default, P9_91(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_91, gpio, P9_91(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_91, gpio_pu, P9_91(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_91, gpio_pd, P9_91(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_91, eqep, P9_91(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_91, pruout, P9_91(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_91, pruin, P9_91(PIN_INPUT | MUX_MODE6))
+
+	/* P9_42 (ZCZ ball C18) eCAP0_in_PWM0_out (gpio0_7) */
+	BONE_PIN(P9_42, default, P9_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_42, gpio, P9_42(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_42, gpio_pu, P9_42(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_42, gpio_pd, P9_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_42, pwm, P9_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE0))
+	BONE_PIN(P9_42, uart, P9_42(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_42, spi_cs, P9_42(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P9_42, pru_ecap_pwm, P9_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_42, spi_sclk, P9_42(PIN_INPUT_PULLUP | MUX_MODE4))
+
+	/* P9_42.1 */
+	/* P9_92 (ZCZ ball B12) mcasp0_aclkr (gpio3_18) */
+	BONE_PIN(P9_92, default, P9_92(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_92, gpio, P9_92(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_92, gpio_pu, P9_92(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_92, gpio_pd, P9_92(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_92, eqep, P9_92(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_92, pruout, P9_92(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_92, pruin, P9_92(PIN_INPUT | MUX_MODE6))
+
+	/* P9_43                GND */
+
+	/* P9_44                GND */
+
+	/* P9_45                GND */
+
+	/* P9_46                GND */
+};
+
+&i2c1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+
+	clock-frequency = <100000>;
+	symlink = "bone/i2c/1";
+};
+
+&i2c2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+
+	clock-frequency = <100000>;
+	symlink = "bone/i2c/2";
+};
+
+&uart1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/uart/1";
+};
+
+&uart2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/uart/2";
+};
+
+&uart3 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/uart/3";
+};
+
+&uart4 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/uart/4";
+};
+
+&uart5 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/uart/5";
+};
+
+&dcan0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/can/0";
+};
+
+&dcan1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/can/1";
+};
+
+&eqep0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/eqep/0";
+};
+
+&eqep1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/eqep/1";
+};
+
+&eqep2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/eqep/2";
+};
+
+&epwmss0 {
+	status = "okay";
+};
+
+&epwmss1 {
+	status = "okay";
+};
+
+&epwmss2 {
+	status = "okay";
+};
+
+&ehrpwm0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
+&ehrpwm1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
+&ehrpwm2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
+&ecap0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
+&ecap1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
+&ecap2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
+&spi0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+
+	channel@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "rohm,dh2228fv";
+		symlink = "bone/spi/0.0";
+
+		reg = <0>;
+		spi-max-frequency = <16000000>;
+		spi-cpha;
+	};
+
+	channel@1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "rohm,dh2228fv";
+		symlink = "bone/spi/0.1";
+
+		reg = <1>;
+		spi-max-frequency = <16000000>;
+	};
+};
+
+&spi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+
+	channel@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "rohm,dh2228fv";
+		symlink = "bone/spi/1.0";
+
+		reg = <0>;
+		spi-max-frequency = <16000000>;
+		spi-cpha;
+	};
+
+	channel@1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "rohm,dh2228fv";
+		symlink = "bone/spi/1.1";
+
+		reg = <1>;
+		spi-max-frequency = <16000000>;
+	};
+};
+
+/**********************************************************************/
+/* Pin Multiplex Helpers                                              */
+/*                                                                    */
+/* These provide userspace runtime pin configuration for the          */
+/* BeagleBone cape expansion headers                                  */
+/**********************************************************************/
+
+&ocp {
+	/************************/
+	/* P8 Header */
+	/************************/
+
+	/* P8_01                GND */
+
+	/* P8_02                GND */
+
+
+	/* P8_03 (ZCZ ball R9) emmc */
+	P8_03_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_03_default_pin>;
+		pinctrl-1 = <&P8_03_gpio_pin>;
+		pinctrl-2 = <&P8_03_gpio_pu_pin>;
+		pinctrl-3 = <&P8_03_gpio_pd_pin>;
+	};
+
+	/* P8_04 (ZCZ ball T9) emmc */
+	P8_04_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_04_default_pin>;
+		pinctrl-1 = <&P8_04_gpio_pin>;
+		pinctrl-2 = <&P8_04_gpio_pu_pin>;
+		pinctrl-3 = <&P8_04_gpio_pd_pin>;
+	};
+
+	/* P8_05 (ZCZ ball R8) emmc */
+	P8_05_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_05_default_pin>;
+		pinctrl-1 = <&P8_05_gpio_pin>;
+		pinctrl-2 = <&P8_05_gpio_pu_pin>;
+		pinctrl-3 = <&P8_05_gpio_pd_pin>;
+	};
+
+	/* P8_06 (ZCZ ball T8) emmc */
+	P8_06_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_06_default_pin>;
+		pinctrl-1 = <&P8_06_gpio_pin>;
+		pinctrl-2 = <&P8_06_gpio_pu_pin>;
+		pinctrl-3 = <&P8_06_gpio_pd_pin>;
+	};
+
+	/* P8_07 (ZCZ ball R7) */
+	P8_07_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer";
+		pinctrl-0 = <&P8_07_default_pin>;
+		pinctrl-1 = <&P8_07_gpio_pin>;
+		pinctrl-2 = <&P8_07_gpio_pu_pin>;
+		pinctrl-3 = <&P8_07_gpio_pd_pin>;
+		pinctrl-4 = <&P8_07_timer_pin>;
+	};
+
+	/* P8_08 (ZCZ ball T7) */
+	P8_08_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer";
+		pinctrl-0 = <&P8_08_default_pin>;
+		pinctrl-1 = <&P8_08_gpio_pin>;
+		pinctrl-2 = <&P8_08_gpio_pu_pin>;
+		pinctrl-3 = <&P8_08_gpio_pd_pin>;
+		pinctrl-4 = <&P8_08_timer_pin>;
+	};
+
+	/* P8_09 (ZCZ ball T6) */
+	P8_09_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer";
+		pinctrl-0 = <&P8_09_default_pin>;
+		pinctrl-1 = <&P8_09_gpio_pin>;
+		pinctrl-2 = <&P8_09_gpio_pu_pin>;
+		pinctrl-3 = <&P8_09_gpio_pd_pin>;
+		pinctrl-4 = <&P8_09_timer_pin>;
+	};
+
+	/* P8_10 (ZCZ ball U6) */
+	P8_10_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer";
+		pinctrl-0 = <&P8_10_default_pin>;
+		pinctrl-1 = <&P8_10_gpio_pin>;
+		pinctrl-2 = <&P8_10_gpio_pu_pin>;
+		pinctrl-3 = <&P8_10_gpio_pd_pin>;
+		pinctrl-4 = <&P8_10_timer_pin>;
+	};
+
+	/* P8_11 (ZCZ ball R12) */
+	P8_11_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout";
+		pinctrl-0 = <&P8_11_default_pin>;
+		pinctrl-1 = <&P8_11_gpio_pin>;
+		pinctrl-2 = <&P8_11_gpio_pu_pin>;
+		pinctrl-3 = <&P8_11_gpio_pd_pin>;
+		pinctrl-4 = <&P8_11_eqep_pin>;
+		pinctrl-5 = <&P8_11_pruout_pin>;
+	};
+
+	/* P8_12 (ZCZ ball T12) */
+	P8_12_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout";
+		pinctrl-0 = <&P8_12_default_pin>;
+		pinctrl-1 = <&P8_12_gpio_pin>;
+		pinctrl-2 = <&P8_12_gpio_pu_pin>;
+		pinctrl-3 = <&P8_12_gpio_pd_pin>;
+		pinctrl-4 = <&P8_12_eqep_pin>;
+		pinctrl-5 = <&P8_12_pruout_pin>;
+	};
+
+	/* P8_13 (ZCZ ball T10) */
+	P8_13_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P8_13_default_pin>;
+		pinctrl-1 = <&P8_13_gpio_pin>;
+		pinctrl-2 = <&P8_13_gpio_pu_pin>;
+		pinctrl-3 = <&P8_13_gpio_pd_pin>;
+		pinctrl-4 = <&P8_13_pwm_pin>;
+	};
+
+	/* P8_14 (ZCZ ball T11) */
+	P8_14_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P8_14_default_pin>;
+		pinctrl-1 = <&P8_14_gpio_pin>;
+		pinctrl-2 = <&P8_14_gpio_pu_pin>;
+		pinctrl-3 = <&P8_14_gpio_pd_pin>;
+		pinctrl-4 = <&P8_14_pwm_pin>;
+	};
+
+	/* P8_15 (ZCZ ball U13) */
+	P8_15_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pru_ecap_pwm", "pruin";
+		pinctrl-0 = <&P8_15_default_pin>;
+		pinctrl-1 = <&P8_15_gpio_pin>;
+		pinctrl-2 = <&P8_15_gpio_pu_pin>;
+		pinctrl-3 = <&P8_15_gpio_pd_pin>;
+		pinctrl-4 = <&P8_15_eqep_pin>;
+		pinctrl-5 = <&P8_15_pru_ecap_pwm_pin>;
+		pinctrl-6 = <&P8_15_pruin_pin>;
+	};
+
+	/* P8_16 (ZCZ ball V13) */
+	P8_16_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruin";
+		pinctrl-0 = <&P8_16_default_pin>;
+		pinctrl-1 = <&P8_16_gpio_pin>;
+		pinctrl-2 = <&P8_16_gpio_pu_pin>;
+		pinctrl-3 = <&P8_16_gpio_pd_pin>;
+		pinctrl-4 = <&P8_16_eqep_pin>;
+		pinctrl-5 = <&P8_16_pruin_pin>;
+	};
+
+	/* P8_17 (ZCZ ball U12) */
+	P8_17_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P8_17_default_pin>;
+		pinctrl-1 = <&P8_17_gpio_pin>;
+		pinctrl-2 = <&P8_17_gpio_pu_pin>;
+		pinctrl-3 = <&P8_17_gpio_pd_pin>;
+		pinctrl-4 = <&P8_17_pwm_pin>;
+	};
+
+	/* P8_18 (ZCZ ball V12) */
+	P8_18_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_18_default_pin>;
+		pinctrl-1 = <&P8_18_gpio_pin>;
+		pinctrl-2 = <&P8_18_gpio_pu_pin>;
+		pinctrl-3 = <&P8_18_gpio_pd_pin>;
+	};
+
+	/* P8_19 (ZCZ ball U10) */
+	P8_19_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P8_19_default_pin>;
+		pinctrl-1 = <&P8_19_gpio_pin>;
+		pinctrl-2 = <&P8_19_gpio_pu_pin>;
+		pinctrl-3 = <&P8_19_gpio_pd_pin>;
+		pinctrl-4 = <&P8_19_pwm_pin>;
+	};
+
+	/* P8_20 (ZCZ ball V9) emmc */
+	P8_20_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin";
+		pinctrl-0 = <&P8_20_default_pin>;
+		pinctrl-1 = <&P8_20_gpio_pin>;
+		pinctrl-2 = <&P8_20_gpio_pu_pin>;
+		pinctrl-3 = <&P8_20_gpio_pd_pin>;
+		pinctrl-4 = <&P8_20_pruout_pin>;
+		pinctrl-5 = <&P8_20_pruin_pin>;
+	};
+
+	/* P8_21 (ZCZ ball U9) emmc */
+	P8_21_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin";
+		pinctrl-0 = <&P8_21_default_pin>;
+		pinctrl-1 = <&P8_21_gpio_pin>;
+		pinctrl-2 = <&P8_21_gpio_pu_pin>;
+		pinctrl-3 = <&P8_21_gpio_pd_pin>;
+		pinctrl-4 = <&P8_21_pruout_pin>;
+		pinctrl-5 = <&P8_21_pruin_pin>;
+	};
+
+	/* P8_22 (ZCZ ball V8) emmc */
+	P8_22_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_22_default_pin>;
+		pinctrl-1 = <&P8_22_gpio_pin>;
+		pinctrl-2 = <&P8_22_gpio_pu_pin>;
+		pinctrl-3 = <&P8_22_gpio_pd_pin>;
+	};
+
+	/* P8_23 (ZCZ ball U8) emmc */
+	P8_23_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_23_default_pin>;
+		pinctrl-1 = <&P8_23_gpio_pin>;
+		pinctrl-2 = <&P8_23_gpio_pu_pin>;
+		pinctrl-3 = <&P8_23_gpio_pd_pin>;
+	};
+
+	/* P8_24 (ZCZ ball V7) emmc */
+	P8_24_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_24_default_pin>;
+		pinctrl-1 = <&P8_24_gpio_pin>;
+		pinctrl-2 = <&P8_24_gpio_pu_pin>;
+		pinctrl-3 = <&P8_24_gpio_pd_pin>;
+	};
+
+	/* P8_25 (ZCZ ball U7) emmc */
+	P8_25_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_25_default_pin>;
+		pinctrl-1 = <&P8_25_gpio_pin>;
+		pinctrl-2 = <&P8_25_gpio_pu_pin>;
+		pinctrl-3 = <&P8_25_gpio_pd_pin>;
+	};
+
+	/* P8_26 (ZCZ ball V6) */
+	P8_26_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_26_default_pin>;
+		pinctrl-1 = <&P8_26_gpio_pin>;
+		pinctrl-2 = <&P8_26_gpio_pu_pin>;
+		pinctrl-3 = <&P8_26_gpio_pd_pin>;
+	};
+
+	/* P8_27 (ZCZ ball U5) hdmi */
+	P8_27_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin";
+		pinctrl-0 = <&P8_27_default_pin>;
+		pinctrl-1 = <&P8_27_gpio_pin>;
+		pinctrl-2 = <&P8_27_gpio_pu_pin>;
+		pinctrl-3 = <&P8_27_gpio_pd_pin>;
+		pinctrl-4 = <&P8_27_pruout_pin>;
+		pinctrl-5 = <&P8_27_pruin_pin>;
+	};
+
+	/* P8_28 (ZCZ ball V5) hdmi */
+	P8_28_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin";
+		pinctrl-0 = <&P8_28_default_pin>;
+		pinctrl-1 = <&P8_28_gpio_pin>;
+		pinctrl-2 = <&P8_28_gpio_pu_pin>;
+		pinctrl-3 = <&P8_28_gpio_pd_pin>;
+		pinctrl-4 = <&P8_28_pruout_pin>;
+		pinctrl-5 = <&P8_28_pruin_pin>;
+	};
+
+	/* P8_29 (ZCZ ball R5) hdmi */
+	P8_29_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin";
+		pinctrl-0 = <&P8_29_default_pin>;
+		pinctrl-1 = <&P8_29_gpio_pin>;
+		pinctrl-2 = <&P8_29_gpio_pu_pin>;
+		pinctrl-3 = <&P8_29_gpio_pd_pin>;
+		pinctrl-4 = <&P8_29_pruout_pin>;
+		pinctrl-5 = <&P8_29_pruin_pin>;
+	};
+
+	/* P8_30 (ZCZ ball R6) hdmi */
+	P8_30_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin";
+		pinctrl-0 = <&P8_30_default_pin>;
+		pinctrl-1 = <&P8_30_gpio_pin>;
+		pinctrl-2 = <&P8_30_gpio_pu_pin>;
+		pinctrl-3 = <&P8_30_gpio_pd_pin>;
+		pinctrl-4 = <&P8_30_pruout_pin>;
+		pinctrl-5 = <&P8_30_pruin_pin>;
+	};
+
+	/* P8_31 (ZCZ ball V4) hdmi */
+	P8_31_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "eqep";
+		pinctrl-0 = <&P8_31_default_pin>;
+		pinctrl-1 = <&P8_31_gpio_pin>;
+		pinctrl-2 = <&P8_31_gpio_pu_pin>;
+		pinctrl-3 = <&P8_31_gpio_pd_pin>;
+		pinctrl-4 = <&P8_31_uart_pin>;
+		pinctrl-5 = <&P8_31_eqep_pin>;
+	};
+
+	/* P8_32 (ZCZ ball T5) hdmi */
+	P8_32_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep";
+		pinctrl-0 = <&P8_32_default_pin>;
+		pinctrl-1 = <&P8_32_gpio_pin>;
+		pinctrl-2 = <&P8_32_gpio_pu_pin>;
+		pinctrl-3 = <&P8_32_gpio_pd_pin>;
+		pinctrl-4 = <&P8_32_eqep_pin>;
+	};
+
+	/* P8_33 (ZCZ ball V3) hdmi */
+	P8_33_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep";
+		pinctrl-0 = <&P8_33_default_pin>;
+		pinctrl-1 = <&P8_33_gpio_pin>;
+		pinctrl-2 = <&P8_33_gpio_pu_pin>;
+		pinctrl-3 = <&P8_33_gpio_pd_pin>;
+		pinctrl-4 = <&P8_33_eqep_pin>;
+	};
+
+	/* P8_34 (ZCZ ball U4) hdmi */
+	P8_34_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P8_34_default_pin>;
+		pinctrl-1 = <&P8_34_gpio_pin>;
+		pinctrl-2 = <&P8_34_gpio_pu_pin>;
+		pinctrl-3 = <&P8_34_gpio_pd_pin>;
+		pinctrl-4 = <&P8_34_pwm_pin>;
+	};
+
+	/* P8_35 (ZCZ ball V2) hdmi */
+	P8_35_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep";
+		pinctrl-0 = <&P8_35_default_pin>;
+		pinctrl-1 = <&P8_35_gpio_pin>;
+		pinctrl-2 = <&P8_35_gpio_pu_pin>;
+		pinctrl-3 = <&P8_35_gpio_pd_pin>;
+		pinctrl-4 = <&P8_35_eqep_pin>;
+	};
+
+	/* P8_36 (ZCZ ball U3) hdmi */
+	P8_36_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P8_36_default_pin>;
+		pinctrl-1 = <&P8_36_gpio_pin>;
+		pinctrl-2 = <&P8_36_gpio_pu_pin>;
+		pinctrl-3 = <&P8_36_gpio_pd_pin>;
+		pinctrl-4 = <&P8_36_pwm_pin>;
+	};
+
+	/* P8_37 (ZCZ ball U1) hdmi */
+	P8_37_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "pwm";
+		pinctrl-0 = <&P8_37_default_pin>;
+		pinctrl-1 = <&P8_37_gpio_pin>;
+		pinctrl-2 = <&P8_37_gpio_pu_pin>;
+		pinctrl-3 = <&P8_37_gpio_pd_pin>;
+		pinctrl-4 = <&P8_37_uart_pin>;
+		pinctrl-5 = <&P8_37_pwm_pin>;
+	};
+
+	/* P8_38 (ZCZ ball U2) hdmi */
+	P8_38_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "pwm";
+		pinctrl-0 = <&P8_38_default_pin>;
+		pinctrl-1 = <&P8_38_gpio_pin>;
+		pinctrl-2 = <&P8_38_gpio_pu_pin>;
+		pinctrl-3 = <&P8_38_gpio_pd_pin>;
+		pinctrl-4 = <&P8_38_uart_pin>;
+		pinctrl-5 = <&P8_38_pwm_pin>;
+	};
+
+	/* P8_39 (ZCZ ball T3) hdmi */
+	P8_39_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P8_39_default_pin>;
+		pinctrl-1 = <&P8_39_gpio_pin>;
+		pinctrl-2 = <&P8_39_gpio_pu_pin>;
+		pinctrl-3 = <&P8_39_gpio_pd_pin>;
+		pinctrl-4 = <&P8_39_eqep_pin>;
+		pinctrl-5 = <&P8_39_pruout_pin>;
+		pinctrl-6 = <&P8_39_pruin_pin>;
+	};
+
+	/* P8_40 (ZCZ ball T4) hdmi */
+	P8_40_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P8_40_default_pin>;
+		pinctrl-1 = <&P8_40_gpio_pin>;
+		pinctrl-2 = <&P8_40_gpio_pu_pin>;
+		pinctrl-3 = <&P8_40_gpio_pd_pin>;
+		pinctrl-4 = <&P8_40_eqep_pin>;
+		pinctrl-5 = <&P8_40_pruout_pin>;
+		pinctrl-6 = <&P8_40_pruin_pin>;
+	};
+
+	/* P8_41 (ZCZ ball T1) hdmi */
+	P8_41_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P8_41_default_pin>;
+		pinctrl-1 = <&P8_41_gpio_pin>;
+		pinctrl-2 = <&P8_41_gpio_pu_pin>;
+		pinctrl-3 = <&P8_41_gpio_pd_pin>;
+		pinctrl-4 = <&P8_41_eqep_pin>;
+		pinctrl-5 = <&P8_41_pruout_pin>;
+		pinctrl-6 = <&P8_41_pruin_pin>;
+	};
+
+	/* P8_42 (ZCZ ball T2) hdmi */
+	P8_42_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P8_42_default_pin>;
+		pinctrl-1 = <&P8_42_gpio_pin>;
+		pinctrl-2 = <&P8_42_gpio_pu_pin>;
+		pinctrl-3 = <&P8_42_gpio_pd_pin>;
+		pinctrl-4 = <&P8_42_eqep_pin>;
+		pinctrl-5 = <&P8_42_pruout_pin>;
+		pinctrl-6 = <&P8_42_pruin_pin>;
+	};
+
+	/* P8_43 (ZCZ ball R3) hdmi */
+	P8_43_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P8_43_default_pin>;
+		pinctrl-1 = <&P8_43_gpio_pin>;
+		pinctrl-2 = <&P8_43_gpio_pu_pin>;
+		pinctrl-3 = <&P8_43_gpio_pd_pin>;
+		pinctrl-4 = <&P8_43_pwm_pin>;
+		pinctrl-5 = <&P8_43_pruout_pin>;
+		pinctrl-6 = <&P8_43_pruin_pin>;
+	};
+
+	/* P8_44 (ZCZ ball R4) hdmi */
+	P8_44_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P8_44_default_pin>;
+		pinctrl-1 = <&P8_44_gpio_pin>;
+		pinctrl-2 = <&P8_44_gpio_pu_pin>;
+		pinctrl-3 = <&P8_44_gpio_pd_pin>;
+		pinctrl-4 = <&P8_44_pwm_pin>;
+		pinctrl-5 = <&P8_44_pruout_pin>;
+		pinctrl-6 = <&P8_44_pruin_pin>;
+	};
+
+	/* P8_45 (ZCZ ball R1) hdmi */
+	P8_45_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P8_45_default_pin>;
+		pinctrl-1 = <&P8_45_gpio_pin>;
+		pinctrl-2 = <&P8_45_gpio_pu_pin>;
+		pinctrl-3 = <&P8_45_gpio_pd_pin>;
+		pinctrl-4 = <&P8_45_pwm_pin>;
+		pinctrl-5 = <&P8_45_pruout_pin>;
+		pinctrl-6 = <&P8_45_pruin_pin>;
+	};
+
+	/* P8_46 (ZCZ ball R2) hdmi */
+	P8_46_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P8_46_default_pin>;
+		pinctrl-1 = <&P8_46_gpio_pin>;
+		pinctrl-2 = <&P8_46_gpio_pu_pin>;
+		pinctrl-3 = <&P8_46_gpio_pd_pin>;
+		pinctrl-4 = <&P8_46_pwm_pin>;
+		pinctrl-5 = <&P8_46_pruout_pin>;
+		pinctrl-6 = <&P8_46_pruin_pin>;
+	};
+
+	/************************/
+	/* P9 Header */
+	/************************/
+
+	/* P9_01                GND */
+
+	/* P9_02                GND */
+
+	/* P9_03                3V3 */
+
+	/* P9_04                3V3 */
+
+	/* P9_05                VDD_5V */
+
+	/* P9_06                VDD_5V */
+
+	/* P9_07                SYS_5V */
+
+	/* P9_08                SYS_5V */
+
+	/* P9_09                PWR_BUT */
+
+	/* P9_10                RSTn */
+
+	/* P9_11 (ZCZ ball T17) */
+	P9_11_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart";
+		pinctrl-0 = <&P9_11_default_pin>;
+		pinctrl-1 = <&P9_11_gpio_pin>;
+		pinctrl-2 = <&P9_11_gpio_pu_pin>;
+		pinctrl-3 = <&P9_11_gpio_pd_pin>;
+		pinctrl-4 = <&P9_11_uart_pin>;
+	};
+
+	/* P9_12 (ZCZ ball U18) */
+	P9_12_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P9_12_default_pin>;
+		pinctrl-1 = <&P9_12_gpio_pin>;
+		pinctrl-2 = <&P9_12_gpio_pu_pin>;
+		pinctrl-3 = <&P9_12_gpio_pd_pin>;
+	};
+
+	/* P9_13 (ZCZ ball U17) */
+	P9_13_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart";
+		pinctrl-0 = <&P9_13_default_pin>;
+		pinctrl-1 = <&P9_13_gpio_pin>;
+		pinctrl-2 = <&P9_13_gpio_pu_pin>;
+		pinctrl-3 = <&P9_13_gpio_pd_pin>;
+		pinctrl-4 = <&P9_13_uart_pin>;
+	};
+
+	/* P9_14 (ZCZ ball U14) */
+	P9_14_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P9_14_default_pin>;
+		pinctrl-1 = <&P9_14_gpio_pin>;
+		pinctrl-2 = <&P9_14_gpio_pu_pin>;
+		pinctrl-3 = <&P9_14_gpio_pd_pin>;
+		pinctrl-4 = <&P9_14_pwm_pin>;
+	};
+
+	/* P9_15 (ZCZ ball R13) */
+	P9_15_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P9_15_default_pin>;
+		pinctrl-1 = <&P9_15_gpio_pin>;
+		pinctrl-2 = <&P9_15_gpio_pu_pin>;
+		pinctrl-3 = <&P9_15_gpio_pd_pin>;
+		pinctrl-4 = <&P9_15_pwm_pin>;
+	};
+
+	/* P9_16 (ZCZ ball T14) */
+	P9_16_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P9_16_default_pin>;
+		pinctrl-1 = <&P9_16_gpio_pin>;
+		pinctrl-2 = <&P9_16_gpio_pu_pin>;
+		pinctrl-3 = <&P9_16_gpio_pd_pin>;
+		pinctrl-4 = <&P9_16_pwm_pin>;
+	};
+
+	/* P9_17 (ZCZ ball A16) */
+	P9_17_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_cs", "i2c", "pwm", "pru_uart";
+		pinctrl-0 = <&P9_17_default_pin>;
+		pinctrl-1 = <&P9_17_gpio_pin>;
+		pinctrl-2 = <&P9_17_gpio_pu_pin>;
+		pinctrl-3 = <&P9_17_gpio_pd_pin>;
+		pinctrl-4 = <&P9_17_spi_cs_pin>;
+		pinctrl-5 = <&P9_17_i2c_pin>;
+		pinctrl-6 = <&P9_17_pwm_pin>;
+		pinctrl-7 = <&P9_17_pru_uart_pin>;
+	};
+
+	/* P9_18 (ZCZ ball B16) */
+	P9_18_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "i2c", "pwm", "pru_uart";
+		pinctrl-0 = <&P9_18_default_pin>;
+		pinctrl-1 = <&P9_18_gpio_pin>;
+		pinctrl-2 = <&P9_18_gpio_pu_pin>;
+		pinctrl-3 = <&P9_18_gpio_pd_pin>;
+		pinctrl-4 = <&P9_18_spi_pin>;
+		pinctrl-5 = <&P9_18_i2c_pin>;
+		pinctrl-6 = <&P9_18_pwm_pin>;
+		pinctrl-7 = <&P9_18_pru_uart_pin>;
+	};
+
+	/* P9_19 (ZCZ ball D17) i2c */
+	P9_19_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_cs", "can", "i2c", "pru_uart", "timer";
+		pinctrl-0 = <&P9_19_default_pin>;
+		pinctrl-1 = <&P9_19_gpio_pin>;
+		pinctrl-2 = <&P9_19_gpio_pu_pin>;
+		pinctrl-3 = <&P9_19_gpio_pd_pin>;
+		pinctrl-4 = <&P9_19_spi_cs_pin>;
+		pinctrl-5 = <&P9_19_can_pin>;
+		pinctrl-6 = <&P9_19_i2c_pin>;
+		pinctrl-7 = <&P9_19_pru_uart_pin>;
+		pinctrl-8 = <&P9_19_timer_pin>;
+	};
+
+	/* P9_20 (ZCZ ball D18) i2c */
+	P9_20_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_cs", "can", "i2c", "pru_uart", "timer";
+		pinctrl-0 = <&P9_20_default_pin>;
+		pinctrl-1 = <&P9_20_gpio_pin>;
+		pinctrl-2 = <&P9_20_gpio_pu_pin>;
+		pinctrl-3 = <&P9_20_gpio_pd_pin>;
+		pinctrl-4 = <&P9_20_spi_cs_pin>;
+		pinctrl-5 = <&P9_20_can_pin>;
+		pinctrl-6 = <&P9_20_i2c_pin>;
+		pinctrl-7 = <&P9_20_pru_uart_pin>;
+		pinctrl-8 = <&P9_20_timer_pin>;
+	};
+
+	/* P9_21 (ZCZ ball B17) */
+	P9_21_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm", "pru_uart";
+		pinctrl-0 = <&P9_21_default_pin>;
+		pinctrl-1 = <&P9_21_gpio_pin>;
+		pinctrl-2 = <&P9_21_gpio_pu_pin>;
+		pinctrl-3 = <&P9_21_gpio_pd_pin>;
+		pinctrl-4 = <&P9_21_spi_pin>;
+		pinctrl-5 = <&P9_21_uart_pin>;
+		pinctrl-6 = <&P9_21_i2c_pin>;
+		pinctrl-7 = <&P9_21_pwm_pin>;
+		pinctrl-8 = <&P9_21_pru_uart_pin>;
+	};
+
+	/* P9_22 (ZCZ ball A17) */
+	P9_22_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_sclk", "uart", "i2c", "pwm", "pru_uart";
+		pinctrl-0 = <&P9_22_default_pin>;
+		pinctrl-1 = <&P9_22_gpio_pin>;
+		pinctrl-2 = <&P9_22_gpio_pu_pin>;
+		pinctrl-3 = <&P9_22_gpio_pd_pin>;
+		pinctrl-4 = <&P9_22_spi_sclk_pin>;
+		pinctrl-5 = <&P9_22_uart_pin>;
+		pinctrl-6 = <&P9_22_i2c_pin>;
+		pinctrl-7 = <&P9_22_pwm_pin>;
+		pinctrl-8 = <&P9_22_pru_uart_pin>;
+	};
+
+	/* P9_23 (ZCZ ball V14) */
+	P9_23_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P9_23_default_pin>;
+		pinctrl-1 = <&P9_23_gpio_pin>;
+		pinctrl-2 = <&P9_23_gpio_pu_pin>;
+		pinctrl-3 = <&P9_23_gpio_pd_pin>;
+		pinctrl-4 = <&P9_23_pwm_pin>;
+	};
+
+	/* P9_24 (ZCZ ball D15) */
+	P9_24_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pru_uart", "pruin";
+		pinctrl-0 = <&P9_24_default_pin>;
+		pinctrl-1 = <&P9_24_gpio_pin>;
+		pinctrl-2 = <&P9_24_gpio_pu_pin>;
+		pinctrl-3 = <&P9_24_gpio_pd_pin>;
+		pinctrl-4 = <&P9_24_uart_pin>;
+		pinctrl-5 = <&P9_24_can_pin>;
+		pinctrl-6 = <&P9_24_i2c_pin>;
+		pinctrl-7 = <&P9_24_pru_uart_pin>;
+		pinctrl-8 = <&P9_24_pruin_pin>;
+	};
+
+	/* P9_25 (ZCZ ball A14) audio */
+	P9_25_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P9_25_default_pin>;
+		pinctrl-1 = <&P9_25_gpio_pin>;
+		pinctrl-2 = <&P9_25_gpio_pu_pin>;
+		pinctrl-3 = <&P9_25_gpio_pd_pin>;
+		pinctrl-4 = <&P9_25_eqep_pin>;
+		pinctrl-5 = <&P9_25_pruout_pin>;
+		pinctrl-6 = <&P9_25_pruin_pin>;
+	};
+
+	/* P9_26 (ZCZ ball D16) */
+	P9_26_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pru_uart", "pruin";
+		pinctrl-0 = <&P9_26_default_pin>;
+		pinctrl-1 = <&P9_26_gpio_pin>;
+		pinctrl-2 = <&P9_26_gpio_pu_pin>;
+		pinctrl-3 = <&P9_26_gpio_pd_pin>;
+		pinctrl-4 = <&P9_26_uart_pin>;
+		pinctrl-5 = <&P9_26_can_pin>;
+		pinctrl-6 = <&P9_26_i2c_pin>;
+		pinctrl-7 = <&P9_26_pru_uart_pin>;
+		pinctrl-8 = <&P9_26_pruin_pin>;
+	};
+
+	/* P9_27 (ZCZ ball C13) */
+	P9_27_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P9_27_default_pin>;
+		pinctrl-1 = <&P9_27_gpio_pin>;
+		pinctrl-2 = <&P9_27_gpio_pu_pin>;
+		pinctrl-3 = <&P9_27_gpio_pd_pin>;
+		pinctrl-4 = <&P9_27_eqep_pin>;
+		pinctrl-5 = <&P9_27_pruout_pin>;
+		pinctrl-6 = <&P9_27_pruin_pin>;
+	};
+
+	/* P9_28 (ZCZ ball C12) audio */
+	P9_28_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_cs", "pwm", "pwm2", "pruout", "pruin";
+		pinctrl-0 = <&P9_28_default_pin>;
+		pinctrl-1 = <&P9_28_gpio_pin>;
+		pinctrl-2 = <&P9_28_gpio_pu_pin>;
+		pinctrl-3 = <&P9_28_gpio_pd_pin>;
+		pinctrl-4 = <&P9_28_spi_cs_pin>;
+		pinctrl-5 = <&P9_28_pwm_pin>;
+		pinctrl-6 = <&P9_28_pwm2_pin>;
+		pinctrl-7 = <&P9_28_pruout_pin>;
+		pinctrl-8 = <&P9_28_pruin_pin>;
+	};
+
+	/* P9_29 (ZCZ ball B13) audio */
+	P9_29_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P9_29_default_pin>;
+		pinctrl-1 = <&P9_29_gpio_pin>;
+		pinctrl-2 = <&P9_29_gpio_pu_pin>;
+		pinctrl-3 = <&P9_29_gpio_pd_pin>;
+		pinctrl-4 = <&P9_29_spi_pin>;
+		pinctrl-5 = <&P9_29_pwm_pin>;
+		pinctrl-6 = <&P9_29_pruout_pin>;
+		pinctrl-7 = <&P9_29_pruin_pin>;
+	};
+
+	/* P9_30 (ZCZ ball D12) */
+	P9_30_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P9_30_default_pin>;
+		pinctrl-1 = <&P9_30_gpio_pin>;
+		pinctrl-2 = <&P9_30_gpio_pu_pin>;
+		pinctrl-3 = <&P9_30_gpio_pd_pin>;
+		pinctrl-4 = <&P9_30_spi_pin>;
+		pinctrl-5 = <&P9_30_pwm_pin>;
+		pinctrl-6 = <&P9_30_pruout_pin>;
+		pinctrl-7 = <&P9_30_pruin_pin>;
+	};
+
+	/* P9_31 (ZCZ ball A13) audio */
+	P9_31_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_sclk", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P9_31_default_pin>;
+		pinctrl-1 = <&P9_31_gpio_pin>;
+		pinctrl-2 = <&P9_31_gpio_pu_pin>;
+		pinctrl-3 = <&P9_31_gpio_pd_pin>;
+		pinctrl-4 = <&P9_31_spi_sclk_pin>;
+		pinctrl-5 = <&P9_31_pwm_pin>;
+		pinctrl-6 = <&P9_31_pruout_pin>;
+		pinctrl-7 = <&P9_31_pruin_pin>;
+	};
+
+	/* P9_32                VADC */
+
+	/* P9_33 (ZCZ ball C8)  AIN4 */
+
+	/* P9_34                AGND */
+
+	/* P9_35 (ZCZ ball A8)  AIN6 */
+
+	/* P9_36 (ZCZ ball B8)  AIN5 */
+
+	/* P9_37 (ZCZ ball B7)  AIN2 */
+
+	/* P9_38 (ZCZ ball A7)  AIN3 */
+
+	/* P9_39 (ZCZ ball B6)  AIN0 */
+
+	/* P9_40 (ZCZ ball C7)  AIN1 */
+
+	/* P9_41 (ZCZ ball D14) */
+	P9_41_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer", "pruin";
+		pinctrl-0 = <&P9_41_default_pin>;
+		pinctrl-1 = <&P9_41_gpio_pin>;
+		pinctrl-2 = <&P9_41_gpio_pu_pin>;
+		pinctrl-3 = <&P9_41_gpio_pd_pin>;
+		pinctrl-4 = <&P9_41_timer_pin>;
+		pinctrl-5 = <&P9_41_pruin_pin>;
+	};
+
+	/* P9_41.1 */
+	/* P9_91 (ZCZ ball D13) */
+	P9_91_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P9_91_default_pin>;
+		pinctrl-1 = <&P9_91_gpio_pin>;
+		pinctrl-2 = <&P9_91_gpio_pu_pin>;
+		pinctrl-3 = <&P9_91_gpio_pd_pin>;
+		pinctrl-4 = <&P9_91_eqep_pin>;
+		pinctrl-5 = <&P9_91_pruout_pin>;
+		pinctrl-6 = <&P9_91_pruin_pin>;
+	};
+
+	/* P9_42 (ZCZ ball C18) */
+	P9_42_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_cs", "spi_sclk", "uart", "pwm", "pru_ecap_pwm";
+		pinctrl-0 = <&P9_42_default_pin>;
+		pinctrl-1 = <&P9_42_gpio_pin>;
+		pinctrl-2 = <&P9_42_gpio_pu_pin>;
+		pinctrl-3 = <&P9_42_gpio_pd_pin>;
+		pinctrl-4 = <&P9_42_spi_cs_pin>;
+		pinctrl-5 = <&P9_42_spi_sclk_pin>;
+		pinctrl-6 = <&P9_42_uart_pin>;
+		pinctrl-7 = <&P9_42_pwm_pin>;
+		pinctrl-8 = <&P9_42_pru_ecap_pwm_pin>;
+	};
+
+	/* P9_42.1 */
+	/* P9_92 (ZCZ ball B12) */
+	P9_92_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P9_92_default_pin>;
+		pinctrl-1 = <&P9_92_gpio_pin>;
+		pinctrl-2 = <&P9_92_gpio_pu_pin>;
+		pinctrl-3 = <&P9_92_gpio_pd_pin>;
+		pinctrl-4 = <&P9_92_eqep_pin>;
+		pinctrl-5 = <&P9_92_pruout_pin>;
+		pinctrl-6 = <&P9_92_pruin_pin>;
+	};
+
+	/* P9_43                GND */
+
+	/* P9_44                GND */
+
+	/* P9_45                GND */
+
+	/* P9_46                GND */
+
+	cape-universal {
+		compatible = "gpio-of-helper";
+		status = "okay";
+		pinctrl-names = "default";
+		pinctrl-0 = <>;
+
+		P8_03 {
+			gpio-name = "P8_03";
+			gpio = <&gpio1 6 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_04 {
+			gpio-name = "P8_04";
+			gpio = <&gpio1 7 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_05 {
+			gpio-name = "P8_05";
+			gpio = <&gpio1 2 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_06 {
+			gpio-name = "P8_06";
+			gpio = <&gpio1 3 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_07 {
+			gpio-name = "P8_07";
+			gpio = <&gpio2 2 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_08 {
+			gpio-name = "P8_08";
+			gpio = <&gpio2 3 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_09 {
+			gpio-name = "P8_09";
+			gpio = <&gpio2 5 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_10 {
+			gpio-name = "P8_10";
+			gpio = <&gpio2 4 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_11 {
+			gpio-name = "P8_11";
+			gpio = <&gpio1 13 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_12 {
+			gpio-name = "P8_12";
+			gpio = <&gpio1 12 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_13 {
+			gpio-name = "P8_13";
+			gpio = <&gpio0 23 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_14 {
+			gpio-name = "P8_14";
+			gpio = <&gpio0 26 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_15 {
+			gpio-name = "P8_15";
+			gpio = <&gpio1 15 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_16 {
+			gpio-name = "P8_16";
+			gpio = <&gpio1 14 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_17 {
+			gpio-name = "P8_17";
+			gpio = <&gpio0 27 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_18 {
+			gpio-name = "P8_18";
+			gpio = <&gpio2 1 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_19 {
+			gpio-name = "P8_19";
+			gpio = <&gpio0 22 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_20 {
+			gpio-name = "P8_20";
+			gpio = <&gpio1 31 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_21 {
+			gpio-name = "P8_21";
+			gpio = <&gpio1 30 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_22 {
+			gpio-name = "P8_22";
+			gpio = <&gpio1 5 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_23 {
+			gpio-name = "P8_23";
+			gpio = <&gpio1 4 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_24 {
+			gpio-name = "P8_24";
+			gpio = <&gpio1 1 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_25 {
+			gpio-name = "P8_25";
+			gpio = <&gpio1 0 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_26 {
+			gpio-name = "P8_26";
+			gpio = <&gpio1 29 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_27 {
+			gpio-name = "P8_27";
+			gpio = <&gpio2 22 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_28 {
+			gpio-name = "P8_28";
+			gpio = <&gpio2 24 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_29 {
+			gpio-name = "P8_29";
+			gpio = <&gpio2 23 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_30 {
+			gpio-name = "P8_30";
+			gpio = <&gpio2 25 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_31 {
+			gpio-name = "P8_31";
+			gpio = <&gpio0 10 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_32 {
+			gpio-name = "P8_32";
+			gpio = <&gpio0 11 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_33 {
+			gpio-name = "P8_33";
+			gpio = <&gpio0 9 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_34 {
+			gpio-name = "P8_34";
+			gpio = <&gpio2 17 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_35 {
+			gpio-name = "P8_35";
+			gpio = <&gpio0 8 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_36 {
+			gpio-name = "P8_36";
+			gpio = <&gpio2 16 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_37 {
+			gpio-name = "P8_37";
+			gpio = <&gpio2 14 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_38 {
+			gpio-name = "P8_38";
+			gpio = <&gpio2 15 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_39 {
+			gpio-name = "P8_39";
+			gpio = <&gpio2 12 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_40 {
+			gpio-name = "P8_40";
+			gpio = <&gpio2 13 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_41 {
+			gpio-name = "P8_41";
+			gpio = <&gpio2 10 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_42 {
+			gpio-name = "P8_42";
+			gpio = <&gpio2 11 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_43 {
+			gpio-name = "P8_43";
+			gpio = <&gpio2 8 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_44 {
+			gpio-name = "P8_44";
+			gpio = <&gpio2 9 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_45 {
+			gpio-name = "P8_45";
+			gpio = <&gpio2 6 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_46 {
+			gpio-name = "P8_46";
+			gpio = <&gpio2 7 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_11 {
+			gpio-name = "P9_11";
+			gpio = <&gpio0 30 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_12 {
+			gpio-name = "P9_12";
+			gpio = <&gpio1 28 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_13 {
+			gpio-name = "P9_13";
+			gpio = <&gpio0 31 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_14 {
+			gpio-name = "P9_14";
+			gpio = <&gpio1 18 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_15 {
+			gpio-name = "P9_15";
+			gpio = <&gpio1 16 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_16 {
+			gpio-name = "P9_16";
+			gpio = <&gpio1 19 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_17 {
+			gpio-name = "P9_17";
+			gpio = <&gpio0 5 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_18 {
+			gpio-name = "P9_18";
+			gpio = <&gpio0 4 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_19 {
+			gpio-name = "P9_19";
+			gpio = <&gpio0 13 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_20 {
+			gpio-name = "P9_20";
+			gpio = <&gpio0 12 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_21 {
+			gpio-name = "P9_21";
+			gpio = <&gpio0 3 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_22 {
+			gpio-name = "P9_22";
+			gpio = <&gpio0 2 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_23 {
+			gpio-name = "P9_23";
+			gpio = <&gpio1 17 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_24 {
+			gpio-name = "P9_24";
+			gpio = <&gpio0 15 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_25 {
+			gpio-name = "P9_25";
+			gpio = <&gpio3 21 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_26 {
+			gpio-name = "P9_26";
+			gpio = <&gpio0 14 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_27 {
+			gpio-name = "P9_27";
+			gpio = <&gpio3 19 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_28 {
+			gpio-name = "P9_28";
+			gpio = <&gpio3 17 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_29 {
+			gpio-name = "P9_29";
+			gpio = <&gpio3 15 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_30 {
+			gpio-name = "P9_30";
+			gpio = <&gpio3 16 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_31 {
+			gpio-name = "P9_31";
+			gpio = <&gpio3 14 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_41 {
+			gpio-name = "P9_41";
+			gpio = <&gpio0 20 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_91 {
+			gpio-name = "P9_91";
+			gpio = <&gpio3 20 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_42 {
+			gpio-name = "P9_42";
+			gpio = <&gpio0 7 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_92 {
+			gpio-name = "P9_92";
+			gpio = <&gpio3 18 0>;
+			input;
+			dir-changeable;
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-bone.dts b/arch/arm/boot/dts/ti/omap/am335x-bone.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-bone.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-bone.dts	2025-10-23 09:30:40.281462084 -0400
@@ -10,6 +10,11 @@
 / {
 	model = "TI AM335x BeagleBone";
 	compatible = "ti,am335x-bone", "ti,am33xx";
+
+	chosen {
+		base_dtb = "am335x-bone.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
 };
 
 &ldo3_reg {
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-common.dtsi b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-common.dtsi
--- a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-common.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-common.dtsi	2025-10-23 09:30:40.281462084 -0400
@@ -34,6 +34,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart2_pins>;
 	status = "okay";
+	symlink = "bone/uart/2";
 };
 
 &rtc {
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-bonegreen.dts b/arch/arm/boot/dts/ti/omap/am335x-bonegreen.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-bonegreen.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-bonegreen.dts	2025-10-23 09:30:40.281462084 -0400
@@ -11,4 +11,157 @@
 / {
 	model = "TI AM335x BeagleBone Green";
 	compatible = "ti,am335x-bone-green", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+
+	chosen {
+		base_dtb = "am335x-bonegreen.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
 };
+
+&gpio0 {
+	gpio-line-names =
+		"[mdio_data]",
+		"[mdio_clk]",
+		"P9_22 [spi0_sclk]",
+		"P9_21 [spi0_d0]",
+		"P9_18 [spi0_d1]",
+		"P9_17 [spi0_cs0]",
+		"[mmc0_cd]",
+		"P9_42A [ecappwm0]",
+		"P8_35 [lcd d12]",
+		"P8_33 [lcd d13]",
+		"P8_31 [lcd d14]",
+		"P8_32 [lcd d15]",
+		"P9_20 [i2c2_sda]",
+		"P9_19 [i2c2_scl]",
+		"P9_26 [uart1_rxd]",
+		"P9_24 [uart1_txd]",
+		"[rmii1_txd3]",
+		"[rmii1_txd2]",
+		"[usb0_drvvbus]",
+		"[hdmi cec]",
+		"P9_41B",
+		"[rmii1_txd1]",
+		"P8_19 [ehrpwm2a]",
+		"P8_13 [ehrpwm2b]",
+		"NC",
+		"NC",
+		"P8_14",
+		"P8_17",
+		"[rmii1_txd0]",
+		"[rmii1_refclk]",
+		"P9_11 [uart4_rxd]",
+		"P9_13 [uart4_txd]";
+};
+
+&gpio1 {
+	gpio-line-names =
+		"P8_25 [mmc1_dat0]",
+		"[mmc1_dat1]",
+		"P8_5 [mmc1_dat2]",
+		"P8_6 [mmc1_dat3]",
+		"P8_23 [mmc1_dat4]",
+		"P8_22 [mmc1_dat5]",
+		"P8_3 [mmc1_dat6]",
+		"P8_4 [mmc1_dat7]",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"P8_12",
+		"P8_11",
+		"P8_16",
+		"P8_15",
+		"P9_15A",
+		"P9_23",
+		"P9_14 [ehrpwm1a]",
+		"P9_16 [ehrpwm1b]",
+		"[emmc rst]",
+		"[usr0 led]",
+		"[usr1 led]",
+		"[usr2 led]",
+		"[usr3 led]",
+		"[hdmi irq]",
+		"[usb vbus oc]",
+		"[hdmi audio]",
+		"P9_12",
+		"P8_26",
+		"P8_21 [emmc]",
+		"P8_20 [emmc]";
+};
+
+&gpio2 {
+	gpio-line-names =
+		"P9_15B",
+		"P8_18",
+		"P8_7",
+		"P8_8",
+		"P8_10",
+		"P8_9",
+		"P8_45",
+		"P8_46",
+		"P8_43",
+		"P8_44",
+		"P8_41",
+		"P8_42",
+		"P8_39",
+		"P8_40",
+		"P8_37",
+		"P8_38",
+		"P8_36",
+		"P8_34",
+		"[rmii1_rxd3]",
+		"[rmii1_rxd2]",
+		"[rmii1_rxd1]",
+		"[rmii1_rxd0]",
+		"P8_27",
+		"P8_29",
+		"P8_28",
+		"P8_30",
+		"[mmc0_dat3]",
+		"[mmc0_dat2]",
+		"[mmc0_dat1]",
+		"[mmc0_dat0]",
+		"[mmc0_clk]",
+		"[mmc0_cmd]";
+};
+
+&gpio3 {
+	gpio-line-names =
+		"[mii col]",
+		"[mii crs]",
+		"[mii rx err]",
+		"[mii tx en]",
+		"[mii rx dv]",
+		"[i2c0 sda]",
+		"[i2c0 scl]",
+		"[jtag emu0]",
+		"[jtag emu1]",
+		"[mii tx clk]",
+		"[mii rx clk]",
+		"NC",
+		"NC",
+		"[usb vbus en]",
+		"P9_31 [spi1_sclk]",
+		"P9_29 [spi1_d0]",
+		"P9_30 [spi1_d1]",
+		"P9_28 [spi1_cs0]",
+		"P9_42B [ecappwm0]",
+		"P9_27",
+		"P9_41A",
+		"P9_25",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC",
+		"NC";
+};
+
+&baseboard_eeprom {
+	vcc-supply = <&ldo4_reg>;
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-eco.dts b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-eco.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-eco.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-eco.dts	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2025 Bootlin
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-bone-common.dtsi"
+#include "am335x-bonegreen-common.dtsi"
+#include <dt-bindings/net/ti-dp83867.h>
+
+/ {
+	model = "Seeed Studio BeagleBone Green Eco";
+	compatible = "seeed,am335x-bone-green-eco", "ti,am33xx";
+
+	chosen {
+		base_dtb = "am335x-bonegreen-eco.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
+
+	cpus {
+		cpu@0 {
+			cpu0-supply = <&buck1>;
+		};
+	};
+
+	sys_5v: regulator-sys-5v {
+		compatible = "regulator-fixed";
+		regulator-name = "sys_5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	v3v3: regulator-v3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "v3v3";
+		regulator-always-on;
+	};
+};
+
+&usb0 {
+	interrupts-extended = <&intc 18>;
+	interrupt-names = "mc";
+};
+
+&baseboard_eeprom {
+	vcc-supply = <&v3v3>;
+};
+
+&i2c0 {
+	/delete-node/ pmic@24;
+
+	tps65214: pmic@30 {
+		compatible = "ti,tps65214";
+		reg = <0x30>;
+		buck1-supply = <&sys_5v>;
+		buck2-supply = <&sys_5v>;
+		buck3-supply = <&sys_5v>;
+		ldo1-supply = <&sys_5v>;
+		ldo2-supply = <&sys_5v>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <7>;
+		pinctrl-0 = <&pmic_irq_pins_default>;
+
+		regulators {
+			buck1: buck1 {
+				regulator-name = "vdd_mpu";
+				regulator-min-microvolt = <925000>;
+				regulator-max-microvolt = <1298500>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck2: buck2 {
+				regulator-name = "vdd_core";
+				regulator-min-microvolt = <925000>;
+				regulator-max-microvolt = <1150000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck3: buck3 {
+				regulator-name = "vdds_ddr";
+				regulator-min-microvolt = <1350000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+			};
+
+			ldo1_reg: ldo1 {
+				regulator-name = "vdd_1v8_1";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo2_reg: ldo2 {
+				regulator-name = "vdd_1v8_2";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&cpsw_port1 {
+	phy-mode = "rgmii-id";
+	phy-handle = <&dp83867_0>;
+	ti,dual-emac-pvid = <1>;
+};
+
+&mac_sw {
+	pinctrl-0 = <&cpsw_b_default>;
+	pinctrl-1 = <&cpsw_b_sleep>;
+};
+
+&davinci_mdio_sw {
+	/delete-node/ ethernet-phy@0;
+
+	dp83867_0: ethernet-phy@0 {
+		reg = <0>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
+		ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
+		ti,min-output-impedance;
+		ti,dp83867-rxctrl-strap-quirk;
+
+		reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+		reset-assert-us = <300>;
+		reset-deassert-us = <50000>;
+	};
+};
+
+&am33xx_pinmux {
+	cpsw_b_default: cpsw-b-default-pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_TX_EN, PIN_OUTPUT_PULLDOWN, MUX_MODE2)
+			AM33XX_PADCONF(AM335X_PIN_MII1_RX_DV, PIN_INPUT_PULLDOWN, MUX_MODE2)
+			AM33XX_PADCONF(AM335X_PIN_MII1_TX_CLK, PIN_OUTPUT_PULLDOWN, MUX_MODE2)
+			AM33XX_PADCONF(AM335X_PIN_MII1_RX_CLK, PIN_INPUT_PULLDOWN, MUX_MODE2)
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD0, PIN_OUTPUT_PULLDOWN, MUX_MODE2)
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD1, PIN_OUTPUT_PULLDOWN, MUX_MODE2)
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD2, PIN_OUTPUT_PULLDOWN, MUX_MODE2)
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD3, PIN_OUTPUT_PULLDOWN, MUX_MODE2)
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_INPUT_PULLDOWN, MUX_MODE2)
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD1, PIN_INPUT_PULLDOWN, MUX_MODE2)
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD2, PIN_INPUT_PULLDOWN, MUX_MODE2)
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD3, PIN_INPUT_PULLDOWN, MUX_MODE2)
+		>;
+	};
+
+	cpsw_b_sleep: cpsw-b-sleep-pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_TX_EN, PIN_INPUT_PULLDOWN, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_MII1_RX_DV, PIN_INPUT_PULLDOWN, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_MII1_TX_CLK, PIN_INPUT_PULLDOWN, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_MII1_RX_CLK, PIN_INPUT_PULLDOWN, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD0, PIN_INPUT_PULLDOWN, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD1, PIN_INPUT_PULLDOWN, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD2, PIN_INPUT_PULLDOWN, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD3, PIN_INPUT_PULLDOWN, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_INPUT_PULLDOWN, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD1, PIN_INPUT_PULLDOWN, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD2, PIN_INPUT_PULLDOWN, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD3, PIN_INPUT_PULLDOWN, MUX_MODE7)
+		>;
+	};
+
+	pmic_irq_pins_default: pmic-irq-default-pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(AM335X_PIN_NNMI, PIN_INPUT_PULLUP | MUX_MODE0)
+		>;
+	};
+};
+
+&tscadc {
+	status = "okay";
+};
+
+&rtc {
+	pinctrl-0 = <&ext_wakeup>;
+	pinctrl-names = "default";
+
+	ext_wakeup: ext-wakeup {
+		pins = "ext_wakeup0";
+		input-enable;
+	};
+ };
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-gateway.dts b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-gateway.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-gateway.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-gateway.dts	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-bone-common.dtsi"
+#include "am335x-bonegreen-common.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	model = "SeeedStudio BeagleBone Green Gateway";
+	compatible = "ti,am335x-bone-green-gateway", "ti,am335x-bone-green", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+
+	aliases {
+		rtc0 = &extrtc;
+		rtc1 = &rtc;
+	};
+
+	chosen {
+		base_dtb = "am335x-bonegreen-gateway.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+		wl1835_bt = "S3-texas-300000";
+	};
+
+	wlan_en_reg: fixedregulator@2 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan-en-regulator";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us= <70000>;
+
+		/* WL_EN */
+		gpio = <&gpio3 9 0>;
+		enable-active-high;
+	};
+
+	leds {
+		pinctrl-names = "default";
+		//pinctrl-0 = <&user_leds_s0>;
+		pinctrl-0 = <&user_leds_s0 &bt_pins>;
+
+		compatible = "gpio-leds";
+
+		led2 {
+			label = "beaglebone:green:usr0";
+			gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+			default-state = "off";
+		};
+
+		led3 {
+			label = "beaglebone:green:usr1";
+			gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc0";
+			default-state = "off";
+		};
+
+		led4 {
+			label = "beaglebone:green:usr2";
+			gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "cpu0";
+			default-state = "off";
+		};
+
+		led5 {
+			label = "beaglebone:green:usr3";
+			gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc1";
+			default-state = "off";
+		};
+
+		led6 {
+			label = "beaglebone:green:usr4";
+			gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "netdev";
+			default-state = "off";
+		};
+
+		wl18xx_bt_en: led7 {
+			label = "wl18xx_bt_en";
+			gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+};
+
+&cpu0_opp_table {
+	/*
+	 * Octavo Systems:
+	 * The EFUSE_SMA register is not programmed for any of the AM335x wafers
+	 * we get and we are not programming them during our production test.
+	 * Therefore, from a DEVICE_ID revision point of view, the silicon looks
+	 * like it is Revision 2.1.  However, from an EFUSE_SMA point of view for
+	 * the HW OPP table, the silicon looks like it is Revision 1.0 (ie the
+	 * EFUSE_SMA register reads as all zeros).
+	 */
+	oppnitro-1000000000 {
+		opp-supported-hw = <0x06 0x0100>;
+	};
+};
+
+&am33xx_pinmux {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usbhost_pins>;
+
+	user_leds_s0: user-leds-s0-pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A5, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gpmc_a5.gpio1_21 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A6, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpmc_a6.gpio1_22 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A7, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gpmc_a7.gpio1_23 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A8, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpmc_a8.gpio1_24 */
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* WL_Active_LED / USR4 */
+		>;
+	};
+
+	bt_pins: bt-pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD0, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gmii1_txd0.gpio0_28 - BT_EN */
+		>;
+	};
+
+	mmc3_pins: mmc3-pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD1, PIN_INPUT_PULLUP, MUX_MODE6 ) /* (L15) gmii1_rxd1.mmc2_clk */
+			AM33XX_PADCONF(AM335X_PIN_MII1_TX_EN, PIN_INPUT_PULLUP, MUX_MODE6 ) /* (J16) gmii1_txen.mmc2_cmd */
+			AM33XX_PADCONF(AM335X_PIN_MII1_RX_DV, PIN_INPUT_PULLUP, MUX_MODE5 ) /* (J17) gmii1_rxdv.mmc2_dat0 */
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD3, PIN_INPUT_PULLUP, MUX_MODE5 ) /* (J18) gmii1_txd3.mmc2_dat1 */
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD2, PIN_INPUT_PULLUP, MUX_MODE5 ) /* (K15) gmii1_txd2.mmc2_dat2 */
+			AM33XX_PADCONF(AM335X_PIN_MII1_COL, PIN_INPUT_PULLUP, MUX_MODE5 ) /* (H16) gmii1_col.mmc2_dat3 */
+		>;
+	};
+
+	uart2_grove_pins: pinmux_uart2_grove_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x90c, PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE6)
+			AM33XX_IOPAD(0x910, PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE6)
+		>;
+	};
+
+	uart3_pins: uart3-pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD3, PIN_INPUT_PULLUP, MUX_MODE1)	/* gmii1_rxd3.uart3_rxd */
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD2, PIN_OUTPUT_PULLDOWN, MUX_MODE1)	/* gmii1_rxd2.uart3_txd */
+			AM33XX_PADCONF(AM335X_PIN_MDIO, PIN_INPUT, MUX_MODE3)		/* mdio_data.uart3_ctsn */
+			AM33XX_PADCONF(AM335X_PIN_MDC, PIN_OUTPUT_PULLDOWN, MUX_MODE3)	/* mdio_clk.uart3_rtsn */
+		>;
+	};
+
+	usbhost_pins: pinmux_usbhost_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD1, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gmii1_txd1.gpio0[21] */
+		>;
+	};
+
+	wl18xx_pins: wl18xx-pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_TX_CLK, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gmii1_txclk.gpio3_9 WL_EN */
+			AM33XX_PADCONF(AM335X_PIN_RMII1_REF_CLK, PIN_INPUT_PULLDOWN, MUX_MODE7)	/* rmii1_refclk.gpio0_29 WL_IRQ */
+			AM33XX_PADCONF(AM335X_PIN_MII1_RX_CLK, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gmii1_rxclk.gpio3_10 LS_BUF_EN */
+		>;
+	};
+};
+
+&mac_sw {
+	/delete-property/pinctrl-names;
+	/delete-property/pinctrl-0;
+	/delete-property/pinctrl-1;
+	status = "disabled";
+};
+
+&mmc3 {
+	dmas = <&edma_xbar 12 0 1
+		&edma_xbar 13 0 2>;
+	dma-names = "tx", "rx";
+	status = "okay";
+	vmmc-supply = <&wlan_en_reg>;
+	bus-width = <4>;
+	non-removable;
+	cap-power-off-card;
+	keep-power-in-suspend;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc3_pins &wl18xx_pins>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	wlcore: wlcore@2 {
+		compatible = "ti,wl1835";
+		reg = <2>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <29 IRQ_TYPE_EDGE_RISING>;
+	};
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_grove_pins>;
+	status = "okay";
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>;
+	//pinctrl-0 = <&uart3_pins &bt_pins>;
+	status = "okay";
+
+	//bluetooth {
+	//	compatible = "ti,wl1835-st";
+	//	enable-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+	//};
+};
+
+&i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	extrtc: rtc@68 {
+		compatible = "dallas,ds1340";
+		reg = <0x68>;
+	};
+};
+
+// (K16) gmii1_txd1.gpio0[21]
+&gpio0 {
+	usb-reset-hog {
+		gpio-hog;
+		gpios = <21 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "usb_reset";
+	};
+};
+
+&gpio3 {
+	ls-buf-en-hog {
+		gpio-hog;
+		gpios = <10 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "LS_BUF_EN";
+	};
+};
+
+&usb1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	hub@1 {
+		compatible = "usb424,9512";
+		reg = <1>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethernet: ethernet@1 {
+			compatible = "usb424,ec00";
+			reg = <1>;
+		};
+	};
+};
+
+&baseboard_eeprom {
+	vcc-supply = <&ldo4_reg>;
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-wireless-common-univ.dtsi b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-wireless-common-univ.dtsi
--- a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-wireless-common-univ.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-wireless-common-univ.dtsi	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,2197 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <dt-bindings/board/am335x-bone-pins.h>
+
+&am33xx_pinmux {
+
+/* macro: BONE_PIN( <pin>, <mode_name>, <register_value_macro(s)> */
+#define BONE_PIN(XX,ZZ,QQ) \
+	XX##_##ZZ##_pin: pinmux_##XX##_##ZZ##_pin { pinctrl-single,pins = < QQ >; };
+
+	/************************/
+	/* P8 Header */
+	/************************/
+
+	/* P8_01                GND */
+
+	/* P8_02                GND */
+
+
+	/* P8_03 (ZCZ ball R9) gpmc_ad6 (emmc) */
+	BONE_PIN(P8_03, default, P8_03(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_03, gpio, P8_03(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_03, gpio_pu, P8_03(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_03, gpio_pd, P8_03(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_04 (ZCZ ball T9) gpmc_ad7 (emmc) */
+	BONE_PIN(P8_04, default, P8_04(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_04, gpio, P8_04(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_04, gpio_pu, P8_04(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_04, gpio_pd, P8_04(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_05 (ZCZ ball R8) gpmc_ad2 (emmc) */
+	BONE_PIN(P8_05, default, P8_05(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_05, gpio, P8_05(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_05, gpio_pu, P8_05(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_05, gpio_pd, P8_05(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_06 (ZCZ ball T8) gpmc_ad3 (emmc) */
+	BONE_PIN(P8_06, default, P8_06(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_06, gpio, P8_06(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_06, gpio_pu, P8_06(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_06, gpio_pd, P8_06(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_07 (ZCZ ball R7) gpmc_advn_ale (gpio2_2) */
+	BONE_PIN(P8_07, default, P8_07(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_07, gpio, P8_07(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_07, gpio_pu, P8_07(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_07, gpio_pd, P8_07(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_07, timer, P8_07(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_08 (ZCZ ball T7) gpmc_oen_ren (gpio2_3) */
+	BONE_PIN(P8_08, default, P8_08(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_08, gpio, P8_08(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_08, gpio_pu, P8_08(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_08, gpio_pd, P8_08(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_08, timer, P8_08(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_09 (ZCZ ball T6) gpmc_be0n_cle (gpio2_5) */
+	BONE_PIN(P8_09, default, P8_09(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_09, gpio, P8_09(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_09, gpio_pu, P8_09(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_09, gpio_pd, P8_09(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_09, timer, P8_09(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_10 (ZCZ ball U6) gpmc_wen (gpio2_4) */
+	BONE_PIN(P8_10, default, P8_10(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_10, gpio, P8_10(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_10, gpio_pu, P8_10(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_10, gpio_pd, P8_10(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_10, timer, P8_10(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_11 (ZCZ ball R12) gpmc_ad13 (gpio1_13) */
+	BONE_PIN(P8_11, default, P8_11(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_11, gpio, P8_11(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_11, gpio_pu, P8_11(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_11, gpio_pd, P8_11(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_11, eqep, P8_11(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P8_11, pruout, P8_11(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE6))
+
+	/* P8_12 (ZCZ ball T12) gpmc_ad12 (gpio1_12) */
+	BONE_PIN(P8_12, default, P8_12(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_12, gpio, P8_12(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_12, gpio_pu, P8_12(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_12, gpio_pd, P8_12(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_12, eqep, P8_12(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P8_12, pruout, P8_12(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE6))
+
+	/* P8_13 (ZCZ ball T10) gpmc_ad9 (gpio0_23) */
+	BONE_PIN(P8_13, default, P8_13(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_13, gpio, P8_13(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_13, gpio_pu, P8_13(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_13, gpio_pd, P8_13(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_13, pwm, P8_13(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE4))
+
+	/* P8_14 (ZCZ ball T11) wl1835: wl_en */
+
+	/* P8_15 (ZCZ ball U13) gpmc_ad15 (gpio1_15) */
+	BONE_PIN(P8_15, default, P8_15(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_15, gpio, P8_15(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_15, gpio_pu, P8_15(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_15, gpio_pd, P8_15(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_15, eqep, P8_15(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P8_15, pru_ecap_pwm, P8_15(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_15, pruin, P8_15(PIN_INPUT | MUX_MODE6))
+
+	/* P8_16 (ZCZ ball V13) gpmc_ad14 (gpio1_14) */
+	BONE_PIN(P8_16, default, P8_16(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_16, gpio, P8_16(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_16, gpio_pu, P8_16(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_16, gpio_pd, P8_16(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_16, eqep, P8_16(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P8_16, pruin, P8_16(PIN_INPUT | MUX_MODE6))
+
+	/* P8_17 (ZCZ ball U12) wl1835: wl_irq */
+
+	/* P8_18 (ZCZ ball V12) gpmc_clk (gpio2_1) */
+	BONE_PIN(P8_18, default, P8_18(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_18, gpio, P8_18(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_18, gpio_pu, P8_18(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_18, gpio_pd, P8_18(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_19 (ZCZ ball U10) gpmc_ad8 (gpio0_22) */
+	BONE_PIN(P8_19, default, P8_19(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_19, gpio, P8_19(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_19, gpio_pu, P8_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_19, gpio_pd, P8_19(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_19, pwm, P8_19(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE4))
+
+	/* P8_20 (ZCZ ball V9) gpmc_csn2 (emmc) */
+	BONE_PIN(P8_20, default, P8_20(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_20, gpio, P8_20(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_20, gpio_pu, P8_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_20, gpio_pd, P8_20(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_20, pruout, P8_20(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_20, pruin, P8_20(PIN_INPUT | MUX_MODE6))
+
+	/* P8_21 (ZCZ ball U9) gpmc_csn1 (emmc) */
+	BONE_PIN(P8_21, default, P8_21(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_21, gpio, P8_21(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_21, gpio_pu, P8_21(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_21, gpio_pd, P8_21(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_21, pruout, P8_21(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_21, pruin, P8_21(PIN_INPUT | MUX_MODE6))
+
+	/* P8_22 (ZCZ ball V8) gpmc_ad5 (emmc) */
+	BONE_PIN(P8_22, default, P8_22(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_22, gpio, P8_22(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_22, gpio_pu, P8_22(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_22, gpio_pd, P8_22(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_23 (ZCZ ball U8) gpmc_ad4 (emmc) */
+	BONE_PIN(P8_23, default, P8_23(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_23, gpio, P8_23(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_23, gpio_pu, P8_23(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_23, gpio_pd, P8_23(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_24 (ZCZ ball V7) gpmc_ad1 (emmc) */
+	BONE_PIN(P8_24, default, P8_24(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_24, gpio, P8_24(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_24, gpio_pu, P8_24(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_24, gpio_pd, P8_24(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_25 (ZCZ ball U7) gpmc_ad0 (emmc) */
+	BONE_PIN(P8_25, default, P8_25(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_25, gpio, P8_25(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_25, gpio_pu, P8_25(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_25, gpio_pd, P8_25(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P8_26 (ZCZ ball V6) gpio-hog wl1835 */
+
+	/* P8_27 (ZCZ ball U5) lcd_vsync (hdmi) */
+	BONE_PIN(P8_27, default, P8_27(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_27, gpio, P8_27(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_27, gpio_pu, P8_27(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_27, gpio_pd, P8_27(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_27, pruout, P8_27(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_27, pruin, P8_27(PIN_INPUT | MUX_MODE6))
+
+	/* P8_28 (ZCZ ball V5) lcd_pclk (hdmi) */
+	BONE_PIN(P8_28, default, P8_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_28, gpio, P8_28(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_28, gpio_pu, P8_28(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_28, gpio_pd, P8_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_28, pruout, P8_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_28, pruin, P8_28(PIN_INPUT | MUX_MODE6))
+
+	/* P8_29 (ZCZ ball R5) lcd_hsync (hdmi) */
+	BONE_PIN(P8_29, default, P8_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_29, gpio, P8_29(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_29, gpio_pu, P8_29(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_29, gpio_pd, P8_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_29, pruout, P8_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_29, pruin, P8_29(PIN_INPUT | MUX_MODE6))
+
+	/* P8_30 (ZCZ ball R6) lcd_ac_bias_en (hdmi) */
+	BONE_PIN(P8_30, default, P8_30(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_30, gpio, P8_30(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_30, gpio_pu, P8_30(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_30, gpio_pd, P8_30(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_30, pruout, P8_30(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_30, pruin, P8_30(PIN_INPUT | MUX_MODE6))
+
+	/* P8_31 (ZCZ ball V4) lcd_data14 (hdmi) */
+	BONE_PIN(P8_31, default, P8_31(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_31, gpio, P8_31(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_31, gpio_pu, P8_31(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_31, gpio_pd, P8_31(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_31, eqep, P8_31(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P8_31, uart, P8_31(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P8_32 (ZCZ ball T5) lcd_data15 (hdmi) */
+	BONE_PIN(P8_32, default, P8_32(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_32, gpio, P8_32(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_32, gpio_pu, P8_32(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_32, gpio_pd, P8_32(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_32, eqep, P8_32(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_33 (ZCZ ball V3) lcd_data13 (hdmi) */
+	BONE_PIN(P8_33, default, P8_33(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_33, gpio, P8_33(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_33, gpio_pu, P8_33(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_33, gpio_pd, P8_33(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_33, eqep, P8_33(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_34 (ZCZ ball U4) lcd_data11 (hdmi) */
+	BONE_PIN(P8_34, default, P8_34(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_34, gpio, P8_34(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_34, gpio_pu, P8_34(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_34, gpio_pd, P8_34(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_34, pwm, P8_34(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE2))
+
+	/* P8_35 (ZCZ ball V2) lcd_data12 (hdmi) */
+	BONE_PIN(P8_35, default, P8_35(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_35, gpio, P8_35(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_35, gpio_pu, P8_35(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_35, gpio_pd, P8_35(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_35, eqep, P8_35(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+
+	/* P8_36 (ZCZ ball U3) lcd_data10 (hdmi) */
+	BONE_PIN(P8_36, default, P8_36(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_36, gpio, P8_36(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_36, gpio_pu, P8_36(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_36, gpio_pd, P8_36(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_36, pwm, P8_36(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE2))
+
+	/* P8_37 (ZCZ ball U1) lcd_data8 (hdmi) */
+	BONE_PIN(P8_37, default, P8_37(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_37, gpio, P8_37(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_37, gpio_pu, P8_37(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_37, gpio_pd, P8_37(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_37, pwm, P8_37(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P8_37, uart, P8_37(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P8_38 (ZCZ ball U2) lcd_data9 (hdmi) */
+	BONE_PIN(P8_38, default, P8_38(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_38, gpio, P8_38(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_38, gpio_pu, P8_38(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_38, gpio_pd, P8_38(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_38, pwm, P8_38(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P8_38, uart, P8_38(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P8_39 (ZCZ ball T3) lcd_data6 (hdmi) */
+	BONE_PIN(P8_39, default, P8_39(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_39, gpio, P8_39(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_39, gpio_pu, P8_39(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_39, gpio_pd, P8_39(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_39, eqep, P8_39(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_39, pruout, P8_39(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_39, pruin, P8_39(PIN_INPUT | MUX_MODE6))
+
+	/* P8_40 (ZCZ ball T4) lcd_data7 (hdmi) */
+	BONE_PIN(P8_40, default, P8_40(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_40, gpio, P8_40(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_40, gpio_pu, P8_40(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_40, gpio_pd, P8_40(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_40, eqep, P8_40(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_40, pruout, P8_40(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_40, pruin, P8_40(PIN_INPUT | MUX_MODE6))
+
+	/* P8_41 (ZCZ ball T1) lcd_data4 (hdmi) */
+	BONE_PIN(P8_41, default, P8_41(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_41, gpio, P8_41(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_41, gpio_pu, P8_41(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_41, gpio_pd, P8_41(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_41, eqep, P8_41(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_41, pruout, P8_41(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_41, pruin, P8_41(PIN_INPUT | MUX_MODE6))
+
+	/* P8_42 (ZCZ ball T2) lcd_data5 (hdmi) */
+	BONE_PIN(P8_42, default, P8_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_42, gpio, P8_42(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_42, gpio_pu, P8_42(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_42, gpio_pd, P8_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_42, eqep, P8_42(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_42, pruout, P8_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_42, pruin, P8_42(PIN_INPUT | MUX_MODE6))
+
+	/* P8_43 (ZCZ ball R3) lcd_data2 (hdmi) */
+	BONE_PIN(P8_43, default, P8_43(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_43, gpio, P8_43(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_43, gpio_pu, P8_43(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_43, gpio_pd, P8_43(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_43, pwm, P8_43(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_43, pruout, P8_43(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_43, pruin, P8_43(PIN_INPUT | MUX_MODE6))
+
+	/* P8_44 (ZCZ ball R4) lcd_data3 (hdmi) */
+	BONE_PIN(P8_44, default, P8_44(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_44, gpio, P8_44(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_44, gpio_pu, P8_44(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_44, gpio_pd, P8_44(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_44, pwm, P8_44(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_44, pruout, P8_44(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_44, pruin, P8_44(PIN_INPUT | MUX_MODE6))
+
+	/* P8_45 (ZCZ ball R1) lcd_data0 (hdmi) */
+	BONE_PIN(P8_45, default, P8_45(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_45, gpio, P8_45(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_45, gpio_pu, P8_45(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_45, gpio_pd, P8_45(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_45, pwm, P8_45(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_45, pruout, P8_45(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_45, pruin, P8_45(PIN_INPUT | MUX_MODE6))
+
+	/* P8_46 (ZCZ ball R2) lcd_data1 (hdmi) */
+	BONE_PIN(P8_46, default, P8_46(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_46, gpio, P8_46(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_46, gpio_pu, P8_46(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_46, gpio_pd, P8_46(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P8_46, pwm, P8_46(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P8_46, pruout, P8_46(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P8_46, pruin, P8_46(PIN_INPUT | MUX_MODE6))
+
+	/************************/
+	/* P9 Header */
+	/************************/
+
+	/* P9_01                GND */
+
+	/* P9_02                GND */
+
+	/* P9_03                3V3 */
+
+	/* P9_04                3V3 */
+
+	/* P9_05                VDD_5V */
+
+	/* P9_06                VDD_5V */
+
+	/* P9_07                SYS_5V */
+
+	/* P9_08                SYS_5V */
+
+	/* P9_09                PWR_BUT */
+
+	/* P9_10                RSTn */
+
+	/* P9_11 (ZCZ ball T17) gpmc_wait0 (gpio0_30) */
+	BONE_PIN(P9_11, default, P9_11(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_11, gpio, P9_11(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_11, gpio_pu, P9_11(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_11, gpio_pd, P9_11(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_11, uart, P9_11(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE6))
+
+	/* P9_12 (ZCZ ball U18) gpmc_be1n (gpio1_28) */
+	BONE_PIN(P9_12, default, P9_12(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_12, gpio, P9_12(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_12, gpio_pu, P9_12(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_12, gpio_pd, P9_12(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+
+	/* P9_13 (ZCZ ball U17) gpmc_wpn (gpio0_31) */
+	BONE_PIN(P9_13, default, P9_13(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_13, gpio, P9_13(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_13, gpio_pu, P9_13(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_13, gpio_pd, P9_13(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_13, uart, P9_13(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE6))
+
+	/* P9_14 (ZCZ ball U14) gpmc_a2 (gpio1_18) */
+	BONE_PIN(P9_14, default, P9_14(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_14, gpio, P9_14(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_14, gpio_pu, P9_14(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_14, gpio_pd, P9_14(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_14, pwm, P9_14(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE6))
+
+	/* P9_15 (ZCZ ball R13) gpmc_a0 (gpio1_16) */
+	BONE_PIN(P9_15, default, P9_15(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_15, gpio, P9_15(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_15, gpio_pu, P9_15(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_15, gpio_pd, P9_15(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_15, pwm, P9_15(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE6))
+
+	/* P9_16 (ZCZ ball T14) gpmc_a3 (gpio1_19) */
+	BONE_PIN(P9_16, default, P9_16(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_16, gpio, P9_16(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_16, gpio_pu, P9_16(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_16, gpio_pd, P9_16(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_16, pwm, P9_16(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE6))
+
+	/* P9_17 (ZCZ ball A16) spi0_cs0 (gpio0_5) */
+	BONE_PIN(P9_17, default, P9_17(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_17, gpio, P9_17(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_17, gpio_pu, P9_17(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_17, gpio_pd, P9_17(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_17, spi_cs, P9_17(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE0))
+	BONE_PIN(P9_17, i2c, P9_17(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P9_17, pwm, P9_17(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_17, pru_uart, P9_17(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P9_18 (ZCZ ball B16) spi0_d1 (gpio0_4) */
+	BONE_PIN(P9_18, default, P9_18(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_18, gpio, P9_18(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_18, gpio_pu, P9_18(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_18, gpio_pd, P9_18(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_18, spi, P9_18(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE0))
+	BONE_PIN(P9_18, i2c, P9_18(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P9_18, pwm, P9_18(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_18, pru_uart, P9_18(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P9_19 (ZCZ ball D17) uart1_rtsn (i2c2_scl) */
+	BONE_PIN(P9_19, default, P9_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_19, gpio, P9_19(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_19, gpio_pu, P9_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_19, gpio_pd, P9_19(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_19, timer, P9_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_19, can, P9_19(PIN_INPUT_PULLUP | MUX_MODE2))
+	BONE_PIN(P9_19, i2c, P9_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_19, spi_cs, P9_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P9_19, pru_uart, P9_19(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE5))
+
+	/* P9_20 (ZCZ ball D18) uart1_ctsn (i2c2_sda) */
+	BONE_PIN(P9_20, default, P9_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_20, gpio, P9_20(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_20, gpio_pu, P9_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_20, gpio_pd, P9_20(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_20, timer, P9_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_20, can, P9_20(PIN_OUTPUT_PULLUP | MUX_MODE2))
+	BONE_PIN(P9_20, i2c, P9_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_20, spi_cs, P9_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P9_20, pru_uart, P9_20(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE5))
+
+	/* P9_21 (ZCZ ball B17) spi0_d0 (gpio0_3) */
+	BONE_PIN(P9_21, default, P9_21(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_21, gpio, P9_21(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_21, gpio_pu, P9_21(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_21, gpio_pd, P9_21(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_21, spi, P9_21(PIN_INPUT_PULLUP | MUX_MODE0))
+	BONE_PIN(P9_21, uart, P9_21(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_21, i2c, P9_21(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P9_21, pwm, P9_21(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_21, pru_uart, P9_21(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P9_22 (ZCZ ball A17) spi0_sclk (gpio0_2) */
+	BONE_PIN(P9_22, default, P9_22(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_22, gpio, P9_22(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_22, gpio_pu, P9_22(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_22, gpio_pd, P9_22(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_22, spi_sclk, P9_22(PIN_INPUT_PULLUP | MUX_MODE0))
+	BONE_PIN(P9_22, uart, P9_22(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_22, i2c, P9_22(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P9_22, pwm, P9_22(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_22, pru_uart, P9_22(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+
+	/* P9_23 (ZCZ ball V14) gpmc_a1 (gpio1_17) */
+	BONE_PIN(P9_23, default, P9_23(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_23, gpio, P9_23(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_23, gpio_pu, P9_23(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_23, gpio_pd, P9_23(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_23, pwm, P9_23(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE6))
+
+	/* P9_24 (ZCZ ball D15) uart1_txd (gpio0_15) */
+	BONE_PIN(P9_24, default, P9_24(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_24, gpio, P9_24(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_24, gpio_pu, P9_24(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_24, gpio_pd, P9_24(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_24, uart, P9_24(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE0))
+	BONE_PIN(P9_24, can, P9_24(PIN_INPUT_PULLUP | MUX_MODE2))
+	BONE_PIN(P9_24, i2c, P9_24(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_24, pru_uart, P9_24(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_24, pruin, P9_24(PIN_INPUT | MUX_MODE6))
+
+	/* P9_25 (ZCZ ball A14) mcasp0_ahclkx (audio) */
+	BONE_PIN(P9_25, default, P9_25(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_25, gpio, P9_25(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_25, gpio_pu, P9_25(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_25, gpio_pd, P9_25(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_25, eqep, P9_25(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_25, pruout, P9_25(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_25, pruin, P9_25(PIN_INPUT | MUX_MODE6))
+
+	/* P9_26 (ZCZ ball D16) uart1_rxd (gpio0_14) */
+	BONE_PIN(P9_26, default, P9_26(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_26, gpio, P9_26(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_26, gpio_pu, P9_26(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_26, gpio_pd, P9_26(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_26, uart, P9_26(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE0))
+	BONE_PIN(P9_26, can, P9_26(PIN_OUTPUT_PULLUP | MUX_MODE2))
+	BONE_PIN(P9_26, i2c, P9_26(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_26, pru_uart, P9_26(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_26, pruin, P9_26(PIN_INPUT | MUX_MODE6))
+
+	/* P9_27 (ZCZ ball C13) mcasp0_fsr (gpio3_19) */
+	BONE_PIN(P9_27, default, P9_27(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_27, gpio, P9_27(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_27, gpio_pu, P9_27(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_27, gpio_pd, P9_27(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_27, eqep, P9_27(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_27, pruout, P9_27(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_27, pruin, P9_27(PIN_INPUT | MUX_MODE6))
+
+	/* P9_28 (ZCZ ball C12) mcasp0_ahclkr (audio) */
+	BONE_PIN(P9_28, default, P9_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_28, gpio, P9_28(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_28, gpio_pu, P9_28(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_28, gpio_pd, P9_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_28, pwm, P9_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_28, spi_cs, P9_28(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_28, pwm2, P9_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P9_28, pruout, P9_28(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_28, pruin, P9_28(PIN_INPUT | MUX_MODE6))
+
+	/* P9_29 (ZCZ ball B13) mcasp0_fsx (audio) */
+	BONE_PIN(P9_29, default, P9_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_29, gpio, P9_29(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_29, gpio_pu, P9_29(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_29, gpio_pd, P9_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_29, pwm, P9_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_29, spi, P9_29(PIN_INPUT_PULLUP | MUX_MODE3))
+	BONE_PIN(P9_29, pruout, P9_29(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_29, pruin, P9_29(PIN_INPUT | MUX_MODE6))
+
+	/* P9_30 (ZCZ ball D12) gpio-hog wl1835 */
+
+	/* P9_31 (ZCZ ball A13) mcasp0_aclkx (audio) */
+	BONE_PIN(P9_31, default, P9_31(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_31, gpio, P9_31(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_31, gpio_pu, P9_31(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_31, gpio_pd, P9_31(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_31, pwm, P9_31(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_31, spi_sclk, P9_31(PIN_INPUT_PULLUP | MUX_MODE3))
+	BONE_PIN(P9_31, pruout, P9_31(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_31, pruin, P9_31(PIN_INPUT | MUX_MODE6))
+
+	/* P9_32                VADC */
+
+	/* P9_33 (ZCZ ball C8)  AIN4 */
+
+	/* P9_34                AGND */
+
+	/* P9_35 (ZCZ ball A8)  AIN6 */
+
+	/* P9_36 (ZCZ ball B8)  AIN5 */
+
+	/* P9_37 (ZCZ ball B7)  AIN2 */
+
+	/* P9_38 (ZCZ ball A7)  AIN3 */
+
+	/* P9_39 (ZCZ ball B6)  AIN0 */
+
+	/* P9_40 (ZCZ ball C7)  AIN1 */
+
+	/* P9_41 (ZCZ ball D14) xdma_event_intr1 (gpio0_20) */
+	BONE_PIN(P9_41, default, P9_41(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_41, gpio, P9_41(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_41, gpio_pu, P9_41(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_41, gpio_pd, P9_41(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_41, timer, P9_41(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4))
+	BONE_PIN(P9_41, pruin, P9_41(PIN_INPUT | MUX_MODE5))
+
+	/* P9_41.1 */
+	/* P9_91 (ZCZ ball D13) mcasp0_axr1 (gpio3_20) */
+	BONE_PIN(P9_91, default, P9_91(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_91, gpio, P9_91(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_91, gpio_pu, P9_91(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_91, gpio_pd, P9_91(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_91, eqep, P9_91(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_91, pruout, P9_91(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_91, pruin, P9_91(PIN_INPUT | MUX_MODE6))
+
+	/* P9_42 (ZCZ ball C18) eCAP0_in_PWM0_out (gpio0_7) */
+	BONE_PIN(P9_42, default, P9_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_42, gpio, P9_42(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_42, gpio_pu, P9_42(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_42, gpio_pd, P9_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_42, pwm, P9_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE0))
+	BONE_PIN(P9_42, uart, P9_42(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_42, spi_cs, P9_42(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE2))
+	BONE_PIN(P9_42, pru_ecap_pwm, P9_42(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3))
+	BONE_PIN(P9_42, spi_sclk, P9_42(PIN_INPUT_PULLUP | MUX_MODE4))
+
+	/* P9_42.1 */
+	/* P9_92 (ZCZ ball B12) mcasp0_aclkr (gpio3_18) */
+	BONE_PIN(P9_92, default, P9_92(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_92, gpio, P9_92(PIN_OUTPUT | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_92, gpio_pu, P9_92(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_92, gpio_pd, P9_92(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE7))
+	BONE_PIN(P9_92, eqep, P9_92(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE1))
+	BONE_PIN(P9_92, pruout, P9_92(PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE5))
+	BONE_PIN(P9_92, pruin, P9_92(PIN_INPUT | MUX_MODE6))
+
+	/* P9_43                GND */
+
+	/* P9_44                GND */
+
+	/* P9_45                GND */
+
+	/* P9_46                GND */
+};
+
+&i2c1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+
+	clock-frequency = <100000>;
+	symlink = "bone/i2c/1";
+};
+
+&i2c2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+
+	clock-frequency = <100000>;
+	symlink = "bone/i2c/2";
+};
+
+&uart1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/uart/1";
+};
+
+&uart2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/uart/2";
+};
+
+&uart3 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/uart/3";
+};
+
+&uart4 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/uart/4";
+};
+
+&uart5 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/uart/5";
+};
+
+&dcan0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/can/0";
+};
+
+&dcan1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/can/1";
+};
+
+&eqep0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/eqep/0";
+};
+
+&eqep1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/eqep/1";
+};
+
+&eqep2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+	symlink = "bone/eqep/2";
+};
+
+&epwmss0 {
+	status = "okay";
+};
+
+&epwmss1 {
+	status = "okay";
+};
+
+&epwmss2 {
+	status = "okay";
+};
+
+&ehrpwm0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
+&ehrpwm1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
+&ehrpwm2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
+&ecap0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
+&ecap1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
+&ecap2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+};
+
+&spi0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+
+	channel@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "rohm,dh2228fv";
+		symlink = "bone/spi/0.0";
+
+		reg = <0>;
+		spi-max-frequency = <16000000>;
+		spi-cpha;
+	};
+
+	channel@1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "rohm,dh2228fv";
+		symlink = "bone/spi/0.1";
+
+		reg = <1>;
+		spi-max-frequency = <16000000>;
+	};
+};
+
+&spi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <>;
+
+	channel@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "rohm,dh2228fv";
+		symlink = "bone/spi/1.0";
+
+		reg = <0>;
+		spi-max-frequency = <16000000>;
+		spi-cpha;
+	};
+
+	channel@1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "rohm,dh2228fv";
+		symlink = "bone/spi/1.1";
+
+		reg = <1>;
+		spi-max-frequency = <16000000>;
+	};
+};
+
+/**********************************************************************/
+/* Pin Multiplex Helpers                                              */
+/*                                                                    */
+/* These provide userspace runtime pin configuration for the          */
+/* BeagleBone cape expansion headers                                  */
+/**********************************************************************/
+
+&ocp {
+	/************************/
+	/* P8 Header */
+	/************************/
+
+	/* P8_01                GND */
+
+	/* P8_02                GND */
+
+
+	/* P8_03 (ZCZ ball R9) emmc */
+	P8_03_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_03_default_pin>;
+		pinctrl-1 = <&P8_03_gpio_pin>;
+		pinctrl-2 = <&P8_03_gpio_pu_pin>;
+		pinctrl-3 = <&P8_03_gpio_pd_pin>;
+	};
+
+	/* P8_04 (ZCZ ball T9) emmc */
+	P8_04_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_04_default_pin>;
+		pinctrl-1 = <&P8_04_gpio_pin>;
+		pinctrl-2 = <&P8_04_gpio_pu_pin>;
+		pinctrl-3 = <&P8_04_gpio_pd_pin>;
+	};
+
+	/* P8_05 (ZCZ ball R8) emmc */
+	P8_05_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_05_default_pin>;
+		pinctrl-1 = <&P8_05_gpio_pin>;
+		pinctrl-2 = <&P8_05_gpio_pu_pin>;
+		pinctrl-3 = <&P8_05_gpio_pd_pin>;
+	};
+
+	/* P8_06 (ZCZ ball T8) emmc */
+	P8_06_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_06_default_pin>;
+		pinctrl-1 = <&P8_06_gpio_pin>;
+		pinctrl-2 = <&P8_06_gpio_pu_pin>;
+		pinctrl-3 = <&P8_06_gpio_pd_pin>;
+	};
+
+	/* P8_07 (ZCZ ball R7) */
+	P8_07_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer";
+		pinctrl-0 = <&P8_07_default_pin>;
+		pinctrl-1 = <&P8_07_gpio_pin>;
+		pinctrl-2 = <&P8_07_gpio_pu_pin>;
+		pinctrl-3 = <&P8_07_gpio_pd_pin>;
+		pinctrl-4 = <&P8_07_timer_pin>;
+	};
+
+	/* P8_08 (ZCZ ball T7) */
+	P8_08_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer";
+		pinctrl-0 = <&P8_08_default_pin>;
+		pinctrl-1 = <&P8_08_gpio_pin>;
+		pinctrl-2 = <&P8_08_gpio_pu_pin>;
+		pinctrl-3 = <&P8_08_gpio_pd_pin>;
+		pinctrl-4 = <&P8_08_timer_pin>;
+	};
+
+	/* P8_09 (ZCZ ball T6) */
+	P8_09_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer";
+		pinctrl-0 = <&P8_09_default_pin>;
+		pinctrl-1 = <&P8_09_gpio_pin>;
+		pinctrl-2 = <&P8_09_gpio_pu_pin>;
+		pinctrl-3 = <&P8_09_gpio_pd_pin>;
+		pinctrl-4 = <&P8_09_timer_pin>;
+	};
+
+	/* P8_10 (ZCZ ball U6) */
+	P8_10_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer";
+		pinctrl-0 = <&P8_10_default_pin>;
+		pinctrl-1 = <&P8_10_gpio_pin>;
+		pinctrl-2 = <&P8_10_gpio_pu_pin>;
+		pinctrl-3 = <&P8_10_gpio_pd_pin>;
+		pinctrl-4 = <&P8_10_timer_pin>;
+	};
+
+	/* P8_11 (ZCZ ball R12) */
+	P8_11_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout";
+		pinctrl-0 = <&P8_11_default_pin>;
+		pinctrl-1 = <&P8_11_gpio_pin>;
+		pinctrl-2 = <&P8_11_gpio_pu_pin>;
+		pinctrl-3 = <&P8_11_gpio_pd_pin>;
+		pinctrl-4 = <&P8_11_eqep_pin>;
+		pinctrl-5 = <&P8_11_pruout_pin>;
+	};
+
+	/* P8_12 (ZCZ ball T12) */
+	P8_12_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout";
+		pinctrl-0 = <&P8_12_default_pin>;
+		pinctrl-1 = <&P8_12_gpio_pin>;
+		pinctrl-2 = <&P8_12_gpio_pu_pin>;
+		pinctrl-3 = <&P8_12_gpio_pd_pin>;
+		pinctrl-4 = <&P8_12_eqep_pin>;
+		pinctrl-5 = <&P8_12_pruout_pin>;
+	};
+
+	/* P8_13 (ZCZ ball T10) */
+	P8_13_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P8_13_default_pin>;
+		pinctrl-1 = <&P8_13_gpio_pin>;
+		pinctrl-2 = <&P8_13_gpio_pu_pin>;
+		pinctrl-3 = <&P8_13_gpio_pd_pin>;
+		pinctrl-4 = <&P8_13_pwm_pin>;
+	};
+
+	/* P8_14 (ZCZ ball T11) wl1835: wl_en */
+
+	/* P8_15 (ZCZ ball U13) */
+	P8_15_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pru_ecap_pwm", "pruin";
+		pinctrl-0 = <&P8_15_default_pin>;
+		pinctrl-1 = <&P8_15_gpio_pin>;
+		pinctrl-2 = <&P8_15_gpio_pu_pin>;
+		pinctrl-3 = <&P8_15_gpio_pd_pin>;
+		pinctrl-4 = <&P8_15_eqep_pin>;
+		pinctrl-5 = <&P8_15_pru_ecap_pwm_pin>;
+		pinctrl-6 = <&P8_15_pruin_pin>;
+	};
+
+	/* P8_16 (ZCZ ball V13) */
+	P8_16_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruin";
+		pinctrl-0 = <&P8_16_default_pin>;
+		pinctrl-1 = <&P8_16_gpio_pin>;
+		pinctrl-2 = <&P8_16_gpio_pu_pin>;
+		pinctrl-3 = <&P8_16_gpio_pd_pin>;
+		pinctrl-4 = <&P8_16_eqep_pin>;
+		pinctrl-5 = <&P8_16_pruin_pin>;
+	};
+
+	/* P8_17 (ZCZ ball U12) wl1835: wl_irq */
+
+	/* P8_18 (ZCZ ball V12) */
+	P8_18_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_18_default_pin>;
+		pinctrl-1 = <&P8_18_gpio_pin>;
+		pinctrl-2 = <&P8_18_gpio_pu_pin>;
+		pinctrl-3 = <&P8_18_gpio_pd_pin>;
+	};
+
+	/* P8_19 (ZCZ ball U10) */
+	P8_19_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P8_19_default_pin>;
+		pinctrl-1 = <&P8_19_gpio_pin>;
+		pinctrl-2 = <&P8_19_gpio_pu_pin>;
+		pinctrl-3 = <&P8_19_gpio_pd_pin>;
+		pinctrl-4 = <&P8_19_pwm_pin>;
+	};
+
+	/* P8_20 (ZCZ ball V9) emmc */
+	P8_20_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin";
+		pinctrl-0 = <&P8_20_default_pin>;
+		pinctrl-1 = <&P8_20_gpio_pin>;
+		pinctrl-2 = <&P8_20_gpio_pu_pin>;
+		pinctrl-3 = <&P8_20_gpio_pd_pin>;
+		pinctrl-4 = <&P8_20_pruout_pin>;
+		pinctrl-5 = <&P8_20_pruin_pin>;
+	};
+
+	/* P8_21 (ZCZ ball U9) emmc */
+	P8_21_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin";
+		pinctrl-0 = <&P8_21_default_pin>;
+		pinctrl-1 = <&P8_21_gpio_pin>;
+		pinctrl-2 = <&P8_21_gpio_pu_pin>;
+		pinctrl-3 = <&P8_21_gpio_pd_pin>;
+		pinctrl-4 = <&P8_21_pruout_pin>;
+		pinctrl-5 = <&P8_21_pruin_pin>;
+	};
+
+	/* P8_22 (ZCZ ball V8) emmc */
+	P8_22_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_22_default_pin>;
+		pinctrl-1 = <&P8_22_gpio_pin>;
+		pinctrl-2 = <&P8_22_gpio_pu_pin>;
+		pinctrl-3 = <&P8_22_gpio_pd_pin>;
+	};
+
+	/* P8_23 (ZCZ ball U8) emmc */
+	P8_23_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_23_default_pin>;
+		pinctrl-1 = <&P8_23_gpio_pin>;
+		pinctrl-2 = <&P8_23_gpio_pu_pin>;
+		pinctrl-3 = <&P8_23_gpio_pd_pin>;
+	};
+
+	/* P8_24 (ZCZ ball V7) emmc */
+	P8_24_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_24_default_pin>;
+		pinctrl-1 = <&P8_24_gpio_pin>;
+		pinctrl-2 = <&P8_24_gpio_pu_pin>;
+		pinctrl-3 = <&P8_24_gpio_pd_pin>;
+	};
+
+	/* P8_25 (ZCZ ball U7) emmc */
+	P8_25_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P8_25_default_pin>;
+		pinctrl-1 = <&P8_25_gpio_pin>;
+		pinctrl-2 = <&P8_25_gpio_pu_pin>;
+		pinctrl-3 = <&P8_25_gpio_pd_pin>;
+	};
+
+	/* P8_26 (ZCZ ball V6) gpio-hog wl1835 */
+
+	/* P8_27 (ZCZ ball U5) hdmi */
+	P8_27_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin";
+		pinctrl-0 = <&P8_27_default_pin>;
+		pinctrl-1 = <&P8_27_gpio_pin>;
+		pinctrl-2 = <&P8_27_gpio_pu_pin>;
+		pinctrl-3 = <&P8_27_gpio_pd_pin>;
+		pinctrl-4 = <&P8_27_pruout_pin>;
+		pinctrl-5 = <&P8_27_pruin_pin>;
+	};
+
+	/* P8_28 (ZCZ ball V5) hdmi */
+	P8_28_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin";
+		pinctrl-0 = <&P8_28_default_pin>;
+		pinctrl-1 = <&P8_28_gpio_pin>;
+		pinctrl-2 = <&P8_28_gpio_pu_pin>;
+		pinctrl-3 = <&P8_28_gpio_pd_pin>;
+		pinctrl-4 = <&P8_28_pruout_pin>;
+		pinctrl-5 = <&P8_28_pruin_pin>;
+	};
+
+	/* P8_29 (ZCZ ball R5) hdmi */
+	P8_29_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin";
+		pinctrl-0 = <&P8_29_default_pin>;
+		pinctrl-1 = <&P8_29_gpio_pin>;
+		pinctrl-2 = <&P8_29_gpio_pu_pin>;
+		pinctrl-3 = <&P8_29_gpio_pd_pin>;
+		pinctrl-4 = <&P8_29_pruout_pin>;
+		pinctrl-5 = <&P8_29_pruin_pin>;
+	};
+
+	/* P8_30 (ZCZ ball R6) hdmi */
+	P8_30_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin";
+		pinctrl-0 = <&P8_30_default_pin>;
+		pinctrl-1 = <&P8_30_gpio_pin>;
+		pinctrl-2 = <&P8_30_gpio_pu_pin>;
+		pinctrl-3 = <&P8_30_gpio_pd_pin>;
+		pinctrl-4 = <&P8_30_pruout_pin>;
+		pinctrl-5 = <&P8_30_pruin_pin>;
+	};
+
+	/* P8_31 (ZCZ ball V4) hdmi */
+	P8_31_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "eqep";
+		pinctrl-0 = <&P8_31_default_pin>;
+		pinctrl-1 = <&P8_31_gpio_pin>;
+		pinctrl-2 = <&P8_31_gpio_pu_pin>;
+		pinctrl-3 = <&P8_31_gpio_pd_pin>;
+		pinctrl-4 = <&P8_31_uart_pin>;
+		pinctrl-5 = <&P8_31_eqep_pin>;
+	};
+
+	/* P8_32 (ZCZ ball T5) hdmi */
+	P8_32_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep";
+		pinctrl-0 = <&P8_32_default_pin>;
+		pinctrl-1 = <&P8_32_gpio_pin>;
+		pinctrl-2 = <&P8_32_gpio_pu_pin>;
+		pinctrl-3 = <&P8_32_gpio_pd_pin>;
+		pinctrl-4 = <&P8_32_eqep_pin>;
+	};
+
+	/* P8_33 (ZCZ ball V3) hdmi */
+	P8_33_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep";
+		pinctrl-0 = <&P8_33_default_pin>;
+		pinctrl-1 = <&P8_33_gpio_pin>;
+		pinctrl-2 = <&P8_33_gpio_pu_pin>;
+		pinctrl-3 = <&P8_33_gpio_pd_pin>;
+		pinctrl-4 = <&P8_33_eqep_pin>;
+	};
+
+	/* P8_34 (ZCZ ball U4) hdmi */
+	P8_34_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P8_34_default_pin>;
+		pinctrl-1 = <&P8_34_gpio_pin>;
+		pinctrl-2 = <&P8_34_gpio_pu_pin>;
+		pinctrl-3 = <&P8_34_gpio_pd_pin>;
+		pinctrl-4 = <&P8_34_pwm_pin>;
+	};
+
+	/* P8_35 (ZCZ ball V2) hdmi */
+	P8_35_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep";
+		pinctrl-0 = <&P8_35_default_pin>;
+		pinctrl-1 = <&P8_35_gpio_pin>;
+		pinctrl-2 = <&P8_35_gpio_pu_pin>;
+		pinctrl-3 = <&P8_35_gpio_pd_pin>;
+		pinctrl-4 = <&P8_35_eqep_pin>;
+	};
+
+	/* P8_36 (ZCZ ball U3) hdmi */
+	P8_36_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P8_36_default_pin>;
+		pinctrl-1 = <&P8_36_gpio_pin>;
+		pinctrl-2 = <&P8_36_gpio_pu_pin>;
+		pinctrl-3 = <&P8_36_gpio_pd_pin>;
+		pinctrl-4 = <&P8_36_pwm_pin>;
+	};
+
+	/* P8_37 (ZCZ ball U1) hdmi */
+	P8_37_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "pwm";
+		pinctrl-0 = <&P8_37_default_pin>;
+		pinctrl-1 = <&P8_37_gpio_pin>;
+		pinctrl-2 = <&P8_37_gpio_pu_pin>;
+		pinctrl-3 = <&P8_37_gpio_pd_pin>;
+		pinctrl-4 = <&P8_37_uart_pin>;
+		pinctrl-5 = <&P8_37_pwm_pin>;
+	};
+
+	/* P8_38 (ZCZ ball U2) hdmi */
+	P8_38_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "pwm";
+		pinctrl-0 = <&P8_38_default_pin>;
+		pinctrl-1 = <&P8_38_gpio_pin>;
+		pinctrl-2 = <&P8_38_gpio_pu_pin>;
+		pinctrl-3 = <&P8_38_gpio_pd_pin>;
+		pinctrl-4 = <&P8_38_uart_pin>;
+		pinctrl-5 = <&P8_38_pwm_pin>;
+	};
+
+	/* P8_39 (ZCZ ball T3) hdmi */
+	P8_39_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P8_39_default_pin>;
+		pinctrl-1 = <&P8_39_gpio_pin>;
+		pinctrl-2 = <&P8_39_gpio_pu_pin>;
+		pinctrl-3 = <&P8_39_gpio_pd_pin>;
+		pinctrl-4 = <&P8_39_eqep_pin>;
+		pinctrl-5 = <&P8_39_pruout_pin>;
+		pinctrl-6 = <&P8_39_pruin_pin>;
+	};
+
+	/* P8_40 (ZCZ ball T4) hdmi */
+	P8_40_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P8_40_default_pin>;
+		pinctrl-1 = <&P8_40_gpio_pin>;
+		pinctrl-2 = <&P8_40_gpio_pu_pin>;
+		pinctrl-3 = <&P8_40_gpio_pd_pin>;
+		pinctrl-4 = <&P8_40_eqep_pin>;
+		pinctrl-5 = <&P8_40_pruout_pin>;
+		pinctrl-6 = <&P8_40_pruin_pin>;
+	};
+
+	/* P8_41 (ZCZ ball T1) hdmi */
+	P8_41_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P8_41_default_pin>;
+		pinctrl-1 = <&P8_41_gpio_pin>;
+		pinctrl-2 = <&P8_41_gpio_pu_pin>;
+		pinctrl-3 = <&P8_41_gpio_pd_pin>;
+		pinctrl-4 = <&P8_41_eqep_pin>;
+		pinctrl-5 = <&P8_41_pruout_pin>;
+		pinctrl-6 = <&P8_41_pruin_pin>;
+	};
+
+	/* P8_42 (ZCZ ball T2) hdmi */
+	P8_42_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P8_42_default_pin>;
+		pinctrl-1 = <&P8_42_gpio_pin>;
+		pinctrl-2 = <&P8_42_gpio_pu_pin>;
+		pinctrl-3 = <&P8_42_gpio_pd_pin>;
+		pinctrl-4 = <&P8_42_eqep_pin>;
+		pinctrl-5 = <&P8_42_pruout_pin>;
+		pinctrl-6 = <&P8_42_pruin_pin>;
+	};
+
+	/* P8_43 (ZCZ ball R3) hdmi */
+	P8_43_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P8_43_default_pin>;
+		pinctrl-1 = <&P8_43_gpio_pin>;
+		pinctrl-2 = <&P8_43_gpio_pu_pin>;
+		pinctrl-3 = <&P8_43_gpio_pd_pin>;
+		pinctrl-4 = <&P8_43_pwm_pin>;
+		pinctrl-5 = <&P8_43_pruout_pin>;
+		pinctrl-6 = <&P8_43_pruin_pin>;
+	};
+
+	/* P8_44 (ZCZ ball R4) hdmi */
+	P8_44_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P8_44_default_pin>;
+		pinctrl-1 = <&P8_44_gpio_pin>;
+		pinctrl-2 = <&P8_44_gpio_pu_pin>;
+		pinctrl-3 = <&P8_44_gpio_pd_pin>;
+		pinctrl-4 = <&P8_44_pwm_pin>;
+		pinctrl-5 = <&P8_44_pruout_pin>;
+		pinctrl-6 = <&P8_44_pruin_pin>;
+	};
+
+	/* P8_45 (ZCZ ball R1) hdmi */
+	P8_45_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P8_45_default_pin>;
+		pinctrl-1 = <&P8_45_gpio_pin>;
+		pinctrl-2 = <&P8_45_gpio_pu_pin>;
+		pinctrl-3 = <&P8_45_gpio_pd_pin>;
+		pinctrl-4 = <&P8_45_pwm_pin>;
+		pinctrl-5 = <&P8_45_pruout_pin>;
+		pinctrl-6 = <&P8_45_pruin_pin>;
+	};
+
+	/* P8_46 (ZCZ ball R2) hdmi */
+	P8_46_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P8_46_default_pin>;
+		pinctrl-1 = <&P8_46_gpio_pin>;
+		pinctrl-2 = <&P8_46_gpio_pu_pin>;
+		pinctrl-3 = <&P8_46_gpio_pd_pin>;
+		pinctrl-4 = <&P8_46_pwm_pin>;
+		pinctrl-5 = <&P8_46_pruout_pin>;
+		pinctrl-6 = <&P8_46_pruin_pin>;
+	};
+
+	/************************/
+	/* P9 Header */
+	/************************/
+
+	/* P9_01                GND */
+
+	/* P9_02                GND */
+
+	/* P9_03                3V3 */
+
+	/* P9_04                3V3 */
+
+	/* P9_05                VDD_5V */
+
+	/* P9_06                VDD_5V */
+
+	/* P9_07                SYS_5V */
+
+	/* P9_08                SYS_5V */
+
+	/* P9_09                PWR_BUT */
+
+	/* P9_10                RSTn */
+
+	/* P9_11 (ZCZ ball T17) */
+	P9_11_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart";
+		pinctrl-0 = <&P9_11_default_pin>;
+		pinctrl-1 = <&P9_11_gpio_pin>;
+		pinctrl-2 = <&P9_11_gpio_pu_pin>;
+		pinctrl-3 = <&P9_11_gpio_pd_pin>;
+		pinctrl-4 = <&P9_11_uart_pin>;
+	};
+
+	/* P9_12 (ZCZ ball U18) */
+	P9_12_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd";
+		pinctrl-0 = <&P9_12_default_pin>;
+		pinctrl-1 = <&P9_12_gpio_pin>;
+		pinctrl-2 = <&P9_12_gpio_pu_pin>;
+		pinctrl-3 = <&P9_12_gpio_pd_pin>;
+	};
+
+	/* P9_13 (ZCZ ball U17) */
+	P9_13_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart";
+		pinctrl-0 = <&P9_13_default_pin>;
+		pinctrl-1 = <&P9_13_gpio_pin>;
+		pinctrl-2 = <&P9_13_gpio_pu_pin>;
+		pinctrl-3 = <&P9_13_gpio_pd_pin>;
+		pinctrl-4 = <&P9_13_uart_pin>;
+	};
+
+	/* P9_14 (ZCZ ball U14) */
+	P9_14_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P9_14_default_pin>;
+		pinctrl-1 = <&P9_14_gpio_pin>;
+		pinctrl-2 = <&P9_14_gpio_pu_pin>;
+		pinctrl-3 = <&P9_14_gpio_pd_pin>;
+		pinctrl-4 = <&P9_14_pwm_pin>;
+	};
+
+	/* P9_15 (ZCZ ball R13) */
+	P9_15_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P9_15_default_pin>;
+		pinctrl-1 = <&P9_15_gpio_pin>;
+		pinctrl-2 = <&P9_15_gpio_pu_pin>;
+		pinctrl-3 = <&P9_15_gpio_pd_pin>;
+		pinctrl-4 = <&P9_15_pwm_pin>;
+	};
+
+	/* P9_16 (ZCZ ball T14) */
+	P9_16_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P9_16_default_pin>;
+		pinctrl-1 = <&P9_16_gpio_pin>;
+		pinctrl-2 = <&P9_16_gpio_pu_pin>;
+		pinctrl-3 = <&P9_16_gpio_pd_pin>;
+		pinctrl-4 = <&P9_16_pwm_pin>;
+	};
+
+	/* P9_17 (ZCZ ball A16) */
+	P9_17_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_cs", "i2c", "pwm", "pru_uart";
+		pinctrl-0 = <&P9_17_default_pin>;
+		pinctrl-1 = <&P9_17_gpio_pin>;
+		pinctrl-2 = <&P9_17_gpio_pu_pin>;
+		pinctrl-3 = <&P9_17_gpio_pd_pin>;
+		pinctrl-4 = <&P9_17_spi_cs_pin>;
+		pinctrl-5 = <&P9_17_i2c_pin>;
+		pinctrl-6 = <&P9_17_pwm_pin>;
+		pinctrl-7 = <&P9_17_pru_uart_pin>;
+	};
+
+	/* P9_18 (ZCZ ball B16) */
+	P9_18_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "i2c", "pwm", "pru_uart";
+		pinctrl-0 = <&P9_18_default_pin>;
+		pinctrl-1 = <&P9_18_gpio_pin>;
+		pinctrl-2 = <&P9_18_gpio_pu_pin>;
+		pinctrl-3 = <&P9_18_gpio_pd_pin>;
+		pinctrl-4 = <&P9_18_spi_pin>;
+		pinctrl-5 = <&P9_18_i2c_pin>;
+		pinctrl-6 = <&P9_18_pwm_pin>;
+		pinctrl-7 = <&P9_18_pru_uart_pin>;
+	};
+
+	/* P9_19 (ZCZ ball D17) i2c */
+	P9_19_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_cs", "can", "i2c", "pru_uart", "timer";
+		pinctrl-0 = <&P9_19_default_pin>;
+		pinctrl-1 = <&P9_19_gpio_pin>;
+		pinctrl-2 = <&P9_19_gpio_pu_pin>;
+		pinctrl-3 = <&P9_19_gpio_pd_pin>;
+		pinctrl-4 = <&P9_19_spi_cs_pin>;
+		pinctrl-5 = <&P9_19_can_pin>;
+		pinctrl-6 = <&P9_19_i2c_pin>;
+		pinctrl-7 = <&P9_19_pru_uart_pin>;
+		pinctrl-8 = <&P9_19_timer_pin>;
+	};
+
+	/* P9_20 (ZCZ ball D18) i2c */
+	P9_20_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_cs", "can", "i2c", "pru_uart", "timer";
+		pinctrl-0 = <&P9_20_default_pin>;
+		pinctrl-1 = <&P9_20_gpio_pin>;
+		pinctrl-2 = <&P9_20_gpio_pu_pin>;
+		pinctrl-3 = <&P9_20_gpio_pd_pin>;
+		pinctrl-4 = <&P9_20_spi_cs_pin>;
+		pinctrl-5 = <&P9_20_can_pin>;
+		pinctrl-6 = <&P9_20_i2c_pin>;
+		pinctrl-7 = <&P9_20_pru_uart_pin>;
+		pinctrl-8 = <&P9_20_timer_pin>;
+	};
+
+	/* P9_21 (ZCZ ball B17) */
+	P9_21_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm", "pru_uart";
+		pinctrl-0 = <&P9_21_default_pin>;
+		pinctrl-1 = <&P9_21_gpio_pin>;
+		pinctrl-2 = <&P9_21_gpio_pu_pin>;
+		pinctrl-3 = <&P9_21_gpio_pd_pin>;
+		pinctrl-4 = <&P9_21_spi_pin>;
+		pinctrl-5 = <&P9_21_uart_pin>;
+		pinctrl-6 = <&P9_21_i2c_pin>;
+		pinctrl-7 = <&P9_21_pwm_pin>;
+		pinctrl-8 = <&P9_21_pru_uart_pin>;
+	};
+
+	/* P9_22 (ZCZ ball A17) */
+	P9_22_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_sclk", "uart", "i2c", "pwm", "pru_uart";
+		pinctrl-0 = <&P9_22_default_pin>;
+		pinctrl-1 = <&P9_22_gpio_pin>;
+		pinctrl-2 = <&P9_22_gpio_pu_pin>;
+		pinctrl-3 = <&P9_22_gpio_pd_pin>;
+		pinctrl-4 = <&P9_22_spi_sclk_pin>;
+		pinctrl-5 = <&P9_22_uart_pin>;
+		pinctrl-6 = <&P9_22_i2c_pin>;
+		pinctrl-7 = <&P9_22_pwm_pin>;
+		pinctrl-8 = <&P9_22_pru_uart_pin>;
+	};
+
+	/* P9_23 (ZCZ ball V14) */
+	P9_23_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm";
+		pinctrl-0 = <&P9_23_default_pin>;
+		pinctrl-1 = <&P9_23_gpio_pin>;
+		pinctrl-2 = <&P9_23_gpio_pu_pin>;
+		pinctrl-3 = <&P9_23_gpio_pd_pin>;
+		pinctrl-4 = <&P9_23_pwm_pin>;
+	};
+
+	/* P9_24 (ZCZ ball D15) */
+	P9_24_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pru_uart", "pruin";
+		pinctrl-0 = <&P9_24_default_pin>;
+		pinctrl-1 = <&P9_24_gpio_pin>;
+		pinctrl-2 = <&P9_24_gpio_pu_pin>;
+		pinctrl-3 = <&P9_24_gpio_pd_pin>;
+		pinctrl-4 = <&P9_24_uart_pin>;
+		pinctrl-5 = <&P9_24_can_pin>;
+		pinctrl-6 = <&P9_24_i2c_pin>;
+		pinctrl-7 = <&P9_24_pru_uart_pin>;
+		pinctrl-8 = <&P9_24_pruin_pin>;
+	};
+
+	/* P9_25 (ZCZ ball A14) audio */
+	P9_25_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P9_25_default_pin>;
+		pinctrl-1 = <&P9_25_gpio_pin>;
+		pinctrl-2 = <&P9_25_gpio_pu_pin>;
+		pinctrl-3 = <&P9_25_gpio_pd_pin>;
+		pinctrl-4 = <&P9_25_eqep_pin>;
+		pinctrl-5 = <&P9_25_pruout_pin>;
+		pinctrl-6 = <&P9_25_pruin_pin>;
+	};
+
+	/* P9_26 (ZCZ ball D16) */
+	P9_26_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pru_uart", "pruin";
+		pinctrl-0 = <&P9_26_default_pin>;
+		pinctrl-1 = <&P9_26_gpio_pin>;
+		pinctrl-2 = <&P9_26_gpio_pu_pin>;
+		pinctrl-3 = <&P9_26_gpio_pd_pin>;
+		pinctrl-4 = <&P9_26_uart_pin>;
+		pinctrl-5 = <&P9_26_can_pin>;
+		pinctrl-6 = <&P9_26_i2c_pin>;
+		pinctrl-7 = <&P9_26_pru_uart_pin>;
+		pinctrl-8 = <&P9_26_pruin_pin>;
+	};
+
+	/* P9_27 (ZCZ ball C13) */
+	P9_27_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P9_27_default_pin>;
+		pinctrl-1 = <&P9_27_gpio_pin>;
+		pinctrl-2 = <&P9_27_gpio_pu_pin>;
+		pinctrl-3 = <&P9_27_gpio_pd_pin>;
+		pinctrl-4 = <&P9_27_eqep_pin>;
+		pinctrl-5 = <&P9_27_pruout_pin>;
+		pinctrl-6 = <&P9_27_pruin_pin>;
+	};
+
+	/* P9_28 (ZCZ ball C12) audio */
+	P9_28_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_cs", "pwm", "pwm2", "pruout", "pruin";
+		pinctrl-0 = <&P9_28_default_pin>;
+		pinctrl-1 = <&P9_28_gpio_pin>;
+		pinctrl-2 = <&P9_28_gpio_pu_pin>;
+		pinctrl-3 = <&P9_28_gpio_pd_pin>;
+		pinctrl-4 = <&P9_28_spi_cs_pin>;
+		pinctrl-5 = <&P9_28_pwm_pin>;
+		pinctrl-6 = <&P9_28_pwm2_pin>;
+		pinctrl-7 = <&P9_28_pruout_pin>;
+		pinctrl-8 = <&P9_28_pruin_pin>;
+	};
+
+	/* P9_29 (ZCZ ball B13) audio */
+	P9_29_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P9_29_default_pin>;
+		pinctrl-1 = <&P9_29_gpio_pin>;
+		pinctrl-2 = <&P9_29_gpio_pu_pin>;
+		pinctrl-3 = <&P9_29_gpio_pd_pin>;
+		pinctrl-4 = <&P9_29_spi_pin>;
+		pinctrl-5 = <&P9_29_pwm_pin>;
+		pinctrl-6 = <&P9_29_pruout_pin>;
+		pinctrl-7 = <&P9_29_pruin_pin>;
+	};
+
+	/* P9_30 (ZCZ ball D12) gpio-hog wl1835 */
+
+	/* P9_31 (ZCZ ball A13) audio */
+	P9_31_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_sclk", "pwm", "pruout", "pruin";
+		pinctrl-0 = <&P9_31_default_pin>;
+		pinctrl-1 = <&P9_31_gpio_pin>;
+		pinctrl-2 = <&P9_31_gpio_pu_pin>;
+		pinctrl-3 = <&P9_31_gpio_pd_pin>;
+		pinctrl-4 = <&P9_31_spi_sclk_pin>;
+		pinctrl-5 = <&P9_31_pwm_pin>;
+		pinctrl-6 = <&P9_31_pruout_pin>;
+		pinctrl-7 = <&P9_31_pruin_pin>;
+	};
+
+	/* P9_32                VADC */
+
+	/* P9_33 (ZCZ ball C8)  AIN4 */
+
+	/* P9_34                AGND */
+
+	/* P9_35 (ZCZ ball A8)  AIN6 */
+
+	/* P9_36 (ZCZ ball B8)  AIN5 */
+
+	/* P9_37 (ZCZ ball B7)  AIN2 */
+
+	/* P9_38 (ZCZ ball A7)  AIN3 */
+
+	/* P9_39 (ZCZ ball B6)  AIN0 */
+
+	/* P9_40 (ZCZ ball C7)  AIN1 */
+
+	/* P9_41 (ZCZ ball D14) */
+	P9_41_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer", "pruin";
+		pinctrl-0 = <&P9_41_default_pin>;
+		pinctrl-1 = <&P9_41_gpio_pin>;
+		pinctrl-2 = <&P9_41_gpio_pu_pin>;
+		pinctrl-3 = <&P9_41_gpio_pd_pin>;
+		pinctrl-4 = <&P9_41_timer_pin>;
+		pinctrl-5 = <&P9_41_pruin_pin>;
+	};
+
+	/* P9_41.1 */
+	/* P9_91 (ZCZ ball D13) */
+	P9_91_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P9_91_default_pin>;
+		pinctrl-1 = <&P9_91_gpio_pin>;
+		pinctrl-2 = <&P9_91_gpio_pu_pin>;
+		pinctrl-3 = <&P9_91_gpio_pd_pin>;
+		pinctrl-4 = <&P9_91_eqep_pin>;
+		pinctrl-5 = <&P9_91_pruout_pin>;
+		pinctrl-6 = <&P9_91_pruin_pin>;
+	};
+
+	/* P9_42 (ZCZ ball C18) */
+	P9_42_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi_cs", "spi_sclk", "uart", "pwm", "pru_ecap_pwm";
+		pinctrl-0 = <&P9_42_default_pin>;
+		pinctrl-1 = <&P9_42_gpio_pin>;
+		pinctrl-2 = <&P9_42_gpio_pu_pin>;
+		pinctrl-3 = <&P9_42_gpio_pd_pin>;
+		pinctrl-4 = <&P9_42_spi_cs_pin>;
+		pinctrl-5 = <&P9_42_spi_sclk_pin>;
+		pinctrl-6 = <&P9_42_uart_pin>;
+		pinctrl-7 = <&P9_42_pwm_pin>;
+		pinctrl-8 = <&P9_42_pru_ecap_pwm_pin>;
+	};
+
+	/* P9_42.1 */
+	/* P9_92 (ZCZ ball B12) */
+	P9_92_pinmux {
+		compatible = "bone-pinmux-helper";
+		status = "okay";
+		pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "eqep", "pruout", "pruin";
+		pinctrl-0 = <&P9_92_default_pin>;
+		pinctrl-1 = <&P9_92_gpio_pin>;
+		pinctrl-2 = <&P9_92_gpio_pu_pin>;
+		pinctrl-3 = <&P9_92_gpio_pd_pin>;
+		pinctrl-4 = <&P9_92_eqep_pin>;
+		pinctrl-5 = <&P9_92_pruout_pin>;
+		pinctrl-6 = <&P9_92_pruin_pin>;
+	};
+
+	/* P9_43                GND */
+
+	/* P9_44                GND */
+
+	/* P9_45                GND */
+
+	/* P9_46                GND */
+
+	cape-universal {
+		compatible = "gpio-of-helper";
+		status = "okay";
+		pinctrl-names = "default";
+		pinctrl-0 = <>;
+
+		P8_03 {
+			gpio-name = "P8_03";
+			gpio = <&gpio1 6 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_04 {
+			gpio-name = "P8_04";
+			gpio = <&gpio1 7 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_05 {
+			gpio-name = "P8_05";
+			gpio = <&gpio1 2 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_06 {
+			gpio-name = "P8_06";
+			gpio = <&gpio1 3 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_07 {
+			gpio-name = "P8_07";
+			gpio = <&gpio2 2 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_08 {
+			gpio-name = "P8_08";
+			gpio = <&gpio2 3 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_09 {
+			gpio-name = "P8_09";
+			gpio = <&gpio2 5 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_10 {
+			gpio-name = "P8_10";
+			gpio = <&gpio2 4 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_11 {
+			gpio-name = "P8_11";
+			gpio = <&gpio1 13 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_12 {
+			gpio-name = "P8_12";
+			gpio = <&gpio1 12 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_13 {
+			gpio-name = "P8_13";
+			gpio = <&gpio0 23 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_15 {
+			gpio-name = "P8_15";
+			gpio = <&gpio1 15 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_16 {
+			gpio-name = "P8_16";
+			gpio = <&gpio1 14 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_18 {
+			gpio-name = "P8_18";
+			gpio = <&gpio2 1 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_19 {
+			gpio-name = "P8_19";
+			gpio = <&gpio0 22 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_20 {
+			gpio-name = "P8_20";
+			gpio = <&gpio1 31 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_21 {
+			gpio-name = "P8_21";
+			gpio = <&gpio1 30 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_22 {
+			gpio-name = "P8_22";
+			gpio = <&gpio1 5 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_23 {
+			gpio-name = "P8_23";
+			gpio = <&gpio1 4 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_24 {
+			gpio-name = "P8_24";
+			gpio = <&gpio1 1 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_25 {
+			gpio-name = "P8_25";
+			gpio = <&gpio1 0 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_27 {
+			gpio-name = "P8_27";
+			gpio = <&gpio2 22 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_28 {
+			gpio-name = "P8_28";
+			gpio = <&gpio2 24 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_29 {
+			gpio-name = "P8_29";
+			gpio = <&gpio2 23 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_30 {
+			gpio-name = "P8_30";
+			gpio = <&gpio2 25 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_31 {
+			gpio-name = "P8_31";
+			gpio = <&gpio0 10 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_32 {
+			gpio-name = "P8_32";
+			gpio = <&gpio0 11 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_33 {
+			gpio-name = "P8_33";
+			gpio = <&gpio0 9 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_34 {
+			gpio-name = "P8_34";
+			gpio = <&gpio2 17 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_35 {
+			gpio-name = "P8_35";
+			gpio = <&gpio0 8 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_36 {
+			gpio-name = "P8_36";
+			gpio = <&gpio2 16 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_37 {
+			gpio-name = "P8_37";
+			gpio = <&gpio2 14 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_38 {
+			gpio-name = "P8_38";
+			gpio = <&gpio2 15 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_39 {
+			gpio-name = "P8_39";
+			gpio = <&gpio2 12 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_40 {
+			gpio-name = "P8_40";
+			gpio = <&gpio2 13 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_41 {
+			gpio-name = "P8_41";
+			gpio = <&gpio2 10 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_42 {
+			gpio-name = "P8_42";
+			gpio = <&gpio2 11 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_43 {
+			gpio-name = "P8_43";
+			gpio = <&gpio2 8 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_44 {
+			gpio-name = "P8_44";
+			gpio = <&gpio2 9 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_45 {
+			gpio-name = "P8_45";
+			gpio = <&gpio2 6 0>;
+			input;
+			dir-changeable;
+		};
+
+		P8_46 {
+			gpio-name = "P8_46";
+			gpio = <&gpio2 7 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_11 {
+			gpio-name = "P9_11";
+			gpio = <&gpio0 30 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_12 {
+			gpio-name = "P9_12";
+			gpio = <&gpio1 28 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_13 {
+			gpio-name = "P9_13";
+			gpio = <&gpio0 31 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_14 {
+			gpio-name = "P9_14";
+			gpio = <&gpio1 18 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_15 {
+			gpio-name = "P9_15";
+			gpio = <&gpio1 16 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_16 {
+			gpio-name = "P9_16";
+			gpio = <&gpio1 19 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_17 {
+			gpio-name = "P9_17";
+			gpio = <&gpio0 5 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_18 {
+			gpio-name = "P9_18";
+			gpio = <&gpio0 4 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_19 {
+			gpio-name = "P9_19";
+			gpio = <&gpio0 13 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_20 {
+			gpio-name = "P9_20";
+			gpio = <&gpio0 12 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_21 {
+			gpio-name = "P9_21";
+			gpio = <&gpio0 3 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_22 {
+			gpio-name = "P9_22";
+			gpio = <&gpio0 2 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_23 {
+			gpio-name = "P9_23";
+			gpio = <&gpio1 17 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_24 {
+			gpio-name = "P9_24";
+			gpio = <&gpio0 15 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_25 {
+			gpio-name = "P9_25";
+			gpio = <&gpio3 21 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_26 {
+			gpio-name = "P9_26";
+			gpio = <&gpio0 14 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_27 {
+			gpio-name = "P9_27";
+			gpio = <&gpio3 19 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_28 {
+			gpio-name = "P9_28";
+			gpio = <&gpio3 17 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_29 {
+			gpio-name = "P9_29";
+			gpio = <&gpio3 15 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_31 {
+			gpio-name = "P9_31";
+			gpio = <&gpio3 14 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_41 {
+			gpio-name = "P9_41";
+			gpio = <&gpio0 20 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_91 {
+			gpio-name = "P9_91";
+			gpio = <&gpio3 20 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_42 {
+			gpio-name = "P9_42";
+			gpio = <&gpio0 7 0>;
+			input;
+			dir-changeable;
+		};
+
+		P9_92 {
+			gpio-name = "P9_92";
+			gpio = <&gpio3 18 0>;
+			input;
+			dir-changeable;
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-wireless.dts b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-wireless.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-wireless.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-wireless.dts	2025-10-23 09:30:40.281462084 -0400
@@ -13,6 +13,12 @@
 	model = "TI AM335x BeagleBone Green Wireless";
 	compatible = "ti,am335x-bone-green-wireless", "ti,am335x-bone-green", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
 
+	chosen {
+		base_dtb = "am335x-bonegreen-wireless.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+		wl1835_bt = "S3-texas-300000";
+	};
+
 	wlan_en_reg: fixedregulator@2 {
 		compatible = "regulator-fixed";
 		regulator-name = "wlan-en-regulator";
@@ -24,9 +30,60 @@
 		gpio = <&gpio0 26 0>;
 		enable-active-high;
 	};
+
+	leds {
+		pinctrl-names = "default";
+		//pinctrl-0 = <&user_leds_s0>;
+		pinctrl-0 = <&user_leds_s0 &bt_pins>;
+
+		compatible = "gpio-leds";
+
+		led2 {
+			label = "beaglebone:green:usr0";
+			gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+			default-state = "off";
+		};
+
+		led3 {
+			label = "beaglebone:green:usr1";
+			gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc0";
+			default-state = "off";
+		};
+
+		led4 {
+			label = "beaglebone:green:usr2";
+			gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "cpu0";
+			default-state = "off";
+		};
+
+		led5 {
+			label = "beaglebone:green:usr3";
+			gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc1";
+			default-state = "off";
+		};
+
+		wl18xx_bt_en: led7 {
+			label = "wl18xx_bt_en";
+			gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
 };
 
 &am33xx_pinmux {
+	user_leds_s0: user-leds-s0-pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A5, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gpmc_a5.gpio1_21 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A6, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpmc_a6.gpio1_22 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A7, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gpmc_a7.gpio1_23 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A8, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpmc_a8.gpio1_24 */
+		>;
+	};
+
 	bt_pins: bt-pins {
 		pinctrl-single,pins = <
 			AM33XX_PADCONF(AM335X_PIN_GPMC_BEN1, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpmc_ad12.gpio1_28 BT_EN */
@@ -63,6 +120,9 @@
 };
 
 &mac_sw {
+	/delete-property/pinctrl-names;
+	/delete-property/pinctrl-0;
+	/delete-property/pinctrl-1;
 	status = "disabled";
 };
 
@@ -91,13 +151,14 @@
 
 &uart3 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&uart3_pins &bt_pins>;
+	pinctrl-0 = <&uart3_pins>;
+	//pinctrl-0 = <&uart3_pins &bt_pins>;
 	status = "okay";
 
-	bluetooth {
-		compatible = "ti,wl1835-st";
-		enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
-	};
+	//bluetooth {
+	//	compatible = "ti,wl1835-st";
+	//	enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+	//};
 };
 
 &gpio1 {
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-wireless-uboot-univ.dts b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-wireless-uboot-univ.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-wireless-uboot-univ.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-wireless-uboot-univ.dts	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-bone-common.dtsi"
+#include "am335x-bonegreen-wireless-common-univ.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	model = "TI AM335x BeagleBone Green Wireless";
+	compatible = "ti,am335x-bone-green-wireless", "ti,am335x-bone-green", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+
+	chosen {
+		base_dtb = "am335x-bonegreen-wireless-uboot-univ.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
+};
+
+&ldo3_reg {
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-always-on;
+};
+
+&mmc1 {
+	vmmc-supply = <&vmmcsd_fixed>;
+};
+
+&gpio1 {
+	ls-buf-en-hog {
+		gpio-hog;
+		gpios = <29 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "LS_BUF_EN";
+	};
+};
+
+/* BT_AUD_OUT from wl1835 has to be pulled low when WL_EN is activated.*/
+/* in case it isn't, wilink8 ends up in one of the test modes that     */
+/* intruces various issues (elp wkaeup timeouts etc.)                  */
+/* On the BBGW this pin is routed through the level shifter (U21) that */
+/* introduces a pullup on the line and wilink8 ends up in a bad state. */
+/* use a gpio hog to force this pin low. An alternative may be adding  */
+/* an external pulldown on U21 pin 4.                                  */
+
+&gpio3 {
+	bt-aud-in-hog {
+		gpio-hog;
+		gpios = <16 GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "MCASP0_AHCLKR";
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts b/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts	2025-10-23 09:30:40.281462084 -0400
@@ -29,6 +29,11 @@
 		reg = <0x80000000 0x10000000>; /* 256 MB */
 	};
 
+	aliases {
+		serial0 = &uart0;
+		serial1 = &pruss_uart;
+	};
+
 	chosen {
 		stdout-path = &uart0;
 	};
@@ -441,6 +446,22 @@
 			AM33XX_PADCONF(AM335X_PIN_GPMC_CSN0, PIN_OUTPUT_PULLUP, MUX_MODE7) /* gpmc_csn0.gpio1_29 */
 		>;
 	};
+
+	pruss_uart_pins: pruss-uart-pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_SPI0_SCLK, PIN_INPUT_PULLDOWN, MUX_MODE4) /* spi0_sclk.pr1_uart0_cts_n */
+			AM33XX_PADCONF(AM335X_PIN_SPI0_D0, PIN_OUTPUT_PULLDOWN, MUX_MODE4) /* spi0_d0.pr1_uart0_rts_n */
+			AM33XX_PADCONF(AM335X_PIN_SPI0_D1, PIN_INPUT_PULLUP, MUX_MODE4) /* spi0_d1.pr1_uart0_rxd */
+			AM33XX_PADCONF(AM335X_PIN_SPI0_CS0, PIN_OUTPUT_PULLUP, MUX_MODE4) /* spi0_cs9.pr1_uart0_txd */
+		>;
+	};
+};
+
+&pruss_uart {
+	interrupts = <6 2 2>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pruss_uart_pins>;
+	status = "okay";
 };
 
 &uart0 {
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts b/arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts	2025-10-23 09:30:40.282462115 -0400
@@ -10,13 +10,16 @@
 
 #include "am33xx.dtsi"
 #include "am335x-osd335x-common.dtsi"
-#include <dt-bindings/interrupt-controller/irq.h>
-
-#include <dt-bindings/display/tda998x.h>
+#include "am335x-boneblack-hdmi.dtsi"
 
 / {
 	model = "Octavo Systems OSD3358-SM-RED";
 	compatible = "oct,osd3358-sm-refdesign", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+
+	chosen {
+		base_dtb = "am335x-osd3358-sm-red.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
 };
 
 &ldo3_reg {
@@ -33,48 +36,7 @@
 	status = "okay";
 };
 
-&lcdc {
-	status = "okay";
-
-	/* If you want to get 24 bit RGB and 16 BGR mode instead of
-	 * current 16 bit RGB and 24 BGR modes, set the propety
-	 * below to "crossed" and uncomment the video-ports -property
-	 * in tda19988 node.
-	 * AM335x errata for wiring:
-	 * https://www.ti.com/lit/er/sprz360i/sprz360i.pdf
-	 */
-
-	blue-and-red-wiring = "straight";
-
-	port {
-		lcdc_0: endpoint {
-			remote-endpoint = <&hdmi_0>;
-		};
-	};
-};
-
 &i2c0 {
-	tda19988: hdmi-encoder@70 {
-		compatible = "nxp,tda998x";
-		reg = <0x70>;
-
-		pinctrl-names = "default", "off";
-		pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
-		pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
-
-		/* Convert 24bit BGR to RGB, e.g. cross red and blue wiring */
-		/* video-ports = <0x234501>; */
-
-		#sound-dai-cells = <0>;
-		audio-ports = <	TDA998x_I2S	0x03>;
-
-		port {
-			hdmi_0: endpoint {
-				remote-endpoint = <&lcdc_0>;
-			};
-		};
-	};
-
 	mpu9250: imu@68 {
 		compatible = "invensense,mpu6050";
 		reg = <0x68>;
@@ -101,51 +63,7 @@
 	};
 };
 
-&mcasp0 {
-	#sound-dai-cells = <0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&mcasp0_pins>;
-	status = "okay";
-	op-mode = <0>;	/* MCASP_IIS_MODE */
-	tdm-slots = <2>;
-	serial-dir = <	/* 0: INACTIVE, 1: TX, 2: RX */
-			0 0 1 0
-		>;
-	tx-num-evt = <32>;
-	rx-num-evt = <32>;
-};
-
 / {
-	clk_mcasp0_fixed: clk-mcasp0-fixed {
-		#clock-cells = <0>;
-		compatible = "fixed-clock";
-		clock-frequency = <24576000>;
-	};
-
-	clk_mcasp0: clk-mcasp0 {
-		#clock-cells = <0>;
-		compatible = "gpio-gate-clock";
-		clocks = <&clk_mcasp0_fixed>;
-		enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */
-	};
-
-	sound {
-		compatible = "simple-audio-card";
-		simple-audio-card,name = "TI BeagleBone Black";
-		simple-audio-card,format = "i2s";
-		simple-audio-card,bitclock-master = <&dailink0_master>;
-		simple-audio-card,frame-master = <&dailink0_master>;
-
-		dailink0_master: simple-audio-card,cpu {
-			sound-dai = <&mcasp0>;
-			clocks = <&clk_mcasp0>;
-		};
-
-		simple-audio-card,codec {
-			sound-dai = <&tda19988>;
-		};
-	};
-
 	chosen {
 		stdout-path = &uart0;
 	};
@@ -194,51 +112,6 @@
 };
 
 &am33xx_pinmux {
-	pinctrl-names = "default";
-	pinctrl-0 = <&clkout2_pin>;
-
-	nxp_hdmi_bonelt_pins: nxp-hdmi-bonelt-pins {
-		pinctrl-single,pins = <
-			AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR0, PIN_OUTPUT_PULLDOWN, MUX_MODE3)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA0, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA1, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA2, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA3, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA4, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA5, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA6, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA7, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA10, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA11, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA14, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_DATA15, PIN_OUTPUT, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_HSYNC, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
-		>;
-	};
-
-	nxp_hdmi_bonelt_off_pins: nxp-hdmi-bonelt-off-pins {
-		pinctrl-single,pins = <
-			AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR0, PIN_OUTPUT_PULLDOWN, MUX_MODE3)
-		>;
-	};
-
-	mcasp0_pins: mcasp0-pins {
-		pinctrl-single,pins = <
-			AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKX, PIN_INPUT_PULLUP, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKR, PIN_OUTPUT_PULLDOWN, MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/
-			AM33XX_PADCONF(AM335X_PIN_MCASP0_FSX, PIN_OUTPUT_PULLUP, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKX, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
-			AM33XX_PADCONF(AM335X_PIN_GPMC_A11, PIN_OUTPUT_PULLDOWN, MUX_MODE7) /* gpmc_a11.GPIO1_27 */
-		>;
-	};
-
 	flash_enable: flash-enable-pins {
 		pinctrl-single,pins = <
 			AM33XX_PADCONF(AM335X_PIN_RMII1_REF_CLK, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* rmii1_ref_clk.gpio0_29 */
@@ -280,12 +153,6 @@
 		>;
 	};
 
-	clkout2_pin: pinmux-clkout2-pins {
-		pinctrl-single,pins = <
-			AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR1, PIN_OUTPUT_PULLDOWN, MUX_MODE3)	/* xdma_event_intr1.clkout2 */
-		>;
-	};
-
 	cpsw_default: cpsw-default-pins {
 		pinctrl-single,pins = <
 			/* Slave 1 */
@@ -372,6 +239,7 @@
 	pinctrl-0 = <&uart0_pins>;
 
 	status = "okay";
+	symlink = "bone/uart/0";
 };
 
 &usb0 {
@@ -389,6 +257,7 @@
 	pinctrl-0 = <&i2c2_pins>;
 	status = "okay";
 	clock-frequency = <100000>;
+	symlink = "bone/i2c/2";
 };
 
 &cpsw_port1 {
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-osd335x-common.dtsi b/arch/arm/boot/dts/ti/omap/am335x-osd335x-common.dtsi
--- a/arch/arm/boot/dts/ti/omap/am335x-osd335x-common.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-osd335x-common.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -49,6 +49,7 @@
 
 	status = "okay";
 	clock-frequency = <400000>;
+	symlink = "bone/i2c/0";
 
 	tps: tps@24 {
 		reg = <0x24>;
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts b/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts	2025-10-23 09:30:40.282462115 -0400
@@ -16,6 +16,8 @@
 
 	chosen {
 		stdout-path = &uart0;
+		base_dtb = "am335x-pocketbeagle.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
 	};
 
 	leds {
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe.dts b/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe.dts	2025-10-23 09:30:40.282462115 -0400
@@ -14,6 +14,11 @@
 / {
 	model = "SanCloud BeagleBone Enhanced";
 	compatible = "sancloud,am335x-boneenhanced", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+
+	chosen {
+		base_dtb = "am335x-sancloud-bbe.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
 };
 
 &am33xx_pinmux {
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts b/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts	2025-10-23 09:30:40.282462115 -0400
@@ -18,6 +18,11 @@
 		     "ti,am335x-bone",
 		     "ti,am33xx";
 
+	chosen {
+		base_dtb = "am335x-sancloud-bbe-extended-wifi.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
+
 	wlan_en_reg: fixedregulator@2 {
 		compatible = "regulator-fixed";
 		regulator-name = "wlan-en-regulator";
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-lite.dts b/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-lite.dts
--- a/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-lite.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-lite.dts	2025-10-23 09:30:40.282462115 -0400
@@ -16,6 +16,11 @@
 		     "ti,am335x-bone-black",
 		     "ti,am335x-bone",
 		     "ti,am33xx";
+
+	chosen {
+		base_dtb = "am335x-sancloud-bbe-lite.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
 };
 
 &am33xx_pinmux {
@@ -42,6 +47,7 @@
 		#size-cells = <0>;
 
 		compatible = "micron,spi-authenta";
+		symlink = "bone/spi/0.0";
 
 		reg = <0>;
 		spi-max-frequency = <16000000>;
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am33xx-l4.dtsi b/arch/arm/boot/dts/ti/omap/am33xx-l4.dtsi
--- a/arch/arm/boot/dts/ti/omap/am33xx-l4.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am33xx-l4.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -302,7 +302,7 @@
 				am33xx_pinmux: pinmux@800 {
 					compatible = "pinctrl-single";
 					reg = <0x800 0x238>;
-					#pinctrl-cells = <2>;
+					#pinctrl-cells = <1>;
 					pinctrl-single,register-width = <32>;
 					pinctrl-single,function-mask = <0x7f>;
 				};
@@ -891,6 +891,14 @@
 					};
 				};
 
+				pruss_uart: serial@28000 {
+					compatible = "ti,pruss-uart";
+					reg = <0x28000 0x38>;
+					clocks = <&dpll_per_m2_ck>;
+					interrupt-parent = <&pruss_intc>;
+					status = "disabled";
+				};
+
 				pruss_mii_rt: mii-rt@32000 {
 					compatible = "ti,pruss-mii", "syscon";
 					reg = <0x32000 0x58>;
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts b/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts
--- a/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts	2025-10-23 09:30:40.282462115 -0400
@@ -12,6 +12,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pinctrl/dra.h>
+#include "bbai-bone-buses.dtsi"
 
 / {
 	model = "BeagleBoard.org BeagleBone AI";
@@ -22,10 +23,19 @@
 		rtc0 = &tps659038_rtc;
 		rtc1 = &rtc;
 		display0 = &hdmi_conn;
+		mmc0 = &mmc1;
+		mmc1 = &mmc2;
+		mmc2 = &mmc4;
+		i2c0 = &i2c1;
+		i2c1 = &i2c5;
+		i2c2 = &i2c4;
+		i2c3 = &i2c3;
 	};
 
 	chosen {
 		stdout-path = &uart1;
+		base_dtb = "am5729-beagleboneai.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
 	};
 
 	memory@0 {
@@ -103,6 +113,8 @@
 
 	leds {
 		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins_default>;
 
 		led0 {
 			label = "beaglebone:green:usr0";
@@ -186,23 +198,100 @@
 	emmc_pwrseq: emmc_pwrseq {
 		compatible = "mmc-pwrseq-emmc";
 		reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&emmc_pwrseq_pins_default>;
 	};
 
 	brcmf_pwrseq: brcmf_pwrseq {
 		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		pinctrl-0 = <&brcmf_pwrseq_pins_default>;
 		reset-gpios = <&gpio3 22 GPIO_ACTIVE_LOW>,	/* BT-REG-ON */
 				<&gpio3 18 GPIO_ACTIVE_LOW>;	/* WL-REG-ON */
 	};
 
 	extcon_usb1: extcon_usb1 {
 		compatible = "linux,extcon-usb-gpio";
+		ti,enable-id-detection;
 		id-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&extcon_usb1_pins_default>;
+	};
+};
+
+&dra7_pmx_core {
+	extcon_usb1_pins_default: extcon_usb1_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3518, PIN_INPUT | MUX_MODE14) /* AG2: vin1a_d9.gpio3_13  - USR0 */
+		>;
+	};
+
+	led_pins_default: led_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3528, PIN_OUTPUT | MUX_MODE14) /* AF6: vin1a_d13.gpio3_17  - USR0 */
+			DRA7XX_CORE_IOPAD(0x36c0, PIN_OUTPUT | MUX_MODE14) /* J11: mcasp1_axr3.gpio5_5 - USR1 */
+			DRA7XX_CORE_IOPAD(0x3520, PIN_OUTPUT | MUX_MODE14) /* AG5: vin1a_d12.gpio3_15  - USR2 */
+			DRA7XX_CORE_IOPAD(0x351c, PIN_OUTPUT | MUX_MODE14) /* AG3: vin1a_d10.gpio3_14  - USR3 */
+			DRA7XX_CORE_IOPAD(0x3500, PIN_OUTPUT | MUX_MODE14) /* AH6: vin1a_d3.gpio3_7    - USR4 */
+		>;
+	};
+
+	emmc_pwrseq_pins_default: emmc_pwrseq_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x36c8, PIN_OUTPUT_PULLUP | MUX_MODE14) /* F13: mcasp1_axr5.gpio5_7 - eMMC_RSTn */
+		>;
+	};
+
+	brcmf_pwrseq_pins_default: brcmf_pwrseq_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x352c, PIN_OUTPUT_PULLUP | MUX_MODE14) /* AF3: vin1a_d14.gpio3_18 - WL_REG_ON */
+			DRA7XX_CORE_IOPAD(0x353c, PIN_OUTPUT_PULLUP | MUX_MODE14) /* AE5: vin1a_d18.gpio3_22 - BT_REG_ON */
+		>;
+	};
+
+	wifibt_extra_pins_default: wifibt_extra_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3540, PIN_INPUT | MUX_MODE14) /* AE1: vin1a_d19.gpio3_23 - WL_HOST_WAKE */
+			DRA7XX_CORE_IOPAD(0x3450, PIN_INPUT | MUX_MODE8) /* P6: vin1a_d20.uart6_rxd - UART6_RXD */
+			DRA7XX_CORE_IOPAD(0x3454, PIN_INPUT | MUX_MODE8) /* R9: vin1a_d21.uart6_txd - UART6_TXD */
+			DRA7XX_CORE_IOPAD(0x3458, PIN_INPUT | MUX_MODE8) /* R5: vin1a_d22.uart6_ctsn - UART6_CTSN */
+			DRA7XX_CORE_IOPAD(0x345c, PIN_INPUT | MUX_MODE8) /* P5: vin1a_d23.uart6_rtsn - UART6_RTSN */
+			DRA7XX_CORE_IOPAD(0x3534, PIN_INPUT_PULLDOWN | MUX_MODE14) /* AF1: vin1a_d16.gpio3_20 - BT_HOST_WAKE */
+			DRA7XX_CORE_IOPAD(0x3538, PIN_OUTPUT_PULLDOWN | MUX_MODE14) /* AE3: vin1a_d6.gpio3_21 - BT_WAKE */
+		>;
+	};
+
+	adc_pins_default: adc_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3550, PIN_OUTPUT | MUX_MODE14) /* AD3: vin1a_d23.gpio3_27 - VDD_ADC_SEL */
+			DRA7XX_CORE_IOPAD(0x34DC, PIN_INPUT_PULLUP | MUX_MODE14) /* AG8: vin1a_clk0.gpio2_30 - INT_ADC */
+		>;
+	};
+
+	pmic_pins_default: pmic_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3690, PIN_INPUT_PULLUP | MUX_MODE14) /* F21: gpio6_16.gpio6_16 - PMIC_INT */
+		>;
+	};
+
+	hdmi_pins_default: hdmi_pins_default {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3808, PIN_INPUT | MUX_MODE1) /* C25: i2c2_sda.hdmi1_ddc_scl - HDMI_DDC_SCL */
+			DRA7XX_CORE_IOPAD(0x380C, PIN_INPUT | MUX_MODE1) /* F17: i2c2_scl.hdmi1_ddc_sda - HDMI_DDC_SDA */
+			DRA7XX_CORE_IOPAD(0x37BC, PIN_INPUT | MUX_MODE6) /* B20: spi1_cs3.hdmi1_cec - HDMI_DDC_CEC */
+#if 0
+			DRA7XX_CORE_IOPAD(0x37B8, PIN_INPUT | MUX_MODE6) /* B21: spi1_cs2.hdmi1_hpd - HDMI_DDC_HPD */
+#else
+			DRA7XX_CORE_IOPAD(0x37B8, PIN_INPUT | MUX_MODE14) /* B21: spi1_cs2.gpio7_12 - HDMI_DDC_HPD */
+#endif
+		>;
 	};
 };
 
 &i2c1 {
 	status = "okay";
 	clock-frequency = <400000>;
+	symlink = "bone/i2c/0";
 
 	tps659038: tps659038@58 {
 		compatible = "ti,tps659038";
@@ -210,6 +299,9 @@
 		interrupt-parent = <&gpio6>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
 
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_pins_default>;
+
 		#interrupt-cells = <2>;
 		interrupt-controller;
 
@@ -422,6 +514,9 @@
 		st,adc-freq = <1>; /* 3.25 MHz ADC clock speed */
 		st,sample-time = <4>; /* ADC converstion time: 80 clocks */
 
+		pinctrl-names = "default";
+		pinctrl-0 = <&adc_pins_default>;
+
 		stmpe_adc {
 			compatible = "st,stmpe-adc";
 			st,norequest-mask = <0x00>; /* mask any channels to be used by touchscreen */
@@ -460,6 +555,11 @@
 			#pwm-cells = <2>;
 		};
 	};
+
+	eeprom: eeprom@50 {
+		compatible = "atmel,24c32";
+		reg = <0x50>;
+	};
 };
 
 &mcspi3 {
@@ -484,6 +584,7 @@
 
 &uart1 {
 	status = "okay";
+	symlink = "bone/uart/0";
 };
 
 &davinci_mdio_sw {
@@ -548,7 +649,11 @@
 	ti,needs-special-reset;
 	dmas = <&sdma_xbar 47>, <&sdma_xbar 48>;
 	dma-names = "tx", "rx";
-
+	pinctrl-names = "default", "hs", "ddr_1_8v", "hs200_1_8v";
+	pinctrl-0 = <&mmc2_pins_default>;
+	pinctrl-1 = <&mmc2_pins_hs>;
+	pinctrl-2 = <&mmc2_pins_ddr_rev20>;
+	pinctrl-3 = <&mmc2_pins_hs200>;
 };
 
 &mmc4 {
@@ -561,6 +666,10 @@
 	/* DDR50: DDR up to 50 MHz (1.8 V signaling). */
 	status = "okay";
 
+	pinctrl-names = "default", "hs";
+	pinctrl-0 = <&mmc4_pins_default &wifibt_extra_pins_default>;
+	pinctrl-1 = <&mmc4_pins_hs &wifibt_extra_pins_default>;
+
 	ti,needs-special-reset;
 	vmmc-supply = <&vdd_3v3>;
 	cap-power-off-card;
@@ -620,6 +729,8 @@
 &hdmi {
 	status = "okay";
 	vdda-supply = <&vdd_1v8_phy_ldo4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&hdmi_pins_default>;
 
 	port {
 		hdmi_out: endpoint {
@@ -673,6 +784,7 @@
 &i2c4 {
 	status = "okay";
 	clock-frequency = <100000>;
+	symlink = "bone/i2c/2";
 };
 
 &ipu2 {
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15.dts b/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15.dts
--- a/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15.dts	2025-10-23 09:30:40.282462115 -0400
@@ -8,6 +8,11 @@
 / {
 	/* NOTE: This describes the "original" pre-production A2 revision */
 	model = "TI AM5728 BeagleBoard-X15";
+
+	chosen {
+		base_dtb = "am57xx-beagle-x15.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
 };
 
 &tpd12s015 {
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15-revb1.dts b/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15-revb1.dts
--- a/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15-revb1.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15-revb1.dts	2025-10-23 09:30:40.282462115 -0400
@@ -7,6 +7,11 @@
 
 / {
 	model = "TI AM5728 BeagleBoard-X15 rev B1";
+
+	chosen {
+		base_dtb = "am57xx-beagle-x15-revb1.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
 };
 
 &tpd12s015 {
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15-revc.dts b/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15-revc.dts
--- a/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15-revc.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15-revc.dts	2025-10-23 09:30:40.282462115 -0400
@@ -7,6 +7,11 @@
 
 / {
 	model = "TI AM5728 BeagleBoard-X15 rev C";
+
+	chosen {
+		base_dtb = "am57xx-beagle-x15-revc.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
 };
 
 &tpd12s015 {
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/am57xx-evm-ov10635.dtso b/arch/arm/boot/dts/ti/omap/am57xx-evm-ov10635.dtso
--- a/arch/arm/boot/dts/ti/omap/am57xx-evm-ov10635.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/am57xx-evm-ov10635.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+#include <dt-bindings/gpio/gpio.h>
+
+&vip1 {
+	status = "okay";
+};
+
+&vip2 {
+	status = "okay";
+};
+
+
+&vip3 {
+	status = "okay";
+};
+
+/ {
+	fragment@101 {
+		target-path = "/";
+
+		__overlay__ {
+			clk_ov10635: clock-gate {
+				compatible = "gpio-gate-clock";
+				#clock-cells = <0>;
+				clocks = <&clk_ov10635_fixed>;
+				enable-gpios = <&gpio5 10 GPIO_ACTIVE_HIGH>;
+			};
+
+			clk_ov10635_fixed: clock-fixed {
+				compatible = "fixed-clock";
+				#clock-cells = <0>;
+				clock-frequency = <24000000>;
+			};
+		};
+	};
+};
+
+&i2c5 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ov10635@30 {
+		compatible = "ovti,ov10635";
+		reg = <0x30>;
+		clock-names = "xvclk";
+		clocks = <&clk_ov10635>;
+		powerdown-gpios = <&gpio5 11 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio4 17 GPIO_ACTIVE_HIGH>;
+
+		port {
+			cam: endpoint {
+				remote-endpoint = <&vin3a_ep>;
+				hsync-active = <1>;
+				pclk-sample = <1>;
+				vsync-active = <1>;
+				bus-width = <8>;
+			};
+		};
+	};
+};
+
+&vin3a {
+	vin3a_ep: endpoint {
+		remote-endpoint = <&cam>;
+		hsync-active = <1>;
+		pclk-sample = <1>;
+		vsync-active = <1>;
+	};
+};
+
+&gpio6 {
+	p11 {
+		gpio-hog;
+		gpios = <11 GPIO_ACTIVE_LOW>;
+		line-name = "cm-camen-gpio";
+		output-high;
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-ADC-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-ADC-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-ADC-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-ADC-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-ADC-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+&tscadc {
+	status = "okay";
+	adc {
+		// Configure one or more (up to 8) steps for the adc to execute:
+
+
+		// For each step, the channel to sample.
+		//	range: 0 .. 7
+		ti,adc-channels = <0 1 2 3 4 5 6 7>;
+		//
+		// BeagleBone Black (and most other variants):
+		//	ch 0	P9.39
+		//	ch 1	P9.40
+		//	ch 2	P9.37
+		//	ch 3	P9.38
+		//	ch 4	P9.33
+		//	ch 5	P9.36
+		//	ch 6	P9.35
+		//	ch 7	measures 0.5 * VDD_3V3B with 2.4 kÎ© source impedance
+		//
+		// PocketBeagle:
+		//	ch 0	P1.19
+		//	ch 1	P1.21
+		//	ch 2	P1.23
+		//	ch 3	P1.25
+		//	ch 4	P1.27
+		//	ch 5	P2.35 via 10k/10k voltage divider
+		//	ch 6	P1.02 via 10k/10k voltage divider
+		//	ch 7	P2.36 via pmic mux
+		//
+		// The divider used on PocketBeagle channels 5 and 6 makes the effective voltage V_eff and
+		// source impedance Z_eff seen by the adc on these channels depend on the voltage V_src and
+		// impedance Z_src of the source connected to the corresponding pin as follows:
+		//
+		//	V_eff = V_src / (2 + Z_src / (10 kÎ©))
+		//	Z_eff = 5 kÎ© * (1 + Z_src / (Z_src + 20 kÎ©))
+		//		â‰ˆ 5 kÎ© + Z_src / 4    for small values of Z_src (up to 2 kÎ© or so)
+
+
+		// For each step, number of adc clock cycles to wait between setting up muxes and sampling.
+		//	range: 0 .. 262143
+		//	optional, default is 152 (XXX but why?!)
+		ti,chan-step-opendelay = <152 152 152 152 152 152 152 152>;
+		//`
+		// XXX is there any purpose to set this nonzero other than to fine-tune the sample rate?
+
+
+		// For each step, how many times it should sample to average.
+		//	range: 1 .. 16, must be power of two (i.e. 1, 2, 4, 8, or 16)
+		//	optional, default is 16
+		ti,chan-step-avg = <16 16 16 16 16 16 16 16>;
+		//
+		// If you're using periodic sampling (using the iio block device rather than sysfs) then
+		// you should consider setting this to 1 and if desired reduce the samplerate in userspace
+		// instead since averaging isn't a particularly good low-pass filter.
+		//
+		// If you're using sysfs to occasionally read a value, then the default value of 16 will
+		// still get you the most accurate readings.
+
+
+		// For each step, number of adc clock cycles to sample minus two.
+		//	range: 0 .. 255   (resulting in sampling time of 2 .. 257 cycles)
+		//	optional, default is 0
+		ti,chan-step-sampledelay = <0 0 0 0 0 0 0 0>;
+		//
+		// If this is set too low, accuracy will deteriorate when the thing you're measuring has a
+		// high source impedance.  The maximum source impedance recommended (by erratum 1.0.32) is:
+		//	(2 + sampledelay) * 2.873 kÎ© - 0.2 kÎ©
+		// which means that the default should be fine for source impedance up to 5.5 kÎ©.
+		//
+		// (This seems to ensure the sampling time is at least 21 times the RC constant, based on
+		// the 5.5 pF nominal capacitance specified in the datasheet.)
+
+
+		// After sampling, conversion time is 13 adc clock cycles.
+		//
+		// The adc clock frequency is 3 MHz, therefore the total time per step in microseconds is:
+		//	( opendelay + avg * ( 2 + sampledelay + 13 ) ) / 3
+		//
+		// If all steps use the same timings then the sample rate will be:
+		//	3 MHz / ( opendelay + avg * ( 2 + sampledelay + 13 ) ) / number_of_steps
+		//
+		// The highest samplerate obtainable (avg=1, opendelay=0, sampledelay=0) is therefore:
+		//	200 kHz / number_of_steps
+		//	= 25 kHz    when using all 8 steps.
+		//
+		// Using avg=16 reduces that to:
+		//	12.5 kHz / number_of_steps
+		//	= 1.5625 kHz    when using all 8 steps.
+		//
+		// Using the default values (avg=16, opendelay=152, sampledelay=0) reduces that to:
+		//	7.653 kHz / number_of_steps
+		//	= 0.9566 kHz    when using all 8 steps.
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/bbai-bone-buses.dtsi b/arch/arm/boot/dts/ti/omap/bbai-bone-buses.dtsi
--- a/arch/arm/boot/dts/ti/omap/bbai-bone-buses.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/bbai-bone-buses.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 Deepak Khatri <deepaklorkhatri7@gmail.com>
+ * Copyright (C) 2021 Robert Nelson <robertcnelson@gmail.com>
+ * See Cape Interface Spec page for more info on Bone Buses
+ * https://elinux.org/Beagleboard:BeagleBone_cape_interface_spec
+ * https://docs.beagleboard.io/latest/boards/capes/cape-interface-spec.html
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/dra.h>
+
+// For dummy refrence when peripheral is not available.
+&{/} {
+	not_available: not_available {
+		// Use &not_available phandle when bus not available!
+		// This node is responsible to create these entries,
+		// /sys/firmware/devicetree/base/__symbols__/not_available
+		// /sys/firmware/devicetree/base/not_available
+	};
+};
+
+// For compatible bone pinmuxing
+bone_pinmux: &dra7_pmx_core {
+	bborg_comms_can_pins: pinmux_comms_can_pins {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x368C, PIN_INPUT_PULLUP | MUX_MODE2)		/* P9_24: F20: gpio6_15.dcan2_rx */
+			DRA7XX_CORE_IOPAD(0x3688, PIN_OUTPUT_PULLUP | MUX_MODE2)	/* P9_26A: E21: gpio6_14.dcan2_tx */
+			DRA7XX_CORE_IOPAD(0x3544, PIN_OUTPUT | MUX_MODE15)	/* P9_26B: AE2: vin1a_d20.off */
+		>;
+	};
+
+	bborg_comms_rs485_pins: pinmux_comms_rs485_pins {
+		pinctrl-single,pins = <
+			DRA7XX_CORE_IOPAD(0x3730, PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4)	/* P9_13A: C17: mcasp3_axr1.uart5_txd */
+			DRA7XX_CORE_IOPAD(0x3680, PIN_OUTPUT | MUX_MODE15)			/* P9_13B: AB10: usb1_drvvbus.off */
+			DRA7XX_CORE_IOPAD(0x372C, PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE4)	/* P9_11A: B19: mcasp3_axr0.uart5_rxd */
+			DRA7XX_CORE_IOPAD(0x3620, PIN_OUTPUT | MUX_MODE15)			/* P9_11B: B8: vout1_d17.off */
+		>;
+	};
+};
+
+// UART
+// https://docs.beagleboard.io/latest/boards/capes/cape-interface-spec.html#uart
+bone_uart_1: &uart10 {
+	symlink = "bone/uart/1";
+};
+
+bone_uart_2: &uart3 {
+	symlink = "bone/uart/2";
+};
+
+bone_uart_3: &not_available {
+	// not available on BBAI
+};
+
+bone_uart_4: &uart5 {
+	symlink = "bone/uart/4";
+	status = "disabled";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bborg_comms_rs485_pins>;
+};
+
+// CAN
+// https://docs.beagleboard.io/latest/boards/capes/cape-interface-spec.html#can
+bone_can_0: &not_available {
+	// Not available on BBAI
+};
+
+bone_can_1: &dcan2 {
+	symlink = "bone/can/1";
+	status = "disabled";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bborg_comms_can_pins>;
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-BBBW-WL1835-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-BBBW-WL1835-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-BBBW-WL1835-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-BBBW-WL1835-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-BBBW-WL1835-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+&{/} {
+	model = "TI AM335x BeagleBone Black Wireless";
+	compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+
+	wlan_en_reg: fixedregulator@2 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan-en-regulator";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us= <70000>;
+
+		/* WL_EN */
+		gpio = <&gpio3 9 0>;
+		enable-active-high;
+	};
+};
+
+&am33xx_pinmux {
+	bt_pins: pinmux_bt_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD0, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gmii1_txd0.gpio0_28 - BT_EN */
+		>;
+	};
+
+	mmc3_pins: pinmux_mmc3_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD1, PIN_INPUT_PULLUP, MUX_MODE6 ) /* (L15) gmii1_rxd1.mmc2_clk */
+			AM33XX_PADCONF(AM335X_PIN_MII1_TX_EN, PIN_INPUT_PULLUP, MUX_MODE6 ) /* (J16) gmii1_txen.mmc2_cmd */
+			AM33XX_PADCONF(AM335X_PIN_MII1_RX_DV, PIN_INPUT_PULLUP, MUX_MODE5 ) /* (J17) gmii1_rxdv.mmc2_dat0 */
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD3, PIN_INPUT_PULLUP, MUX_MODE5 ) /* (J18) gmii1_txd3.mmc2_dat1 */
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD2, PIN_INPUT_PULLUP, MUX_MODE5 ) /* (K15) gmii1_txd2.mmc2_dat2 */
+			AM33XX_PADCONF(AM335X_PIN_MII1_COL, PIN_INPUT_PULLUP, MUX_MODE5 ) /* (H16) gmii1_col.mmc2_dat3 */
+		>;
+	};
+
+	uart3_pins: pinmux_uart3_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD3, PIN_INPUT_PULLUP, MUX_MODE1)	/* gmii1_rxd3.uart3_rxd */
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD2, PIN_OUTPUT_PULLDOWN, MUX_MODE1)	/* gmii1_rxd2.uart3_txd */
+			AM33XX_PADCONF(AM335X_PIN_MDIO, PIN_INPUT, MUX_MODE3)		/* mdio_data.uart3_ctsn */
+			AM33XX_PADCONF(AM335X_PIN_MDC, PIN_OUTPUT_PULLDOWN, MUX_MODE3)	/* mdio_clk.uart3_rtsn */
+		>;
+	};
+
+	wl18xx_pins: pinmux_wl18xx_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_TX_CLK, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gmii1_txclk.gpio3_9 WL_EN */
+			AM33XX_PADCONF(AM335X_PIN_RMII1_REF_CLK, PIN_INPUT_PULLDOWN, MUX_MODE7)	/* rmii1_refclk.gpio0_29 WL_IRQ */
+			AM33XX_PADCONF(AM335X_PIN_MII1_RX_CLK, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gmii1_rxclk.gpio3_10 LS_BUF_EN */
+		>;
+	};
+};
+
+&mac_sw {
+	/delete-property/pinctrl-names;
+	/delete-property/pinctrl-0;
+	/delete-property/pinctrl-1;
+	status = "disabled";
+};
+
+&mmc3 {
+	dmas = <&edma_xbar 12 0 1
+		&edma_xbar 13 0 2>;
+	dma-names = "tx", "rx";
+	status = "okay";
+	vmmc-supply = <&wlan_en_reg>;
+	bus-width = <4>;
+	non-removable;
+	cap-power-off-card;
+	keep-power-in-suspend;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc3_pins &wl18xx_pins>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	wlcore: wlcore@2 {
+		compatible = "ti,wl1835";
+		reg = <2>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <29 IRQ_TYPE_EDGE_RISING>;
+	};
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins &bt_pins>;
+	status = "okay";
+
+	bluetooth {
+		compatible = "ti,wl1835-st";
+		enable-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&gpio3 {
+	ls-buf-en-hog {
+		gpio-hog;
+		gpios = <10 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "LS_BUF_EN";
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-BBGG-WL1835-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-BBGG-WL1835-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-BBGG-WL1835-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-BBGG-WL1835-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-BBGG-WL1835-00A0.kernel = __TIMESTAMP__;
+		wl1835_bt = "S3-texas-300000";
+	};
+};
+
+&{/} {
+	model = "SeeedStudio BeagleBone Green Gateway";
+	compatible = "ti,am335x-bone-green-gateway", "ti,am335x-bone-green", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+
+	aliases {
+		rtc0 = &extrtc;
+		rtc1 = "/ocp/rtc@44e3e000";
+	};
+
+	wlan_en_reg: fixedregulator@2 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan-en-regulator";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us= <70000>;
+
+		/* WL_EN */
+		gpio = <&gpio3 9 0>;
+		enable-active-high;
+	};
+
+	leds {
+		pinctrl-names = "default";
+		//pinctrl-0 = <&user_leds_s0>;
+		pinctrl-0 = <&user_leds_s0 &bt_pins>;
+
+		compatible = "gpio-leds";
+
+		led2 {
+			label = "beaglebone:green:usr0";
+			gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+			default-state = "off";
+		};
+
+		led3 {
+			label = "beaglebone:green:usr1";
+			gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc0";
+			default-state = "off";
+		};
+
+		led4 {
+			label = "beaglebone:green:usr2";
+			gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "cpu0";
+			default-state = "off";
+		};
+
+		led5 {
+			label = "beaglebone:green:usr3";
+			gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc1";
+			default-state = "off";
+		};
+
+		led6 {
+			label = "beaglebone:green:usr4";
+			gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "netdev";
+			default-state = "off";
+		};
+
+		wl18xx_bt_en: led7 {
+			label = "wl18xx_bt_en";
+			gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+};
+
+&am33xx_pinmux {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usbhost_pins>;
+
+	user_leds_s0: user_leds_s0 {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A5, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gpmc_a5.gpio1_21 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A6, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpmc_a6.gpio1_22 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A7, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gpmc_a7.gpio1_23 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A8, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpmc_a8.gpio1_24 */
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* WL_Active_LED / USR4 */
+		>;
+	};
+
+	bt_pins: pinmux_bt_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD0, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gmii1_txd0.gpio0_28 - BT_EN */
+		>;
+	};
+
+	mmc3_pins: pinmux_mmc3_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD1, PIN_INPUT_PULLUP, MUX_MODE6 ) /* (L15) gmii1_rxd1.mmc2_clk */
+			AM33XX_PADCONF(AM335X_PIN_MII1_TX_EN, PIN_INPUT_PULLUP, MUX_MODE6 ) /* (J16) gmii1_txen.mmc2_cmd */
+			AM33XX_PADCONF(AM335X_PIN_MII1_RX_DV, PIN_INPUT_PULLUP, MUX_MODE5 ) /* (J17) gmii1_rxdv.mmc2_dat0 */
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD3, PIN_INPUT_PULLUP, MUX_MODE5 ) /* (J18) gmii1_txd3.mmc2_dat1 */
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD2, PIN_INPUT_PULLUP, MUX_MODE5 ) /* (K15) gmii1_txd2.mmc2_dat2 */
+			AM33XX_PADCONF(AM335X_PIN_MII1_COL, PIN_INPUT_PULLUP, MUX_MODE5 ) /* (H16) gmii1_col.mmc2_dat3 */
+		>;
+	};
+
+	uart2_grove_pins: pinmux_uart2_grove_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x90c, PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE6)
+			AM33XX_IOPAD(0x910, PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE6)
+		>;
+	};
+
+	uart3_pins: pinmux_uart3_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD3, PIN_INPUT_PULLUP, MUX_MODE1)	/* gmii1_rxd3.uart3_rxd */
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD2, PIN_OUTPUT_PULLDOWN, MUX_MODE1)	/* gmii1_rxd2.uart3_txd */
+			AM33XX_PADCONF(AM335X_PIN_MDIO, PIN_INPUT, MUX_MODE3)		/* mdio_data.uart3_ctsn */
+			AM33XX_PADCONF(AM335X_PIN_MDC, PIN_OUTPUT_PULLDOWN, MUX_MODE3)	/* mdio_clk.uart3_rtsn */
+		>;
+	};
+
+	usbhost_pins: pinmux_usbhost_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_TXD1, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gmii1_txd1.gpio0[21] */
+		>;
+	};
+
+	wl18xx_pins: pinmux_wl18xx_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_TX_CLK, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gmii1_txclk.gpio3_9 WL_EN */
+			AM33XX_PADCONF(AM335X_PIN_RMII1_REF_CLK, PIN_INPUT_PULLDOWN, MUX_MODE7)	/* rmii1_refclk.gpio0_29 WL_IRQ */
+			AM33XX_PADCONF(AM335X_PIN_MII1_RX_CLK, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gmii1_rxclk.gpio3_10 LS_BUF_EN */
+		>;
+	};
+};
+
+&mac_sw {
+	/delete-property/pinctrl-names;
+	/delete-property/pinctrl-0;
+	/delete-property/pinctrl-1;
+	status = "disabled";
+};
+
+&mmc3 {
+	dmas = <&edma_xbar 12 0 1
+		&edma_xbar 13 0 2>;
+	dma-names = "tx", "rx";
+	status = "okay";
+	vmmc-supply = <&wlan_en_reg>;
+	bus-width = <4>;
+	non-removable;
+	cap-power-off-card;
+	keep-power-in-suspend;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc3_pins &wl18xx_pins>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	wlcore: wlcore@2 {
+		compatible = "ti,wl1835";
+		reg = <2>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <29 IRQ_TYPE_EDGE_RISING>;
+	};
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_grove_pins>;
+	status = "okay";
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>;
+	//pinctrl-0 = <&uart3_pins &bt_pins>;
+	status = "okay";
+
+	//bluetooth {
+	//	compatible = "ti,wl1835-st";
+	//	enable-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+	//};
+};
+
+&i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	extrtc: rtc@68 {
+		compatible = "dallas,ds1340";
+		reg = <0x68>;
+	};
+};
+
+// (K16) gmii1_txd1.gpio0[21]
+&gpio0 {
+	usb-reset-hog {
+		gpio-hog;
+		gpios = <21 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "usb_reset";
+	};
+};
+
+&gpio3 {
+	ls-buf-en-hog {
+		gpio-hog;
+		gpios = <10 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "LS_BUF_EN";
+	};
+};
+
+&usb1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	hub@1 {
+		compatible = "usb424,9512";
+		reg = <1>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethernet: ethernet@1 {
+			compatible = "usb424,ec00";
+			reg = <1>;
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-BBGW-WL1835-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-BBGW-WL1835-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-BBGW-WL1835-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-BBGW-WL1835-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-BBGW-WL1835-00A0.kernel = __TIMESTAMP__;
+		wl1835_bt = "S3-texas-300000";
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_12_pinmux { status = "disabled"; };	/* gpmc_ad12.gpio1_28 BT_EN */
+	P8_12_pinmux { status = "disabled"; };	/* gpmc_ad12.mmc2_dat0 */
+	P8_11_pinmux { status = "disabled"; };	/* gpmc_ad13.mmc2_dat1 */
+	P8_16_pinmux { status = "disabled"; };	/* gpmc_ad14.mmc2_dat2 */
+	P8_15_pinmux { status = "disabled"; };	/* gpmc_ad15.mmc2_dat3 */
+
+	P8_18_pinmux { status = "disabled"; };	/* gpmc_clk.mmc2_clk */
+
+	//Audio...
+	P9_28_pinmux { status = "disabled"; };
+	P9_29_pinmux { status = "disabled"; };
+	P9_31_pinmux { status = "disabled"; };
+
+	/* wl1835 */
+	P8_14_pinmux { status = "disabled"; };	/* wl1835: wl_en */
+	P8_17_pinmux { status = "disabled"; };	/* wl1835: wl_irq */
+	P8_26_pinmux { status = "disabled"; };	/* wl1835: LS_BUF_EN */
+	P9_30_pinmux { status = "disabled"; };	/* wl1835: MCASP0_AHCLKR */
+};
+
+&{/} {
+	model = "TI AM335x BeagleBone Green Wireless";
+	compatible = "ti,am335x-bone-green-wireless", "ti,am335x-bone-green", "ti,am335x-bone", "ti,am33xx";
+
+	wlan_en_reg: fixedregulator@2 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan-en-regulator";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us= <70000>;
+
+		/* WL_EN */
+		gpio = <&gpio0 26 0>;
+		enable-active-high;
+	};
+
+	leds {
+		pinctrl-names = "default";
+		//pinctrl-0 = <&user_leds_s0>;
+		pinctrl-0 = <&user_leds_s0 &bt_pins>;
+
+		compatible = "gpio-leds";
+
+		led2 {
+			label = "beaglebone:green:usr0";
+			gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+			default-state = "off";
+		};
+
+		led3 {
+			label = "beaglebone:green:usr1";
+			gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc0";
+			default-state = "off";
+		};
+
+		led4 {
+			label = "beaglebone:green:usr2";
+			gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "cpu0";
+			default-state = "off";
+		};
+
+		led5 {
+			label = "beaglebone:green:usr3";
+			gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc1";
+			default-state = "off";
+		};
+
+		wl18xx_bt_en: led7 {
+			label = "wl18xx_bt_en";
+			gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+};
+
+&am33xx_pinmux {
+	user_leds_s0: user_leds_s0 {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A5, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gpmc_a5.gpio1_21 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A6, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpmc_a6.gpio1_22 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A7, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gpmc_a7.gpio1_23 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A8, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpmc_a8.gpio1_24 */
+		>;
+	};
+
+	bt_pins: pinmux_bt_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_BEN1, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpmc_ad12.gpio1_28 BT_EN */
+		>;
+	};
+
+	mmc3_pins: pinmux_mmc3_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD12, PIN_INPUT_PULLUP, MUX_MODE3)	/* gpmc_ad12.mmc2_dat0 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD13, PIN_INPUT_PULLUP, MUX_MODE3)	/* gpmc_ad13.mmc2_dat1 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD14, PIN_INPUT_PULLUP, MUX_MODE3)	/* gpmc_ad14.mmc2_dat2 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD15, PIN_INPUT_PULLUP, MUX_MODE3)	/* gpmc_ad15.mmc2_dat3 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_CSN3, PIN_INPUT_PULLUP, MUX_MODE3)	/* gpmc_csn3.mmc2_cmd */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_CLK, PIN_INPUT_PULLUP, MUX_MODE3)	/* gpmc_clk.mmc2_clk */
+		>;
+	};
+
+	uart3_pins: pinmux_uart3_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD3, PIN_INPUT_PULLUP, MUX_MODE1)	/* gmii1_rxd3.uart3_rxd */
+			AM33XX_PADCONF(AM335X_PIN_MII1_RXD2, PIN_OUTPUT_PULLDOWN, MUX_MODE1)	/* gmii1_rxd2.uart3_txd */
+			AM33XX_PADCONF(AM335X_PIN_MDIO, PIN_INPUT, MUX_MODE3)		/* mdio_data.uart3_ctsn */
+			AM33XX_PADCONF(AM335X_PIN_MDC, PIN_OUTPUT_PULLDOWN, MUX_MODE3)	/* mdio_clk.uart3_rtsn */
+		>;
+	};
+
+	wl18xx_pins: pinmux_wl18xx_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD10, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* gpmc_ad10.gpio0_26 WL_EN */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD11, PIN_INPUT_PULLDOWN, MUX_MODE7)	/* gpmc_ad11.gpio0_27 WL_IRQ */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_CSN0, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpmc_csn0.gpio1_29 LS_BUF_EN */
+		>;
+	};
+};
+
+&mac_sw {
+	/delete-property/pinctrl-names;
+	/delete-property/pinctrl-0;
+	/delete-property/pinctrl-1;
+	status = "disabled";
+};
+
+&mmc3 {
+	dmas = <&edma_xbar 12 0 1
+		&edma_xbar 13 0 2>;
+	dma-names = "tx", "rx";
+	status = "okay";
+	vmmc-supply = <&wlan_en_reg>;
+	bus-width = <4>;
+	non-removable;
+	cap-power-off-card;
+	keep-power-in-suspend;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc3_pins &wl18xx_pins>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	wlcore: wlcore@2 {
+		compatible = "ti,wl1835";
+		reg = <2>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <27 IRQ_TYPE_EDGE_RISING>;
+	};
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>;
+	//pinctrl-0 = <&uart3_pins &bt_pins>;
+	status = "okay";
+
+	//bluetooth {
+	//	compatible = "ti,wl1835-st";
+	//	enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+	//};
+};
+
+&gpio1 {
+	ls-buf-en-hog {
+		gpio-hog;
+		gpios = <29 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "LS_BUF_EN";
+	};
+};
+
+/* BT_AUD_OUT from wl1835 has to be pulled low when WL_EN is activated.*/
+/* in case it isn't, wilink8 ends up in one of the test modes that     */
+/* intruces various issues (elp wkaeup timeouts etc.)                  */
+/* On the BBGW this pin is routed through the level shifter (U21) that */
+/* introduces a pullup on the line and wilink8 ends up in a bad state. */
+/* use a gpio hog to force this pin low. An alternative may be adding  */
+/* an external pulldown on U21 pin 4.                                  */
+
+&gpio3 {
+	bt-aud-in-hog {
+		gpio-hog;
+		gpios = <16 GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "MCASP0_AHCLKR";
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-BONE-4D5R-01-00A1.dtso b/arch/arm/boot/dts/ti/omap/BB-BONE-4D5R-01-00A1.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-BONE-4D5R-01-00A1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-BONE-4D5R-01-00A1.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,224 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-BONE-4D5R-01-00A1.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P8_45_pinmux { status = "disabled"; };	/* lcd: lcd_data0 */
+	P8_46_pinmux { status = "disabled"; };	/* lcd: lcd_data1 */
+	P8_43_pinmux { status = "disabled"; };	/* lcd: lcd_data2 */
+	P8_44_pinmux { status = "disabled"; };	/* lcd: lcd_data3 */
+	P8_41_pinmux { status = "disabled"; };	/* lcd: lcd_data4 */
+	P8_42_pinmux { status = "disabled"; };	/* lcd: lcd_data5 */
+	P8_39_pinmux { status = "disabled"; };	/* lcd: lcd_data6 */
+	P8_40_pinmux { status = "disabled"; };	/* lcd: lcd_data7 */
+	P8_37_pinmux { status = "disabled"; };	/* lcd: lcd_data8 */
+	P8_38_pinmux { status = "disabled"; };	/* lcd: lcd_data9 */
+	P8_36_pinmux { status = "disabled"; };	/* lcd: lcd_data10 */
+	P8_34_pinmux { status = "disabled"; };	/* lcd: lcd_data11 */
+	P8_35_pinmux { status = "disabled"; };	/* lcd: lcd_data12 */
+	P8_33_pinmux { status = "disabled"; };	/* lcd: lcd_data13 */
+	P8_31_pinmux { status = "disabled"; };	/* lcd: lcd_data14 */
+	P8_32_pinmux { status = "disabled"; };	/* lcd: lcd_data15 */
+
+	P8_27_pinmux { status = "disabled"; };	/* lcd: lcd_vsync */
+	P8_29_pinmux { status = "disabled"; };	/* lcd: lcd_hsync */
+	P8_28_pinmux { status = "disabled"; };	/* lcd: lcd_pclk */
+	P8_30_pinmux { status = "disabled"; };	/* lcd: lcd_ac_bias_en */
+
+	P9_27_pinmux { status = "disabled"; };	/* lcd: gpio3_19 DISPEN */
+
+	P9_14_pinmux { status = "disabled"; };	/* pwm: ehrpwm1a PWM_BL */
+
+	P9_18_pinmux { status = "disabled"; };	/* i2c1_sda */
+	P9_17_pinmux { status = "disabled"; };	/* i2c1_scl */
+	P9_26_pinmux { status = "disabled"; };	/* touch interrupt on gpio0_14 */
+};
+
+&am33xx_pinmux {
+	bb_lcd_pwm_backlight_pins: pinmux_bb_lcd_pwm_backlight_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A2, PIN_OUTPUT, MUX_MODE6) /* gpmc_a2.ehrpwm1a, OMAP_MUX_MODE6 | AM33XX_PIN_OUTPUT */
+		>;
+	};
+
+	bb_lcd_lcd_pins: pinmux_bb_lcd_lcd_pins {
+		pinctrl-single,pins = <
+			/*LCD enable */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_FSR, PIN_OUTPUT, MUX_MODE7) /* mcasp0_fsr.gpio3_19, OUTPUT | MODE7  LCD DISEN */
+
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA0, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA1, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA2, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA3, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA4, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA5, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA6, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA7, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA10, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA11, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA14, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA15, PIN_OUTPUT, MUX_MODE0)
+
+			AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_HSYNC, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_OUTPUT, MUX_MODE0)
+		>;
+	};
+
+	bb_i2c1_pins: pinmux_bb_i2c1_pins {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | SLEWCTRL_SLOW | MUX_MODE2) /* spi0_d1.i2c1_sda */
+			AM33XX_IOPAD(0x95C, PIN_INPUT_PULLUP | SLEWCTRL_SLOW | MUX_MODE2) /* spi0_cs0.i2c1_scl */
+		>;
+	};
+
+	ar1021_pins: pinmux_ar1021_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_UART1_RXD, PIN_INPUT, MUX_MODE7)
+		>;
+	};
+};
+
+&epwmss1 {
+	status = "okay";
+};
+
+&ehrpwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_lcd_pwm_backlight_pins>;
+	status = "okay";
+};
+
+&lcdc {
+	status = "okay";
+
+	blue-and-red-wiring = "straight";
+
+	//FIXME - LCD doesn't init...
+	//port {
+	//	lcdc_0: endpoint@0 {
+	//		remote-endpoint = <&panel_0>;
+	//	};
+	//};
+};
+
+&i2c1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_i2c1_pins>;
+
+	clock-frequency = <100000>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ar1021: ar1021@4d {
+		status = "okay";
+		compatible = "microchip,ar1021-i2c";
+		reg = <0x4d>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ar1021_pins>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <14 IRQ_TYPE_LEVEL_HIGH>;
+
+		touchscreen-offset-x=<250>;
+		touchscreen-offset-y=<300>;
+
+		touchscreen-inverted-y;
+	};
+};
+
+&{/} {
+	backlight: backlight {
+		status = "okay";
+		compatible = "pwm-backlight";
+		pwms = <&ehrpwm1 0 500000 0>;
+		brightness-levels = <
+			0  1  2  3  4  5  6  7  8  9
+			10 11 12 13 14 15 16 17 18 19
+			20 21 22 23 24 25 26 27 28 29
+			30 31 32 33 34 35 36 37 38 39
+			40 41 42 43 44 45 46 47 48 49
+			50 51 52 53 54 55 56 57 58 59
+			60 61 62 63 64 65 66 67 68 69
+			70 71 72 73 74 75 76 77 78 79
+			80 81 82 83 84 85 86 87 88 89
+			90 91 92 93 94 95 96 97 98 99
+			100
+		>;
+		default-brightness-level = <100>;
+	};
+
+	panel {
+		status = "okay";
+		compatible = "ti,tilcdc,panel";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bb_lcd_lcd_pins>;
+		backlight = <&backlight>;
+		enable-gpios = <&gpio3 19 0>;
+
+		//FIXME - LCD doesn't init...
+		//port {
+		//	panel_0: endpoint@0 {
+		//		remote-endpoint = <&lcdc_0>;
+		//	};
+		//};
+
+		panel-info {
+			ac-bias           = <255>;
+			ac-bias-intrpt    = <0>;
+			dma-burst-sz      = <16>;
+			bpp               = <16>;
+			fdd               = <0x80>;
+			sync-edge         = <0>;
+			sync-ctrl         = <1>;
+			raster-order      = <0>;
+			fifo-th           = <0>;
+		};
+
+		display-timings {
+			native-mode = <&timing0>;
+			/* Settings for ThreeFive S9700RTWV35TR / LCD7 cape: */
+			timing0: 800x480 {
+				clock-frequency = <30000000>;
+				hactive = <800>;
+				vactive = <480>;
+				hfront-porch = <40>;
+				hback-porch = <40>;
+				hsync-len = <48>;
+				vback-porch = <30>;
+				vfront-porch = <13>;
+				vsync-len = <3>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <1>;
+				pixelclk-active = <0>;
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-BONE-eMMC1-01-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-BONE-eMMC1-01-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-BONE-eMMC1-01-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-BONE-eMMC1-01-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-BONE-eMMC1-01-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P8_21_pinmux { status = "disabled"; };	/* mmc1_clk */
+	P8_20_pinmux { status = "disabled"; };	/* mmc1_cmd */
+	P8_25_pinmux { status = "disabled"; };	/* mmc1_dat0 */
+	P8_24_pinmux { status = "disabled"; };	/* mmc1_dat1 */
+	P8_05_pinmux { status = "disabled"; };	/* mmc1_dat2 */
+	P8_06_pinmux { status = "disabled"; };	/* mmc1_dat3 */
+	P8_23_pinmux { status = "disabled"; };	/* mmc1_dat4 */
+	P8_22_pinmux { status = "disabled"; };	/* mmc1_dat5 */
+	P8_03_pinmux { status = "disabled"; };	/* mmc1_dat6 */
+	P8_04_pinmux { status = "disabled"; };	/* mmc1_dat7 */
+};
+
+&am33xx_pinmux {
+	emmc_pins: pinmux_emmc_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_CSN1, PIN_INPUT_PULLUP, MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_CSN2, PIN_INPUT_PULLUP, MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD0, PIN_INPUT_PULLUP, MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD1, PIN_INPUT_PULLUP, MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD2, PIN_INPUT_PULLUP, MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD3, PIN_INPUT_PULLUP, MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD4, PIN_INPUT_PULLUP, MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD5, PIN_INPUT_PULLUP, MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD6, PIN_INPUT_PULLUP, MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD7, PIN_INPUT_PULLUP, MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
+		>;
+	};
+};
+
+&mmc2 {
+	vmmc-supply = <&vmmcsd_fixed>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_pins>;
+	bus-width = <8>;
+	status = "okay";
+	non-removable;
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-BONE-LCD4-01-00A1.dtso b/arch/arm/boot/dts/ti/omap/BB-BONE-LCD4-01-00A1.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-BONE-LCD4-01-00A1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-BONE-LCD4-01-00A1.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-BONE-LCD4-01-00A1.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_12_pinmux { status = "disabled"; };	/* P9_12: gpmc_ben1.gpio1_28, INPUT | PULLDIS | MODE7 */
+
+	P9_14_pinmux { status = "disabled"; };	/* P9_14: gpmc_a2.ehrpwm1a */
+
+	P9_27_pinmux { status = "disabled"; };	/* P9_27: mcasp0_fsr.gpio3_19 */
+
+	P8_45_pinmux { status = "disabled"; };	/* P8_45: lcd_data0.lcd_data0 */
+	P8_46_pinmux { status = "disabled"; };	/* P8_46: lcd_data1.lcd_data1 */
+	P8_43_pinmux { status = "disabled"; };	/* P8_43: lcd_data2.lcd_data2 */
+	P8_44_pinmux { status = "disabled"; };	/* P8_44: lcd_data3.lcd_data3 */
+	P8_41_pinmux { status = "disabled"; };	/* P8_41: lcd_data4.lcd_data4 */
+	P8_42_pinmux { status = "disabled"; };	/* P8_42: lcd_data5.lcd_data5 */
+	P8_39_pinmux { status = "disabled"; };	/* P8_39: lcd_data6.lcd_data6 */
+	P8_40_pinmux { status = "disabled"; };	/* P8_40: lcd_data7.lcd_data7 */
+	P8_37_pinmux { status = "disabled"; };	/* P8_37: lcd_data8.lcd_data8 */
+	P8_38_pinmux { status = "disabled"; };	/* P8_38: lcd_data9.lcd_data9 */
+	P8_36_pinmux { status = "disabled"; };	/* P8_36: lcd_data10.lcd_data10 */
+	P8_34_pinmux { status = "disabled"; };	/* P8_34: lcd_data11.lcd_data11 */
+	P8_35_pinmux { status = "disabled"; };	/* P8_35: lcd_data12.lcd_data12 */
+	P8_33_pinmux { status = "disabled"; };	/* P8_33: lcd_data13.lcd_data13 */
+	P8_31_pinmux { status = "disabled"; };	/* P8_31: lcd_data14.lcd_data14 */
+	P8_32_pinmux { status = "disabled"; };	/* P8_32: lcd_data15.lcd_data15 */
+
+	P8_27_pinmux { status = "disabled"; };	/* P8_27: lcd_vsync.lcd_vsync */
+	P8_29_pinmux { status = "disabled"; };	/* P8_29: lcd_hsync.lcd_hsync */
+	P8_28_pinmux { status = "disabled"; };	/* P8_28: lcd_pclk.lcd_pclk */
+	P8_30_pinmux { status = "disabled"; };	/* P8_30: lcd_ac_bias_en.lcd_ac_bias_en */
+
+	P9_15_pinmux { status = "disabled"; };	/* P9_15: gpmc_a0.gpio1_16 */
+	P9_23_pinmux { status = "disabled"; };	/* P9_23: gpmc_a1.gpio1_17 */
+	P9_16_pinmux { status = "disabled"; };	/* P9_16: gpmc_a3.gpio1_19 */
+	P9_30_pinmux { status = "disabled"; };	/* P9_30: mcasp0_axr0.gpio3_16 */
+	P9_24_pinmux { status = "disabled"; };	/* P9_24: uart1_txd.gpio0_15 */
+};
+
+&am33xx_pinmux {
+	bb_lcd_led_pins: pinmux_bb_lcd_led_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_BEN1, PIN_INPUT, MUX_MODE7)	/* P9_12: gpmc_ben1.gpio1_28, INPUT | PULLDIS | MODE7 */
+		>;
+	};
+
+	bb_lcd_pwm_backlight_pins: pinmux_bb_lcd_pwm_backlight_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A2, PIN_OUTPUT_PULLDOWN, MUX_MODE6)	/* P9_14: gpmc_a2.ehrpwm1a */
+		>;
+	};
+
+	bb_lcd_lcd_pins: pinmux_bb_lcd_lcd_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_FSR, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* P9_27: mcasp0_fsr.gpio3_19 */
+
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA0, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA1, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA2, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA3, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA4, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA5, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA6, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA7, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA10, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA11, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA14, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA15, PIN_OUTPUT, MUX_MODE0)
+
+			AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_HSYNC, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_OUTPUT, MUX_MODE0)
+		>;
+	};
+
+	bb_lcd_keymap_pins: pinmux_bb_lcd_keymap_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A0, PIN_INPUT, MUX_MODE7)	/* P9_15: gpmc_a0.gpio1_16 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A1, PIN_INPUT, MUX_MODE7)	/* P9_23: gpmc_a1.gpio1_17 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A3, PIN_INPUT, MUX_MODE7)	/* P9_16: gpmc_a3.gpio1_19 */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_AXR0, PIN_INPUT, MUX_MODE7)	/* P9_30: mcasp0_axr0.gpio3_16 */
+			AM33XX_PADCONF(AM335X_PIN_UART1_TXD, PIN_INPUT, MUX_MODE7)	/* P9_24: uart1_txd.gpio0_15 */
+		>;
+	};
+};
+
+&epwmss1 {
+	status = "okay";
+};
+
+&ehrpwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_lcd_pwm_backlight_pins>;
+	status = "okay";
+};
+
+&lcdc {
+	status = "okay";
+
+	blue-and-red-wiring = "straight";
+
+	//FIXME - LCD doesn't init...
+	//port {
+	//	lcdc_0: endpoint@0 {
+	//		remote-endpoint = <&panel_0>;
+	//	};
+	//};
+};
+
+&tscadc {
+	status = "okay";
+	tsc {
+		ti,wires = <4>;
+		ti,x-plate-resistance = <200>;
+		ti,coordinate-readouts = <5>;
+		ti,wire-config = <0x00 0x11 0x22 0x33>;
+		ti,charge-delay = <0x400>;
+	};
+
+	adc {
+		ti,adc-channels = <4 5 6 7>;
+	};
+};
+
+&{/} {
+	backlight: backlight {
+		status = "okay";
+		compatible = "pwm-backlight";
+		pwms = <&ehrpwm1 0 500000 0>;
+		brightness-levels = <
+			0  1  2  3  4  5  6  7  8  9
+			10 11 12 13 14 15 16 17 18 19
+			20 21 22 23 24 25 26 27 28 29
+			30 31 32 33 34 35 36 37 38 39
+			40 41 42 43 44 45 46 47 48 49
+			50 51 52 53 54 55 56 57 58 59
+			60 61 62 63 64 65 66 67 68 69
+			70 71 72 73 74 75 76 77 78 79
+			80 81 82 83 84 85 86 87 88 89
+			90 91 92 93 94 95 96 97 98 99
+			100
+		>;
+		default-brightness-level = <100>;
+	};
+
+	panel {
+		status = "okay";
+		compatible = "ti,tilcdc,panel";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bb_lcd_lcd_pins>;
+		backlight = <&backlight>;
+
+		//FIXME - LCD doesn't init...
+		//port {
+		//	panel_0: endpoint@0 {
+		//		remote-endpoint = <&lcdc_0>;
+		//	};
+		//};
+
+		panel-info {
+			ac-bias           = <255>;
+			ac-bias-intrpt    = <0>;
+			dma-burst-sz      = <16>;
+			bpp               = <16>;
+			fdd               = <0x80>;
+			sync-edge         = <0>;
+			sync-ctrl         = <1>;
+			raster-order      = <0>;
+			fifo-th           = <0>;
+		};
+		display-timings {
+			native-mode = <&timing0>;
+			/* www.newhavendisplay.com/app_notes/OTA5180A.pdf */
+			timing0: 480x272 {
+				clock-frequency = <9200000>;
+				hactive = <480>;
+				vactive = <272>;
+				hfront-porch = <8>;
+				hback-porch = <47>;
+				hsync-len = <41>;
+				vback-porch = <2>;
+				vfront-porch = <3>;
+				vsync-len = <10>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <1>;
+				pixelclk-active = <0>;
+			};
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bb_lcd_led_pins>;
+
+		led-ld0 {
+			label = "lcd:green:usr0";
+			gpios = <&gpio1 28 0>;
+			linux,default-trigger = "heartbeat";
+			default-state = "off";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bb_lcd_keymap_pins>;
+
+		button-1 {
+			debounce_interval = <50>;
+			linux,code = <105>;
+			label = "left";
+			gpios = <&gpio1 16 0x1>;
+			gpio-key,wakeup;
+			autorepeat;
+		};
+		button-2 {
+			debounce_interval = <50>;
+			linux,code = <106>;
+			label = "right";
+			gpios = <&gpio1 17 0x1>;
+			gpio-key,wakeup;
+			autorepeat;
+		};
+		button-3 {
+			debounce_interval = <50>;
+			linux,code = <103>;
+			label = "up";
+			gpios = <&gpio1 19 0x1>;
+			gpio-key,wakeup;
+			autorepeat;
+		};
+		button-4 {
+			debounce_interval = <50>;
+			linux,code = <108>;
+			label = "down";
+			gpios = <&gpio3 16 0x1>;
+			gpio-key,wakeup;
+			autorepeat;
+		};
+		button-5 {
+			debounce_interval = <50>;
+			linux,code = <28>;
+			label = "enter";
+			gpios = <&gpio0 15 0x1>;
+			gpio-key,wakeup;
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-BONE-NH7C-01-A0.dtso b/arch/arm/boot/dts/ti/omap/BB-BONE-NH7C-01-A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-BONE-NH7C-01-A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-BONE-NH7C-01-A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-BONE-NH7C-01-A0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P8_45_pinmux { status = "disabled"; };	/* lcd: lcd_data0 */
+	P8_46_pinmux { status = "disabled"; };	/* lcd: lcd_data1 */
+	P8_43_pinmux { status = "disabled"; };	/* lcd: lcd_data2 */
+	P8_44_pinmux { status = "disabled"; };	/* lcd: lcd_data3 */
+	P8_41_pinmux { status = "disabled"; };	/* lcd: lcd_data4 */
+	P8_42_pinmux { status = "disabled"; };	/* lcd: lcd_data5 */
+	P8_39_pinmux { status = "disabled"; };	/* lcd: lcd_data6 */
+	P8_40_pinmux { status = "disabled"; };	/* lcd: lcd_data7 */
+	P8_37_pinmux { status = "disabled"; };	/* lcd: lcd_data8 */
+	P8_38_pinmux { status = "disabled"; };	/* lcd: lcd_data9 */
+	P8_36_pinmux { status = "disabled"; };	/* lcd: lcd_data10 */
+	P8_34_pinmux { status = "disabled"; };	/* lcd: lcd_data11 */
+	P8_35_pinmux { status = "disabled"; };	/* lcd: lcd_data12 */
+	P8_33_pinmux { status = "disabled"; };	/* lcd: lcd_data13 */
+	P8_31_pinmux { status = "disabled"; };	/* lcd: lcd_data14 */
+	P8_32_pinmux { status = "disabled"; };	/* lcd: lcd_data15 */
+
+	P8_15_pinmux { status = "disabled"; };	/* gpmc_ad15.lcd_data16 */
+	P8_16_pinmux { status = "disabled"; };	/* gpmc_ad14.lcd_data17 */
+	P8_11_pinmux { status = "disabled"; };	/* gpmc_ad13.lcd_data18 */
+	P8_12_pinmux { status = "disabled"; };	/* gpmc_ad12.lcd_data19 */
+	P8_17_pinmux { status = "disabled"; };	/* gpmc_ad11.lcd_data20 */
+	P8_14_pinmux { status = "disabled"; };	/* gpmc_ad10.lcd_data21 */
+	P8_13_pinmux { status = "disabled"; };	/* gpmc_ad9.lcd_data22 */
+	P8_19_pinmux { status = "disabled"; };	/* gpmc_ad8.lcd_data23 */
+
+	P8_27_pinmux { status = "disabled"; };	/* lcd: lcd_vsync */
+	P8_29_pinmux { status = "disabled"; };	/* lcd: lcd_hsync */
+	P8_28_pinmux { status = "disabled"; };	/* lcd: lcd_pclk */
+	P8_30_pinmux { status = "disabled"; };	/* lcd: lcd_ac_bias_en */
+
+	P8_18_pinmux { status = "disabled"; };	/* lcd: enable */
+
+	P9_14_pinmux { status = "disabled"; };	/* pwm: ehrpwm1a */
+
+	P9_27_pinmux { status = "disabled"; };	/* ft5336: gpio3_15 */
+};
+
+&am33xx_pinmux {
+	bb_lcd_pwm_backlight_pins: pinmux_bb_lcd_pwm_backlight_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A2, PIN_OUTPUT_PULLDOWN, MUX_MODE6)	/* P9_14: gpmc_a2.ehrpwm1a */
+		>;
+	};
+
+	bb_lcd_lcd_pins: pinmux_bb_lcd_lcd_pins {
+		pinctrl-single,pins = <
+			/*LCD enable */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_CLK, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpmc_clk_mux0.gpio2_1 */
+
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA0, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA1, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA2, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA3, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA4, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA5, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA6, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA7, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA10, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA11, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA14, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA15, PIN_OUTPUT, MUX_MODE0)
+
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD15, PIN_OUTPUT, MUX_MODE1)	/* P8_15: gpmc_ad15.lcd_data16 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD14, PIN_OUTPUT, MUX_MODE1)	/* P8_16: gpmc_ad14.lcd_data17 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD13, PIN_OUTPUT, MUX_MODE1)	/* P8_11: gpmc_ad13.lcd_data18 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD12, PIN_OUTPUT, MUX_MODE1)	/* P8_12: gpmc_ad12.lcd_data19 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD11, PIN_OUTPUT, MUX_MODE1)	/* P8_17: gpmc_ad11.lcd_data20 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD10, PIN_OUTPUT, MUX_MODE1)	/* P8_14: gpmc_ad10.lcd_data21 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD9, PIN_OUTPUT, MUX_MODE1)	/* P8_13: gpmc_ad9.lcd_data22 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_AD8, PIN_OUTPUT, MUX_MODE1)	/* P8_19: gpmc_ad8.lcd_data23 */
+
+			AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_HSYNC, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_OUTPUT, MUX_MODE0)
+		>;
+	};
+
+	edt_ft5x06_pins: pinmux_edt_ft5x06_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_FSR, PIN_INPUT_PULLDOWN, MUX_MODE7)	/* mcasp0_fsr.gpio3_19 */
+		>;
+	};
+};
+
+&epwmss1 {
+	status = "okay";
+};
+
+&ehrpwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_lcd_pwm_backlight_pins>;
+	status = "okay";
+};
+
+&lcdc {
+	status = "okay";
+
+	blue-and-red-wiring = "crossed";
+
+	//FIXME - LCD doesn't init...
+	//port {
+	//	lcdc_0: endpoint@0 {
+	//		remote-endpoint = <&panel_0>;
+	//	};
+	//};
+};
+
+&i2c2 {
+	status = "okay";
+
+	clock-frequency = <100000>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	edt-ft5x06@38 {
+		status = "okay";
+		compatible = "edt,edt-ft5406";
+		reg = <0x38>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&edt_ft5x06_pins>;
+		interrupt-parent = <&gpio3>;
+		interrupts = <19 0>;
+		//reset-gpios = <&gpio3 14 GPIO_ACTIVE_LOW>;
+
+		touchscreen-size-x = <800>;
+		touchscreen-size-y = <480>;
+		//touchscreen-swapped-x-y;
+	};
+};
+
+&{/} {
+	backlight: backlight {
+		status = "okay";
+		compatible = "pwm-backlight";
+		pwms = <&ehrpwm1 0 500000 0>;
+		brightness-levels = <
+			0  1  2  3  4  5  6  7  8  9
+			10 11 12 13 14 15 16 17 18 19
+			20 21 22 23 24 25 26 27 28 29
+			30 31 32 33 34 35 36 37 38 39
+			40 41 42 43 44 45 46 47 48 49
+			50 51 52 53 54 55 56 57 58 59
+			60 61 62 63 64 65 66 67 68 69
+			70 71 72 73 74 75 76 77 78 79
+			80 81 82 83 84 85 86 87 88 89
+			90 91 92 93 94 95 96 97 98 99
+			100
+		>;
+		default-brightness-level = <100>;
+	};
+
+	/* NHD-7.0-800480EF-ATXL# */
+	panel {
+		status = "okay";
+		compatible = "ti,tilcdc,panel";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bb_lcd_lcd_pins>;
+		backlight = <&backlight>;
+		enable-gpios = <&gpio2 1 0>;
+
+		//FIXME - LCD doesn't init...
+		//port {
+		//	panel_0: endpoint@0 {
+		//		remote-endpoint = <&lcdc_0>;
+		//	};
+		//};
+
+		panel-info {
+			ac-bias           = <255>;
+			ac-bias-intrpt    = <0>;
+			dma-burst-sz      = <16>;
+			bpp               = <32>;
+			fdd               = <0x80>;
+			tft-alt-mode      = <0>;
+			stn-565-mode      = <0>;
+			mono-8bit-mode    = <0>;
+			sync-edge         = <0>;
+			sync-ctrl         = <0>;
+			raster-order      = <0>;
+			fifo-th           = <0>;
+		};
+
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: 800x480 {
+				clock-frequency = <45000000>;
+				hactive = <800>;
+				vactive = <480>;
+				hfront-porch = <40>;
+				hback-porch = <40>;
+				hsync-len = <48>;
+				vback-porch = <29>;
+				vfront-porch = <13>;
+				vsync-len = <3>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-CAPE-DISP-CT4-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-CAPE-DISP-CT4-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-CAPE-DISP-CT4-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-CAPE-DISP-CT4-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,210 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-CAPE-DISP-CT4-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P8_45_pinmux { status = "disabled"; };	/* lcd: lcd_data0 */
+	P8_46_pinmux { status = "disabled"; };	/* lcd: lcd_data1 */
+	P8_43_pinmux { status = "disabled"; };	/* lcd: lcd_data2 */
+	P8_44_pinmux { status = "disabled"; };	/* lcd: lcd_data3 */
+	P8_41_pinmux { status = "disabled"; };	/* lcd: lcd_data4 */
+	P8_42_pinmux { status = "disabled"; };	/* lcd: lcd_data5 */
+	P8_39_pinmux { status = "disabled"; };	/* lcd: lcd_data6 */
+	P8_40_pinmux { status = "disabled"; };	/* lcd: lcd_data7 */
+	P8_37_pinmux { status = "disabled"; };	/* lcd: lcd_data8 */
+	P8_38_pinmux { status = "disabled"; };	/* lcd: lcd_data9 */
+	P8_36_pinmux { status = "disabled"; };	/* lcd: lcd_data10 */
+	P8_34_pinmux { status = "disabled"; };	/* lcd: lcd_data11 */
+	P8_35_pinmux { status = "disabled"; };	/* lcd: lcd_data12 */
+	P8_33_pinmux { status = "disabled"; };	/* lcd: lcd_data13 */
+	P8_31_pinmux { status = "disabled"; };	/* lcd: lcd_data14 */
+	P8_32_pinmux { status = "disabled"; };	/* lcd: lcd_data15 */
+
+	P8_27_pinmux { status = "disabled"; };	/* lcd: lcd_vsync */
+	P8_29_pinmux { status = "disabled"; };	/* lcd: lcd_hsync */
+	P8_28_pinmux { status = "disabled"; };	/* lcd: lcd_pclk */
+	P8_30_pinmux { status = "disabled"; };	/* lcd: lcd_ac_bias_en */
+
+	P9_28_pinmux { status = "disabled"; };	/* pwm: eCAP2_in_PWM2_out */
+
+	P9_29_pinmux { status = "disabled"; };	/* ft5336: gpio3_15 */
+	P9_31_pinmux { status = "disabled"; };	/* ft5336: gpio3_14 */
+};
+
+&am33xx_pinmux {
+	bb_lcd_pwm_backlight_pins: pinmux_bb_lcd_pwm_backlight_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKR, PIN_OUTPUT_PULLDOWN,  MUX_MODE4) /* mcasp0_ahclkr.eCAP2_in_PWM2_out */
+		>;
+	};
+
+	bb_lcd_lcd_pins: pinmux_bb_lcd_lcd_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA0, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA1, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA2, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA3, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA4, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA5, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA6, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA7, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA10, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA11, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA14, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA15, PIN_OUTPUT, MUX_MODE0)
+
+			AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_HSYNC, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_OUTPUT, MUX_MODE0)
+		>;
+	};
+
+	edt_ft5336_ts_pins: pinmux_edt_ft5336_ts_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_FSX, PIN_INPUT_PULLDOWN, MUX_MODE7)	/* mcasp0_fsx.gpio3_15 */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKX, PIN_INPUT_PULLDOWN, MUX_MODE7)	/* mcasp0_aclkx.gpio3_14 */
+		>;
+	};
+};
+
+&epwmss2 {
+	status = "okay";
+};
+
+&ecap2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_lcd_pwm_backlight_pins>;
+	status = "okay";
+};
+
+&lcdc {
+	status = "okay";
+
+	blue-and-red-wiring = "straight";
+
+	//FIXME - LCD doesn't init...
+	//port {
+	//	lcdc_0: endpoint@0 {
+	//		remote-endpoint = <&panel_0>;
+	//	};
+	//};
+};
+
+&i2c2 {
+	status = "okay";
+
+	/* this is the configuration part */
+	clock-frequency = <100000>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	edt-ft5336@38 {
+		status = "okay";
+		compatible = "edt,edt-ft5336", "edt,edt-ft5306", "edt,edt-ft5x06";
+		reg = <0x38>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&edt_ft5336_ts_pins>;
+		interrupt-parent = <&gpio3>;
+		interrupts = <15 0>;
+		reset-gpios = <&gpio3 14 GPIO_ACTIVE_LOW>;
+
+		touchscreen-size-x = <272>;
+		touchscreen-size-y = <480>;
+		touchscreen-swapped-x-y;
+	};
+};
+
+&{/} {
+	backlight: backlight {
+		status = "okay";
+		compatible = "pwm-backlight";
+		pwms = <&ecap2 0 500000 0>;
+		brightness-levels = <
+			0  1  2  3  4  5  6  7  8  9
+			10 11 12 13 14 15 16 17 18 19
+			20 21 22 23 24 25 26 27 28 29
+			30 31 32 33 34 35 36 37 38 39
+			40 41 42 43 44 45 46 47 48 49
+			50 51 52 53 54 55 56 57 58 59
+			60 61 62 63 64 65 66 67 68 69
+			70 71 72 73 74 75 76 77 78 79
+			80 81 82 83 84 85 86 87 88 89
+			90 91 92 93 94 95 96 97 98 99
+			100
+		>;
+		default-brightness-level = <50>;
+	};
+
+	panel {
+		status = "okay";
+		compatible = "ti,tilcdc,panel";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bb_lcd_lcd_pins>;
+		backlight = <&backlight>;
+
+		//FIXME - LCD doesn't init...
+		//port {
+		//	panel_0: endpoint@0 {
+		//		remote-endpoint = <&lcdc_0>;
+		//	};
+		//};
+
+		panel-info {
+			ac-bias           = <255>;
+			ac-bias-intrpt    = <0>;
+			dma-burst-sz      = <16>;
+			bpp               = <16>;
+			fdd               = <0x80>;
+			tft-alt-mode      = <0>;
+			stn-565-mode      = <0>;
+			mono-8bit-mode    = <0>;
+			sync-edge         = <0>;
+			sync-ctrl         = <1>;
+			raster-order      = <0>;
+			fifo-th           = <0>;
+		};
+		/* ILI6480 */
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: 480x272 {
+				clock-frequency = <9000000>;
+				hactive = <480>;
+				vactive = <272>;
+				hfront-porch = <5>;
+				hback-porch = <40>;
+				hsync-len = <1>;
+				vback-porch = <8>;
+				vfront-porch = <8>;
+				vsync-len = <1>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-HDMI-TDA998x-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-HDMI-TDA998x-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-HDMI-TDA998x-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-HDMI-TDA998x-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+#include <dt-bindings/display/tda998x.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-HDMI-TDA998x-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_25_pinmux { status = "disabled"; };	/* mcasp0_ahclkx */
+	P9_28_pinmux { status = "disabled"; };	/* mcasp0_axr2 */
+	P9_29_pinmux { status = "disabled"; };	/* mcasp0_fsx */
+	P9_31_pinmux { status = "disabled"; };	/* mcasp0_aclkx */
+	P8_45_pinmux { status = "disabled"; };	/* lcd_data0 */
+	P8_46_pinmux { status = "disabled"; };	/* lcd_data1 */
+	P8_43_pinmux { status = "disabled"; };	/* lcd_data2 */
+	P8_44_pinmux { status = "disabled"; };	/* lcd_data3 */
+	P8_41_pinmux { status = "disabled"; };	/* lcd_data4 */
+	P8_42_pinmux { status = "disabled"; };	/* lcd_data5 */
+	P8_39_pinmux { status = "disabled"; };	/* lcd_data6 */
+	P8_40_pinmux { status = "disabled"; };	/* lcd_data7 */
+	P8_37_pinmux { status = "disabled"; };	/* lcd_data8 */
+	P8_38_pinmux { status = "disabled"; };	/* lcd_data9 */
+	P8_36_pinmux { status = "disabled"; };	/* lcd_data10 */
+	P8_34_pinmux { status = "disabled"; };	/* lcd_data11 */
+	P8_35_pinmux { status = "disabled"; };	/* lcd_data12 */
+	P8_33_pinmux { status = "disabled"; };	/* lcd_data13 */
+	P8_31_pinmux { status = "disabled"; };	/* lcd_data14 */
+	P8_32_pinmux { status = "disabled"; };	/* lcd_data15 */
+	P8_27_pinmux { status = "disabled"; };	/* lcd_vsync */
+	P8_29_pinmux { status = "disabled"; };	/* lcd_hsync */
+	P8_28_pinmux { status = "disabled"; };	/* lcd_pclk */
+	P8_30_pinmux { status = "disabled"; };	/* lcd_ac_bias_en */
+};
+
+&am33xx_pinmux {
+	nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR0, PIN_OUTPUT_PULLUP, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA0, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA1, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA2, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA3, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA4, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA5, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA6, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA7, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA10, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA11, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA14, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA15, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_HSYNC, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+		>;
+	};
+
+	nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR0, PIN_OUTPUT_PULLDOWN, MUX_MODE7)
+		>;
+	};
+
+	mcasp0_pins: mcasp0_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKX, PIN_INPUT_PULLUP, MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKR, PIN_OUTPUT_PULLDOWN, MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_FSX, PIN_OUTPUT_PULLUP, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKX, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A11, PIN_OUTPUT_PULLDOWN, MUX_MODE7) /* gpmc_a11.GPIO1_27 */
+		>;
+	};
+};
+
+&lcdc {
+	status = "okay";
+
+	/* If you want to get 24 bit RGB and 16 BGR mode instead of
+	 * current 16 bit RGB and 24 BGR modes, set the propety
+	 * below to "crossed" and uncomment the video-ports -property
+	 * in tda19988 node.
+	 */
+	blue-and-red-wiring = "straight";
+
+	port {
+		lcdc_0: endpoint@0 {
+			remote-endpoint = <&hdmi_0>;
+		};
+	};
+};
+
+&i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	tda19988: tda19988@70 {
+		compatible = "nxp,tda998x";
+		reg = <0x70>;
+		nxp,calib-gpios = <&gpio1 25 0>;
+		interrupts-extended = <&gpio1 25 IRQ_TYPE_LEVEL_LOW>;
+
+		pinctrl-names = "default", "off";
+		pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+		pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+
+		/* Convert 24bit BGR to RGB, e.g. cross red and blue wiring */
+		/* video-ports = <0x234501>; */
+
+		#sound-dai-cells = <0>;
+		audio-ports = <	TDA998x_I2S	0x03>;
+
+		ports {
+			port@0 {
+				hdmi_0: endpoint@0 {
+					remote-endpoint = <&lcdc_0>;
+				};
+			};
+		};
+	};
+};
+
+&mcasp0 {
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcasp0_pins>;
+	status = "okay";
+	op-mode = <0>;	/* MCASP_IIS_MODE */
+	tdm-slots = <2>;
+	serial-dir = <	/* 0: INACTIVE, 1: TX, 2: RX */
+			0 0 1 0
+		>;
+	tx-num-evt = <32>;
+	rx-num-evt = <32>;
+};
+
+&{/} {
+	clk_mcasp0_fixed: clk_mcasp0_fixed {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <24576000>;
+	};
+
+	clk_mcasp0: clk_mcasp0 {
+		#clock-cells = <0>;
+		compatible = "gpio-gate-clock";
+		clocks = <&clk_mcasp0_fixed>;
+		enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */
+	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "TI BeagleBone Black";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&dailink0_master>;
+		simple-audio-card,frame-master = <&dailink0_master>;
+
+		dailink0_master: simple-audio-card,cpu {
+			sound-dai = <&mcasp0>;
+			clocks = <&clk_mcasp0>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&tda19988>;
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-I2C1-MCP7940X-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-I2C1-MCP7940X-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-I2C1-MCP7940X-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-I2C1-MCP7940X-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015 Robert Nelson <robertcnelson@gmail.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/pinctrl/am33xx.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-I2C1-MCP7940X-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_17_pinmux { status = "disabled"; };	/* spi0_d1.i2c1_sda */
+	P9_18_pinmux { status = "disabled"; };	/* spi0_cs0.i2c1_scl */
+	P8_26_pinmux { status = "disabled"; };	/* rtc: gpio1_29 */
+};
+
+&{/} {
+	aliases {
+		rtc0 = &extrtc;
+		/* find /sys/firmware/devicetree/ | grep rtc@ */
+		rtc1 = "/ocp/interconnect@44c00000/segment@200000/target-module@3e000/rtc@0";
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bb_gpio1_29_pins>;
+
+		rtc_mfp@1 {
+			label = "rtc_mfp";
+			gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>;
+			linux,code = <143>; /* System Wake Up */
+			gpio-key,wakeup;
+		};
+	};
+};
+
+&am33xx_pinmux {
+	bb_gpio1_29_pins: pinmux_bb_gpio1_29_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_CSN0, PIN_INPUT, MUX_MODE7) /* gpmc_csn0.gpio1_29 */
+		>;
+	};
+
+	bb_i2c1_pins: pinmux_bb_i2c1_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_SPI0_D1, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE2)		/* spi0_d1.i2c1_sda */
+			AM33XX_PADCONF(AM335X_PIN_SPI0_CS0, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE2)	/* spi0_cs0.i2c1_scl */
+		>;
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_i2c1_pins>;
+
+	clock-frequency = <100000>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	extrtc: mcp7940x@68 {
+		status = "okay";
+		compatible = "microchip,mcp7940x";
+		reg = <0x68>;
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-I2C1-RTC-DS3231.dtso b/arch/arm/boot/dts/ti/omap/BB-I2C1-RTC-DS3231.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-I2C1-RTC-DS3231.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-I2C1-RTC-DS3231.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Sam Cohen <samc1213@gmail.com>
+ *
+ * Based on BB-I2C2-RTC-DS3231.dts:
+ * Copyright (C) 2019 Tomas Arturo Herrera Castro <taherrera@uc.cl>
+ *
+ * DTS file for DS3231 Real Time Clock, running on the I2C1 interface. Also see
+ * BB-I2C2-RTC-DS3231.dts to run this RTC on I2C2.
+ *
+ * Tested on BeagleBone Black Wireless
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/pinctrl/am33xx.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-I2C1-RTC-DS3231.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_17_pinmux { status = "disabled"; };	/* spi0_d1.i2c1_sda */
+	P9_18_pinmux { status = "disabled"; };	/* spi0_cs0.i2c1_scl */
+};
+
+&{/} {
+	aliases {
+		rtc0 = &extrtc;
+		/* find /sys/firmware/devicetree/ | grep rtc@ */
+		rtc1 = "/ocp/interconnect@44c00000/segment@200000/target-module@3e000/rtc@0";
+	};
+};
+
+&am33xx_pinmux {
+	bb_i2c1_pins: pinmux_bb_i2c1_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_SPI0_D1, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE2)		/* spi0_d1.i2c1_sda */
+			AM33XX_PADCONF(AM335X_PIN_SPI0_CS0, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE2)	/* spi0_cs0.i2c1_scl */
+		>;
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_i2c1_pins>;
+
+	clock-frequency = <100000>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	extrtc: ds3231@68 {
+		status = "okay";
+		compatible = "maxim,ds3231";
+		reg = <0x68>;
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-I2C1-RTC-PCF8563.dtso b/arch/arm/boot/dts/ti/omap/BB-I2C1-RTC-PCF8563.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-I2C1-RTC-PCF8563.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-I2C1-RTC-PCF8563.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2018 Robert Nelson <robertcnelson@gmail.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/pinctrl/am33xx.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-I2C1-RTC-PCF8563.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_17_pinmux { status = "disabled"; };	/* spi0_d1.i2c1_sda */
+	P9_18_pinmux { status = "disabled"; };	/* spi0_cs0.i2c1_scl */
+};
+
+&{/} {
+	aliases {
+		rtc0 = &extrtc;
+		/* find /sys/firmware/devicetree/ | grep rtc@ */
+		rtc1 = "/ocp/interconnect@44c00000/segment@200000/target-module@3e000/rtc@0";
+	};
+};
+
+&am33xx_pinmux {
+	bb_i2c1_pins: pinmux_bb_i2c1_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_SPI0_D1, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE2)		/* spi0_d1.i2c1_sda */
+			AM33XX_PADCONF(AM335X_PIN_SPI0_CS0, SLEWCTRL_SLOW | PIN_INPUT_PULLUP, MUX_MODE2)	/* spi0_cs0.i2c1_scl */
+		>;
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_i2c1_pins>;
+
+	clock-frequency = <100000>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	extrtc: pcf8563@51 {
+		status = "okay";
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-I2C2-BME680.dtso b/arch/arm/boot/dts/ti/omap/BB-I2C2-BME680.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-I2C2-BME680.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-I2C2-BME680.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 Robert Nelson <robertcnelson@gmail.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-I2C2-BME680.kernel = __TIMESTAMP__;
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	clock-frequency = <100000>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	bme680@76 {
+		status = "okay";
+		compatible = "bosch,bme680";
+		reg = <0x76>;
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-I2C2-MPU6050.dtso b/arch/arm/boot/dts/ti/omap/BB-I2C2-MPU6050.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-I2C2-MPU6050.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-I2C2-MPU6050.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 Robert Nelson <robertcnelson@gmail.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/pinctrl/am33xx.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-I2C2-MPU6050.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_12_pinmux { status = "disabled"; };
+};
+
+&am33xx_pinmux {
+	mpu6050_pins: pinmux_mpu6050_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_BEN1, PIN_INPUT, MUX_MODE7) /* gpio1_28 */
+		>;
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	clock-frequency = <400000>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	imu@68 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&mpu6050_pins>;
+		compatible = "invensense,mpu6050";
+		reg = <0x68>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <28 IRQ_TYPE_EDGE_RISING>;
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-LCD-ADAFRUIT-24-SPI1-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-LCD-ADAFRUIT-24-SPI1-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-LCD-ADAFRUIT-24-SPI1-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-LCD-ADAFRUIT-24-SPI1-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 CircuitCo
+ * Copyright (C) 2018 Drew Fustini <drew@beagleboard.org>
+ * Copyright (C) 2019 Mark A. Yoder <mark.a.yoder@beagleboard.org>
+ *
+ * Adafruit 2.4" TFT LCD on SPI1 bus using tinydrm ili9341 driver
+ *
+ * DOCUMENTATION:
+ * --------------
+ * This file was copied from src/arm/BB-SPIDEV1-00A0.dts and modified
+ * by Drew Fustini based on an exmample from David Lechner.
+ * Later modified by Mark A. Yoder for the 2.4" LCD.
+ *
+ * This is the Adafruit 2.4" TFT LCD:
+ * https://www.adafruit.com/product/2478
+ *
+ * It should be connected to BeagleBone SPI1 bus:
+ *
+ *   P9.16 <--> lite (pwm) [OPTIONAL]
+ *   P9.23 <--> lite (gpio) [OPTIONAL]
+ *   P9.25 <--> reset
+ *   P9.27 <--> dc
+ *   P9.28 <--> tft_cs
+ *   P9.29 <--> miso
+ *   P9.30 <--> mosi
+ *   P9.31 <--> clk
+ *
+ * This overlay will load the mainline tinydrm ili9341 driver by David Lechner:
+ * https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/tiny/ili9341.c
+ *
+ * Tested with 4.19.59-ti-r26 kernel on Debian 10.1 image
+ *
+ * Run libdrm modetest for colorbar test based on instructions from:
+ * https://github.com/notro/tinydrm/wiki/Development#modetest
+ *
+ * modetest -M "ili9341" -c #this will display connector id
+ * modetest -M "ili9341" -s 28:128x160 #connector id and resolution
+ * # you should now see a color bar on the LCD
+ *
+ * Mailing list post with more information:
+ * https://groups.google.com/d/msg/beagleboard/GuMQIP_XCW0/b3lxbx_8AwAJ
+ *
+ * Discussion with notro on how to test tinydrm driver:
+ * https://github.com/notro/tinydrm/issues/1#issuecomment-367279037
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-LCD-ADAFRUIT-24-SPI1-00A0 = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_25_pinmux { status = "disabled"; };	/* lcd reset */
+	P9_16_pinmux { status = "disabled"; };  /* lcd pwm backlight (OPTIONAL) */
+	P9_27_pinmux { status = "disabled"; };	/* lcd dc */
+	P9_28_pinmux { status = "disabled"; };	/* spi1_cs0 */
+	P9_29_pinmux { status = "disabled"; };	/* spi1_d0 */
+	P9_30_pinmux { status = "disabled"; };	/* spi1_d1 */
+	P9_31_pinmux { status = "disabled"; };	/* spi1_sclk */
+};
+
+&am33xx_pinmux {
+	/* default state has all gpios released and mode set to uart1 */
+	/* See page 1446 of am35xx TRM */
+	bb_spi1_pins: pinmux_bb_spi1_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKX, PIN_INPUT, MUX_MODE3)	/* mcasp0_aclkx.spi1_sclk */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_FSX, PIN_INPUT, MUX_MODE3)	/* mcasp0_fsx.spi1_d0 */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_AXR0, PIN_INPUT, MUX_MODE3)	/* mcasp0_axr0.spi1_d1 */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKR, PIN_INPUT, MUX_MODE3)	/* mcasp0_ahclkr.spi1_cs0 */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_FSR, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpio, dc */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKX, PIN_OUTPUT_PULLUP, MUX_MODE7)	/* gpio, reset */
+		>;
+	};
+
+	backlight_pwm_pins: pinmux_backlight_pwm_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_A3, PIN_OUTPUT, MUX_MODE6) /* gpmc_a2.ehrpwm1b */
+		>;
+	};  /* gpmc_a2.ehrpwm1b */
+};
+
+&epwmss1 {
+	status = "okay";
+};
+
+&ehrpwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&backlight_pwm_pins>;
+	status = "okay";
+};
+
+&spi1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_spi1_pins>;
+
+	channel@0{
+		status = "disabled";
+		reg = <0>;
+	};
+
+	display@0{
+		status = "okay";
+		compatible = "adafruit,yx240qv29", "ilitek,ili9341";
+		reg = <0>;
+		spi-max-frequency = <32000000>;
+		dc-gpios    = <&gpio3 19 0>;   // lcd dc    P9.27 gpio3[19]
+		reset-gpios = <&gpio3 21 0>;   // lcd reset P9.25 gpio3[21]
+		// backlight is optional
+		// choose either pwm or gpio control
+		//backlight = <&backlight_gpio>; // lcd lite  P9.23 gpio1[17]
+		backlight = <&backlight_pwm>;    // lcd lite  P9.16 gpmc_a2.ehrpwm1b
+		// refer to https://elinux.org/Beagleboard:Cape_Expansion_Headers
+		// rotation is optional
+		rotation = <270>;
+	};
+};
+
+&{/} {
+	bl_reg: backlight-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "backlight";
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	/* backlight is optional */
+	backlight_gpio: backlight_gpio {
+		compatible = "gpio-backlight";
+		gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
+		// connect lcd lite pin to P9.23 which is gpio1[17]
+		// refer to https://elinux.org/Beagleboard:Cape_Expansion_Headers
+	};
+
+	/*
+	 * Turn the PWM backlight on by setting bl_power to 0:
+	 * echo 0 > /sys/class/backlight/backlight_pwm/bl_power
+	 */
+	backlight_pwm: backlight_pwm {
+		// P9.16 <--> lite (pwm-backlight EHRPWM1B)
+		status = "okay";
+		compatible = "pwm-backlight";
+		pwms = <&ehrpwm1 1 500000 0>;	// First digit: 0 for A side of pwm, 1 for B side
+										// 500000 is the PWM period in ns
+										// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/pwm/pwm.txt
+		brightness-levels = <
+			0  1  2  3  4  5  6  7  8  9
+			10 11 12 13 14 15 16 17 18 19
+			20 21 22 23 24 25 26 27 28 29
+			30 31 32 33 34 35 36 37 38 39
+			40 41 42 43 44 45 46 47 48 49
+			50 51 52 53 54 55 56 57 58 59
+			60 61 62 63 64 65 66 67 68 69
+			70 71 72 73 74 75 76 77 78 79
+			80 81 82 83 84 85 86 87 88 89
+			90 91 92 93 94 95 96 97 98 99
+			100
+		>;
+		default-brightness-level = <100>;
+		power-supply = <&bl_reg>;
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-NHDMI-TDA998x-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-NHDMI-TDA998x-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-NHDMI-TDA998x-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-NHDMI-TDA998x-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+#include <dt-bindings/display/tda998x.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-NHDMI-TDA998x-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P8_45_pinmux { status = "disabled"; };	/* lcd_data0 */
+	P8_46_pinmux { status = "disabled"; };	/* lcd_data1 */
+	P8_43_pinmux { status = "disabled"; };	/* lcd_data2 */
+	P8_44_pinmux { status = "disabled"; };	/* lcd_data3 */
+	P8_41_pinmux { status = "disabled"; };	/* lcd_data4 */
+	P8_42_pinmux { status = "disabled"; };	/* lcd_data5 */
+	P8_39_pinmux { status = "disabled"; };	/* lcd_data6 */
+	P8_40_pinmux { status = "disabled"; };	/* lcd_data7 */
+	P8_37_pinmux { status = "disabled"; };	/* lcd_data8 */
+	P8_38_pinmux { status = "disabled"; };	/* lcd_data9 */
+	P8_36_pinmux { status = "disabled"; };	/* lcd_data10 */
+	P8_34_pinmux { status = "disabled"; };	/* lcd_data11 */
+	P8_35_pinmux { status = "disabled"; };	/* lcd_data12 */
+	P8_33_pinmux { status = "disabled"; };	/* lcd_data13 */
+	P8_31_pinmux { status = "disabled"; };	/* lcd_data14 */
+	P8_32_pinmux { status = "disabled"; };	/* lcd_data15 */
+	P8_27_pinmux { status = "disabled"; };	/* lcd_vsync */
+	P8_29_pinmux { status = "disabled"; };	/* lcd_hsync */
+	P8_28_pinmux { status = "disabled"; };	/* lcd_pclk */
+	P8_30_pinmux { status = "disabled"; };	/* lcd_ac_bias_en */
+};
+
+&am33xx_pinmux {
+	nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR0, PIN_OUTPUT_PULLUP, MUX_MODE7)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA0, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA1, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA2, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA3, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA4, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA5, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA6, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA7, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA10, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA11, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA14, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_DATA15, PIN_OUTPUT, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_HSYNC, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+			AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+		>;
+	};
+
+	nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR0, PIN_OUTPUT_PULLDOWN, MUX_MODE7)
+		>;
+	};
+};
+
+&lcdc {
+	status = "okay";
+
+	/* If you want to get 24 bit RGB and 16 BGR mode instead of
+	 * current 16 bit RGB and 24 BGR modes, set the propety
+	 * below to "crossed" and uncomment the video-ports -property
+	 * in tda19988 node.
+	 */
+	blue-and-red-wiring = "straight";
+
+	port {
+		lcdc_0: endpoint@0 {
+			remote-endpoint = <&hdmi_0>;
+		};
+	};
+};
+
+&i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	tda19988: tda19988@70 {
+		compatible = "nxp,tda998x";
+		reg = <0x70>;
+		nxp,calib-gpios = <&gpio1 25 0>;
+		interrupts-extended = <&gpio1 25 IRQ_TYPE_LEVEL_LOW>;
+
+		pinctrl-names = "default", "off";
+		pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+		pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+
+		/* Convert 24bit BGR to RGB, e.g. cross red and blue wiring */
+		/* video-ports = <0x234501>; */
+
+		ports {
+			port@0 {
+				hdmi_0: endpoint@0 {
+					remote-endpoint = <&lcdc_0>;
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BBORG_COMMS-00A2.dtso b/arch/arm/boot/dts/ti/omap/BBORG_COMMS-00A2.dtso
--- a/arch/arm/boot/dts/ti/omap/BBORG_COMMS-00A2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BBORG_COMMS-00A2.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012,2019 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2015 Robert Nelson <robertcnelson@gmail.com>
+ * Copyright (C) 2015 Sebastian JegerÃ¥s
+ */
+
+/*
+ * Tested RobertCNelson [20240119] BBB and BBAI (6.1.69-ti-r21)
+ *
+ * sudo ip link set can0 type can bitrate 500000
+ * sudo ifconfig can0 up
+ *
+ * candump can0
+ * cansend can0 123#DEADBEEF
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BBORG_COMMS-00A2.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_24_pinmux { status = "disabled"; };
+	P9_26_pinmux { status = "disabled"; };
+	P9_13_pinmux { status = "disabled"; };
+	P9_11_pinmux { status = "disabled"; };
+};
+
+&bone_can_1 {
+	status = "okay";
+};
+
+&bone_uart_4 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BBORG_FAN-A000.dtso b/arch/arm/boot/dts/ti/omap/BBORG_FAN-A000.dtso
--- a/arch/arm/boot/dts/ti/omap/BBORG_FAN-A000.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BBORG_FAN-A000.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 Robert Nelson <robercnelson@gmail.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BBORG_FAN-A000.kernel = __TIMESTAMP__;
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BBORG_RELAY-00A2.dtso b/arch/arm/boot/dts/ti/omap/BBORG_RELAY-00A2.dtso
--- a/arch/arm/boot/dts/ti/omap/BBORG_RELAY-00A2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BBORG_RELAY-00A2.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015 Robert Nelson <robertcnelson@gmail.com>
+ * Copyright (C) 2019 Amilcar Lucas <amilcar.lucas@iav.de>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BBORG_RELAY-00A2.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_41_pinmux { status = "disabled"; };	/* P9_41: gpmc_a0.gpio0_20 */
+	P9_42_pinmux { status = "disabled"; };	/* P9_42: gpmc_a1.gpio0_07 */
+	P9_30_pinmux { status = "disabled"; };	/* P9_30: gpmc_be1n.gpio3_16 */
+	P9_27_pinmux { status = "disabled"; };	/* P9_27: mcasp0_fsr.gpio3_19 */
+};
+
+&am33xx_pinmux {
+	bb_gpio_relay_pins: pinmux_bb_gpio_relay_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR1, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* P9_41: Relay1 */
+			AM33XX_PADCONF(AM335X_PIN_ECAP0_IN_PWM0_OUT, PIN_OUTPUT_PULLDOWN, MUX_MODE7)	/* P9_42: Relay2 */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_AXR0, PIN_OUTPUT_PULLDOWN, MUX_MODE7)		/* P9_30: Relay3 */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_FSR, PIN_OUTPUT_PULLDOWN, MUX_MODE7)		/* P9_27: Relay4 */
+		>;
+	};
+};
+
+&{/} {
+	leds {
+		pinctrl-names = "default";
+		pinctrl-0 = <&bb_gpio_relay_pins>;
+
+		compatible = "gpio-leds";
+
+		jp@1 {
+			label = "relay-jp1";
+			gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+			default-state = "keep";
+		};
+
+		jp@2 {
+			label = "relay-jp2";
+			gpios = <&gpio0 07 GPIO_ACTIVE_HIGH>;
+			default-state = "keep";
+		};
+
+		jp@3 {
+			label = "relay-jp3";
+			gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>;
+			default-state = "keep";
+		};
+
+		jp@4 {
+			label = "relay-jp4";
+			gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
+			default-state = "keep";
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-SPIDEV0-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-SPIDEV0-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-SPIDEV0-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-SPIDEV0-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 CircuitCo
+ * Virtual cape for SPI0 on connector pins P9.22 P9.21 P9.18 P9.17
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-SPIDEV0-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_17_pinmux { status = "disabled"; };	/* P9_17 (A16) spi0_cs0.spi0_cs0 */
+	P9_18_pinmux { status = "disabled"; };	/* P9_18 (B16) spi0_d1.spi0_d1 */
+	P9_21_pinmux { status = "disabled"; };	/* P9_21 (B17) spi0_d0.spi0_d0 */
+	P9_22_pinmux { status = "disabled"; };	/* P9_22 (A17) spi0_sclk.spi0_sclk */
+};
+
+&am33xx_pinmux {
+	bb_spi0_pins: pinmux_bb_spi0_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_SPI0_SCLK, PIN_INPUT, MUX_MODE0)	/* P9_22 (A17) spi0_sclk.spi0_sclk */
+			AM33XX_PADCONF(AM335X_PIN_SPI0_D0, PIN_INPUT, MUX_MODE0)	/* P9_21 (B17) spi0_d0.spi0_d0 */
+			AM33XX_PADCONF(AM335X_PIN_SPI0_D1, PIN_INPUT, MUX_MODE0)	/* P9_18 (B16) spi0_d1.spi0_d1 */
+			AM33XX_PADCONF(AM335X_PIN_SPI0_CS0, PIN_INPUT, MUX_MODE0)	/* P9_17 (A16) spi0_cs0.spi0_cs0 */
+		>;
+	};
+};
+
+&spi0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_spi0_pins>;
+
+	/*
+	 * Select the D0 pin as output and D1 as
+	 * input. The default is D0 as input and
+	 * D1 as output.
+	 */
+	//ti,pindir-d0-out-d1-in;
+
+	channel@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "rohm,dh2228fv";
+		symlink = "bone/spi/0.0";
+
+		reg = <0>;
+		spi-max-frequency = <16000000>;
+		spi-cpha;
+	};
+
+	channel@1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "rohm,dh2228fv";
+		symlink = "bone/spi/0.1";
+
+		reg = <1>;
+		spi-max-frequency = <16000000>;
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-SPIDEV1-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-SPIDEV1-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-SPIDEV1-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-SPIDEV1-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 CircuitCo
+ * Virtual cape for SPI1 on connector pins P9.29 P9.31 P9.30 P9.28
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-SPIDEV1-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_28_pinmux { status = "disabled"; };	/* P9_28 (C12) mcasp0_ahclkr.spi1_cs0 */
+	P9_30_pinmux { status = "disabled"; };	/* P9_30 (D12) mcasp0_axr0.spi1_d1 */
+	P9_29_pinmux { status = "disabled"; };	/* P9_29 (B13) mcasp0_fsx.spi1_d0 */
+	P9_31_pinmux { status = "disabled"; };	/* P9_31 (A13) mcasp0_aclkx.spi1_sclk */
+};
+
+&am33xx_pinmux {
+	bb_spi1_pins: pinmux_bb_spi1_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKX, PIN_INPUT, MUX_MODE3)	/* P9_31 (A13) mcasp0_aclkx.spi1_sclk */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_FSX, PIN_INPUT, MUX_MODE3)	/* P9_29 (B13) mcasp0_fsx.spi1_d0 */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_AXR0, PIN_INPUT, MUX_MODE3)	/* P9_30 (D12) mcasp0_axr0.spi1_d1 */
+			AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKR, PIN_INPUT, MUX_MODE3)	/* P9_28 (C12) mcasp0_ahclkr.spi1_cs0 */
+		>;
+	};
+};
+
+&spi1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_spi1_pins>;
+
+	/*
+	 * Select the D0 pin as output and D1 as
+	 * input. The default is D0 as input and
+	 * D1 as output.
+	 */
+	//ti,pindir-d0-out-d1-in;
+
+	channel@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "rohm,dh2228fv";
+		symlink = "bone/spi/1.0";
+
+		reg = <0>;
+		spi-max-frequency = <16000000>;
+		spi-cpha;
+	};
+
+	channel@1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "rohm,dh2228fv";
+		symlink = "bone/spi/1.1";
+
+		reg = <1>;
+		spi-max-frequency = <16000000>;
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-UART1-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-UART1-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-UART1-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-UART1-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 CircuitCo
+ * Virtual cape for UART1 on connector pins P9.24 P9.26
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-UART1-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_24_pinmux { status = "disabled"; };	/* uart1_txd */
+	P9_26_pinmux { status = "disabled"; };	/* uart1_rxd */
+};
+
+&am33xx_pinmux {
+	bb_uart1_pins: pinmux_bb_uart1_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_UART1_TXD, PIN_OUTPUT, MUX_MODE0)	/* P9_24 uart1_txd.uart1_txd */
+			AM33XX_PADCONF(AM335X_PIN_UART1_RXD, PIN_INPUT, MUX_MODE0)	/* P9_26 uart1_rxd.uart1_rxd */
+			//AM33XX_PADCONF(AM335X_PIN_UART1_RTSN, PIN_OUTPUT, MUX_MODE0)	/* P9_19 uart1_rtsn.uart1_rtsn */
+			//AM33XX_PADCONF(AM335X_PIN_UART1_CTSN, PIN_INPUT, MUX_MODE0)	/* P9_20 uart1_ctsn.uart1_ctsn */
+		>;
+	};
+};
+
+&uart1 {
+	/* sudo agetty 115200 ttyS1 */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_uart1_pins>;
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-UART2-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-UART2-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-UART2-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-UART2-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 CircuitCo
+ * Virtual cape for UART2 on connector pins P9.21 P9.22
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-UART2-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_21_pinmux { status = "disabled"; };	/* P9_21: spi0_d0.uart2_txd */
+	P9_22_pinmux { status = "disabled"; };	/* P9_22: spi0_sclk.uart2_rxd */
+};
+
+&am33xx_pinmux {
+	bb_uart2_pins: pinmux_bb_uart2_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_SPI0_D0, PIN_OUTPUT, MUX_MODE1)	/* P9_21 spi0_d0.uart2_txd */
+			AM33XX_PADCONF(AM335X_PIN_SPI0_SCLK, PIN_INPUT, MUX_MODE1)	/* P9_22 spi0_sclk.uart2_rxd */
+			//AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_OUTPUT, MUX_MODE6)	/* P8_38 lcd_data9.uart2_rtsn */
+			//AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_INPUT, MUX_MODE6)	/* P8_37 lcd_data8.uart2_ctsn */
+		>;
+	};
+};
+
+&uart2 {
+	/* sudo agetty 115200 ttyS2 */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_uart2_pins>;
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-UART4-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-UART4-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-UART4-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-UART4-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 CircuitCo
+ * Virtual cape for UART4 on connector pins P9.13 P9.11
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-UART4-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_13_pinmux { status = "disabled"; };	/* P9_13: uart4_txd */
+	P9_11_pinmux { status = "disabled"; };	/* P9_11: uart4_rxd */
+};
+
+&am33xx_pinmux {
+	bb_uart4_pins: pinmux_bb_uart4_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_OUTPUT, MUX_MODE6)	/* P9_13 gpmc_wpn.uart4_txd_mux2 */
+			AM33XX_PADCONF(AM335X_PIN_GPMC_WAIT0, PIN_INPUT, MUX_MODE6)	/* P9_13 gpmc_wait0.uart4_rxd_mux2 */
+		>;
+	};
+};
+
+&uart4 {
+	/* sudo agetty 115200 ttyS4 */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&bb_uart4_pins>;
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BB-W1-P9.12-00A0.dtso b/arch/arm/boot/dts/ti/omap/BB-W1-P9.12-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/BB-W1-P9.12-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BB-W1-P9.12-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015 Robert Nelson <robertcnelson@gmail.com>
+ * Virtual cape for onewire on connector pin P9.12
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BB-W1-P9.12-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P9_12_pinmux { status = "disabled"; };	/* P9_12 (U18) gpmc_be1n.gpio1_28 */
+};
+
+&am33xx_pinmux {
+	bb_dallas_w1_pins: pinmux_bb_dallas_w1_pins {
+		pinctrl-single,pins = <
+			AM33XX_PADCONF(AM335X_PIN_GPMC_BEN1, PIN_INPUT_PULLUP, MUX_MODE7)	/* P9_12 (U18) gpmc_be1n.gpio1_28 */
+		>;
+	};
+};
+
+&{/} {
+	onewire {
+		status = "okay";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bb_dallas_w1_pins>;
+
+		compatible = "w1-gpio";
+		gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+	};
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/BONE-ADC.dtso b/arch/arm/boot/dts/ti/omap/BONE-ADC.dtso
--- a/arch/arm/boot/dts/ti/omap/BONE-ADC.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/BONE-ADC.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 Deepak Khatri <deepaklorkhatri7@gmail.com>
+ * See Cape Interface Spec page for more info on Bone Buses
+ * https://elinux.org/Beagleboard:BeagleBone_cape_interface_spec
+ *
+ * Virtual cape for Bone ADC
+ */
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BONE-ADC.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * See these files for the phandles (&bone_*) and other bone bus nodes
+ * am335x-bbb-bone-buses.dtsi
+ */
+&bone_adc {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/dra74x.dtsi b/arch/arm/boot/dts/ti/omap/dra74x.dtsi
--- a/arch/arm/boot/dts/ti/omap/dra74x.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/dra74x.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -229,4 +229,127 @@
 			};
 		};
 	};
+
+	target-module@190000 {			/* 0x48990000, ap 23 2e.0 */
+		compatible = "ti,sysc-omap4", "ti,sysc";
+		reg = <0x190010 0x4>;
+		reg-names = "sysc";
+		ti,sysc-midle = <SYSC_IDLE_FORCE>,
+				<SYSC_IDLE_NO>,
+				<SYSC_IDLE_SMART>;
+		ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+				<SYSC_IDLE_NO>,
+				<SYSC_IDLE_SMART>;
+		clocks = <&cam_clkctrl DRA7_CAM_VIP2_CLKCTRL 0>;
+		clock-names = "fck";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x190000 0x10000>;
+
+		vip2: vip@0 {
+			compatible = "ti,dra7-vip";
+			status = "disabled";
+			label = "vip2";
+			reg = <0x0000 0x114>,
+			      <0x5500 0xd8>,
+			      <0x5700 0x18>,
+			      <0x5800 0x80>,
+			      <0x5a00 0xd8>,
+			      <0x5c00 0x18>,
+			      <0x5d00 0x80>,
+			      <0xd000 0x400>;
+			reg-names = "vip",
+				    "parser0",
+				    "csc0",
+				    "sc0",
+				    "parser1",
+				    "csc1",
+				    "sc1",
+				    "vpdma";
+			interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>;
+			/* CTRL_CORE_SMA_SW_1 */
+			ti,vip-clk-polarity = <&scm_conf 0x534>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				vin3a: port@0 {
+					reg = <0>;
+					label = "vin3a";
+				};
+				vin4a: port@1 {
+					reg = <1>;
+					label = "vin4a";
+				};
+				vin3b: port@2 {
+					reg = <2>;
+					label = "vin3b";
+				};
+				vin4b: port@3 {
+					reg = <3>;
+					label = "vin4b";
+				};
+			};
+		};
+	};
+
+	target-module@1b0000 {			/* 0x489b0000, ap 25 34.0 */
+		compatible = "ti,sysc-omap4", "ti,sysc";
+		reg = <0x1b0000 0x4>,
+		      <0x1b0010 0x4>;
+		reg-names = "rev", "sysc";
+		ti,sysc-midle = <SYSC_IDLE_FORCE>,
+				<SYSC_IDLE_NO>,
+				<SYSC_IDLE_SMART>;
+		ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+				<SYSC_IDLE_NO>,
+				<SYSC_IDLE_SMART>;
+		clocks = <&cam_clkctrl DRA7_CAM_VIP3_CLKCTRL 0>;
+		clock-names = "fck";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x1b0000 0x10000>;
+
+		vip3: vip@0 {
+			compatible = "ti,dra7-vip";
+			status = "disabled";
+			label = "vip3";
+			reg = <0x0000 0x114>,
+			      <0x5500 0xd8>,
+			      <0x5700 0x18>,
+			      <0x5800 0x80>,
+			      <0x5a00 0xd8>,
+			      <0x5c00 0x18>,
+			      <0x5d00 0x80>,
+			      <0xd000 0x400>;
+			reg-names = "vip",
+				    "parser0",
+				    "csc0",
+				    "sc0",
+				    "parser1",
+				    "csc1",
+				    "sc1",
+				    "vpdma";
+			interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH>;
+			/* CTRL_CORE_SMA_SW_1 */
+			ti,vip-clk-polarity = <&scm_conf 0x534>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				vin5a: port@0 {
+					reg = <0>;
+					label = "vin5a";
+				};
+				vin6a: port@1 {
+					reg = <1>;
+					label = "vin6a";
+				};
+			};
+		};
+	};
 };
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi b/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi
--- a/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -4145,7 +4145,50 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 			ranges = <0x0 0x170000 0x10000>;
-			status = "disabled";
+
+			vip1: vip@0 {
+				compatible = "ti,dra7-vip";
+				status = "disabled";
+				label = "vip1";
+				reg = <0x0000 0x114>,
+				      <0x5500 0xd8>,
+				      <0x5700 0x18>,
+				      <0x5800 0x80>,
+				      <0x5a00 0xd8>,
+				      <0x5c00 0x18>,
+				      <0x5d00 0x80>,
+				      <0xd000 0x400>;
+				reg-names = "vip",
+					    "parser0",
+					    "csc0",
+					    "sc0",
+					    "parser1",
+					    "csc1",
+					    "sc1",
+					    "vpdma";
+				interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH>;
+				/* CTRL_CORE_SMA_SW_1 */
+				ti,vip-clk-polarity = <&scm_conf 0x534>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					vin1a: port@0 {
+						reg = <0>;
+					};
+					vin2a: port@1 {
+						reg = <1>;
+					};
+					vin1b: port@2 {
+						reg = <2>;
+					};
+					vin2b: port@3 {
+						reg = <3>;
+					};
+				};
+			};
 		};
 
 		target-module@190000 {			/* 0x48990000, ap 23 2e.0 */
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi b/arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi
--- a/arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -1376,7 +1376,6 @@
 		clocks = <&apll_pcie_ck>;
 		#clock-cells = <0>;
 		reg = <0x021c>;
-		ti,dividers = <2>, <1>;
 		ti,bit-shift = <8>;
 		ti,max-div = <2>;
 	};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/Makefile b/arch/arm/boot/dts/ti/omap/Makefile
--- a/arch/arm/boot/dts/ti/omap/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/Makefile	2025-10-23 09:30:40.281462084 -0400
@@ -1,4 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
+
+ifeq ($(CONFIG_OF_OVERLAY),y)
+DTC_FLAGS += -@
+endif
+
 dtb-$(CONFIG_ARCH_OMAP2) += \
 	omap2420-h4.dtb \
 	omap2420-n800.dtb \
@@ -89,10 +94,44 @@
 	am335x-base0033.dtb \
 	am335x-bone.dtb \
 	am335x-boneblack.dtb \
+	am335x-boneblack-revd.dtb \
+	am335x-boneblack-uboot.dtb \
+	PB-MIKROBUS-1.dtbo \
+	PB-MIKROBUS-0.dtbo \
+	M-BB-BBGG-00A0.dtbo \
+	M-BB-BBG-00A0.dtbo \
+	BONE-ADC.dtbo \
+	BBORG_RELAY-00A2.dtbo \
+	BBORG_FAN-A000.dtbo \
+	BBORG_COMMS-00A2.dtbo \
+	BB-W1-P9.12-00A0.dtbo \
+	BB-UART4-00A0.dtbo \
+	BB-UART2-00A0.dtbo \
+	BB-UART1-00A0.dtbo \
+	BB-SPIDEV1-00A0.dtbo \
+	BB-SPIDEV0-00A0.dtbo \
+	BB-NHDMI-TDA998x-00A0.dtbo \
+	BB-LCD-ADAFRUIT-24-SPI1-00A0.dtbo \
+	BB-I2C2-MPU6050.dtbo \
+	BB-I2C2-BME680.dtbo \
+	BB-I2C1-RTC-PCF8563.dtbo \
+	BB-I2C1-RTC-DS3231.dtbo \
+	BB-I2C1-MCP7940X-00A0.dtbo \
+	BB-HDMI-TDA998x-00A0.dtbo \
+	BB-CAPE-DISP-CT4-00A0.dtbo \
+	BB-BONE-eMMC1-01-00A0.dtbo \
+	BB-BONE-NH7C-01-A0.dtbo \
+	BB-BONE-LCD4-01-00A1.dtbo \
+	BB-BONE-4D5R-01-00A1.dtbo \
+	BB-BBGW-WL1835-00A0.dtbo \
+	BB-BBGG-WL1835-00A0.dtbo \
+	BB-BBBW-WL1835-00A0.dtbo \
+	BB-ADC-00A0.dtbo \
 	am335x-boneblack-wireless.dtb \
 	am335x-boneblue.dtb \
 	am335x-bonegreen.dtb \
 	am335x-bonegreen-wireless.dtb \
+	am335x-bonegreen-eco.dtb \
 	am335x-chiliboard.dtb \
 	am335x-cm-t335.dtb \
 	am335x-evm.dtb \
@@ -136,7 +175,6 @@
 am572x-idk-overlays-dtbs := am572x-idk.dtb \
 	am572x-idk-touchscreen.dtbo am57xx-idk-lcd-osd101t2045.dtbo
 
-# Build time test only, enabled by CONFIG_OF_ALL_DTBS
 dtb- += \
 	am571x-idk-overlays.dtb \
 	am572x-idk-overlays.dtb
@@ -158,6 +196,7 @@
 	am57xx-idk-lcd-osd101t2045.dtbo \
 	am57xx-idk-lcd-osd101t2587.dtbo \
 	dra7-evm.dtb \
+	am57xx-evm-ov10635.dtbo \
 	dra72-evm.dtb \
 	dra72-evm-revc.dtb \
 	dra71-evm.dtb \
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/M-BB-BBG-00A0.dtso b/arch/arm/boot/dts/ti/omap/M-BB-BBG-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/M-BB-BBG-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/M-BB-BBG-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		M-BB-BBG-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+&{/} {
+	model = "TI AM335x BeagleBone Green";
+	compatible = "ti,am335x-bone-green", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/M-BB-BBGG-00A0.dtso b/arch/arm/boot/dts/ti/omap/M-BB-BBGG-00A0.dtso
--- a/arch/arm/boot/dts/ti/omap/M-BB-BBGG-00A0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/M-BB-BBGG-00A0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		M-BB-BBGG-00A0.kernel = __TIMESTAMP__;
+	};
+};
+
+&{/} {
+	model = "SeeedStudio BeagleBone Green Gateway";
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/omap4-l4.dtsi b/arch/arm/boot/dts/ti/omap/omap4-l4.dtsi
--- a/arch/arm/boot/dts/ti/omap/omap4-l4.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/omap4-l4.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -1414,7 +1414,7 @@
 			uart3: serial@0 {
 				compatible = "ti,omap4-uart";
 				reg = <0x0 0x100>;
-				interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+				interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
 				clock-frequency = <48000000>;
 			};
 		};
@@ -1765,7 +1765,7 @@
 			uart1: serial@0 {
 				compatible = "ti,omap4-uart";
 				reg = <0x0 0x100>;
-				interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+				interrupts-extended = <&wakeupgen GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
 				clock-frequency = <48000000>;
 			};
 		};
@@ -1794,7 +1794,7 @@
 			uart2: serial@0 {
 				compatible = "ti,omap4-uart";
 				reg = <0x0 0x100>;
-				interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+				interrupts-extended = <&wakeupgen GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
 				clock-frequency = <48000000>;
 			};
 		};
@@ -1823,7 +1823,7 @@
 			uart4: serial@0 {
 				compatible = "ti,omap4-uart";
 				reg = <0x0 0x100>;
-				interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+				interrupts-extended = <&wakeupgen GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
 				clock-frequency = <48000000>;
 			};
 		};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/omap4-panda-a4.dts b/arch/arm/boot/dts/ti/omap/omap4-panda-a4.dts
--- a/arch/arm/boot/dts/ti/omap/omap4-panda-a4.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/omap4-panda-a4.dts	2025-10-23 09:30:40.282462115 -0400
@@ -7,6 +7,11 @@
 #include "omap443x.dtsi"
 #include "omap4-panda-common.dtsi"
 
+/ {
+	model = "TI OMAP4 PandaBoard (A4)";
+	compatible = "ti,omap4-panda-a4", "ti,omap4-panda", "ti,omap4430", "ti,omap4";
+};
+
 /* Pandaboard Rev A4+ have external pullups on SCL & SDA */
 &dss_hdmi_pins {
 	pinctrl-single,pins = <
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/omap4-panda-common.dtsi b/arch/arm/boot/dts/ti/omap/omap4-panda-common.dtsi
--- a/arch/arm/boot/dts/ti/omap/omap4-panda-common.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/omap4-panda-common.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -130,6 +130,12 @@
 		clock-frequency = <19200000>;
 	};
 
+	wl12xx_pwrseq: wl12xx-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&twl 0>;
+		clock-names = "ext_clock";
+	};
+
 	/* regulator for wl12xx on sdio5 */
 	wl12xx_vmmc: wl12xx_vmmc {
 		pinctrl-names = "default";
@@ -361,10 +367,8 @@
 	 */
 	wl12xx_gpio: wl12xx-gpio-pins {
 		pinctrl-single,pins = <
-			OMAP4_IOPAD(0x066, PIN_OUTPUT | MUX_MODE3)		/* gpmc_a19.gpio_43 */
-			OMAP4_IOPAD(0x06c, PIN_OUTPUT | MUX_MODE3)		/* gpmc_a22.gpio_46 */
+			OMAP4_IOPAD(0x066, PIN_OUTPUT | MUX_MODE3)		/* gpmc_a19.gpio_43 - WLAN_EN */
 			OMAP4_IOPAD(0x070, PIN_OUTPUT_PULLUP | MUX_MODE3)	/* gpmc_a24.gpio_48 */
-			OMAP4_IOPAD(0x072, PIN_OUTPUT_PULLUP | MUX_MODE3)	/* gpmc_a25.gpio_49 */
 		>;
 	};
 
@@ -387,6 +391,22 @@
 			OMAP4_IOPAD(0x114, PIN_INPUT_PULLUP | MUX_MODE3)	/* gpio_121 */
 		>;
 	};
+
+	bt_pins: bt-pins {
+		pinctrl-single,pins = <
+			OMAP4_IOPAD(0x06c, PIN_OUTPUT | MUX_MODE3)	  /* gpmc_a22.gpio_46 - BTEN */
+			OMAP4_IOPAD(0x072, PIN_OUTPUT_PULLUP | MUX_MODE3) /* gpmc_a25.gpio_49 - BTWAKEUP */
+		>;
+	};
+
+	uart2_pins: uart2-pins {
+		pinctrl-single,pins = <
+			OMAP4_IOPAD(0x118, PIN_INPUT_PULLUP | MUX_MODE0)  /* uart2_cts.uart2_cts - HCI */
+			OMAP4_IOPAD(0x11a, PIN_OUTPUT | MUX_MODE0)	  /* uart2_rts.uart2_rts */
+			OMAP4_IOPAD(0x11c, PIN_INPUT_PULLUP | MUX_MODE0)  /* uart2_rx.uart2_rx */
+			OMAP4_IOPAD(0x11e, PIN_OUTPUT | MUX_MODE0)	  /* uart2_tx.uart2_tx */
+		>;
+	};
 };
 
 &omap4_pmx_wkup {
@@ -408,6 +428,7 @@
 		reg = <0x48>;
 		/* IRQ# = 7 */
 		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
+		#clock-cells = <1>;
 		system-power-controller;
 	};
 
@@ -488,6 +509,7 @@
 	non-removable;
 	bus-width = <4>;
 	cap-power-off-card;
+	mmc-pwrseq = <&wl12xx_pwrseq>;
 
 	#address-cells = <1>;
 	#size-cells = <0>;
@@ -523,8 +545,19 @@
 };
 
 &uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins>;
 	interrupts-extended = <&wakeupgen GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH
 			       &omap4_pmx_core OMAP4_UART2_RX>;
+
+	bluetooth {
+		compatible = "ti,wl1271-st";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_pins>;
+		enable-gpios = <&gpio2 14 GPIO_ACTIVE_HIGH>;	/* GPIO_46 */
+		clocks = <&twl 0>;
+		clock-names = "ext_clock";
+	};
 };
 
 &uart3 {
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/omap4-panda-es.dts b/arch/arm/boot/dts/ti/omap/omap4-panda-es.dts
--- a/arch/arm/boot/dts/ti/omap/omap4-panda-es.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/omap4-panda-es.dts	2025-10-23 09:30:40.282462115 -0400
@@ -49,22 +49,6 @@
 			OMAP4_IOPAD(0x0fc, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */
 		>;
 	};
-
-	bt_pins: bt-pins {
-		pinctrl-single,pins = <
-			OMAP4_IOPAD(0x06c, PIN_OUTPUT | MUX_MODE3)		/* gpmc_a22.gpio_46 - BTEN */
-			OMAP4_IOPAD(0x072, PIN_OUTPUT_PULLUP | MUX_MODE3)	/* gpmc_a25.gpio_49 - BTWAKEUP */
-		>;
-	};
-
-	uart2_pins: uart2-pins {
-		pinctrl-single,pins = <
-			OMAP4_IOPAD(0x118, PIN_INPUT_PULLUP | MUX_MODE0)	/* uart2_cts.uart2_cts - HCI */
-			OMAP4_IOPAD(0x11a, PIN_OUTPUT | MUX_MODE0)		/* uart2_rts.uart2_rts */
-			OMAP4_IOPAD(0x11c, PIN_INPUT_PULLUP | MUX_MODE0)	/* uart2_rx.uart2_rx */
-			OMAP4_IOPAD(0x11e, PIN_OUTPUT | MUX_MODE0)		/* uart2_tx.uart2_tx */
-		>;
-	};
 };
 
 &led_wkgpio_pins {
@@ -96,19 +80,3 @@
 &gpio1_target {
 	 ti,no-reset-on-init;
 };
-
-&wl12xx_gpio {
-	pinctrl-single,pins = <
-		OMAP4_IOPAD(0x066, PIN_OUTPUT | MUX_MODE3)		/* gpmc_a19.gpio_43 */
-		OMAP4_IOPAD(0x070, PIN_OUTPUT_PULLUP | MUX_MODE3)	/* gpmc_a24.gpio_48 */
-	>;
-};
-
-&uart2 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&uart2_pins &bt_pins>;
-	bluetooth: tiwi {
-		compatible = "ti,wl1271-st";
-		enable-gpios = <&gpio2 14 GPIO_ACTIVE_HIGH>;	/* GPIO_46 */
-	};
-};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/PB-MIKROBUS-0.dtso b/arch/arm/boot/dts/ti/omap/PB-MIKROBUS-0.dtso
--- a/arch/arm/boot/dts/ti/omap/PB-MIKROBUS-0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/PB-MIKROBUS-0.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Vaishnav M A, BeagleBoard.org Foundation.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		PB-MIKROBUS-0.kernel = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P2_01_pinmux { status = "disabled"; };
+	P2_03_pinmux { status = "disabled"; };
+	P2_05_pinmux { status = "disabled"; };
+	P2_07_pinmux { status = "disabled"; };
+	P2_09_pinmux { status = "disabled"; };
+	P2_11_pinmux { status = "disabled"; };
+	P1_12_pinmux { status = "disabled"; };
+	P1_10_pinmux { status = "disabled"; };
+	P1_08_pinmux { status = "disabled"; };
+	P1_06_pinmux { status = "disabled"; };
+	P1_04_pinmux { status = "disabled"; };
+	P1_02_pinmux { status = "disabled"; };
+};
+
+&{/} {
+	aliases {
+		mikrobus0 = "/mikrobus-0";
+	};
+
+	mikrobus-0 {
+		compatible = "linux,mikrobus";
+		status = "okay";
+		pinctrl-names = "default", "pwm_default", "pwm_gpio",
+				"uart_default", "uart_gpio", "i2c_default",
+				"i2c_gpio", "spi_default", "spi_gpio";
+		pinctrl-0 = <
+			&P2_03_gpio_input_pin
+			&P1_04_gpio_pin
+			&P1_02_gpio_pin
+		>;
+		pinctrl-1 = <&P2_01_pwm_pin>;
+		pinctrl-2 = <&P2_01_gpio_pin>;
+		pinctrl-3 = <
+			&P2_05_uart_pin
+			&P2_07_uart_pin
+		>;
+		pinctrl-4 = <
+			&P2_05_gpio_pin
+			&P2_07_gpio_pin
+		>;
+		pinctrl-5 = <
+			&P2_09_i2c_pin
+			&P2_11_i2c_pin
+		>;
+		pinctrl-6 = <
+			&P2_09_gpio_pin
+			&P2_11_gpio_pin
+		>;
+		pinctrl-7 = <
+			&P1_12_spi_pin
+			&P1_10_spi_pin
+			&P1_08_spi_sclk_pin
+			&P1_06_spi_cs_pin
+		>;
+		pinctrl-8 = <
+			&P1_12_gpio_pin
+			&P1_10_gpio_pin
+			&P1_08_gpio_pin
+			&P1_06_gpio_pin
+		>;
+		i2c-adapter = <&i2c1>;
+		spi-master = <0>;
+		spi-cs = <0 1>;
+		uart = <&uart4>;
+		pwms = <&ehrpwm1 0 500000 0>;
+		mikrobus-gpios = <&gpio1 18 0> , <&gpio0 23 0>,
+				 <&gpio0 30 0> , <&gpio0 31 0>,
+				 <&gpio0 15 0> , <&gpio0 14 0>,
+				 <&gpio0 4 0>  , <&gpio0 3 0>,
+				 <&gpio0 2 0>  , <&gpio0 5 0>,
+				 <&gpio2 25 0> , <&gpio2 3 0>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+	channel@0{ status = "disabled"; };
+};
+
+&uart4 {
+	status = "okay";
+	force-empty-serdev-controller;
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/PB-MIKROBUS-1.dtso b/arch/arm/boot/dts/ti/omap/PB-MIKROBUS-1.dtso
--- a/arch/arm/boot/dts/ti/omap/PB-MIKROBUS-1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/boot/dts/ti/omap/PB-MIKROBUS-1.dtso	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Vaishnav M A, BeagleBoard.org Foundation.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		PB-MIKROBUS-1 = __TIMESTAMP__;
+	};
+};
+
+/*
+ * Free up the pins used by the cape from the pinmux helpers.
+ */
+&ocp {
+	P1_36_pinmux { status = "disabled"; };
+	P1_34_pinmux { status = "disabled"; };
+	P1_32_pinmux { status = "disabled"; };
+	P1_30_pinmux { status = "disabled"; };
+	P1_28_pinmux { status = "disabled"; };
+	P1_26_pinmux { status = "disabled"; };
+	P2_25_pinmux { status = "disabled"; };
+	P2_27_pinmux { status = "disabled"; };
+	P2_29_pinmux { status = "disabled"; };
+	P2_31_pinmux { status = "disabled"; };
+	P2_33_pinmux { status = "disabled"; };
+	P2_35_pinmux { status = "disabled"; };
+};
+
+&{/} {
+	aliases {
+		mikrobus1 = "/mikrobus-1";
+	};
+
+	mikrobus-1 {
+		compatible = "linux,mikrobus";
+		status = "okay";
+		pinctrl-names = "default", "pwm_default", "pwm_gpio",
+				"uart_default", "uart_gpio", "i2c_default",
+				"i2c_gpio", "spi_default", "spi_gpio";
+		pinctrl-0 = <
+			&P1_34_gpio_input_pin
+			&P2_33_gpio_pin
+			&P2_35_gpio_pin
+		>;
+		pinctrl-1 = <&P1_36_pwm_pin>;
+		pinctrl-2 = <&P1_36_gpio_pin>;
+		pinctrl-3 = <
+			&P1_32_uart_pin
+			&P1_30_uart_pin
+		>;
+		pinctrl-4 = <
+			&P1_32_gpio_pin
+			&P1_30_gpio_pin
+		>;
+		pinctrl-5 = <
+			&P1_26_i2c_pin
+			&P1_28_i2c_pin
+		>;
+		pinctrl-6 = <
+			&P1_26_gpio_pin
+			&P1_28_gpio_pin
+		>;
+		pinctrl-7 = <
+			&P2_25_spi_pin
+			&P2_27_spi_pin
+			&P2_29_spi_sclk_pin
+			&P2_31_spi_cs_pin
+		>;
+		pinctrl-8 = <
+			&P2_25_gpio_pin
+			&P2_27_gpio_pin
+			&P2_29_gpio_pin
+			&P2_31_gpio_pin
+		>;
+		i2c-adapter = <&i2c2>;
+		spi-master = <1>;
+		spi-cs = <1 2>;
+		uart = <&uart0>;
+		pwms = <&ehrpwm0 0 500000 0>;
+		mikrobus-gpios = <&gpio3 14 0> , <&gpio0 26 0>,
+				 <&gpio1 10 0> , <&gpio1 11 0>,
+				 <&gpio0 13 0> , <&gpio0 12 0>,
+				 <&gpio1 9 0>  , <&gpio1 8 0>,
+				 <&gpio0 7 0>  , <&gpio0 19 0>,
+				 <&gpio1 13 0> , <&gpio2 22 0>;
+	};
+};
+
+&spi1 {
+	status = "okay";
+	channel@0{ status = "disabled"; };
+	channel@1{ status = "disabled"; };
+};
+
+&uart0 {
+	status = "okay";
+	force-empty-serdev-controller;
+};
diff -Naur --no-dereference a/arch/arm/boot/dts/ti/omap/twl4030.dtsi b/arch/arm/boot/dts/ti/omap/twl4030.dtsi
--- a/arch/arm/boot/dts/ti/omap/twl4030.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/boot/dts/ti/omap/twl4030.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -16,7 +16,7 @@
 		interrupts = <11>;
 	};
 
-	charger: bci {
+	charger: charger {
 		compatible = "ti,twl4030-bci";
 		interrupts = <9>, <2>;
 		bci3v1-supply = <&vusb3v1>;
diff -Naur --no-dereference a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
--- a/arch/arm/configs/multi_v7_defconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/configs/multi_v7_defconfig	2025-10-23 09:30:40.282462115 -0400
@@ -1,6 +1,7 @@
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
 CONFIG_CGROUPS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
@@ -230,6 +231,7 @@
 CONFIG_QCOM_FASTRPC=m
 CONFIG_APDS9802ALS=y
 CONFIG_ISL29003=y
+CONFIG_SRAM_DMA_HEAP=y
 CONFIG_PCI_ENDPOINT_TEST=m
 CONFIG_EEPROM_AT24=y
 CONFIG_BLK_DEV_SD=y
@@ -343,6 +345,7 @@
 CONFIG_INPUT_MAX8997_HAPTIC=m
 CONFIG_INPUT_GPIO_DECODER=m
 CONFIG_INPUT_CPCAP_PWRBUTTON=m
+CONFIG_INPUT_TPS65219_PWRBUTTON=m
 CONFIG_INPUT_AXP20X_PEK=m
 CONFIG_INPUT_DA9063_ONKEY=m
 CONFIG_INPUT_ADXL34X=m
@@ -362,6 +365,7 @@
 CONFIG_SERIAL_8250_OMAP=y
 CONFIG_SERIAL_8250_MT6577=y
 CONFIG_SERIAL_8250_UNIPHIER=y
+CONFIG_SERIAL_8250_PRUSS=m
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
@@ -617,6 +621,7 @@
 CONFIG_MFD_TPS65090=y
 CONFIG_MFD_TPS65217=y
 CONFIG_MFD_TPS65218=y
+CONFIG_MFD_TPS65219=y
 CONFIG_MFD_TPS6586X=y
 CONFIG_MFD_TPS65910=y
 CONFIG_MFD_STM32_LPTIMER=m
@@ -666,6 +671,7 @@
 CONFIG_REGULATOR_TPS65090=y
 CONFIG_REGULATOR_TPS65217=y
 CONFIG_REGULATOR_TPS65218=y
+CONFIG_REGULATOR_TPS65219=y
 CONFIG_REGULATOR_TPS6586X=y
 CONFIG_REGULATOR_TPS65910=y
 CONFIG_REGULATOR_TWL4030=y
@@ -676,6 +682,7 @@
 CONFIG_MEDIA_SUPPORT=m
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
+CONFIG_VIDEO_TI_VIP=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_ASPEED=m
@@ -707,6 +714,7 @@
 CONFIG_VIDEO_VIVID=m
 CONFIG_VIDEO_S5C73M3=m
 CONFIG_VIDEO_S5K6A3=m
+CONFIG_VIDEO_OV1063X=m
 CONFIG_VIDEO_ADV7180=m
 CONFIG_VIDEO_ADV7604=m
 CONFIG_VIDEO_ADV7604_CEC=y
@@ -733,6 +741,7 @@
 CONFIG_DRM_SUN4I=m
 CONFIG_DRM_OMAP=m
 CONFIG_OMAP5_DSS_HDMI=y
+CONFIG_DRM_TILCDC=m
 CONFIG_DRM_MSM=m
 CONFIG_DRM_FSL_DCU=m
 CONFIG_DRM_TEGRA=y
@@ -1050,6 +1059,10 @@
 CONFIG_RZN1_DMAMUX=m
 CONFIG_RCAR_DMAC=y
 CONFIG_RENESAS_USB_DMAC=m
+CONFIG_DMABUF_HEAPS=y
+CONFIG_DMABUF_HEAPS_SYSTEM=y
+CONFIG_DMABUF_HEAPS_CMA=y
+CONFIG_DMABUF_HEAPS_CARVEOUT=y
 CONFIG_VIRTIO_PCI=y
 CONFIG_VIRTIO_MMIO=y
 CONFIG_STAGING=y
@@ -1094,6 +1107,7 @@
 CONFIG_EXYNOS_IOMMU=y
 CONFIG_QCOM_IOMMU=y
 CONFIG_REMOTEPROC=y
+CONFIG_REMOTEPROC_CDEV=y
 CONFIG_OMAP_REMOTEPROC=m
 CONFIG_OMAP_REMOTEPROC_WATCHDOG=y
 CONFIG_KEYSTONE_REMOTEPROC=m
@@ -1152,6 +1166,7 @@
 CONFIG_QCOM_RPMHPD=y
 CONFIG_QCOM_RPMPD=y
 CONFIG_ROCKCHIP_PM_DOMAINS=y
+CONFIG_TI_PRUSS=m
 CONFIG_TI_SCI_PM_DOMAINS=y
 CONFIG_ARM_EXYNOS_BUS_DEVFREQ=m
 CONFIG_ARM_TEGRA_DEVFREQ=m
@@ -1201,6 +1216,8 @@
 CONFIG_PWM_BCM2835=y
 CONFIG_PWM_BRCMSTB=m
 CONFIG_PWM_FSL_FTM=m
+CONFIG_PWM_TIECAP=m
+CONFIG_PWM_TIEHRPWM=m
 CONFIG_PWM_MESON=m
 CONFIG_PWM_RCAR=m
 CONFIG_PWM_RENESAS_TPU=y
diff -Naur --no-dereference a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
--- a/arch/arm/configs/omap2plus_defconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm/configs/omap2plus_defconfig	2025-10-23 09:30:40.282462115 -0400
@@ -386,6 +386,7 @@
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_CPCAP_PWRBUTTON=m
 CONFIG_INPUT_TPS65218_PWRBUTTON=m
+CONFIG_INPUT_TPS65219_PWRBUTTON=m
 CONFIG_INPUT_TWL4030_PWRBUTTON=m
 CONFIG_INPUT_UINPUT=m
 CONFIG_INPUT_PALMAS_PWRBUTTON=m
@@ -454,6 +455,7 @@
 CONFIG_MFD_TI_LP873X=y
 CONFIG_MFD_TI_LP87565=y
 CONFIG_MFD_TPS65218=y
+CONFIG_MFD_TPS65219=y
 CONFIG_MFD_TPS65910=y
 CONFIG_TWL6040_CORE=y
 CONFIG_REGULATOR_CPCAP=y
@@ -470,6 +472,7 @@
 CONFIG_REGULATOR_TPS6507X=y
 CONFIG_REGULATOR_TPS65217=y
 CONFIG_REGULATOR_TPS65218=y
+CONFIG_REGULATOR_TPS65219=y
 CONFIG_REGULATOR_TPS65910=y
 CONFIG_REGULATOR_TWL4030=y
 CONFIG_RC_CORE=m
diff -Naur --no-dereference a/arch/arm/configs/rcn-ee_defconfig b/arch/arm/configs/rcn-ee_defconfig
--- a/arch/arm/configs/rcn-ee_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm/configs/rcn-ee_defconfig	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,2911 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_XZ=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_JIT=y
+CONFIG_BPF_JIT_ALWAYS_ON=y
+CONFIG_BPF_PRELOAD=y
+CONFIG_BPF_PRELOAD_UMD=y
+CONFIG_BPF_LSM=y
+CONFIG_PREEMPT=y
+CONFIG_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_PSI=y
+CONFIG_PSI_DEFAULT_DISABLED=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_IKHEADERS=m
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_PRINTK_INDEX=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_V1=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_RDMA=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
+CONFIG_CGROUP_MISC=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
+CONFIG_CHECKPOINT_RESTORE=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_EXPERT=y
+# CONFIG_SYSFS_SYSCALL is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PROFILING=y
+CONFIG_KEXEC=y
+CONFIG_SOC_OMAP5=y
+CONFIG_SOC_AM33XX=y
+CONFIG_SOC_DRA7XX=y
+CONFIG_SOC_HAS_OMAP2_SDRC=y
+CONFIG_OMAP5_ERRATA_801819=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_PL310_ERRATA_588369=y
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_PL310_ERRATA_753970=y
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_ARM_ERRATA_773022=y
+CONFIG_ARM_ERRATA_814220=y
+CONFIG_SMP=y
+# CONFIG_ARM_CPU_TOPOLOGY is not set
+CONFIG_MCPM=y
+CONFIG_NR_CPUS=2
+CONFIG_ARM_PSCI=y
+CONFIG_HZ_250=y
+CONFIG_ARCH_FORCE_MAX_ORDER=12
+CONFIG_PARAVIRT=y
+# CONFIG_ATAGS is not set
+CONFIG_EFI=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPUFREQ_DT=m
+# CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_KERNEL_MODE_NEON=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_ADVANCED_DEBUG=y
+CONFIG_APM_EMULATION=y
+CONFIG_ENERGY_MODEL=y
+CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_COMPRESS=y
+CONFIG_MODULE_COMPRESS_XZ=y
+CONFIG_BLK_DEV_ZONED=y
+CONFIG_BLK_DEV_THROTTLING=y
+CONFIG_BLK_WBT=y
+CONFIG_BLK_CGROUP_IOCOST=y
+CONFIG_BLK_SED_OPAL=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_MQ_IOSCHED_KYBER=m
+CONFIG_IOSCHED_BFQ=m
+CONFIG_BINFMT_MISC=m
+CONFIG_ZSWAP=y
+CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
+CONFIG_SLAB_FREELIST_RANDOM=y
+CONFIG_SLAB_FREELIST_HARDENED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_KSM=y
+CONFIG_CMA_AREAS=7
+CONFIG_IDLE_PAGE_TRACKING=y
+CONFIG_ANON_VMA_NAME=y
+CONFIG_USERFAULTFD=y
+CONFIG_LRU_GEN=y
+CONFIG_LRU_GEN_ENABLED=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
+CONFIG_UNIX_DIAG=m
+CONFIG_TLS=m
+CONFIG_TLS_DEVICE=y
+CONFIG_XFRM_USER=m
+CONFIG_XFRM_INTERFACE=m
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=m
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_XDP_SOCKETS=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_FIB_TRIE_STATS=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_NET_IPVTI=m
+CONFIG_NET_FOU_IP_TUNNELS=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
+CONFIG_INET_RAW_DIAG=m
+CONFIG_INET_DIAG_DESTROY=y
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_NV=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_TCP_CONG_DCTCP=m
+CONFIG_TCP_CONG_CDG=m
+CONFIG_TCP_CONG_BBR=m
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_ILA=m
+CONFIG_IPV6_VTI=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_SIT_6RD=y
+CONFIG_IPV6_GRE=m
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_IPV6_SEG6_LWTUNNEL=y
+CONFIG_IPV6_SEG6_HMAC=y
+CONFIG_NETLABEL=y
+CONFIG_MPTCP=y
+CONFIG_NETWORK_PHY_TIMESTAMPING=y
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_ZONES=y
+CONFIG_NF_CONNTRACK_PROCFS=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMEOUT=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NF_CT_NETLINK_TIMEOUT=m
+CONFIG_NF_CT_NETLINK_HELPER=m
+CONFIG_NETFILTER_NETLINK_GLUE_CT=y
+CONFIG_NF_TABLES=m
+CONFIG_NF_TABLES_INET=y
+CONFIG_NF_TABLES_NETDEV=y
+CONFIG_NFT_NUMGEN=m
+CONFIG_NFT_CT=m
+CONFIG_NFT_FLOW_OFFLOAD=m
+CONFIG_NFT_CONNLIMIT=m
+CONFIG_NFT_LOG=m
+CONFIG_NFT_LIMIT=m
+CONFIG_NFT_MASQ=m
+CONFIG_NFT_REDIR=m
+CONFIG_NFT_NAT=m
+CONFIG_NFT_TUNNEL=m
+CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
+CONFIG_NFT_REJECT=m
+CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
+CONFIG_NFT_FIB_INET=m
+CONFIG_NFT_XFRM=m
+CONFIG_NFT_SOCKET=m
+CONFIG_NFT_OSF=m
+CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
+CONFIG_NFT_FIB_NETDEV=m
+CONFIG_NF_FLOW_TABLE_INET=m
+CONFIG_NF_FLOW_TABLE=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CT=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LED=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_CGROUP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_CPU=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPCOMP=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPMARK=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_IPMAC=m
+CONFIG_IP_SET_HASH_MAC=m
+CONFIG_IP_SET_HASH_NETPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETNET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_PROTO_SCTP=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_FO=m
+CONFIG_IP_VS_OVF=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_MH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_TWOS=m
+CONFIG_IP_VS_FTP=m
+CONFIG_IP_VS_PE_SIP=m
+CONFIG_NFT_DUP_IPV4=m
+CONFIG_NFT_FIB_IPV4=m
+CONFIG_NF_TABLES_ARP=y
+CONFIG_NF_LOG_ARP=m
+CONFIG_NF_LOG_IPV4=m
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_SYNPROXY=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_SECURITY=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NFT_DUP_IPV6=m
+CONFIG_NFT_FIB_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_SRH=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_TARGET_SYNPROXY=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_SECURITY=m
+CONFIG_IP6_NF_NAT=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
+CONFIG_NFT_BRIDGE_REJECT=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_NFLOG=m
+CONFIG_IP_DCCP=m
+CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1=y
+CONFIG_SCTP_COOKIE_HMAC_MD5=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_TIPC=m
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+CONFIG_L2TP=m
+CONFIG_L2TP_DEBUGFS=m
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=m
+CONFIG_L2TP_ETH=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VLAN_8021Q_MVRP=y
+CONFIG_LLC2=m
+CONFIG_ATALK=m
+CONFIG_PHONET=m
+CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
+CONFIG_IEEE802154=m
+CONFIG_IEEE802154_6LOWPAN=m
+CONFIG_MAC802154=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFB=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_CBS=m
+CONFIG_NET_SCH_ETF=m
+CONFIG_NET_SCH_TAPRIO=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_SCH_SKBPRIO=m
+CONFIG_NET_SCH_CHOKE=m
+CONFIG_NET_SCH_QFQ=m
+CONFIG_NET_SCH_CODEL=m
+CONFIG_NET_SCH_FQ_CODEL=y
+CONFIG_NET_SCH_CAKE=m
+CONFIG_NET_SCH_FQ=m
+CONFIG_NET_SCH_HHF=m
+CONFIG_NET_SCH_PIE=m
+CONFIG_NET_SCH_FQ_PIE=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_SCH_PLUG=m
+CONFIG_NET_SCH_ETS=m
+CONFIG_NET_SCH_DEFAULT=y
+CONFIG_DEFAULT_FQ_CODEL=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
+CONFIG_NET_CLS_BPF=m
+CONFIG_NET_CLS_FLOWER=m
+CONFIG_NET_CLS_MATCHALL=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_EMATCH_CANID=m
+CONFIG_NET_EMATCH_IPSET=m
+CONFIG_NET_EMATCH_IPT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_SAMPLE=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_ACT_CSUM=m
+CONFIG_NET_ACT_MPLS=m
+CONFIG_NET_ACT_VLAN=m
+CONFIG_NET_ACT_BPF=m
+CONFIG_NET_ACT_CONNMARK=m
+CONFIG_NET_ACT_CTINFO=m
+CONFIG_NET_ACT_SKBMOD=m
+CONFIG_NET_ACT_IFE=m
+CONFIG_NET_ACT_TUNNEL_KEY=m
+CONFIG_NET_ACT_CT=m
+CONFIG_NET_ACT_GATE=m
+CONFIG_NET_IFE_SKBMARK=m
+CONFIG_NET_IFE_SKBPRIO=m
+CONFIG_NET_IFE_SKBTCINDEX=m
+CONFIG_DCB=y
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_NC=y
+CONFIG_OPENVSWITCH=m
+CONFIG_VSOCKETS=m
+CONFIG_VIRTIO_VSOCKETS=m
+CONFIG_NETLINK_DIAG=m
+CONFIG_NET_MPLS_GSO=y
+CONFIG_MPLS_ROUTING=m
+CONFIG_MPLS_IPTUNNEL=m
+CONFIG_HSR=m
+CONFIG_NET_SWITCHDEV=y
+CONFIG_QRTR=m
+CONFIG_QRTR_SMD=m
+CONFIG_QRTR_TUN=m
+CONFIG_NET_NCSI=y
+CONFIG_CGROUP_NET_PRIO=y
+CONFIG_BPF_STREAM_PARSER=y
+CONFIG_NET_PKTGEN=m
+CONFIG_NET_DROP_MONITOR=m
+CONFIG_HAMRADIO=y
+CONFIG_AX25=m
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_YAM=m
+CONFIG_CAN=m
+CONFIG_CAN_J1939=m
+CONFIG_CAN_ISOTP=m
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_6LOWPAN=m
+CONFIG_BT_LEDS=y
+CONFIG_BT_MSFTEXT=y
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTUSB_MTK=y
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_NOKIA=m
+CONFIG_BT_HCIUART_ATH3K=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIUART_INTEL=y
+CONFIG_BT_HCIUART_BCM=y
+CONFIG_BT_HCIUART_RTL=y
+CONFIG_BT_HCIUART_QCA=y
+CONFIG_BT_HCIUART_AG6XX=y
+CONFIG_BT_HCIUART_MRVL=y
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+CONFIG_BT_ATH3K=m
+CONFIG_BT_MTKUART=m
+CONFIG_AF_RXRPC_IPV6=y
+CONFIG_RXKAD=y
+CONFIG_AF_KCM=m
+CONFIG_CFG80211=m
+# CONFIG_CFG80211_DEFAULT_PS is not set
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_NET_9P=m
+CONFIG_NET_9P_VIRTIO=m
+CONFIG_NFC=m
+CONFIG_NFC_DIGITAL=m
+CONFIG_NFC_NCI=m
+CONFIG_NFC_NCI_SPI=m
+CONFIG_NFC_NCI_UART=m
+CONFIG_NFC_TRF7970A=m
+CONFIG_NFC_SIM=m
+CONFIG_NFC_PORT100=m
+CONFIG_NFC_PN533_USB=m
+CONFIG_NFC_PN533_I2C=m
+CONFIG_NFC_ST_NCI_I2C=m
+CONFIG_NFC_ST_NCI_SPI=m
+CONFIG_NFC_NXP_NCI=m
+CONFIG_NFC_NXP_NCI_I2C=m
+CONFIG_NFC_ST95HF=m
+CONFIG_PAGE_POOL_STATS=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_EXTRA_FIRMWARE="regulatory.db regulatory.db.p7s am335x-pm-firmware.elf am335x-bone-scale-data.bin am335x-evm-scale-data.bin am43x-evm-scale-data.bin"
+CONFIG_EXTRA_FIRMWARE_DIR="firmware"
+CONFIG_FW_LOADER_COMPRESS=y
+CONFIG_FW_LOADER_COMPRESS_ZSTD=y
+CONFIG_OMAP_OCP2SCP=y
+CONFIG_CONNECTOR=y
+CONFIG_DMI_SYSFS=y
+CONFIG_SYSFB_SIMPLEFB=y
+CONFIG_TRUSTED_FOUNDATIONS=y
+CONFIG_EFI_BOOTLOADER_CONTROL=m
+CONFIG_EFI_CAPSULE_LOADER=m
+CONFIG_RESET_ATTACK_MITIGATION=y
+CONFIG_GNSS=m
+CONFIG_GNSS_MTK_SERIAL=m
+CONFIG_GNSS_SIRF_SERIAL=m
+CONFIG_GNSS_UBX_SERIAL=m
+CONFIG_MTD=y
+CONFIG_MTD_OF_PARTS=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_RFD_FTL=m
+CONFIG_SSFDC=m
+CONFIG_MTD_OOPS=m
+CONFIG_MTD_SWAP=m
+CONFIG_MTD_PHYSMAP=m
+CONFIG_MTD_PLATRAM=m
+CONFIG_MTD_DATAFLASH=m
+CONFIG_MTD_SST25L=m
+CONFIG_MTD_ONENAND=y
+CONFIG_MTD_ONENAND_VERIFY_WRITE=y
+CONFIG_MTD_ONENAND_2X_PROGRAM=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_NAND_OMAP2=m
+CONFIG_MTD_NAND_NANDSIM=m
+CONFIG_MTD_SPI_NAND=y
+CONFIG_MTD_NAND_ECC_SW_BCH=y
+CONFIG_MTD_LPDDR=m
+CONFIG_MTD_SPI_NOR=m
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_OF_OVERLAY=y
+CONFIG_BLK_DEV_NULL_BLK=m
+CONFIG_ZRAM=m
+CONFIG_ZRAM_BACKEND_LZ4=y
+CONFIG_ZRAM_BACKEND_LZ4HC=y
+CONFIG_ZRAM_BACKEND_ZSTD=y
+CONFIG_ZRAM_BACKEND_DEFLATE=y
+CONFIG_ZRAM_BACKEND_LZO=y
+CONFIG_ZRAM_DEF_COMP_LZ4=y
+CONFIG_ZRAM_WRITEBACK=y
+CONFIG_ZRAM_MEMORY_TRACKING=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_DRBD=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_ATA_OVER_ETH=m
+CONFIG_VIRTIO_BLK=m
+CONFIG_BLK_DEV_RBD=m
+CONFIG_AD525X_DPOT=m
+CONFIG_AD525X_DPOT_I2C=m
+CONFIG_AD525X_DPOT_SPI=m
+CONFIG_RPMB=y
+CONFIG_ICS932S401=m
+CONFIG_APDS9802ALS=m
+CONFIG_ISL29003=m
+CONFIG_ISL29020=m
+CONFIG_SENSORS_TSL2550=m
+CONFIG_SENSORS_BH1770=m
+CONFIG_SENSORS_APDS990X=m
+CONFIG_HMC6352=m
+CONFIG_DS1682=m
+CONFIG_SRAM=y
+CONFIG_SRAM_DMA_HEAP=y
+CONFIG_NSM=m
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+CONFIG_EEPROM_MAX6875=m
+CONFIG_EEPROM_93XX46=m
+CONFIG_EEPROM_EE1004=m
+CONFIG_TI_ST=m
+CONFIG_RAID_ATTRS=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SAS_ATA=y
+CONFIG_SCSI_SRP_ATTRS=m
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_CLUSTER=m
+CONFIG_BCACHE=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_UNSTRIPED=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
+CONFIG_DM_WRITECACHE=m
+CONFIG_DM_ERA=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_DELAY=m
+CONFIG_DM_UEVENT=y
+CONFIG_DM_FLAKEY=m
+CONFIG_DM_VERITY=m
+CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
+CONFIG_DM_SWITCH=m
+CONFIG_DM_LOG_WRITES=m
+CONFIG_DM_INTEGRITY=m
+CONFIG_DM_ZONED=m
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
+CONFIG_TCM_USER2=m
+CONFIG_LOOPBACK_TARGET=m
+CONFIG_ISCSI_TARGET=m
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_DUMMY=y
+CONFIG_WIREGUARD=m
+CONFIG_EQUALIZER=m
+CONFIG_IFB=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_RANDOM=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_IPVLAN=y
+CONFIG_IPVTAP=m
+CONFIG_VXLAN=y
+CONFIG_GENEVE=m
+CONFIG_GTP=m
+CONFIG_MACSEC=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=m
+CONFIG_NLMON=m
+CONFIG_NET_VRF=m
+CONFIG_ATM_DUMMY=m
+# CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_GOOGLE is not set
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_HUAWEI is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+CONFIG_KS8851=m
+CONFIG_ENC28J60=y
+CONFIG_ENCX24J600=y
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SOLARFLARE is not set
+CONFIG_SMC91X=m
+CONFIG_SMSC911X=m
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+CONFIG_TI_CPSW_PHY_SEL=y
+CONFIG_TI_CPSW=y
+CONFIG_TI_CPSW_SWITCHDEV=y
+CONFIG_TI_CPTS=y
+# CONFIG_NET_VENDOR_VIA is not set
+CONFIG_WIZNET_W5100=m
+CONFIG_WIZNET_W5100_SPI=m
+# CONFIG_NET_VENDOR_XILINX is not set
+CONFIG_LED_TRIGGER_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_MICROCHIP_PHY=y
+CONFIG_MICROSEMI_PHY=m
+CONFIG_AT803X_PHY=y
+CONFIG_DP83867_PHY=y
+CONFIG_DP83869_PHY=m
+CONFIG_VITESSE_PHY=y
+CONFIG_CAN_VCAN=m
+CONFIG_CAN_VXCAN=m
+CONFIG_CAN_SLCAN=m
+CONFIG_CAN_C_CAN=m
+CONFIG_CAN_C_CAN_PLATFORM=m
+CONFIG_CAN_HI311X=m
+CONFIG_CAN_MCP251X=m
+CONFIG_CAN_MCP251XFD=m
+CONFIG_CAN_8DEV_USB=m
+CONFIG_CAN_EMS_USB=m
+CONFIG_CAN_ESD_USB=m
+CONFIG_CAN_GS_USB=m
+CONFIG_CAN_KVASER_USB=m
+CONFIG_CAN_MCBA_USB=m
+CONFIG_CAN_PEAK_USB=m
+CONFIG_CAN_UCAN=m
+CONFIG_MDIO_BCM_UNIMAC=m
+CONFIG_MDIO_GPIO=y
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOATM=m
+CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_LAN78XX=m
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_AX88179_178A=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_CDC_EEM=m
+CONFIG_USB_NET_CDC_NCM=m
+CONFIG_USB_NET_HUAWEI_CDC_NCM=m
+CONFIG_USB_NET_CDC_MBIM=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_SR9700=m
+CONFIG_USB_NET_SR9800=m
+CONFIG_USB_NET_SMSC75XX=m
+CONFIG_USB_NET_SMSC95XX=y
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_NET_CX82310_ETH=m
+CONFIG_USB_NET_KALMIA=m
+CONFIG_USB_NET_QMI_WWAN=m
+CONFIG_USB_HSO=m
+CONFIG_USB_NET_INT51X1=m
+CONFIG_USB_CDC_PHONET=m
+CONFIG_USB_IPHETH=m
+CONFIG_USB_SIERRA_NET=m
+CONFIG_USB_VL600=m
+CONFIG_USB_NET_CH9200=m
+CONFIG_USB_NET_AQC111=m
+CONFIG_ATH9K=m
+CONFIG_ATH9K_CHANNEL_CONTEXT=y
+CONFIG_ATH9K_HTC=m
+CONFIG_CARL9170=m
+CONFIG_ATH6KL=m
+CONFIG_ATH6KL_USB=m
+CONFIG_AR5523=m
+CONFIG_ATH10K=m
+CONFIG_ATH10K_USB=m
+CONFIG_ATH11K=m
+CONFIG_ATH11K_AHB=m
+CONFIG_AT76C50X_USB=m
+CONFIG_BRCMFMAC=m
+CONFIG_BRCMFMAC_USB=y
+CONFIG_P54_COMMON=m
+CONFIG_P54_USB=m
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_MESH=y
+CONFIG_LIBERTAS_THINFIRM=m
+CONFIG_LIBERTAS_THINFIRM_USB=m
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_USB=m
+CONFIG_MT7601U=m
+CONFIG_MT76x0U=m
+CONFIG_MT76x2U=m
+CONFIG_MT7663U=m
+CONFIG_MT7921U=m
+CONFIG_WILC1000_SPI=m
+CONFIG_RT2X00=m
+CONFIG_RT2500USB=m
+CONFIG_RT73USB=m
+CONFIG_RT2800USB=m
+CONFIG_RT2800USB_RT3573=y
+CONFIG_RT2800USB_RT53XX=y
+CONFIG_RT2800USB_RT55XX=y
+CONFIG_RTL8187=m
+CONFIG_RTL8192CU=m
+# CONFIG_RTLWIFI_DEBUG is not set
+CONFIG_RTL8XXXU=m
+CONFIG_RTW88=m
+CONFIG_RTW88_8822BU=m
+CONFIG_RTW88_8822CU=m
+CONFIG_RTW88_8723DU=m
+CONFIG_RTW88_8821CU=m
+CONFIG_RTW89=m
+CONFIG_RSI_91X=m
+# CONFIG_RSI_SDIO is not set
+CONFIG_WL1251=m
+CONFIG_WL1251_SPI=m
+CONFIG_WL1251_SDIO=m
+CONFIG_WL12XX=m
+CONFIG_WL18XX=m
+CONFIG_CC33XX=m
+CONFIG_CC33XX_SDIO=m
+CONFIG_WLCORE_SPI=m
+CONFIG_WLCORE_SDIO=m
+CONFIG_ZD1211RW=m
+CONFIG_MAC80211_HWSIM=m
+CONFIG_IEEE802154_AT86RF230=m
+CONFIG_IEEE802154_MRF24J40=m
+CONFIG_IEEE802154_CC2520=m
+CONFIG_IEEE802154_ATUSB=m
+CONFIG_IEEE802154_ADF7242=m
+CONFIG_IEEE802154_CA8210=m
+CONFIG_IEEE802154_MCR20A=m
+CONFIG_IEEE802154_HWSIM=m
+CONFIG_INPUT_SPARSEKMAP=m
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=m
+CONFIG_KEYBOARD_ADP5588=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_QT2160=m
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_TCA8418=m
+CONFIG_KEYBOARD_LM8323=m
+CONFIG_KEYBOARD_MAX7359=m
+CONFIG_KEYBOARD_STOWAWAY=m
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_APPLETOUCH=m
+CONFIG_MOUSE_ELAN_I2C=m
+CONFIG_MOUSE_SYNAPTICS_I2C=m
+CONFIG_MOUSE_SYNAPTICS_USB=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=m
+CONFIG_JOYSTICK_IFORCE_232=m
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_ZHENHUA=m
+CONFIG_JOYSTICK_AS5011=m
+CONFIG_JOYSTICK_XPAD=m
+CONFIG_JOYSTICK_XPAD_FF=y
+CONFIG_JOYSTICK_XPAD_LEDS=y
+CONFIG_JOYSTICK_PSXPAD_SPI=y
+CONFIG_JOYSTICK_PSXPAD_SPI_FF=y
+CONFIG_JOYSTICK_PXRC=m
+CONFIG_JOYSTICK_FSIA6B=m
+CONFIG_INPUT_TABLET=y
+CONFIG_TABLET_USB_ACECAD=m
+CONFIG_TABLET_USB_AIPTEK=m
+CONFIG_TABLET_USB_HANWANG=m
+CONFIG_TABLET_USB_KBTAB=m
+CONFIG_TABLET_USB_PEGASUS=m
+CONFIG_TABLET_SERIAL_WACOM4=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
+CONFIG_TOUCHSCREEN_AD7877=m
+CONFIG_TOUCHSCREEN_AD7879=m
+CONFIG_TOUCHSCREEN_AD7879_I2C=m
+CONFIG_TOUCHSCREEN_AR1021_I2C=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+CONFIG_TOUCHSCREEN_DYNAPRO=m
+CONFIG_TOUCHSCREEN_HAMPSHIRE=m
+CONFIG_TOUCHSCREEN_EETI=m
+CONFIG_TOUCHSCREEN_FUJITSU=m
+CONFIG_TOUCHSCREEN_GOODIX=m
+CONFIG_TOUCHSCREEN_ILI210X=m
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELAN=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_WACOM_W8001=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_INEXIO=m
+CONFIG_TOUCHSCREEN_PENMOUNT=m
+CONFIG_TOUCHSCREEN_EDT_FT5X06=y
+CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
+CONFIG_TOUCHSCREEN_TOUCHWIN=m
+CONFIG_TOUCHSCREEN_TI_AM335X_TSC=y
+CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
+CONFIG_TOUCHSCREEN_TOUCHIT213=m
+CONFIG_TOUCHSCREEN_TSC2005=m
+CONFIG_TOUCHSCREEN_TSC2007=m
+CONFIG_TOUCHSCREEN_SILEAD=y
+CONFIG_TOUCHSCREEN_STMPE=y
+CONFIG_TOUCHSCREEN_TPS6507X=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AD714X=m
+CONFIG_INPUT_MMA8450=m
+CONFIG_INPUT_GPIO_DECODER=m
+CONFIG_INPUT_ATI_REMOTE2=m
+CONFIG_INPUT_KEYSPAN_REMOTE=m
+CONFIG_INPUT_POWERMATE=m
+CONFIG_INPUT_YEALINK=m
+CONFIG_INPUT_CM109=m
+CONFIG_INPUT_TPS65218_PWRBUTTON=y
+CONFIG_INPUT_TPS65219_PWRBUTTON=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_PALMAS_PWRBUTTON=y
+CONFIG_INPUT_PWM_BEEPER=m
+CONFIG_RMI4_F34=y
+CONFIG_RMI4_F3A=y
+CONFIG_RMI4_F55=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_DMA is not set
+CONFIG_SERIAL_8250_NR_UARTS=6
+CONFIG_SERIAL_8250_RUNTIME_UARTS=6
+CONFIG_SERIAL_8250_OMAP=y
+CONFIG_SERIAL_8250_PRUSS=m
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_MAX3100=m
+CONFIG_SERIAL_MAX310X=m
+CONFIG_N_GSM=m
+CONFIG_RPMSG_TTY=m
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_TTY_PRINTK=m
+CONFIG_VIRTIO_CONSOLE=m
+CONFIG_HW_RANDOM_VIRTIO=m
+CONFIG_TCG_TIS_I2C_ATMEL=y
+CONFIG_TCG_TIS_I2C_INFINEON=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_ARB_GPIO_CHALLENGE=m
+CONFIG_I2C_MUX_GPIO=y
+CONFIG_I2C_MUX_PCA954x=m
+CONFIG_I2C_MUX_PINCTRL=y
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_DIOLAN_U2C=m
+CONFIG_I2C_ROBOTFUZZ_OSIF=m
+CONFIG_I2C_TAOS_EVM=m
+CONFIG_I2C_TINY_USB=m
+CONFIG_I2C_SLAVE=y
+CONFIG_I2C_SLAVE_EEPROM=y
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_OMAP24XX=y
+CONFIG_SPI_TI_QSPI=y
+CONFIG_SPI_SPIDEV=m
+CONFIG_SPI_SLAVE=y
+CONFIG_SPI_SLAVE_TIME=m
+CONFIG_SPI_SLAVE_SYSTEM_CONTROL=m
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_GPIO=m
+CONFIG_PINCTRL_MCP23S08=m
+CONFIG_PINCTRL_PALMAS=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_SYSCON=y
+CONFIG_GPIO_ADNP=m
+CONFIG_GPIO_MAX7300=m
+CONFIG_GPIO_MAX732X=m
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_PCF857X=m
+CONFIG_GPIO_TPIC2810=m
+CONFIG_GPIO_PALMAS=y
+CONFIG_GPIO_STMPE=y
+CONFIG_GPIO_TPS65218=y
+CONFIG_GPIO_74X164=m
+CONFIG_GPIO_MAX3191X=m
+CONFIG_GPIO_MAX7301=m
+CONFIG_GPIO_MC33880=m
+CONFIG_GPIO_PISOSR=m
+CONFIG_GPIO_XRA1403=m
+CONFIG_GPIO_AGGREGATOR=y
+CONFIG_W1=y
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+CONFIG_W1_MASTER_GPIO=m
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2405=m
+CONFIG_W1_SLAVE_DS2408=m
+CONFIG_W1_SLAVE_DS2413=m
+CONFIG_W1_SLAVE_DS2406=m
+CONFIG_W1_SLAVE_DS2423=m
+CONFIG_W1_SLAVE_DS2805=m
+CONFIG_W1_SLAVE_DS2430=m
+CONFIG_W1_SLAVE_DS2431=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+CONFIG_W1_SLAVE_DS2438=m
+CONFIG_W1_SLAVE_DS250X=m
+CONFIG_W1_SLAVE_DS2780=m
+CONFIG_W1_SLAVE_DS2781=m
+CONFIG_W1_SLAVE_DS28E04=m
+CONFIG_W1_SLAVE_DS28E17=m
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_RESTART=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_SYSCON_REBOOT_MODE=m
+CONFIG_GENERIC_ADC_BATTERY=m
+CONFIG_BATTERY_DS2760=m
+CONFIG_CHARGER_GPIO=m
+CONFIG_CHARGER_BQ2415X=m
+CONFIG_SENSORS_AD7314=m
+CONFIG_SENSORS_AD7414=m
+CONFIG_SENSORS_AD7418=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1029=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM1177=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ADT7310=m
+CONFIG_SENSORS_ADT7410=m
+CONFIG_SENSORS_ADT7411=m
+CONFIG_SENSORS_ADT7462=m
+CONFIG_SENSORS_ADT7470=m
+CONFIG_SENSORS_ADT7475=m
+CONFIG_SENSORS_AHT10=m
+CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=m
+CONFIG_SENSORS_AS370=m
+CONFIG_SENSORS_ASC7621=m
+CONFIG_SENSORS_AXI_FAN_CONTROL=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_CORSAIR_CPRO=m
+CONFIG_SENSORS_CORSAIR_PSU=m
+CONFIG_SENSORS_DRIVETEMP=m
+CONFIG_SENSORS_DS620=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_F71882FG=m
+CONFIG_SENSORS_F75375S=m
+CONFIG_SENSORS_FTSTEUTATES=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_G760A=m
+CONFIG_SENSORS_G762=m
+CONFIG_SENSORS_GPIO_FAN=y
+CONFIG_SENSORS_HIH6130=m
+CONFIG_SENSORS_IIO_HWMON=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_JC42=m
+CONFIG_SENSORS_POWR1220=m
+CONFIG_SENSORS_LINEAGE=m
+CONFIG_SENSORS_LTC2945=m
+CONFIG_SENSORS_LTC2947_I2C=m
+CONFIG_SENSORS_LTC2947_SPI=m
+CONFIG_SENSORS_LTC2990=m
+CONFIG_SENSORS_LTC2992=m
+CONFIG_SENSORS_LTC4151=m
+CONFIG_SENSORS_LTC4215=m
+CONFIG_SENSORS_LTC4222=m
+CONFIG_SENSORS_LTC4245=m
+CONFIG_SENSORS_LTC4260=m
+CONFIG_SENSORS_LTC4261=m
+CONFIG_SENSORS_MAX1111=m
+CONFIG_SENSORS_MAX127=m
+CONFIG_SENSORS_MAX16065=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_MAX1668=m
+CONFIG_SENSORS_MAX197=m
+CONFIG_SENSORS_MAX31722=m
+CONFIG_SENSORS_MAX31730=m
+CONFIG_SENSORS_MAX31760=m
+CONFIG_SENSORS_MAX6620=m
+CONFIG_SENSORS_MAX6621=m
+CONFIG_SENSORS_MAX6639=m
+CONFIG_SENSORS_MAX6650=m
+CONFIG_SENSORS_MAX6697=m
+CONFIG_SENSORS_MAX31790=m
+CONFIG_SENSORS_MCP3021=m
+CONFIG_SENSORS_TC654=m
+CONFIG_SENSORS_TPS23861=m
+CONFIG_SENSORS_MR75203=m
+CONFIG_SENSORS_ADCXX=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM70=m
+CONFIG_SENSORS_LM73=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_LM93=m
+CONFIG_SENSORS_LM95234=m
+CONFIG_SENSORS_LM95241=m
+CONFIG_SENSORS_LM95245=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_PC87427=m
+CONFIG_SENSORS_NTC_THERMISTOR=m
+CONFIG_SENSORS_NCT6683=m
+CONFIG_SENSORS_NCT6775_I2C=m
+CONFIG_SENSORS_NCT7802=m
+CONFIG_SENSORS_NCT7904=m
+CONFIG_SENSORS_NPCM7XX=m
+CONFIG_SENSORS_NZXT_KRAKEN2=m
+CONFIG_SENSORS_NZXT_SMART2=m
+CONFIG_SENSORS_OCC_P8_I2C=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_PMBUS=m
+CONFIG_SENSORS_ADM1266=m
+CONFIG_SENSORS_ADM1275=m
+CONFIG_SENSORS_IBM_CFFPS=m
+CONFIG_SENSORS_INSPUR_IPSPS=m
+CONFIG_SENSORS_IR35221=m
+CONFIG_SENSORS_IR38064=m
+CONFIG_SENSORS_IRPS5401=m
+CONFIG_SENSORS_ISL68137=m
+CONFIG_SENSORS_LM25066=m
+CONFIG_SENSORS_LTC2978=m
+CONFIG_SENSORS_LTC2978_REGULATOR=y
+CONFIG_SENSORS_LTC3815=m
+CONFIG_SENSORS_MAX16064=m
+CONFIG_SENSORS_MAX16601=m
+CONFIG_SENSORS_MAX20730=m
+CONFIG_SENSORS_MAX20751=m
+CONFIG_SENSORS_MAX31785=m
+CONFIG_SENSORS_MAX34440=m
+CONFIG_SENSORS_MAX8688=m
+CONFIG_SENSORS_MP2975=m
+CONFIG_SENSORS_PXE1610=m
+CONFIG_SENSORS_TPS40422=m
+CONFIG_SENSORS_TPS53679=m
+CONFIG_SENSORS_UCD9000=m
+CONFIG_SENSORS_UCD9200=m
+CONFIG_SENSORS_XDPE122=m
+CONFIG_SENSORS_ZL6100=m
+CONFIG_SENSORS_PWM_FAN=m
+CONFIG_SENSORS_SBTSI=m
+CONFIG_SENSORS_SBRMI=m
+CONFIG_SENSORS_SHT15=m
+CONFIG_SENSORS_SHT21=m
+CONFIG_SENSORS_SHT3x=m
+CONFIG_SENSORS_SHT4x=m
+CONFIG_SENSORS_SHTC1=m
+CONFIG_SENSORS_DME1737=m
+CONFIG_SENSORS_EMC1403=m
+CONFIG_SENSORS_EMC2103=m
+CONFIG_SENSORS_EMC2305=m
+CONFIG_SENSORS_EMC6W201=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_SCH5627=m
+CONFIG_SENSORS_SCH5636=m
+CONFIG_SENSORS_STTS751=m
+CONFIG_SENSORS_ADC128D818=m
+CONFIG_SENSORS_ADS7828=m
+CONFIG_SENSORS_ADS7871=m
+CONFIG_SENSORS_AMC6821=m
+CONFIG_SENSORS_INA209=m
+CONFIG_SENSORS_INA2XX=m
+CONFIG_SENSORS_INA238=m
+CONFIG_SENSORS_INA3221=m
+CONFIG_SENSORS_TC74=m
+CONFIG_SENSORS_THMC50=m
+CONFIG_SENSORS_TMP102=m
+CONFIG_SENSORS_TMP103=m
+CONFIG_SENSORS_TMP108=m
+CONFIG_SENSORS_TMP401=m
+CONFIG_SENSORS_TMP421=m
+CONFIG_SENSORS_TMP464=m
+CONFIG_SENSORS_TMP513=m
+CONFIG_SENSORS_VT1211=m
+CONFIG_SENSORS_W83773G=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83795=m
+CONFIG_SENSORS_W83795_FANCTRL=y
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83L786NG=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_THERMAL_STATISTICS=y
+CONFIG_THERMAL_GOV_FAIR_SHARE=y
+CONFIG_THERMAL_GOV_BANG_BANG=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
+CONFIG_CPU_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
+CONFIG_THERMAL_EMULATION=y
+CONFIG_TI_THERMAL=y
+CONFIG_OMAP5_THERMAL=y
+CONFIG_DRA752_THERMAL=y
+CONFIG_GENERIC_ADC_THERMAL=m
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_SYSFS=y
+CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
+CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=m
+CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP=y
+CONFIG_SOFT_WATCHDOG=y
+CONFIG_OMAP_WATCHDOG=y
+CONFIG_MFD_STMPE=y
+CONFIG_MFD_TI_AM335X_TSCADC=y
+CONFIG_MFD_PALMAS=y
+CONFIG_MFD_TPS65217=y
+CONFIG_MFD_TPS65218=y
+CONFIG_MFD_TPS65219=y
+CONFIG_MFD_TPS6594_I2C=y
+CONFIG_MFD_TPS6594_SPI=y
+CONFIG_MFD_WL1273_CORE=m
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_PALMAS=y
+CONFIG_REGULATOR_PBIAS=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=m
+CONFIG_REGULATOR_TI_ABB=y
+CONFIG_REGULATOR_TPS65217=y
+CONFIG_REGULATOR_TPS65218=y
+CONFIG_REGULATOR_TPS65219=y
+CONFIG_RC_CORE=m
+CONFIG_LIRC=y
+CONFIG_RC_DECODERS=y
+CONFIG_IR_IMON_DECODER=m
+CONFIG_IR_JVC_DECODER=m
+CONFIG_IR_MCE_KBD_DECODER=m
+CONFIG_IR_NEC_DECODER=m
+CONFIG_IR_RC5_DECODER=m
+CONFIG_IR_RC6_DECODER=m
+CONFIG_IR_SANYO_DECODER=m
+CONFIG_IR_SHARP_DECODER=m
+CONFIG_IR_SONY_DECODER=m
+CONFIG_IR_XMP_DECODER=m
+CONFIG_RC_DEVICES=y
+CONFIG_IR_GPIO_CIR=m
+CONFIG_IR_IGORPLUGUSB=m
+CONFIG_IR_IGUANA=m
+CONFIG_IR_IMON=m
+CONFIG_IR_IMON_RAW=m
+CONFIG_IR_MCEUSB=m
+CONFIG_IR_REDRAT3=m
+CONFIG_IR_STREAMZAP=m
+CONFIG_IR_TTUSBIR=m
+CONFIG_RC_ATI_REMOTE=m
+CONFIG_RC_LOOPBACK=m
+CONFIG_USB_PULSE8_CEC=m
+CONFIG_USB_RAINSHADOW_CEC=m
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_GSPCA=m
+CONFIG_USB_GSPCA_BENQ=m
+CONFIG_USB_GSPCA_CONEX=m
+CONFIG_USB_GSPCA_CPIA1=m
+CONFIG_USB_GSPCA_DTCS033=m
+CONFIG_USB_GSPCA_ETOMS=m
+CONFIG_USB_GSPCA_FINEPIX=m
+CONFIG_USB_GSPCA_JEILINJ=m
+CONFIG_USB_GSPCA_JL2005BCD=m
+CONFIG_USB_GSPCA_KINECT=m
+CONFIG_USB_GSPCA_KONICA=m
+CONFIG_USB_GSPCA_MARS=m
+CONFIG_USB_GSPCA_MR97310A=m
+CONFIG_USB_GSPCA_NW80X=m
+CONFIG_USB_GSPCA_OV519=m
+CONFIG_USB_GSPCA_OV534=m
+CONFIG_USB_GSPCA_OV534_9=m
+CONFIG_USB_GSPCA_PAC207=m
+CONFIG_USB_GSPCA_PAC7302=m
+CONFIG_USB_GSPCA_PAC7311=m
+CONFIG_USB_GSPCA_SE401=m
+CONFIG_USB_GSPCA_SN9C2028=m
+CONFIG_USB_GSPCA_SN9C20X=m
+CONFIG_USB_GSPCA_SONIXB=m
+CONFIG_USB_GSPCA_SONIXJ=m
+CONFIG_USB_GSPCA_SPCA1528=m
+CONFIG_USB_GSPCA_SPCA500=m
+CONFIG_USB_GSPCA_SPCA501=m
+CONFIG_USB_GSPCA_SPCA505=m
+CONFIG_USB_GSPCA_SPCA506=m
+CONFIG_USB_GSPCA_SPCA508=m
+CONFIG_USB_GSPCA_SPCA561=m
+CONFIG_USB_GSPCA_SQ905=m
+CONFIG_USB_GSPCA_SQ905C=m
+CONFIG_USB_GSPCA_SQ930X=m
+CONFIG_USB_GSPCA_STK014=m
+CONFIG_USB_GSPCA_STK1135=m
+CONFIG_USB_GSPCA_STV0680=m
+CONFIG_USB_GSPCA_SUNPLUS=m
+CONFIG_USB_GSPCA_T613=m
+CONFIG_USB_GSPCA_TOPRO=m
+CONFIG_USB_GSPCA_TOUPTEK=m
+CONFIG_USB_GSPCA_TV8532=m
+CONFIG_USB_GSPCA_VC032X=m
+CONFIG_USB_GSPCA_VICAM=m
+CONFIG_USB_GSPCA_XIRLINK_CIT=m
+CONFIG_USB_GSPCA_ZC3XX=m
+CONFIG_USB_GL860=m
+CONFIG_USB_M5602=m
+CONFIG_USB_STV06XX=m
+CONFIG_USB_PWC=m
+CONFIG_USB_S2255=m
+CONFIG_VIDEO_USBTV=m
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_VIDEO_GO7007=m
+CONFIG_VIDEO_GO7007_USB=m
+CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m
+CONFIG_VIDEO_HDPVR=m
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_STK1160=m
+CONFIG_VIDEO_AU0828=m
+CONFIG_VIDEO_AU0828_RC=y
+CONFIG_VIDEO_CX231XX=m
+CONFIG_VIDEO_CX231XX_ALSA=m
+CONFIG_VIDEO_CX231XX_DVB=m
+CONFIG_DVB_AS102=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+CONFIG_DVB_USB_V2=m
+CONFIG_DVB_USB_AF9015=m
+CONFIG_DVB_USB_AF9035=m
+CONFIG_DVB_USB_ANYSEE=m
+CONFIG_DVB_USB_AU6610=m
+CONFIG_DVB_USB_AZ6007=m
+CONFIG_DVB_USB_CE6230=m
+CONFIG_DVB_USB_DVBSKY=m
+CONFIG_DVB_USB_EC168=m
+CONFIG_DVB_USB_GL861=m
+CONFIG_DVB_USB_LME2510=m
+CONFIG_DVB_USB_MXL111SF=m
+CONFIG_DVB_USB_RTL28XXU=m
+CONFIG_DVB_USB_ZD1301=m
+CONFIG_DVB_USB=m
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_AF9005=m
+CONFIG_DVB_USB_AF9005_REMOTE=m
+CONFIG_DVB_USB_AZ6027=m
+CONFIG_DVB_USB_CINERGY_T2=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIB0700=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_USB_DTV5100=m
+CONFIG_DVB_USB_DW2102=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_M920X=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_OPERA1=m
+CONFIG_DVB_USB_PCTV452E=m
+CONFIG_DVB_USB_TECHNISAT_USB2=m
+CONFIG_DVB_USB_TTUSB2=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_SMS_USB_DRV=m
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_EM28XX_V4L2=m
+CONFIG_VIDEO_EM28XX_ALSA=m
+CONFIG_VIDEO_EM28XX_DVB=m
+CONFIG_USB_AIRSPY=m
+CONFIG_USB_HACKRF=m
+CONFIG_USB_MSI2500=m
+CONFIG_RADIO_SHARK=m
+CONFIG_RADIO_SHARK2=m
+CONFIG_RADIO_SI4713=m
+CONFIG_USB_KEENE=m
+CONFIG_USB_MA901=m
+CONFIG_USB_MR800=m
+CONFIG_USB_RAREMONO=m
+CONFIG_RADIO_SI470X=m
+CONFIG_USB_SI470X=m
+CONFIG_I2C_SI4713=m
+CONFIG_RADIO_WL128X=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_MUX=m
+CONFIG_VIDEO_TI_VPE=m
+CONFIG_SMS_SDIO_DRV=m
+CONFIG_VIDEO_IMX219=m
+CONFIG_VIDEO_IMX290=m
+CONFIG_VIDEO_IMX390=m
+CONFIG_VIDEO_IMX728=m
+CONFIG_VIDEO_MT9P031=m
+CONFIG_VIDEO_OV2312=m
+CONFIG_VIDEO_OV5640=m
+CONFIG_VIDEO_OV5645=m
+CONFIG_VIDEO_OV5647=m
+CONFIG_VIDEO_OV5648=m
+CONFIG_VIDEO_OV5675=m
+CONFIG_VIDEO_OV7251=m
+CONFIG_VIDEO_OV7670=m
+CONFIG_VIDEO_OX05B1S=m
+CONFIG_VIDEO_CS3308=m
+CONFIG_VIDEO_CS5345=m
+CONFIG_VIDEO_TDA7432=m
+CONFIG_VIDEO_TDA9840=m
+CONFIG_VIDEO_TEA6415C=m
+CONFIG_VIDEO_TEA6420=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_TVAUDIO=m
+CONFIG_VIDEO_VP27SMPX=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BT819=m
+CONFIG_VIDEO_BT856=m
+CONFIG_VIDEO_KS0127=m
+CONFIG_VIDEO_SAA7110=m
+CONFIG_VIDEO_VPX3220=m
+CONFIG_VIDEO_SAA717X=m
+CONFIG_VIDEO_ADV7170=m
+CONFIG_VIDEO_ADV7175=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_SAA7185=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+CONFIG_VIDEO_SAA6752HS=m
+CONFIG_VIDEO_M52790=m
+CONFIG_CXD2880_SPI_DRV=m
+CONFIG_MEDIA_TUNER_M88RS6000T=m
+CONFIG_MEDIA_TUNER_MT2131=m
+CONFIG_MEDIA_TUNER_MXL301RF=m
+CONFIG_MEDIA_TUNER_QM1D1B0004=m
+CONFIG_DVB_MXL5XX=m
+CONFIG_DVB_STV0910=m
+CONFIG_DVB_STV6111=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24117=m
+CONFIG_DVB_MB86A16=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_TDA8261=m
+CONFIG_DVB_TUA6100=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_ZL10036=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_DIB9000=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_S5H1432=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_STV0367=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_MN88443X=m
+CONFIG_DVB_ASCOT2E=m
+CONFIG_DVB_HELENE=m
+CONFIG_DVB_HORUS3A=m
+CONFIG_DVB_ISL6405=m
+CONFIG_DVB_LGS8GL5=m
+CONFIG_DVB_LNBH25=m
+CONFIG_DVB_LNBH29=m
+CONFIG_DVB_TDA665x=m
+CONFIG_DVB_CXD2099=m
+CONFIG_DVB_DUMMY_FE=m
+CONFIG_AUXDISPLAY=y
+CONFIG_HD44780=m
+CONFIG_LCD2S=m
+CONFIG_IMG_ASCII_LCD=m
+CONFIG_HT16K33=m
+CONFIG_SEG_LED_GPIO=m
+CONFIG_DRM=y
+CONFIG_DRM_LOAD_EDID_FIRMWARE=y
+CONFIG_DRM_DISPLAY_DP_AUX_CHARDEV=y
+CONFIG_DRM_I2C_NXP_TDA998X=y
+CONFIG_DRM_VGEM=m
+CONFIG_DRM_UDL=m
+CONFIG_DRM_OMAP=y
+CONFIG_OMAP5_DSS_HDMI=y
+CONFIG_DRM_TILCDC=y
+CONFIG_DRM_PANEL_LG_LB035Q02=m
+CONFIG_DRM_PANEL_NEC_NL8048HL11=m
+CONFIG_DRM_PANEL_ORISETECH_OTM8009A=y
+CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS=y
+CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m
+CONFIG_DRM_PANEL_SONY_ACX565AKM=m
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_TPO_TD028TTEC1=m
+CONFIG_DRM_PANEL_TPO_TD043MTEA1=m
+CONFIG_DRM_DISPLAY_CONNECTOR=y
+CONFIG_DRM_ITE_IT66121=y
+CONFIG_DRM_LVDS_CODEC=y
+CONFIG_DRM_SII902X=y
+CONFIG_DRM_SIMPLE_BRIDGE=m
+CONFIG_DRM_TOSHIBA_TC358762=m
+CONFIG_DRM_TOSHIBA_TC358767=y
+CONFIG_DRM_TOSHIBA_TC358768=y
+CONFIG_DRM_TI_TFP410=y
+CONFIG_DRM_TI_TPD12S015=y
+CONFIG_DRM_I2C_ADV7511=y
+CONFIG_DRM_I2C_ADV7511_AUDIO=y
+CONFIG_DRM_ETNAVIV=y
+CONFIG_DRM_GM12U320=m
+CONFIG_TINYDRM_HX8357D=m
+CONFIG_TINYDRM_ILI9225=m
+CONFIG_TINYDRM_ILI9341=m
+CONFIG_TINYDRM_ILI9486=m
+CONFIG_TINYDRM_MI0283QT=m
+CONFIG_TINYDRM_REPAPER=m
+CONFIG_TINYDRM_ST7586=m
+CONFIG_TINYDRM_ST7735R=m
+CONFIG_DRM_TIDSS=y
+CONFIG_FB=y
+CONFIG_FB_SMSCUFX=m
+CONFIG_FB_UDL=m
+CONFIG_FB_SIMPLE=y
+CONFIG_FB_SSD1307=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_BACKLIGHT_GPIO=y
+CONFIG_BACKLIGHT_LED=y
+CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_HRTIMER=m
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_ALOOP=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+CONFIG_SND_HDA_PREALLOC_SIZE=2048
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_UA101=m
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+CONFIG_SND_USB_6FIRE=m
+CONFIG_SND_USB_HIFACE=m
+CONFIG_SND_BCD2000=m
+CONFIG_SND_USB_POD=m
+CONFIG_SND_USB_PODHD=m
+CONFIG_SND_USB_TONEPORT=m
+CONFIG_SND_USB_VARIAX=m
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_DAVINCI_MCASP=m
+CONFIG_SND_SOC_OMAP_DMIC=m
+CONFIG_SND_SOC_OMAP_MCBSP=m
+CONFIG_SND_SOC_OMAP_MCPDM=m
+CONFIG_SND_SOC_OMAP_HDMI=m
+CONFIG_SND_SOC_ADAU1701=m
+CONFIG_SND_SOC_ADAU7002=m
+CONFIG_SND_SOC_AK4554=m
+CONFIG_SND_SOC_CS42L51_I2C=m
+CONFIG_SND_SOC_CS4265=m
+CONFIG_SND_SOC_CS4271_I2C=m
+CONFIG_SND_SOC_DMIC=m
+CONFIG_SND_SOC_ES8328_I2C=m
+CONFIG_SND_SOC_ES8328_SPI=m
+CONFIG_SND_SOC_MAX98357A=m
+CONFIG_SND_SOC_PCM3168A_I2C=m
+CONFIG_SND_SOC_PCM5102A=m
+CONFIG_SND_SOC_PCM512x_I2C=m
+CONFIG_SND_SOC_SGTL5000=m
+CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m
+CONFIG_SND_SOC_SPDIF=m
+CONFIG_SND_SOC_TLV320AIC23_I2C=m
+CONFIG_SND_SOC_TLV320AIC31XX=m
+CONFIG_SND_SOC_TLV320AIC3X_I2C=m
+CONFIG_SND_SOC_TS3A227E=m
+CONFIG_SND_SOC_WM8753=m
+CONFIG_SND_SOC_WM8804_I2C=m
+CONFIG_SND_SOC_WM8903=m
+CONFIG_SND_SOC_WM8904=m
+CONFIG_SND_SOC_WM8960=m
+CONFIG_SND_SOC_TPA6130A2=m
+CONFIG_SND_SIMPLE_CARD=m
+CONFIG_SND_AUDIO_GRAPH_CARD=m
+CONFIG_HID_BATTERY_STRENGTH=y
+CONFIG_HIDRAW=y
+CONFIG_UHID=y
+CONFIG_HID_A4TECH=m
+CONFIG_HID_ACCUTOUCH=m
+CONFIG_HID_ACRUX=m
+CONFIG_HID_ACRUX_FF=y
+CONFIG_HID_APPLE=m
+CONFIG_HID_ASUS=m
+CONFIG_HID_AUREAL=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_BETOP_FF=m
+CONFIG_HID_BIGBEN_FF=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CORSAIR=m
+CONFIG_HID_COUGAR=m
+CONFIG_HID_MACALLY=m
+CONFIG_HID_PRODIKEYS=m
+CONFIG_HID_CMEDIA=m
+CONFIG_HID_CP2112=m
+CONFIG_HID_CREATIVE_SB0540=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DRAGONRISE=m
+CONFIG_DRAGONRISE_FF=y
+CONFIG_HID_EMS_FF=m
+CONFIG_HID_ELAN=m
+CONFIG_HID_ELECOM=m
+CONFIG_HID_ELO=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_FT260=m
+CONFIG_HID_GEMBIRD=m
+CONFIG_HID_GFRM=m
+CONFIG_HID_GLORIOUS=m
+CONFIG_HID_HOLTEK=m
+CONFIG_HOLTEK_FF=y
+CONFIG_HID_VIVALDI=m
+CONFIG_HID_GT683R=m
+CONFIG_HID_KEYTOUCH=m
+CONFIG_HID_KYE=m
+CONFIG_HID_UCLOGIC=m
+CONFIG_HID_WALTOP=m
+CONFIG_HID_VIEWSONIC=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_ICADE=m
+CONFIG_HID_ITE=m
+CONFIG_HID_JABRA=m
+CONFIG_HID_TWINHAN=m
+CONFIG_HID_KENSINGTON=m
+CONFIG_HID_LCPOWER=m
+CONFIG_HID_LENOVO=m
+CONFIG_HID_LOGITECH=y
+CONFIG_HID_LOGITECH_DJ=y
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_LOGIG940_FF=y
+CONFIG_HID_MAGICMOUSE=m
+CONFIG_HID_MALTRON=m
+CONFIG_HID_MAYFLASH=m
+CONFIG_HID_REDRAGON=m
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_MULTITOUCH=m
+CONFIG_HID_NINTENDO=m
+CONFIG_NINTENDO_FF=y
+CONFIG_HID_NTI=m
+CONFIG_HID_NTRIG=m
+CONFIG_HID_ORTEK=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PENMOUNT=m
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_PICOLCD=m
+CONFIG_HID_PICOLCD_FB=y
+CONFIG_HID_PICOLCD_BACKLIGHT=y
+CONFIG_HID_PICOLCD_LEDS=y
+CONFIG_HID_PICOLCD_CIR=y
+CONFIG_HID_PLANTRONICS=m
+CONFIG_HID_PLAYSTATION=m
+CONFIG_PLAYSTATION_FF=y
+CONFIG_HID_PRIMAX=m
+CONFIG_HID_RETRODE=m
+CONFIG_HID_ROCCAT=m
+CONFIG_HID_SAITEK=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SEMITEK=m
+CONFIG_HID_SONY=m
+CONFIG_SONY_FF=y
+CONFIG_HID_SPEEDLINK=m
+CONFIG_HID_STEAM=m
+CONFIG_HID_STEELSERIES=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_RMI=m
+CONFIG_HID_GREENASIA=m
+CONFIG_GREENASIA_FF=y
+CONFIG_HID_SMARTJOYPLUS=m
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_HID_TIVO=m
+CONFIG_HID_TOPSEED=m
+CONFIG_HID_THINGM=m
+CONFIG_HID_THRUSTMASTER=m
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_HID_UDRAW_PS3=m
+CONFIG_HID_U2FZERO=m
+CONFIG_HID_WACOM=m
+CONFIG_HID_WIIMOTE=m
+CONFIG_HID_XINMO=m
+CONFIG_HID_ZEROPLUS=m
+CONFIG_ZEROPLUS_FF=y
+CONFIG_HID_ZYDACRON=m
+CONFIG_HID_SENSOR_HUB=m
+CONFIG_HID_SENSOR_CUSTOM_SENSOR=m
+CONFIG_HID_ALPS=m
+CONFIG_HID_MCP2221=m
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_LED_TRIG=y
+CONFIG_USB_ULPI_BUS=m
+CONFIG_USB_CONN_GPIO=m
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_OTG=y
+CONFIG_USB_LEDS_TRIGGER_USBPORT=m
+CONFIG_USB_MON=m
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_PRINTER=m
+CONFIG_USB_TMC=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_STORAGE_REALTEK=m
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
+CONFIG_USB_STORAGE_USBAT=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
+CONFIG_USB_STORAGE_ALAUDA=m
+CONFIG_USB_STORAGE_ONETOUCH=m
+CONFIG_USB_STORAGE_KARMA=m
+CONFIG_USB_STORAGE_CYPRESS_ATACB=m
+CONFIG_USB_STORAGE_ENE_UB6250=m
+CONFIG_USB_UAS=m
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USBIP_CORE=m
+CONFIG_USBIP_VHCI_HCD=m
+CONFIG_USBIP_VHCI_HC_PORTS=15
+CONFIG_USBIP_VHCI_NR_HCS=8
+CONFIG_USBIP_HOST=m
+CONFIG_USBIP_VUDC=m
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_DSPS=y
+CONFIG_MUSB_PIO_ONLY=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_SIMPLE=m
+CONFIG_USB_SERIAL_AIRCABLE=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_CH341=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_F81232=m
+CONFIG_USB_SERIAL_F8153X=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_IUU=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_METRO=m
+CONFIG_USB_SERIAL_MOS7720=m
+CONFIG_USB_SERIAL_MOS7840=m
+CONFIG_USB_SERIAL_MXUPORT=m
+CONFIG_USB_SERIAL_NAVMAN=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OTI6858=m
+CONFIG_USB_SERIAL_QCAUX=m
+CONFIG_USB_SERIAL_QUALCOMM=m
+CONFIG_USB_SERIAL_SPCP8X5=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SIERRAWIRELESS=m
+CONFIG_USB_SERIAL_SYMBOL=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_SERIAL_OPTICON=m
+CONFIG_USB_SERIAL_XSENS_MT=m
+CONFIG_USB_SERIAL_WISHBONE=m
+CONFIG_USB_SERIAL_SSU100=m
+CONFIG_USB_SERIAL_QT2=m
+CONFIG_USB_SERIAL_UPD78F0730=m
+CONFIG_USB_SERIAL_XR=m
+CONFIG_USB_SERIAL_DEBUG=m
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_SEVSEG=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_CYPRESS_CY7C63=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_APPLE_MFI_FASTCHARGE=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_LD=m
+CONFIG_USB_TRANCEVIBRATOR=m
+CONFIG_USB_IOWARRIOR=m
+CONFIG_USB_TEST=m
+CONFIG_USB_EHSET_TEST_FIXTURE=m
+CONFIG_USB_ISIGHTFW=m
+CONFIG_USB_YUREX=m
+CONFIG_USB_HSIC_USB3503=m
+CONFIG_USB_CHAOSKEY=m
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_AM335X_PHY_USB=y
+CONFIG_USB_GPIO_VBUS=m
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_DUMMY_HCD=m
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_PHONET=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_UAC1=y
+CONFIG_USB_CONFIGFS_F_UAC2=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_CONFIGFS_F_UVC=y
+CONFIG_USB_CONFIGFS_F_PRINTER=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_AUDIO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_G_NCM=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FUNCTIONFS=m
+CONFIG_USB_FUNCTIONFS_ETH=y
+CONFIG_USB_FUNCTIONFS_RNDIS=y
+CONFIG_USB_FUNCTIONFS_GENERIC=y
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_MIDI_GADGET=m
+CONFIG_USB_G_PRINTER=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_USB_G_NOKIA=m
+CONFIG_USB_G_ACM_MS=m
+CONFIG_USB_G_MULTI=m
+CONFIG_USB_G_HID=m
+CONFIG_USB_G_DBGP=m
+CONFIG_USB_G_WEBCAM=m
+CONFIG_TYPEC=y
+CONFIG_TYPEC_HD3SS3220=y
+CONFIG_MMC=y
+CONFIG_PWRSEQ_SD8787=m
+CONFIG_MMC_BLOCK_MINORS=256
+CONFIG_SDIO_UART=m
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SPI=m
+CONFIG_MMC_VUB300=m
+CONFIG_MMC_USHC=m
+CONFIG_MMC_SDHCI_OMAP=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_CLASS_MULTICOLOR=m
+CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_LP3944=m
+CONFIG_LEDS_LP55XX_COMMON=m
+CONFIG_LEDS_LP5523=m
+CONFIG_LEDS_PCA955X=m
+CONFIG_LEDS_PCA963X=m
+CONFIG_LEDS_DAC124S085=m
+CONFIG_LEDS_PWM=m
+CONFIG_LEDS_REGULATOR=m
+CONFIG_LEDS_BD2802=m
+CONFIG_LEDS_LT3593=m
+CONFIG_LEDS_TCA6507=m
+CONFIG_LEDS_SYSCON=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_DISK=y
+CONFIG_LEDS_TRIGGER_MTD=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_ACTIVITY=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_TRANSIENT=m
+CONFIG_LEDS_TRIGGER_CAMERA=m
+CONFIG_LEDS_TRIGGER_PANIC=y
+CONFIG_LEDS_TRIGGER_NETDEV=y
+CONFIG_LEDS_TRIGGER_PATTERN=m
+CONFIG_ACCESSIBILITY=y
+CONFIG_A11Y_BRAILLE_CONSOLE=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_ABB5ZES3=y
+CONFIG_RTC_DRV_ABEOZ9=y
+CONFIG_RTC_DRV_ABX80X=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_DS1374=y
+CONFIG_RTC_DRV_DS1374_WDT=y
+CONFIG_RTC_DRV_DS1672=y
+CONFIG_RTC_DRV_HYM8563=y
+CONFIG_RTC_DRV_MAX6900=y
+CONFIG_RTC_DRV_RS5C372=y
+CONFIG_RTC_DRV_ISL1208=y
+CONFIG_RTC_DRV_ISL12022=y
+CONFIG_RTC_DRV_ISL12026=y
+CONFIG_RTC_DRV_X1205=y
+CONFIG_RTC_DRV_PCF8523=y
+CONFIG_RTC_DRV_PCF85063=y
+CONFIG_RTC_DRV_PCF85363=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_PCF8583=y
+CONFIG_RTC_DRV_M41T80=y
+CONFIG_RTC_DRV_M41T80_WDT=y
+CONFIG_RTC_DRV_BQ32K=y
+CONFIG_RTC_DRV_PALMAS=y
+CONFIG_RTC_DRV_S35390A=y
+CONFIG_RTC_DRV_FM3130=y
+CONFIG_RTC_DRV_RX8010=y
+CONFIG_RTC_DRV_RX8581=y
+CONFIG_RTC_DRV_RX8025=y
+CONFIG_RTC_DRV_EM3027=y
+CONFIG_RTC_DRV_RV8803=y
+CONFIG_RTC_DRV_M41T93=y
+CONFIG_RTC_DRV_M41T94=y
+CONFIG_RTC_DRV_DS1302=y
+CONFIG_RTC_DRV_DS1305=y
+CONFIG_RTC_DRV_DS1343=y
+CONFIG_RTC_DRV_DS1347=y
+CONFIG_RTC_DRV_DS1390=y
+CONFIG_RTC_DRV_MAX6916=y
+CONFIG_RTC_DRV_R9701=y
+CONFIG_RTC_DRV_RX4581=y
+CONFIG_RTC_DRV_RS5C348=y
+CONFIG_RTC_DRV_MAX6902=y
+CONFIG_RTC_DRV_PCF2123=y
+CONFIG_RTC_DRV_MCP795=y
+CONFIG_RTC_DRV_DS3232=y
+CONFIG_RTC_DRV_PCF2127=y
+CONFIG_RTC_DRV_RV3029C2=y
+CONFIG_RTC_DRV_RX6110=y
+CONFIG_RTC_DRV_DS1286=m
+CONFIG_RTC_DRV_DS1511=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_DS1685_FAMILY=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_DS2404=m
+CONFIG_RTC_DRV_EFI=y
+CONFIG_RTC_DRV_STK17TA8=m
+CONFIG_RTC_DRV_M48T86=m
+CONFIG_RTC_DRV_M48T35=m
+CONFIG_RTC_DRV_M48T59=m
+CONFIG_RTC_DRV_MSM6242=m
+CONFIG_RTC_DRV_RP5C01=m
+CONFIG_RTC_DRV_OMAP=y
+CONFIG_RTC_DRV_HID_SENSOR_TIME=m
+CONFIG_DMADEVICES=y
+CONFIG_TI_CPPI41=y
+CONFIG_ASYNC_TX_DMA=y
+CONFIG_UDMABUF=y
+CONFIG_DMABUF_HEAPS=y
+CONFIG_DMABUF_HEAPS_SYSTEM=y
+CONFIG_DMABUF_HEAPS_CMA=y
+CONFIG_DMABUF_HEAPS_CARVEOUT=y
+CONFIG_UIO=m
+CONFIG_UIO_PDRV_GENIRQ=m
+CONFIG_VIRT_DRIVERS=y
+CONFIG_VIRTIO_BALLOON=m
+CONFIG_VIRTIO_INPUT=m
+CONFIG_VIRTIO_MMIO=m
+CONFIG_GREYBUS=m
+CONFIG_GREYBUS_BEAGLEPLAY=m
+CONFIG_GREYBUS_ES2=m
+CONFIG_STAGING=y
+CONFIG_RTLLIB=m
+CONFIG_RTL8723BS=m
+CONFIG_R8712U=m
+CONFIG_ADIS16203=m
+CONFIG_ADIS16240=m
+CONFIG_AD7816=m
+CONFIG_ADT7316=m
+CONFIG_ADT7316_I2C=m
+CONFIG_AD9832=m
+CONFIG_AD9834=m
+CONFIG_AD5933=m
+CONFIG_FB_TFT=m
+CONFIG_FB_TFT_AGM1264K_FL=m
+CONFIG_FB_TFT_BD663474=m
+CONFIG_FB_TFT_HX8340BN=m
+CONFIG_FB_TFT_HX8347D=m
+CONFIG_FB_TFT_HX8353D=m
+CONFIG_FB_TFT_HX8357D=m
+CONFIG_FB_TFT_ILI9163=m
+CONFIG_FB_TFT_ILI9320=m
+CONFIG_FB_TFT_ILI9325=m
+CONFIG_FB_TFT_ILI9340=m
+CONFIG_FB_TFT_ILI9341=m
+CONFIG_FB_TFT_ILI9481=m
+CONFIG_FB_TFT_ILI9486=m
+CONFIG_FB_TFT_PCD8544=m
+CONFIG_FB_TFT_RA8875=m
+CONFIG_FB_TFT_S6D02A1=m
+CONFIG_FB_TFT_S6D1121=m
+CONFIG_FB_TFT_SH1106=m
+CONFIG_FB_TFT_SSD1289=m
+CONFIG_FB_TFT_SSD1305=m
+CONFIG_FB_TFT_SSD1306=m
+CONFIG_FB_TFT_SSD1331=m
+CONFIG_FB_TFT_SSD1351=m
+CONFIG_FB_TFT_ST7735R=m
+CONFIG_FB_TFT_ST7789V=m
+CONFIG_FB_TFT_TINYLCD=m
+CONFIG_FB_TFT_TLS8204=m
+CONFIG_FB_TFT_UC1611=m
+CONFIG_FB_TFT_UC1701=m
+CONFIG_FB_TFT_UPD161704=m
+CONFIG_GREYBUS_AUDIO=m
+CONFIG_GREYBUS_BOOTROM=m
+CONFIG_GREYBUS_FIRMWARE=m
+CONFIG_GREYBUS_HID=m
+CONFIG_GREYBUS_LOG=m
+CONFIG_GREYBUS_LOOPBACK=m
+CONFIG_GREYBUS_POWER=m
+CONFIG_GREYBUS_RAW=m
+CONFIG_GREYBUS_VIBRATOR=m
+CONFIG_GREYBUS_BRIDGED_PHY=m
+CONFIG_GREYBUS_GPIO=m
+CONFIG_GREYBUS_I2C=m
+CONFIG_GREYBUS_PWM=m
+CONFIG_GREYBUS_SDIO=m
+CONFIG_GREYBUS_SPI=m
+CONFIG_GREYBUS_UART=m
+CONFIG_GREYBUS_USB=m
+CONFIG_COMMON_CLK_PALMAS=y
+CONFIG_COMMON_CLK_TI_ADPLL=y
+CONFIG_HWSPINLOCK=y
+CONFIG_HWSPINLOCK_OMAP=y
+CONFIG_OMAP_IOMMU=y
+CONFIG_REMOTEPROC=y
+CONFIG_REMOTEPROC_CDEV=y
+CONFIG_OMAP_REMOTEPROC=m
+CONFIG_WKUP_M3_RPROC=y
+CONFIG_RPMSG_CHAR=m
+CONFIG_RPMSG_CTRL=m
+CONFIG_RPMSG_VIRTIO=y
+CONFIG_SOC_TI=y
+CONFIG_AMX3_PM=m
+CONFIG_WKUP_M3_IPC=m
+CONFIG_TI_PRUSS=m
+CONFIG_PM_DEVFREQ=y
+CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
+CONFIG_DEVFREQ_GOV_PERFORMANCE=y
+CONFIG_DEVFREQ_GOV_POWERSAVE=y
+CONFIG_DEVFREQ_GOV_USERSPACE=y
+CONFIG_DEVFREQ_GOV_PASSIVE=y
+CONFIG_PM_DEVFREQ_EVENT=y
+CONFIG_EXTCON_GPIO=y
+CONFIG_EXTCON_PALMAS=y
+CONFIG_EXTCON_USB_GPIO=y
+CONFIG_TI_EMIF=y
+CONFIG_TI_EMIF_SRAM=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER_DMAENGINE=m
+CONFIG_IIO_BUFFER_HW_CONSUMER=m
+CONFIG_IIO_SW_DEVICE=m
+CONFIG_IIO_SW_TRIGGER=m
+CONFIG_ADIS16201=m
+CONFIG_ADIS16209=m
+CONFIG_ADXL313_I2C=m
+CONFIG_ADXL313_SPI=m
+CONFIG_ADXL345_I2C=m
+CONFIG_ADXL345_SPI=m
+CONFIG_ADXL355_I2C=m
+CONFIG_ADXL355_SPI=m
+CONFIG_ADXL367_SPI=m
+CONFIG_ADXL367_I2C=m
+CONFIG_ADXL372_SPI=m
+CONFIG_ADXL372_I2C=m
+CONFIG_ADXL380_SPI=m
+CONFIG_ADXL380_I2C=m
+CONFIG_BMA180=m
+CONFIG_BMA220=m
+CONFIG_BMA400=m
+CONFIG_BMC150_ACCEL=m
+CONFIG_BMI088_ACCEL=m
+CONFIG_DA280=m
+CONFIG_DA311=m
+CONFIG_DMARD06=m
+CONFIG_DMARD09=m
+CONFIG_DMARD10=m
+CONFIG_FXLS8962AF_I2C=m
+CONFIG_FXLS8962AF_SPI=m
+CONFIG_HID_SENSOR_ACCEL_3D=m
+CONFIG_IIO_KX022A_SPI=m
+CONFIG_IIO_KX022A_I2C=m
+CONFIG_KXSD9=m
+CONFIG_KXCJK1013=m
+CONFIG_MC3230=m
+CONFIG_MMA7455_I2C=m
+CONFIG_MMA7455_SPI=m
+CONFIG_MMA7660=m
+CONFIG_MMA8452=m
+CONFIG_MMA9551=m
+CONFIG_MMA9553=m
+CONFIG_MSA311=m
+CONFIG_MXC4005=m
+CONFIG_MXC6255=m
+CONFIG_SCA3000=m
+CONFIG_SCA3300=m
+CONFIG_STK8312=m
+CONFIG_STK8BA50=m
+CONFIG_AD4000=m
+CONFIG_AD4130=m
+CONFIG_AD4695=m
+CONFIG_AD7091R5=m
+CONFIG_AD7124=m
+CONFIG_AD7192=m
+CONFIG_AD7266=m
+CONFIG_AD7280=m
+CONFIG_AD7291=m
+CONFIG_AD7292=m
+CONFIG_AD7298=m
+CONFIG_AD7476=m
+CONFIG_AD7606_IFACE_PARALLEL=m
+CONFIG_AD7606_IFACE_SPI=m
+CONFIG_AD7766=m
+CONFIG_AD7768_1=m
+CONFIG_AD7780=m
+CONFIG_AD7791=m
+CONFIG_AD7793=m
+CONFIG_AD7887=m
+CONFIG_AD7923=m
+CONFIG_AD7949=m
+CONFIG_AD799X=m
+CONFIG_AD9467=m
+CONFIG_CC10001_ADC=m
+CONFIG_ENVELOPE_DETECTOR=m
+CONFIG_HI8435=m
+CONFIG_HX711=m
+CONFIG_INA2XX_ADC=m
+CONFIG_LTC2471=m
+CONFIG_LTC2485=m
+CONFIG_LTC2496=m
+CONFIG_LTC2497=m
+CONFIG_MAX1027=m
+CONFIG_MAX11100=m
+CONFIG_MAX1118=m
+CONFIG_MAX11205=m
+CONFIG_MAX11410=m
+CONFIG_MAX1241=m
+CONFIG_MAX1363=m
+CONFIG_MAX9611=m
+CONFIG_MCP320X=m
+CONFIG_MCP3422=m
+CONFIG_MCP3911=m
+CONFIG_NAU7802=m
+CONFIG_PAC1921=m
+CONFIG_PALMAS_GPADC=m
+CONFIG_RICHTEK_RTQ6056=m
+CONFIG_SD_ADC_MODULATOR=m
+CONFIG_STMPE_ADC=m
+CONFIG_TI_ADC081C=m
+CONFIG_TI_ADC0832=m
+CONFIG_TI_ADC084S021=m
+CONFIG_TI_ADC12138=m
+CONFIG_TI_ADC108S102=m
+CONFIG_TI_ADC128S052=m
+CONFIG_TI_ADC161S626=m
+CONFIG_TI_ADS1015=m
+CONFIG_TI_ADS7924=m
+CONFIG_TI_ADS1100=m
+CONFIG_TI_ADS7950=m
+CONFIG_TI_ADS8344=m
+CONFIG_TI_ADS8688=m
+CONFIG_TI_ADS124S08=m
+CONFIG_TI_ADS131E08=m
+CONFIG_TI_AM335X_ADC=y
+CONFIG_TI_LMP92064=m
+CONFIG_TI_TLC4541=m
+CONFIG_TI_TSC2046=m
+CONFIG_AD74115=m
+CONFIG_AD74413R=m
+CONFIG_IIO_RESCALE=m
+CONFIG_AD8366=m
+CONFIG_ADA4250=m
+CONFIG_HMC425=m
+CONFIG_AD7150=m
+CONFIG_AD7746=m
+CONFIG_ATLAS_PH_SENSOR=m
+CONFIG_ATLAS_EZO_SENSOR=m
+CONFIG_BME680=m
+CONFIG_CCS811=m
+CONFIG_IAQCORE=m
+CONFIG_PMS7003=m
+CONFIG_SCD30_CORE=m
+CONFIG_SCD30_I2C=m
+CONFIG_SCD30_SERIAL=m
+CONFIG_SCD4X=m
+CONFIG_SENSIRION_SGP30=m
+CONFIG_SENSIRION_SGP40=m
+CONFIG_SPS30_I2C=m
+CONFIG_SPS30_SERIAL=m
+CONFIG_SENSEAIR_SUNRISE_CO2=m
+CONFIG_VZ89X=m
+CONFIG_AD3552R=m
+CONFIG_AD5064=m
+CONFIG_AD5360=m
+CONFIG_AD5380=m
+CONFIG_AD5421=m
+CONFIG_AD5446=m
+CONFIG_AD5449=m
+CONFIG_AD5592R=m
+CONFIG_AD5593R=m
+CONFIG_AD5504=m
+CONFIG_AD5624R_SPI=m
+CONFIG_LTC2688=m
+CONFIG_AD5686_SPI=m
+CONFIG_AD5696_I2C=m
+CONFIG_AD5755=m
+CONFIG_AD5758=m
+CONFIG_AD5761=m
+CONFIG_AD5764=m
+CONFIG_AD5766=m
+CONFIG_AD5770R=m
+CONFIG_AD5791=m
+CONFIG_AD7293=m
+CONFIG_AD7303=m
+CONFIG_AD8801=m
+CONFIG_DPOT_DAC=m
+CONFIG_DS4424=m
+CONFIG_LTC1660=m
+CONFIG_LTC2632=m
+CONFIG_LTC2664=m
+CONFIG_M62332=m
+CONFIG_MAX517=m
+CONFIG_MAX5522=m
+CONFIG_MAX5821=m
+CONFIG_MCP4725=m
+CONFIG_MCP4728=m
+CONFIG_MCP4922=m
+CONFIG_TI_DAC082S085=m
+CONFIG_TI_DAC5571=m
+CONFIG_TI_DAC7311=m
+CONFIG_TI_DAC7612=m
+CONFIG_AD9523=m
+CONFIG_ADF4350=m
+CONFIG_ADF4371=m
+CONFIG_ADF4377=m
+CONFIG_ADMV1013=m
+CONFIG_ADMV4420=m
+CONFIG_ADRF6780=m
+CONFIG_ADIS16080=m
+CONFIG_ADIS16130=m
+CONFIG_ADIS16136=m
+CONFIG_ADIS16260=m
+CONFIG_ADXRS290=m
+CONFIG_ADXRS450=m
+CONFIG_BMG160=m
+CONFIG_FXAS21002C=m
+CONFIG_HID_SENSOR_GYRO_3D=m
+CONFIG_MPU3050_I2C=m
+CONFIG_IIO_ST_GYRO_3AXIS=m
+CONFIG_ITG3200=m
+CONFIG_AFE4403=m
+CONFIG_AFE4404=m
+CONFIG_MAX30100=m
+CONFIG_MAX30102=m
+CONFIG_AM2315=m
+CONFIG_DHT11=m
+CONFIG_ENS210=m
+CONFIG_HDC100X=m
+CONFIG_HDC2010=m
+CONFIG_HID_SENSOR_HUMIDITY=m
+CONFIG_HTS221=m
+CONFIG_HTU21=m
+CONFIG_SI7005=m
+CONFIG_SI7020=m
+CONFIG_ADIS16400=m
+CONFIG_ADIS16460=m
+CONFIG_ADIS16475=m
+CONFIG_ADIS16480=m
+CONFIG_BMI160_I2C=m
+CONFIG_BMI160_SPI=m
+CONFIG_BOSCH_BNO055_SERIAL=m
+CONFIG_BOSCH_BNO055_I2C=m
+CONFIG_FXOS8700_I2C=m
+CONFIG_FXOS8700_SPI=m
+CONFIG_KMX61=m
+CONFIG_INV_ICM42600_I2C=m
+CONFIG_INV_ICM42600_SPI=m
+CONFIG_INV_MPU6050_I2C=m
+CONFIG_INV_MPU6050_SPI=m
+CONFIG_IIO_ST_LSM6DSX=m
+CONFIG_IIO_ST_LSM9DS0=m
+CONFIG_ADJD_S311=m
+CONFIG_ADUX1020=m
+CONFIG_AL3010=m
+CONFIG_AL3320A=m
+CONFIG_APDS9300=m
+CONFIG_APDS9960=m
+CONFIG_AS73211=m
+CONFIG_BH1745=m
+CONFIG_BH1750=m
+CONFIG_BH1780=m
+CONFIG_CM32181=m
+CONFIG_CM3232=m
+CONFIG_CM3323=m
+CONFIG_CM3605=m
+CONFIG_CM36651=m
+CONFIG_GP2AP002=m
+CONFIG_GP2AP020A00F=m
+CONFIG_SENSORS_ISL29018=m
+CONFIG_SENSORS_ISL29028=m
+CONFIG_ISL29125=m
+CONFIG_HID_SENSOR_ALS=m
+CONFIG_HID_SENSOR_PROX=m
+CONFIG_JSA1212=m
+CONFIG_ROHM_BU27008=m
+CONFIG_ROHM_BU27034=m
+CONFIG_RPR0521=m
+CONFIG_LTR501=m
+CONFIG_LTRF216A=m
+CONFIG_LV0104CS=m
+CONFIG_MAX44000=m
+CONFIG_MAX44009=m
+CONFIG_NOA1305=m
+CONFIG_OPT3001=m
+CONFIG_OPT4001=m
+CONFIG_PA12203001=m
+CONFIG_SI1133=m
+CONFIG_SI1145=m
+CONFIG_STK3310=m
+CONFIG_ST_UVIS25=m
+CONFIG_TCS3414=m
+CONFIG_TCS3472=m
+CONFIG_SENSORS_TSL2563=m
+CONFIG_TSL2583=m
+CONFIG_TSL2591=m
+CONFIG_TSL2772=m
+CONFIG_TSL4531=m
+CONFIG_US5182D=m
+CONFIG_VCNL4000=m
+CONFIG_VCNL4035=m
+CONFIG_VEML6030=m
+CONFIG_VEML6070=m
+CONFIG_VL6180=m
+CONFIG_ZOPT2201=m
+CONFIG_AK8974=m
+CONFIG_AK09911=m
+CONFIG_BMC150_MAGN_I2C=m
+CONFIG_BMC150_MAGN_SPI=m
+CONFIG_MAG3110=m
+CONFIG_HID_SENSOR_MAGNETOMETER_3D=m
+CONFIG_MMC35240=m
+CONFIG_SENSORS_HMC5843_I2C=m
+CONFIG_SENSORS_HMC5843_SPI=m
+CONFIG_SENSORS_RM3100_I2C=m
+CONFIG_SENSORS_RM3100_SPI=m
+CONFIG_TI_TMAG5273=m
+CONFIG_YAMAHA_YAS530=m
+CONFIG_IIO_MUX=m
+CONFIG_HID_SENSOR_INCLINOMETER_3D=m
+CONFIG_HID_SENSOR_DEVICE_ROTATION=m
+CONFIG_IIO_HRTIMER_TRIGGER=m
+CONFIG_IIO_INTERRUPT_TRIGGER=m
+CONFIG_IIO_TIGHTLOOP_TRIGGER=m
+CONFIG_IIO_SYSFS_TRIGGER=m
+CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE=m
+CONFIG_AD5110=m
+CONFIG_AD5272=m
+CONFIG_DS1803=m
+CONFIG_MAX5432=m
+CONFIG_MAX5481=m
+CONFIG_MAX5487=m
+CONFIG_MCP4018=m
+CONFIG_MCP4131=m
+CONFIG_MCP4531=m
+CONFIG_MCP41010=m
+CONFIG_TPL0102=m
+CONFIG_X9250=m
+CONFIG_LMP91000=m
+CONFIG_ABP060MG=m
+CONFIG_BMP280=m
+CONFIG_DLHL60D=m
+CONFIG_DPS310=m
+CONFIG_HID_SENSOR_PRESS=m
+CONFIG_HP03=m
+CONFIG_ICP10100=m
+CONFIG_MPL115_I2C=m
+CONFIG_MPL115_SPI=m
+CONFIG_MPL3115=m
+CONFIG_MPRLS0025PA=m
+CONFIG_MS5611=m
+CONFIG_MS5611_I2C=m
+CONFIG_MS5611_SPI=m
+CONFIG_MS5637=m
+CONFIG_SDP500=m
+CONFIG_IIO_ST_PRESS=m
+CONFIG_T5403=m
+CONFIG_HP206C=m
+CONFIG_ZPA2326=m
+CONFIG_AS3935=m
+CONFIG_HX9023S=m
+CONFIG_IRSD200=m
+CONFIG_ISL29501=m
+CONFIG_LIDAR_LITE_V2=m
+CONFIG_MB1232=m
+CONFIG_PING=m
+CONFIG_RFD77402=m
+CONFIG_SRF04=m
+CONFIG_SX9310=m
+CONFIG_SX9324=m
+CONFIG_SX9360=m
+CONFIG_SX9500=m
+CONFIG_SRF08=m
+CONFIG_VCNL3020=m
+CONFIG_VL53L0X_I2C=m
+CONFIG_AW96103=m
+CONFIG_AD2S90=m
+CONFIG_AD2S1200=m
+CONFIG_AD2S1210=m
+CONFIG_LTC2983=m
+CONFIG_MAXIM_THERMOCOUPLE=m
+CONFIG_HID_SENSOR_TEMP=m
+CONFIG_MLX90614=m
+CONFIG_MLX90632=m
+CONFIG_TMP006=m
+CONFIG_TMP007=m
+CONFIG_TMP117=m
+CONFIG_TSYS01=m
+CONFIG_TSYS02D=m
+CONFIG_MAX30208=m
+CONFIG_MAX31856=m
+CONFIG_MAX31865=m
+CONFIG_PWM=y
+CONFIG_PWM_GPIO=m
+CONFIG_PWM_OMAP_DMTIMER=y
+CONFIG_PWM_PCA9685=y
+CONFIG_PWM_STMPE=y
+CONFIG_PWM_TIECAP=y
+CONFIG_PWM_TIEHRPWM=y
+CONFIG_RESET_TI_SYSCON=y
+CONFIG_PHY_CAN_TRANSCEIVER=m
+CONFIG_OMAP_USB2=y
+CONFIG_TI_PIPE3=y
+CONFIG_RAS=y
+CONFIG_FPGA=m
+CONFIG_ALTERA_PR_IP_CORE=m
+CONFIG_ALTERA_PR_IP_CORE_PLAT=m
+CONFIG_FPGA_MGR_ALTERA_PS_SPI=m
+CONFIG_FPGA_MGR_XILINX_SPI=m
+CONFIG_FPGA_MGR_ICE40_SPI=m
+CONFIG_FPGA_MGR_MACHXO2_SPI=m
+CONFIG_FPGA_BRIDGE=m
+CONFIG_ALTERA_FREEZE_BRIDGE=m
+CONFIG_XILINX_PR_DECOUPLER=m
+CONFIG_FPGA_REGION=m
+CONFIG_OF_FPGA_REGION=m
+CONFIG_MUX_ADG792A=m
+CONFIG_MUX_ADGS1408=m
+CONFIG_MUX_GPIO=m
+CONFIG_MUX_MMIO=m
+CONFIG_COUNTER=m
+CONFIG_INTERRUPT_CNT=m
+CONFIG_TI_ECAP_CAPTURE=m
+CONFIG_TI_EQEP=m
+CONFIG_VALIDATE_FS_PARSER=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_DLM=y
+CONFIG_BTRFS_FS=y
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_F2FS_FS=y
+CONFIG_F2FS_FS_SECURITY=y
+CONFIG_F2FS_FS_COMPRESSION=y
+CONFIG_ZONEFS_FS=m
+CONFIG_FS_ENCRYPTION=y
+CONFIG_FS_VERITY=y
+CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_QFMT_V2=y
+CONFIG_AUTOFS_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=m
+CONFIG_VIRTIO_FS=m
+CONFIG_OVERLAY_FS=y
+CONFIG_FSCACHE=y
+CONFIG_FSCACHE_STATS=y
+CONFIG_CACHEFILES=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+CONFIG_FAT_DEFAULT_UTF8=y
+CONFIG_EXFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_ZSTD=y
+CONFIG_ROMFS_FS=m
+CONFIG_ROMFS_BACKED_BY_BOTH=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFS_V4_2_READ_PLUS is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_BLOCKLAYOUT=y
+CONFIG_NFSD_V4_SECURITY_LABEL=y
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2=y
+CONFIG_SUNRPC_DEBUG=y
+CONFIG_CEPH_FS=m
+CONFIG_CEPH_FSCACHE=y
+CONFIG_CEPH_FS_POSIX_ACL=y
+CONFIG_CIFS=m
+CONFIG_CIFS_UPCALL=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_CIFS_FSCACHE=y
+CONFIG_SMB_SERVER=m
+CONFIG_CODA_FS=m
+CONFIG_AFS_FS=m
+CONFIG_AFS_FSCACHE=y
+CONFIG_9P_FS=m
+CONFIG_9P_FSCACHE=y
+CONFIG_9P_FS_POSIX_ACL=y
+CONFIG_9P_FS_SECURITY=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
+CONFIG_DLM=m
+CONFIG_DLM_DEBUG=y
+CONFIG_UNICODE=y
+CONFIG_KEY_DH_OPERATIONS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK_XFRM=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_FORTIFY_SOURCE=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_TOMOYO=y
+CONFIG_SECURITY_APPARMOR=y
+CONFIG_SECURITY_YAMA=y
+CONFIG_SECURITY_LANDLOCK=y
+CONFIG_INTEGRITY_SIGNATURE=y
+CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
+CONFIG_IMA=y
+CONFIG_IMA_SIG_TEMPLATE=y
+CONFIG_IMA_DEFAULT_HASH_SHA256=y
+CONFIG_IMA_APPRAISE=y
+CONFIG_IMA_ARCH_POLICY=y
+CONFIG_EVM=y
+CONFIG_DEFAULT_SECURITY_APPARMOR=y
+CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf"
+CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
+CONFIG_BUG_ON_DATA_CORRUPTION=y
+CONFIG_CRYPTO_USER=m
+CONFIG_CRYPTO_PCRYPT=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_ECDSA=y
+CONFIG_CRYPTO_ECRDSA=m
+CONFIG_CRYPTO_CURVE25519=m
+CONFIG_CRYPTO_AES_TI=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_ADIANTUM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_AEGIS128=m
+CONFIG_CRYPTO_CHACHA20POLY1305=m
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_SM3_GENERIC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_CRC64_ISO3309=m
+CONFIG_CRYPTO_LZ4=m
+CONFIG_CRYPTO_LZ4HC=m
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_DRBG_HASH=y
+CONFIG_CRYPTO_DRBG_CTR=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_USER_API_RNG=m
+CONFIG_CRYPTO_USER_API_AEAD=m
+# CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE is not set
+CONFIG_CRYPTO_GHASH_ARM_CE=m
+CONFIG_CRYPTO_NHPOLY1305_NEON=m
+CONFIG_CRYPTO_BLAKE2B_NEON=m
+CONFIG_CRYPTO_SHA1_ARM_NEON=m
+CONFIG_CRYPTO_SHA1_ARM_CE=m
+CONFIG_CRYPTO_SHA2_ARM_CE=m
+CONFIG_CRYPTO_SHA512_ARM=m
+CONFIG_CRYPTO_AES_ARM_BS=m
+CONFIG_CRYPTO_AES_ARM_CE=m
+CONFIG_CRYPTO_CRC32_ARM_CE=m
+CONFIG_CRYPTO_CRCT10DIF_ARM_CE=m
+CONFIG_CRYPTO_DEV_OMAP=y
+CONFIG_CRYPTO_DEV_OMAP_SHAM=y
+CONFIG_CRYPTO_DEV_OMAP_AES=y
+CONFIG_CRYPTO_DEV_OMAP_DES=y
+CONFIG_CRYPTO_DEV_ATMEL_ECC=y
+CONFIG_CRYPTO_DEV_ATMEL_SHA204A=y
+CONFIG_CRYPTO_DEV_VIRTIO=m
+CONFIG_PKCS8_PRIVATE_KEY_PARSER=m
+# CONFIG_RAID6_PQ_BENCHMARK is not set
+CONFIG_CORDIC=m
+CONFIG_CRC4=m
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_SPARC is not set
+CONFIG_CMA_SIZE_MBYTES=48
+CONFIG_IRQ_POLL=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_TER16x32=y
+CONFIG_PRINTK_TIME=y
+CONFIG_BOOT_PRINTK_DELAY=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_HEADERS_INSTALL=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x01b6
+CONFIG_PAGE_OWNER=y
+CONFIG_PAGE_POISONING=y
+CONFIG_SCHED_STACK_END_CHECK=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_WQ_CPU_INTENSIVE_REPORT=y
+CONFIG_SCHEDSTATS=y
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_LIST=y
+CONFIG_RCU_CPU_STALL_CPUTIME=y
+# CONFIG_RCU_TRACE is not set
+CONFIG_BOOTTIME_TRACING=y
+CONFIG_FUNCTION_PROFILER=y
+CONFIG_STACK_TRACER=y
+CONFIG_SCHED_TRACER=y
+CONFIG_HWLAT_TRACER=y
+CONFIG_TIMERLAT_TRACER=y
+CONFIG_FTRACE_SYSCALLS=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_HIST_TRIGGERS=y
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_NOTIFIER_ERROR_INJECTION=m
+CONFIG_FUNCTION_ERROR_INJECTION=y
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_MEMTEST=y
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/BONE-I2C1.dtso b/arch/arm64/boot/dts/ti/BONE-I2C1.dtso
--- a/arch/arm64/boot/dts/ti/BONE-I2C1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/BONE-I2C1.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 BeagleBoard.org - https://beagleboard.org/
+ *
+ * https://docs.beagleboard.io/latest/boards/capes/cape-interface-spec.html#i2c
+ */
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BONE-I2C1.kernel = __TIMESTAMP__;
+	};
+};
+
+&bone_i2c_1 {
+	status = "okay";
+	clock-frequency = <100000>;
+	symlink = "bone/i2c/1";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/BONE-I2C2.dtso b/arch/arm64/boot/dts/ti/BONE-I2C2.dtso
--- a/arch/arm64/boot/dts/ti/BONE-I2C2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/BONE-I2C2.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 BeagleBoard.org - https://beagleboard.org/
+ *
+ * https://docs.beagleboard.io/latest/boards/capes/cape-interface-spec.html#i2c
+ */
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BONE-I2C2.kernel = __TIMESTAMP__;
+	};
+};
+
+&bone_i2c_2 {
+	status = "okay";
+	clock-frequency = <100000>;
+	symlink = "bone/i2c/2";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/BONE-I2C3.dtso b/arch/arm64/boot/dts/ti/BONE-I2C3.dtso
--- a/arch/arm64/boot/dts/ti/BONE-I2C3.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/BONE-I2C3.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 BeagleBoard.org - https://beagleboard.org/
+ *
+ * https://docs.beagleboard.io/latest/boards/capes/cape-interface-spec.html#i2c
+ */
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		BONE-I2C3.kernel = __TIMESTAMP__;
+	};
+};
+
+&bone_i2c_3 {
+	status = "okay";
+	clock-frequency = <100000>;
+	symlink = "bone/i2c/3";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am6232-pocketbeagle2.dts b/arch/arm64/boot/dts/ti/k3-am6232-pocketbeagle2.dts
--- a/arch/arm64/boot/dts/ti/k3-am6232-pocketbeagle2.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am6232-pocketbeagle2.dts	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,531 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * https://www.beagleboard.org/boards/pocketbeagle-2
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2025 Robert Nelson, BeagleBoard.org Foundation
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "k3-am625.dtsi"
+#include "k3-am62-pocketbeagle2-pinmux.dtsi"
+
+/ {
+	compatible = "beagle,am62-pocketbeagle2", "ti,am625";
+	model = "BeagleBoard.org PocketBeagle2";
+
+	aliases {
+		serial0 = &wkup_uart0;
+		serial1 = &main_uart1;
+		serial2 = &main_uart6;
+		serial3 = &main_uart3;
+		serial4 = &main_uart4;
+		serial5 = &main_uart5;
+		serial6 = &main_uart2;
+		serial7 = &main_uart0;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+		usb0 = &usb0;
+		usb1 = &usb1;
+		i2c0 = &main_i2c0;
+		i2c1 = &main_i2c1;
+		i2c2 = &main_i2c2;
+		i2c3 = &wkup_i2c0;
+		spi0 = &main_spi0;
+		spi2 = &main_spi2;
+	};
+
+	chosen {
+		stdout-path = &main_uart6;
+		base_dtb = "k3-am6232-pocketbeagle2.dts";
+	};
+
+	memory@80000000 {
+		/* 512MB RAM */
+		reg = <0x00000000 0x80000000 0x00000000 0x20000000>;
+		device_type = "memory";
+		bootph-pre-ram;
+	};
+
+	reserved_memory: reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x8000000>;
+			linux,cma-default;
+		};
+
+		mcu_m4fss_dma_memory_region: m4f-dma-memory@9cb00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9cb00000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_m4fss_memory_region: m4f-memory@9cc00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9cc00000 0x00 0xe00000>;
+			no-map;
+		};
+
+		secure_tfa_ddr: tfa@9e780000 {
+			reg = <0x00 0x9e780000 0x00 0x80000>;
+			alignment = <0x1000>;
+			no-map;
+		};
+
+		secure_ddr: optee@9e800000 {
+			reg = <0x00 0x9e800000 0x00 0x01800000>;
+			alignment = <0x1000>;
+			no-map;
+		};
+
+		wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@9db00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9db00000 0x00 0xc00000>;
+			no-map;
+		};
+	};
+
+	vsys_5v0: regulator-1 {
+		compatible = "regulator-fixed";
+		regulator-name = "vsys_5v0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+		bootph-all;
+	};
+
+	vdd_3v3: regulator-2 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vsys_5v0>;
+		regulator-always-on;
+		regulator-boot-on;
+		bootph-all;
+	};
+
+	vdd_mmc1: regulator-3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_mmc1";
+		pinctrl-names = "default";
+		pinctrl-0 = <&vdd_3v3_sd_pins_default>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		enable-active-high;
+		regulator-always-on;
+		vin-supply = <&vdd_3v3>;
+		gpio = <&main_gpio0 0 GPIO_ACTIVE_HIGH>;
+		bootph-all;
+	};
+
+	vdd_sd_dv: regulator-4 {
+		compatible = "regulator-gpio";
+		regulator-name = "sd_hs200_switch";
+		pinctrl-names = "default";
+		pinctrl-0 = <&vdd_sd_dv_pins_default>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		vin-supply = <&vdd_3v3>;
+		gpios = <&main_gpio1 49 GPIO_ACTIVE_HIGH>;
+		states = <1800000 0x0>,
+			 <3300000 0x1>;
+		bootph-all;
+	};
+
+	adc_vref: regulator-5 {
+		compatible = "regulator-fixed";
+		regulator-name = "default";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins_default>;
+		bootph-all;
+
+		led-1 {
+			function = LED_FUNCTION_HEARTBEAT;
+			color = <LED_COLOR_ID_GREEN>;
+			linux,default-trigger = "heartbeat";
+			gpios = <&main_gpio0 6 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+			bootph-all;
+		};
+
+		led-2 {
+			function = LED_FUNCTION_DISK_ACTIVITY;
+			color = <LED_COLOR_ID_GREEN>;
+			linux,default-trigger = "mmc1";
+			gpios = <&main_gpio0 5 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+			bootph-all;
+		};
+
+		led-3 {
+			function = LED_FUNCTION_INDICATOR;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&main_gpio0 4 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			bootph-all;
+		};
+
+		led-4 {
+			function = LED_FUNCTION_INDICATOR;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&main_gpio0 3 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			bootph-all;
+		};
+	};
+};
+
+&main_pmx0 {
+	led_pins_default: led-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x000c, PIN_OUTPUT, 7) /* (E25) OSPI0_D0.GPIO0_3 */
+			AM62X_IOPAD(0x0010, PIN_OUTPUT, 7) /* (G24) OSPI0_D1.GPIO0_4 */
+			AM62X_IOPAD(0x0014, PIN_OUTPUT, 7) /* (F25) OSPI0_D2.GPIO0_5 */
+			AM62X_IOPAD(0x0018, PIN_OUTPUT, 7) /* (F24) OSPI0_D3.GPIO0_6 */
+		>;
+		bootph-all;
+	};
+
+	main_i2c0_pins_default: main-i2c0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (B16) I2C0_SCL */
+			AM62X_IOPAD(0x01e4, PIN_INPUT_PULLUP, 0) /* (A16) I2C0_SDA */
+		>;
+		bootph-all;
+	};
+
+	main_i2c2_pins_default: main-i2c2-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00b0, PIN_INPUT_PULLUP, 1) /* (K22) GPMC0_CSn2.I2C2_SCL */
+			AM62X_IOPAD(0x00b4, PIN_INPUT_PULLUP, 1) /* (K24) GPMC0_CSn3.I2C2_SDA */
+		>;
+		bootph-all;
+	};
+
+	main_uart0_pins_default: main-uart0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x1c8, PIN_INPUT, 0) /* (D14/A13) UART0_RXD */
+			AM62X_IOPAD(0x1cc, PIN_OUTPUT, 0) /* (E14/E11) UART0_TXD */
+		>;
+		bootph-all;
+	};
+
+	main_uart1_pins_default: main-uart1-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x194, PIN_INPUT, 2) /* (B19/B18) MCASP0_AXR3.UART1_CTSn */
+			AM62X_IOPAD(0x198, PIN_OUTPUT, 2) /* (A19/B17) MCASP0_AXR2.UART1_RTSn */
+			AM62X_IOPAD(0x1ac, PIN_INPUT, 2) /* (E19/D15) MCASP0_AFSR.UART1_RXD */
+			AM62X_IOPAD(0x1b0, PIN_OUTPUT, 2) /* (A20/D16) MCASP0_ACLKR.UART1_TXD */
+		>;
+		bootph-all;
+	};
+
+	main_uart6_pins_default: main-uart6-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x001c, PIN_INPUT, 3) /* (J23) OSPI0_D4.UART6_RXD */
+			AM62X_IOPAD(0x0020, PIN_OUTPUT, 3) /* (J25) OSPI0_D5.UART6_TXD */
+		>;
+	};
+
+	main_mmc1_pins_default: main-mmc1-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x23c, PIN_INPUT, 0) /* (A21/C18) MMC1_CMD */
+			AM62X_IOPAD(0x234, PIN_INPUT, 0) /* (B22/A20) MMC1_CLK */
+			AM62X_IOPAD(0x230, PIN_INPUT, 0) /* (A22/A19) MMC1_DAT0 */
+			AM62X_IOPAD(0x22c, PIN_INPUT, 0) /* (B21/B19) MMC1_DAT1 */
+			AM62X_IOPAD(0x228, PIN_INPUT, 0) /* (C21/B20) MMC1_DAT2 */
+			AM62X_IOPAD(0x224, PIN_INPUT, 0) /* (D22/C19) MMC1_DAT3 */
+			AM62X_IOPAD(0x240, PIN_INPUT, 7) /* (D17/C15) MMC1_SDCD.GPIO1_48 */
+		>;
+		bootph-all;
+	};
+
+	vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0244, PIN_OUTPUT, 7) /* (P25) GPMC0_CLK.GPIO1_49 */
+		>;
+		bootph-all;
+	};
+
+	pmic_irq_pins_default: pmic-irq-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01f4, PIN_INPUT_PULLUP, 0) /* (D16) EXTINTn */
+		>;
+		bootph-all;
+	};
+
+	vdd_3v3_sd_pins_default: vdd-3v3-sd-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0000, PIN_OUTPUT, 7) /* (H24) OSPI0_CLK.GPIO0_0 */
+		>;
+		bootph-all;
+	};
+
+	usb1_pins_default: usb1-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0258, PIN_INPUT, 0) /* (F18) USB1_DRVVBUS */
+		>;
+		bootph-all;
+	};
+
+	epwm2_pins_default: epwm2-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01e8, PIN_OUTPUT, 8) /* (B17) I2C1_SCL.EHRPWM2_A */
+		>;
+	};
+};
+
+&epwm2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&epwm2_pins_default>;
+};
+
+&mailbox0_cluster0 {
+	mbox_m4_0: mbox-m4-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&main_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart0_pins_default>;
+	bootph-all;
+	status = "okay";
+};
+
+&main_uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart1_pins_default>;
+	bootph-pre-ram;
+	status = "reserved";
+};
+
+&main_uart6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart6_pins_default>;
+	bootph-all;
+	status = "okay";
+};
+
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+	bootph-all;
+	status = "okay";
+
+	ad7291: adc@20 {
+		/* Emulated with MSPM0L1105 */
+		compatible = "adi,ad7291";
+		reg = <0x20>;
+		vref-supply = <&adc_vref>;
+	};
+
+	eeprom: eeprom@50 {
+		/* Emulated with MSPM0L1105 */
+		compatible = "atmel,24c32";
+		reg = <0x50>;
+	};
+};
+
+&main_i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c2_pins_default>;
+	clock-frequency = <400000>;
+	bootph-all;
+	status = "okay";
+};
+
+&mcu_m4fss {
+	mboxes = <&mailbox0_cluster0 &mbox_m4_0>;
+	memory-region = <&mcu_m4fss_dma_memory_region>,
+			<&mcu_m4fss_memory_region>;
+	status = "okay";
+};
+
+&mcu_pmx0 {
+	wkup_uart0_pins_default: wkup-uart0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x02c, PIN_INPUT, 0)	/* (C6/A7) WKUP_UART0_CTSn */
+			AM62X_MCU_IOPAD(0x030, PIN_OUTPUT, 0)	/* (A4/B4) WKUP_UART0_RTSn */
+			AM62X_MCU_IOPAD(0x024, PIN_INPUT, 0)	/* (B4/B5) WKUP_UART0_RXD */
+			AM62X_MCU_IOPAD(0x028, PIN_OUTPUT, 0)	/* (C5/C6) WKUP_UART0_TXD */
+		>;
+		bootph-all;
+	};
+
+	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x004c, PIN_INPUT_PULLUP, 0)	/* (B9) WKUP_I2C0_SCL */
+			AM62X_MCU_IOPAD(0x0050, PIN_INPUT_PULLUP, 0)	/* (A9) WKUP_I2C0_SDA */
+		>;
+		bootph-all;
+	};
+};
+
+&sdhci1 {
+	/* SD/MMC */
+	vmmc-supply = <&vdd_mmc1>;
+	vqmmc-supply = <&vdd_sd_dv>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc1_pins_default>;
+	disable-wp;
+	cd-gpios = <&main_gpio1 48 GPIO_ACTIVE_LOW>;
+	cd-debounce-delay-ms = <100>;
+	bootph-all;
+	ti,fails-without-test-cd;
+	status = "okay";
+};
+
+&usbss0 {
+	bootph-all;
+	ti,vbus-divider;
+	status = "okay";
+};
+
+&usb0 {
+	/* This is a Type-C socket, but wired as USB 2.0 */
+	dr_mode = "peripheral";
+	bootph-all;
+};
+
+&usbss1 {
+	ti,vbus-divider;
+	status = "okay";
+};
+
+&usb1 {
+	/*
+	 * Default set here is compatible with original PocketBeagle,
+	 * Expansion boards assumed this was pre-setup as host.
+	 */
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb1_pins_default>;
+};
+
+&wkup_uart0 {
+	/* WKUP UART0 is used by Device Manager firmware */
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_uart0_pins_default>;
+	bootph-all;
+	status = "reserved";
+};
+
+&wkup_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_i2c0_pins_default>;
+	clock-frequency = <100000>;
+	bootph-all;
+	status = "okay";
+
+	tps65219: pmic@30 {
+		compatible = "ti,tps65219";
+		reg = <0x30>;
+		buck1-supply = <&vsys_5v0>;
+		buck2-supply = <&vsys_5v0>;
+		buck3-supply = <&vsys_5v0>;
+		ldo1-supply = <&vdd_3v3>;
+		ldo2-supply = <&buck2_reg>;
+		ldo3-supply = <&vdd_3v3>;
+		ldo4-supply = <&vdd_3v3>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_irq_pins_default>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		bootph-all;
+		system-power-controller;
+		ti,power-button;
+
+		regulators {
+			buck1_reg: buck1 {
+				regulator-name = "VDD_CORE";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck2_reg: buck2 {
+				regulator-name = "VDD_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck3_reg: buck3 {
+				regulator-name = "VDD_1V2";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo1_reg: ldo1 {
+				/*
+				 * Regulator is left as is unused, vdd_sd
+				 * is controlled via GPIO with bypass config
+				 * as per the NVM configuration
+				 */
+				regulator-name = "VDD_SD_3V3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-allow-bypass;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo2_reg: ldo2 {
+				regulator-name = "VDDA_0V85";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo3_reg: ldo3 {
+				regulator-name = "VDDA_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo4_reg: ldo4 {
+				regulator-name = "VDD_2V5";
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am6232-pocketbeagle2-techlab-cape.dtso b/arch/arm64/boot/dts/ti/k3-am6232-pocketbeagle2-techlab-cape.dtso
--- a/arch/arm64/boot/dts/ti/k3-am6232-pocketbeagle2-techlab-cape.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am6232-pocketbeagle2-techlab-cape.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,126 @@
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		k3-am6232-pocketbeagle2-techlab-cape.kernel = __TIMESTAMP__;
+	};
+};
+
+&main_spi0 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	techlab_gpio: techlab-gpio@0 {
+		compatible = "microchip,mcp23s18";
+		reg = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		spi-max-frequency = <1000000>;
+		microchip,spi-present-mask = <1>;
+		gpio-line-names = "LD4", "LD7", "LD8",	  /* 0-2 */
+				  "LD6", "LD3", "LD2",    /* 3-5 */
+				  "LD5", "", "LD11",      /* 6-8 */
+				  "LD14", "LD15", "LD13", /* 9-11 */
+				  "LD10", "LD9", "LD12",  /* 12-14 */
+				  "";                     /* 15 */
+	};
+};
+
+&{/} {
+	techlab-led {
+		compatible = "pwm-leds-multicolor";
+		pinctrl-names = "default";
+		pinctrl-0 = <&P1_33_A17_pwm>;
+
+		multi-led {
+			led-red {
+				pwms = <&epwm2 1 255 0>;
+				color = <LED_COLOR_ID_RED>;
+			};
+
+			led-blue {
+				pwms = <&epwm2 0 255 0>;
+				color = <LED_COLOR_ID_BLUE>;
+			};
+
+			led-green {
+				pwms = <&ecap2 0 255 0>;
+				color = <LED_COLOR_ID_GREEN>;
+			};
+		};
+	};
+
+	seven-segments-left {
+		compatible = "gpio-7-segment";
+		segment-gpios = <&techlab_gpio 0 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 1 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 2 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 3 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 4 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 5 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 6 GPIO_ACTIVE_LOW>;
+	};
+
+	seven-segments-right {
+		compatible = "gpio-7-segment";
+		segment-gpios = <&techlab_gpio 8 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 9 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 10 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 11 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 12 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 13 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 14 GPIO_ACTIVE_LOW>;
+	};
+
+	buzzer_pwm: buzzer-pwm {
+		#pwm-cells = <3>;
+		compatible = "pwm-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&P2_30_gpio>;
+		gpios = <&main_gpio0 58 GPIO_ACTIVE_HIGH>;
+	};
+
+
+	buttons {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&P1_29_gpio &P2_33_gpio>;
+
+		left {
+			label = "GPIO Key Left";
+			gpios = <&main_gpio0 52 0>;
+			linux,code = <KEY_LEFT>;
+		};
+
+		right {
+			label = "GPIO Key Right";
+			gpios = <&main_gpio0 62 0>;
+			linux,code = <KEY_RIGHT>;
+		};
+	};
+
+	techlab-buzzer {
+		compatible = "pwm-beeper";
+		pwms = <&buzzer_pwm 0 50000 0>;
+	};
+};
+
+&main_i2c2 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+        accel@1c {
+		compatible = "fsl,mma8453";
+		reg = <0x1c>;
+        };
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am6254xxl.dtsi b/arch/arm64/boot/dts/ti/k3-am6254xxl.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am6254xxl.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am6254xxl.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DTS for AM625 SiP SoC family in Quad core configuration and 512MiB RAM.
+ *
+ * Webpage: https://www.ti.com/product/AM625SIP
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include "k3-am625.dtsi"
+
+/ {
+	model = "Texas Instruments AM6254xxl SiP";
+	compatible = "ti,am6254xxl";
+
+	memory@80000000 {
+		device_type = "memory";
+		/* 512MiB of integrated RAM */
+		reg = <0x00000000 0x80000000 0x00000000 0x20000000>;
+		bootph-all;
+	};
+
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am6254xxl-sk.dts b/arch/arm64/boot/dts/ti/k3-am6254xxl-sk.dts
--- a/arch/arm64/boot/dts/ti/k3-am6254xxl-sk.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am6254xxl-sk.dts	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * AM6254xxl SiP SK: https://www.ti.com/lit/df/sprr482b/sprr482b.zip
+ * Webpage: https://www.ti.com/tool/SK-AM62-SIP
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include "k3-am6254xxl.dtsi"
+#include "k3-am62x-sk-common.dtsi"
+
+/ {
+	model = "Texas Instruments AM6254xxl SK";
+	compatible = "ti,am6254xxl-sk", "ti,am6254xxl";
+
+	vdd_sd_dv: regulator-4 {
+		/* Output of TLV71033 */
+		bootph-all;
+		compatible = "regulator-gpio";
+		regulator-name = "tlv71033";
+		pinctrl-names = "default";
+		pinctrl-0 = <&vdd_sd_dv_pins_default>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		vin-supply = <&vcc_5v0>;
+		gpios = <&main_gpio0 31 GPIO_ACTIVE_HIGH>;
+		states = <1800000 0x0>,
+			 <3300000 0x1>;
+	};
+
+	vcc_1v8: regulator-5 {
+		/* output of TPS6282518DMQ */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_3v3_sys>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&main_pmx0 {
+	main_rgmii2_pins_default: main-rgmii2-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x184, PIN_INPUT, 0) /* (AE23) RGMII2_RD0 */
+			AM62X_IOPAD(0x188, PIN_INPUT, 0) /* (AB20) RGMII2_RD1 */
+			AM62X_IOPAD(0x18c, PIN_INPUT, 0) /* (AC21) RGMII2_RD2 */
+			AM62X_IOPAD(0x190, PIN_INPUT, 0) /* (AE22) RGMII2_RD3 */
+			AM62X_IOPAD(0x180, PIN_INPUT, 0) /* (AD23) RGMII2_RXC */
+			AM62X_IOPAD(0x17c, PIN_INPUT, 0) /* (AD22) RGMII2_RX_CTL */
+			AM62X_IOPAD(0x16c, PIN_OUTPUT, 0) /* (Y18) RGMII2_TD0 */
+			AM62X_IOPAD(0x170, PIN_OUTPUT, 0) /* (AA18) RGMII2_TD1 */
+			AM62X_IOPAD(0x174, PIN_OUTPUT, 0) /* (AD21) RGMII2_TD2 */
+			AM62X_IOPAD(0x178, PIN_OUTPUT, 0) /* (AC20) RGMII2_TD3 */
+			AM62X_IOPAD(0x168, PIN_OUTPUT, 0) /* (AE21) RGMII2_TXC */
+			AM62X_IOPAD(0x164, PIN_OUTPUT, 0) /* (AA19) RGMII2_TX_CTL */
+		>;
+	};
+
+	ospi0_pins_default: ospi0-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x000, PIN_OUTPUT, 0) /* (H24) OSPI0_CLK */
+			AM62X_IOPAD(0x02c, PIN_OUTPUT, 0) /* (F23) OSPI0_CSn0 */
+			AM62X_IOPAD(0x00c, PIN_INPUT, 0) /* (E25) OSPI0_D0 */
+			AM62X_IOPAD(0x010, PIN_INPUT, 0) /* (G24) OSPI0_D1 */
+			AM62X_IOPAD(0x014, PIN_INPUT, 0) /* (F25) OSPI0_D2 */
+			AM62X_IOPAD(0x018, PIN_INPUT, 0) /* (F24) OSPI0_D3 */
+			AM62X_IOPAD(0x01c, PIN_INPUT, 0) /* (J23) OSPI0_D4 */
+			AM62X_IOPAD(0x020, PIN_INPUT, 0) /* (J25) OSPI0_D5 */
+			AM62X_IOPAD(0x024, PIN_INPUT, 0) /* (H25) OSPI0_D6 */
+			AM62X_IOPAD(0x028, PIN_INPUT, 0) /* (J22) OSPI0_D7 */
+			AM62X_IOPAD(0x008, PIN_INPUT, 0) /* (J24) OSPI0_DQS */
+		>;
+	};
+
+	vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x07c, PIN_OUTPUT, 7) /* (P25) GPMC0_CLK.GPIO0_31 */
+		>;
+	};
+
+	main_gpio1_ioexp_intr_pins_default: main-gpio1-ioexp-intr-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01d4, PIN_INPUT, 7) /* (B15) UART0_RTSn.GPIO1_23 */
+		>;
+	};
+};
+
+&vmain_pd {
+	bootph-all;
+};
+
+&vcc_5v0 {
+	bootph-all;
+};
+
+&vcc_3v3_sys {
+	bootph-all;
+};
+
+&vdd_mmc1 {
+	bootph-all;
+};
+
+&main_gpio0 {
+	bootph-all;
+};
+
+&main_gpio1 {
+	bootph-all;
+};
+
+&main_i2c1 {
+	bootph-all;
+	exp1: gpio@22 {
+		bootph-all;
+		compatible = "ti,tca6424";
+		reg = <0x22>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "GPIO_CPSW2_RST", "GPIO_CPSW1_RST",
+				   "PRU_DETECT", "MMC1_SD_EN",
+				   "VPP_LDO_EN", "EXP_PS_3V3_En",
+				   "EXP_PS_5V0_En", "EXP_HAT_DETECT",
+				   "GPIO_AUD_RSTn", "GPIO_eMMC_RSTn",
+				   "UART1_FET_BUF_EN", "WL_LT_EN",
+				   "GPIO_HDMI_RSTn", "CSI_GPIO1",
+				   "CSI_GPIO2", "PRU_3V3_EN",
+				   "HDMI_INTn", "PD_I2C_IRQ",
+				   "MCASP1_FET_EN", "MCASP1_BUF_BT_EN",
+				   "MCASP1_FET_SEL", "UART1_FET_SEL",
+				   "TSINT#", "IO_EXP_TEST_LED";
+
+		interrupt-parent = <&main_gpio1>;
+		interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_gpio1_ioexp_intr_pins_default>;
+	};
+};
+
+&sdhci1 {
+	vmmc-supply = <&vdd_mmc1>;
+	vqmmc-supply = <&vdd_sd_dv>;
+};
+
+&cpsw3g {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_rgmii1_pins_default>, <&main_rgmii2_pins_default>;
+};
+
+&cpsw_port2 {
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&cpsw3g_phy1>;
+};
+
+&cpsw3g_mdio {
+	cpsw3g_phy1: ethernet-phy@1 {
+		reg = <1>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		ti,min-output-impedance;
+	};
+};
+
+&fss {
+	bootph-all;
+};
+
+&ospi0 {
+	bootph-all;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&ospi0_pins_default>;
+
+	flash@0 {
+		bootph-all;
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <4>;
+
+		partitions {
+			bootph-all;
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "ospi.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition@80000 {
+				label = "ospi.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition@280000 {
+				label = "ospi.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition@680000 {
+				label = "ospi.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition@6c0000 {
+				label = "ospi.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition@800000 {
+				label = "ospi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition@3fc0000 {
+				bootph-pre-ram;
+				label = "ospi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-beagleplay-bcfserial-no-firmware.dtso b/arch/arm64/boot/dts/ti/k3-am625-beagleplay-bcfserial-no-firmware.dtso
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay-bcfserial-no-firmware.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay-bcfserial-no-firmware.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,8 @@
+/dts-v1/;
+/plugin/;
+
+&main_uart6 {
+    mcu {
+        status = "disabled";
+    };
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts	2025-10-23 09:30:40.282462115 -0400
@@ -12,6 +12,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include "k3-am625.dtsi"
+#include "k3-am625-beagleplay-pinmux.dtsi"
 
 / {
 	compatible = "beagle,am625-beagleplay", "ti,am625";
@@ -65,6 +66,14 @@
 			pmsg-size = <0x8000>;
 		};
 
+		/* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x8000000>;
+			linux,cma-default;
+		};
+
 		secure_tfa_ddr: tfa@9e780000 {
 			reg = <0x00 0x9e780000 0x00 0x80000>;
 			no-map;
@@ -419,6 +428,12 @@
 		>;
 	};
 
+	mikrobus_pwm_pins_default: mikrobus-pwm-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01a4, PIN_INPUT, 2) /* (B20) MCASP0_ACLKX.ECAP2_IN_APWM_OUT */
+		>;
+	};
+
 	main_uart0_pins_default: main-uart0-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
@@ -496,6 +511,20 @@
 			AM62X_IOPAD(0x0078, PIN_OUTPUT, 1) /* (U24) GPMC0_AD15.VOUT0_DATA23 */
 		>;
 	};
+
+	touchscreen_pins_default: touchscreen-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01b4, PIN_OUTPUT, 7) /* (A13) SPI0_CS0.GPIO1_15 */
+			AM62X_IOPAD(0x00a0, PIN_INPUT, 7) /* (K25) GPMC0_WPn.GPIO0_39 */
+		>;
+	};
+
+	backlight_pins_default: bl-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0000, PIN_OUTPUT, 7) /* (H24) OSPI0_CLK.GPIO0_0 */
+			AM62X_IOPAD(0x01b8, PIN_OUTPUT, 2) /* (C13) SPI0_CS1.EHRPWM0_B */
+		>;
+	};
 };
 
 &mcu_pmx0 {
@@ -604,7 +633,7 @@
 		reg = <1>;
 		reset-gpios = <&main_gpio1 5 GPIO_ACTIVE_LOW>;
 		reset-assert-us = <25>;
-		reset-deassert-us = <60000>; /* T2 */
+		reset-deassert-us = <35>;
 	};
 };
 
@@ -926,3 +955,9 @@
 	       0 0 0 0
 	>;
 };
+
+&ecap2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mikrobus_pwm_pins_default>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-beagleplay-lincolntech-lcd185-panel.dtso b/arch/arm64/boot/dts/ti/k3-am625-beagleplay-lincolntech-lcd185-panel.dtso
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay-lincolntech-lcd185-panel.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay-lincolntech-lcd185-panel.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * Lincoln tech Solutions OLDI panel (LCD185-101CT) and touch DT overlay for AM625-BeaglePlay
+ *
+ * AM625-BeaglePlay: https://www.beagleboard.org/boards/beagleplay
+ * Panel datasheet: https://lincolntechsolutions.com/wp-content/uploads/2023/04/LCD185-101CTL1ARNTT_DS_R1.3.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&{/} {
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&backlight_pins_default>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+		enable-gpios = <&main_gpio0 0 GPIO_ACTIVE_HIGH>;
+		pwms = <&epwm0 1 20000 0>;
+	};
+
+	lcd {
+		compatible = "lincolntech,lcd185-101ct", "panel-simple";
+		backlight = <&backlight>;
+		/*
+		* Note that the OLDI TX 0 transmits the odd set of pixels
+		* while the OLDI TX 1 transmits the even set. This is a
+		* fixed configuration in the IP integration and is not
+		* changeable. The properties, "dual-lvds-odd-pixels" and
+		* "dual-lvds-even-pixels" have been used to merely
+		* identify if a Dual Link configuration is required.
+		* Swapping them will cause an error in the dss oldi driver.
+		*/
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				dual-lvds-odd-pixels;
+				lcd_in0: endpoint {
+					remote-endpoint = <&oldi_0_out>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				dual-lvds-even-pixels;
+				lcd_in1: endpoint {
+					remote-endpoint = <&oldi_1_out>;
+				};
+			};
+		};
+	};
+};
+
+&dss {
+	status = "okay";
+};
+
+&oldi0 {
+	status = "okay";
+	ti,companion-oldi = <&oldi1>;
+};
+
+&oldi1 {
+	status = "okay";
+	ti,secondary-oldi;
+};
+
+&oldi0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		oldi_0_in: endpoint {
+			remote-endpoint = <&dpi0_out0>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		oldi_0_out: endpoint {
+			remote-endpoint = <&lcd_in0>;
+		};
+	};
+};
+
+&oldi1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		oldi_1_in: endpoint {
+			remote-endpoint = <&dpi0_out1>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		oldi_1_out: endpoint {
+			remote-endpoint = <&lcd_in1>;
+		};
+	};
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* VP1: Output to OLDI */
+	port@0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dpi0_out0: endpoint@0 {
+			reg = <0>;
+			remote-endpoint = <&oldi_0_in>;
+		};
+		dpi0_out1: endpoint@1 {
+			reg = <1>;
+			remote-endpoint = <&oldi_1_in>;
+		};
+	};
+};
+
+&main_i2c2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	eeprom@57 {
+		compatible = "atmel,24c256";
+		reg = <0x57>;
+	};
+
+	touchscreen@5d {
+		compatible = "goodix,gt928";
+		reg = <0x5d>;
+		pinctrl-names = "default";
+	        pinctrl-0 = <&touchscreen_pins_default>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <39 IRQ_TYPE_EDGE_FALLING>;
+		irq-gpios = <&main_gpio0 39 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&main_gpio1 15 GPIO_ACTIVE_HIGH>;
+		touchscreen-size-x = <1920>;
+		touchscreen-size-y = <1200>;
+	};
+};
+
+&epwm0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-beagleplay-pinmux.dtsi b/arch/arm64/boot/dts/ti/k3-am625-beagleplay-pinmux.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay-pinmux.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay-pinmux.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * https://beagleplay.org/
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Robert Nelson, BeagleBoard.org Foundation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	/* rtc1 = &wkup_rtc0; diff */
+	aliases {
+		ethernet0 = &cpsw_port1;
+		ethernet1 = &cpsw_port2;
+		gpio0 = &main_gpio0;
+		gpio1 = &main_gpio1;
+		gpio2 = &mcu_gpio0;
+		i2c0 = &main_i2c0;
+		i2c1 = &main_i2c1;
+		i2c2 = &main_i2c2;
+		i2c3 = &main_i2c3;
+		i2c4 = &wkup_i2c0;
+		i2c5 = &mcu_i2c0;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+		mmc2 = &sdhci2;
+		rtc0 = &rtc;
+		rtc1 = &wkup_rtc0;
+		serial0 = &main_uart5;
+		serial1 = &main_uart6;
+		serial2 = &main_uart0;
+		usb0 = &usb0;
+		usb1 = &usb1;
+	};
+
+	chosen {
+		base_dtb = "k3-am625-beagleplay.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
+
+	leds {
+		led-0 {
+			label = "beaglebone:green:usr0";
+		};
+
+		led-1 {
+			label = "beaglebone:green:usr1";
+		};
+
+		led-2 {
+			label = "beaglebone:green:usr2";
+			linux,default-trigger = "cpu";
+		};
+
+		led-3 {
+			label = "beaglebone:green:usr3";
+		};
+
+		led-4 {
+			label = "beaglebone:green:usr4";
+			linux,default-trigger = "phy0tx";
+		};
+	};
+};
+
+&main_pmx0 {
+	pinctrl-single,gpio-range =
+		<&main_pmx0_range 0 32 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 33 38 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 72 22 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 137 5 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 143 3 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 149 2 PIN_GPIO_RANGE_IOPAD>;
+
+	main_pmx0_range: gpio-range {
+		#pinctrl-single,gpio-range-cells = <3>;
+	};
+
+	touchscreen_pins_default: touchscreen-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01b4, PIN_OUTPUT, 7) /* (A13) SPI0_CS0.GPIO1_15 */
+			AM62X_IOPAD(0x00a0, PIN_INPUT, 7) /* (K25) GPMC0_WPn.GPIO0_39 */
+		>;
+	};
+
+	backlight_pins_default: bl-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0000, PIN_OUTPUT, 7) /* (H24) OSPI0_CLK.GPIO0_0 */
+			AM62X_IOPAD(0x01b8, PIN_OUTPUT, 2) /* (C13) SPI0_CS1.EHRPWM0_B */
+		>;
+	};
+};
+
+&mcu_gpio0 {
+	gpio-line-names = "", "", "", "",			/* 0-3 */
+		"", "", "", "",					/* 4-7 */
+		"", "", "", "",					/* 8-11 */
+		"", "", "", "",					/* 12-15 */
+		"", "QWIIC_I2C0_SCL", "QWIIC_I2C0_SDA", "",	/* 16-19 */
+		"", "", "", "";					/* 20-23 */
+};
+
+&wkup_i2c0 {
+	symlink = "play/csi/i2c";
+};
+
+&mcu_i2c0 {
+	symlink = "play/qwiic/i2c";
+};
+
+&main_i2c1 {
+	symlink = "play/grove/i2c";
+};
+
+&main_i2c3 {
+	symlink = "play/mikrobus/i2c";
+};
+
+&main_uart5 {
+	symlink = "play/mikrobus/uart";
+};
+
+&main_uart6 {
+	symlink = "play/cc1352/uart";
+
+	mcu {
+		status = "okay";
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625.dtsi b/arch/arm64/boot/dts/ti/k3-am625.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am625.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am625.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -108,7 +108,7 @@
 	a53_opp_table: opp-table {
 		compatible = "operating-points-v2-ti-cpu";
 		opp-shared;
-		syscon = <&wkup_conf>;
+		syscon = <&opp_efuse_table>;
 
 		opp-200000000 {
 			opp-hz = /bits/ 64 <200000000>;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-1-4-ghz-opp.dtso b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-1-4-ghz-opp.dtso
--- a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-1-4-ghz-opp.dtso	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-1-4-ghz-opp.dtso	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only OR MIT
-/*
- * Copyright (C) 2024 PHYTEC America LLC
- * Author: Nathan Morrisson <nmorrisson@phytec.com>
- */
-
-/dts-v1/;
-/plugin/;
-
-&vdd_core {
-	regulator-min-microvolt = <850000>;
-	regulator-max-microvolt = <850000>;
-};
-
-&a53_opp_table {
-	opp-1400000000 {
-		opp-hz = /bits/ 64 <1400000000>;
-		opp-supported-hw = <0x01 0x0004>;
-	};
-};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-sk.dts b/arch/arm64/boot/dts/ti/k3-am625-sk.dts
--- a/arch/arm64/boot/dts/ti/k3-am625-sk.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am625-sk.dts	2025-10-23 09:30:40.282462115 -0400
@@ -7,8 +7,11 @@
 
 /dts-v1/;
 
+#include "k3-am625.dtsi"
 #include "k3-am62x-sk-common.dtsi"
 
+#include "k3-timesync-router.h"
+
 / {
 	compatible = "ti,am625-sk", "ti,am625";
 	model = "Texas Instruments AM625 SK";
@@ -23,60 +26,13 @@
 	};
 
 	memory@80000000 {
+		bootph-pre-ram;
 		device_type = "memory";
 		/* 2G RAM */
 		reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
 
 	};
 
-	vmain_pd: regulator-0 {
-		/* TPS65988 PD CONTROLLER OUTPUT */
-		bootph-all;
-		compatible = "regulator-fixed";
-		regulator-name = "vmain_pd";
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		regulator-always-on;
-		regulator-boot-on;
-	};
-
-	vcc_5v0: regulator-1 {
-		/* Output of LM34936 */
-		bootph-all;
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_5v0";
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		vin-supply = <&vmain_pd>;
-		regulator-always-on;
-		regulator-boot-on;
-	};
-
-	vcc_3v3_sys: regulator-2 {
-		/* output of LM61460-Q1 */
-		bootph-all;
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_3v3_sys";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		vin-supply = <&vmain_pd>;
-		regulator-always-on;
-		regulator-boot-on;
-	};
-
-	vdd_mmc1: regulator-3 {
-		/* TPS22918DBVR */
-		bootph-all;
-		compatible = "regulator-fixed";
-		regulator-name = "vdd_mmc1";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		regulator-boot-on;
-		enable-active-high;
-		vin-supply = <&vcc_3v3_sys>;
-		gpio = <&exp1 3 GPIO_ACTIVE_HIGH>;
-	};
-
 	vdd_sd_dv: regulator-4 {
 		/* Output of TLV71033 */
 		bootph-all;
@@ -105,7 +61,39 @@
 	};
 };
 
+&vmain_pd {
+	bootph-all;
+};
+
+&vcc_5v0 {
+	bootph-all;
+};
+
+&vcc_3v3_sys {
+	bootph-all;
+};
+
+&vdd_mmc1 {
+	bootph-all;
+};
+
 &main_pmx0 {
+	main_mmc0_pins_default: main-mmc0-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */
+			AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLK */
+			AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */
+			AM62X_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AA1) MMC0_DAT1 */
+			AM62X_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (AA3) MMC0_DAT2 */
+			AM62X_IOPAD(0x208, PIN_INPUT_PULLUP, 0) /* (Y4) MMC0_DAT3 */
+			AM62X_IOPAD(0x204, PIN_INPUT_PULLUP, 0) /* (AB2) MMC0_DAT4 */
+			AM62X_IOPAD(0x200, PIN_INPUT_PULLUP, 0) /* (AC1) MMC0_DAT5 */
+			AM62X_IOPAD(0x1fc, PIN_INPUT_PULLUP, 0) /* (AD2) MMC0_DAT6 */
+			AM62X_IOPAD(0x1f8, PIN_INPUT_PULLUP, 0) /* (AC2) MMC0_DAT7 */
+		>;
+	};
+
 	main_rgmii2_pins_default: main-rgmii2-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
@@ -124,23 +112,6 @@
 		>;
 	};
 
-	ospi0_pins_default: ospi0-default-pins {
-		bootph-all;
-		pinctrl-single,pins = <
-			AM62X_IOPAD(0x000, PIN_OUTPUT, 0) /* (H24) OSPI0_CLK */
-			AM62X_IOPAD(0x02c, PIN_OUTPUT, 0) /* (F23) OSPI0_CSn0 */
-			AM62X_IOPAD(0x00c, PIN_INPUT, 0) /* (E25) OSPI0_D0 */
-			AM62X_IOPAD(0x010, PIN_INPUT, 0) /* (G24) OSPI0_D1 */
-			AM62X_IOPAD(0x014, PIN_INPUT, 0) /* (F25) OSPI0_D2 */
-			AM62X_IOPAD(0x018, PIN_INPUT, 0) /* (F24) OSPI0_D3 */
-			AM62X_IOPAD(0x01c, PIN_INPUT, 0) /* (J23) OSPI0_D4 */
-			AM62X_IOPAD(0x020, PIN_INPUT, 0) /* (J25) OSPI0_D5 */
-			AM62X_IOPAD(0x024, PIN_INPUT, 0) /* (H25) OSPI0_D6 */
-			AM62X_IOPAD(0x028, PIN_INPUT, 0) /* (J22) OSPI0_D7 */
-			AM62X_IOPAD(0x008, PIN_INPUT, 0) /* (J24) OSPI0_DQS */
-		>;
-	};
-
 	vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
@@ -195,6 +166,14 @@
 	};
 };
 
+&sdhci0 {
+	bootph-all;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc0_pins_default>;
+	disable-wp;
+};
+
 &sdhci1 {
 	vmmc-supply = <&vdd_mmc1>;
 	vqmmc-supply = <&vdd_sd_dv>;
@@ -203,6 +182,11 @@
 &cpsw3g {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_rgmii1_pins_default>, <&main_rgmii2_pins_default>;
+
+	cpts@3d000 {
+		/* MAP HW3_TS_PUSH to GENF1 */
+		ti,pps = <2 1>;
+	};
 };
 
 &cpsw_port2 {
@@ -219,23 +203,11 @@
 	};
 };
 
-&mailbox0_cluster0 {
-	mbox_m4_0: mbox-m4-0 {
-		ti,mbox-rx = <0 0 0>;
-		ti,mbox-tx = <1 0 0>;
-	};
-};
-
 &fss {
 	bootph-all;
 };
 
 &ospi0 {
-	bootph-all;
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&ospi0_pins_default>;
-
 	flash@0 {
 		bootph-all;
 		compatible = "jedec,spi-nor";
@@ -248,6 +220,7 @@
 		cdns,tchsh-ns = <60>;
 		cdns,tslch-ns = <60>;
 		cdns,read-delay = <4>;
+		cdns,phy-mode;
 
 		partitions {
 			bootph-all;
@@ -297,3 +270,10 @@
 &tlv320aic3106 {
 	DVDD-supply = <&vcc_1v8>;
 };
+
+&timesync_router {
+	mux-reg-masks-state = <
+		K3_TS_OFFSET(12, 0x0001ffff, 17)
+		>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-sk-lincolntech-lcd185-panel.dtso b/arch/arm64/boot/dts/ti/k3-am625-sk-lincolntech-lcd185-panel.dtso
--- a/arch/arm64/boot/dts/ti/k3-am625-sk-lincolntech-lcd185-panel.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am625-sk-lincolntech-lcd185-panel.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * Lincoln tech Solutions OLDI panel (LCD185-101CT) and touch DT overlay for AM625-SK
+ *
+ * AM625-SKEVM: https://www.ti.com/tool/SK-AM62
+ * Panel datasheet: https://lincolntechsolutions.com/wp-content/uploads/2023/04/LCD185-101CTL1ARNTT_DS_R1.3.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&{/} {
+	display {
+		compatible = "lincolntech,lcd185-101ct", "panel-simple";
+		/*
+		* Note that the OLDI TX 0 transmits the odd set of pixels
+		* while the OLDI TX 1 transmits the even set. This is a
+		* fixed configuration in the IP integration and is not
+		* changeable. The properties, "dual-lvds-odd-pixels" and
+		* "dual-lvds-even-pixels" have been used to merely
+		* identify if a Dual Link configuration is required.
+		* Swapping them will cause an error in the dss oldi driver.
+		*/
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				dual-lvds-odd-pixels;
+				lcd_in0: endpoint {
+					remote-endpoint = <&oldi_0_out>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				dual-lvds-even-pixels;
+				lcd_in1: endpoint {
+					remote-endpoint = <&oldi_1_out>;
+				};
+			};
+		};
+	};
+};
+
+&dss {
+	status = "okay";
+};
+
+&oldi0 {
+	status = "okay";
+	ti,companion-oldi = <&oldi1>;
+};
+
+&oldi1 {
+	status = "okay";
+	ti,secondary-oldi;
+};
+
+&oldi0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		oldi_0_in: endpoint {
+			remote-endpoint = <&dpi0_out0>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		oldi_0_out: endpoint {
+			remote-endpoint = <&lcd_in0>;
+		};
+	};
+};
+
+&oldi1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		oldi_1_in: endpoint {
+			remote-endpoint = <&dpi0_out1>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		oldi_1_out: endpoint {
+			remote-endpoint = <&lcd_in1>;
+		};
+	};
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* VP1: Output to OLDI */
+	port@0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dpi0_out0: endpoint@0 {
+			reg = <0>;
+			remote-endpoint = <&oldi_0_in>;
+		};
+		dpi0_out1: endpoint@1 {
+			reg = <1>;
+			remote-endpoint = <&oldi_1_in>;
+		};
+	};
+};
+
+&main_i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	eeprom@57 {
+		compatible = "atmel,24c256";
+		reg = <0x57>;
+	};
+
+	touchscreen@5d {
+		compatible = "goodix,gt928";
+		reg = <0x5d>;
+		interrupt-parent = <&exp1>;
+		interrupts = <22 IRQ_TYPE_EDGE_FALLING>;
+		irq-gpios = <&exp1 22 GPIO_ACTIVE_LOW>;
+		touchscreen-size-x = <1920>;
+		touchscreen-size-y = <1200>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-sk-m2-cc3351.dtso b/arch/arm64/boot/dts/ti/k3-am625-sk-m2-cc3351.dtso
--- a/arch/arm64/boot/dts/ti/k3-am625-sk-m2-cc3351.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am625-sk-m2-cc3351.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * DT Overlay for M.2-CC3351 board to connect to the M.2 connector on AM625-SK.
+ *
+ * Product page for board: https://www.ti.com/tool/M2-CC3351
+ * CC3351 Datasheet: https://www.ti.com/lit/ds/symlink/cc3351.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	wlan_lten: regulator-30 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan_lten";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vdd_mmc1>;
+		gpios = <&exp1 11 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	wlan_en: regulator-31 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan_en";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&wlan_lten>;
+		enable-active-high;
+		gpios = <&main_gpio0 71 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wlan_en_pins_default>;
+	};
+};
+
+&main_pmx0 {
+	wlan_en_pins_default: wlan-en-pins-default {
+		pinctrl-single,pins = <
+				AM62X_IOPAD(0x124, PIN_OUTPUT, 7) /* (A23) MMC2_SDCD.GPIO0_71 */
+		>;
+	};
+
+	main_mmc2_pins_default: main-mmc2-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x120, PIN_INPUT, 0) /* (C24) MMC2_CMD */
+			AM62X_IOPAD(0x118, PIN_INPUT, 0) /* (D25) MMC2_CLK */
+			AM62X_IOPAD(0x114, PIN_INPUT, 0) /* (B24) MMC2_DAT0 */
+			AM62X_IOPAD(0x110, PIN_INPUT, 0) /* (C25) MMC2_DAT1 */
+			AM62X_IOPAD(0x10c, PIN_INPUT, 0) /* (E23) MMC2_DAT2 */
+			AM62X_IOPAD(0x108, PIN_INPUT, 0) /* (D24) MMC2_DAT3 */
+			AM62X_IOPAD(0x11c, PIN_INPUT, 0) /* (#N/A) MMC2_CLKB */
+		>;
+	};
+
+	main_wlirq_pins_default: main-wlirq-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x128, PIN_INPUT, 7) /* (B23) MMC2_SDWP.GPIO0_72 */
+		>;
+	};
+};
+
+&sdhci2 {
+	status = "okay";
+	bootph-all;
+	vmmc-supply = <&wlan_en>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc2_pins_default>;
+	bus-width = <4>;
+	non-removable;
+	ti,fails-without-test-cd;
+	cap-power-off-card;
+	keep-power-in-suspend;
+	ti,driver-strength-ohm = <50>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	wifi: cc3300@2 {
+		compatible = "ti,cc3300";
+		reg = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_wlirq_pins_default>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <72 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-sk-mcspi-loopback.dtso b/arch/arm64/boot/dts/ti/k3-am625-sk-mcspi-loopback.dtso
--- a/arch/arm64/boot/dts/ti/k3-am625-sk-mcspi-loopback.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am625-sk-mcspi-loopback.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,55 @@
+
+
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT Overlay for using McSPI on the RPi header on AM625-SK board.
+ *
+ * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+	main_spi0_pins_default: main-spi0-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01bc, PIN_INPUT, 0) /* (A14) SPI0_CLK */
+			AM62X_IOPAD(0x01c0, PIN_INPUT, 0) /* (B13) SPI0_D0 */
+			AM62X_IOPAD(0x01c4, PIN_INPUT, 0) /* (B14) SPI0_D1 */
+			AM62X_IOPAD(0x01b4, PIN_INPUT, 0) /* (A13) SPI0_CS0 */
+		>;
+	};
+};
+
+&main_i2c1 {
+	gpio@22 {
+		en_rpi_3v3 {
+			gpio-hog;
+			gpios = <5 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "EXP_PS_3V3_EN";
+		};
+	};
+};
+
+&main_spi0 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-0 = <&main_spi0_pins_default>;
+	pinctrl-names = "default";
+	spidev@0 {
+		/*
+		 * Using spidev compatible is warned loudly,
+		 * thus use another equivalent compatible id
+		 * from spidev.
+		 */
+		compatible = "rohm,dh2228fv";
+		spi-max-frequency = <24000000>;
+		reg = <0>;
+	};
+};
+
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-sk-microtips-mf101hie-panel.dtso b/arch/arm64/boot/dts/ti/k3-am625-sk-microtips-mf101hie-panel.dtso
--- a/arch/arm64/boot/dts/ti/k3-am625-sk-microtips-mf101hie-panel.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am625-sk-microtips-mf101hie-panel.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * Microtips integrated OLDI panel (MF-101HIEBCAF0) and touch DT overlay for AM625 - SK
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "k3-pinctrl.h"
+
+&{/} {
+	display {
+		compatible = "microtips,mf-101hiebcaf0", "panel-simple";
+		/*
+		* Note that the OLDI TX 0 transmits the odd set of pixels
+		* while the OLDI TX 1 transmits the even set. This is a
+		* fixed configuration in the IP integration and is not
+		* changeable. The properties, "dual-lvds-odd-pixels" and
+		* "dual-lvds-even-pixels" have been used to merely
+		* identify if a Dual Link configuration is required.
+		* Swapping them will cause an error in the dss oldi driver.
+		*/
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				dual-lvds-odd-pixels;
+				lcd_in0: endpoint {
+					remote-endpoint = <&oldi_0_out>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				dual-lvds-even-pixels;
+				lcd_in1: endpoint {
+					remote-endpoint = <&oldi_1_out>;
+				};
+			};
+		};
+	};
+};
+
+&dss {
+	status = "okay";
+};
+
+&oldi0 {
+	status = "okay";
+	ti,companion-oldi = <&oldi1>;
+};
+
+&oldi1 {
+	status = "okay";
+	ti,secondary-oldi;
+};
+
+&oldi0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		oldi_0_in: endpoint {
+			remote-endpoint = <&dpi0_out0>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		oldi_0_out: endpoint {
+			remote-endpoint = <&lcd_in0>;
+		};
+	};
+};
+
+&oldi1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		oldi_1_in: endpoint {
+			remote-endpoint = <&dpi0_out1>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		oldi_1_out: endpoint {
+			remote-endpoint = <&lcd_in1>;
+		};
+	};
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* VP1: Output to OLDI */
+	port@0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dpi0_out0: endpoint@0 {
+			reg = <0>;
+			remote-endpoint = <&oldi_0_in>;
+		};
+		dpi0_out1: endpoint@1 {
+			reg = <1>;
+			remote-endpoint = <&oldi_1_in>;
+		};
+	};
+};
+
+&main_i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	touchscreen@41 {
+		compatible = "ilitek,ili251x";
+		reg = <0x41>;
+		interrupt-parent = <&exp1>;
+		interrupts = <22 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-sk-rpi-hdr-ehrpwm.dtso b/arch/arm64/boot/dts/ti/k3-am625-sk-rpi-hdr-ehrpwm.dtso
--- a/arch/arm64/boot/dts/ti/k3-am625-sk-rpi-hdr-ehrpwm.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am625-sk-rpi-hdr-ehrpwm.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT Overlay for enabling RPi header with GPIOs and ePWMs for AM625-SK
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+	rpi_header_gpio0_pins_default: rpi-header-gpio0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0038, PIN_INPUT, 7) /* (E24) OSPI0_CSn3.GPIO0_14 */
+			AM62X_IOPAD(0x0088, PIN_INPUT, 7) /* (L24) GPMC0_OEn_REn.GPIO0_33 */
+			AM62X_IOPAD(0x0094, PIN_INPUT, 7) /* (N20) GPMC0_BE1n.GPIO0_36 */
+			AM62X_IOPAD(0x009c, PIN_INPUT, 7) /* (V25) GPMC0_WAIT1.GPIO0_38 */
+			AM62X_IOPAD(0x00a0, PIN_INPUT, 7) /* (K25) GPMC0_WPn.GPIO0_39 */
+			AM62X_IOPAD(0x00a4, PIN_INPUT, 7) /* (M22) GPMC0_DIR.GPIO0_40 */
+			AM62X_IOPAD(0x00a8, PIN_INPUT, 7) /* (M21) GPMC0_CSn0.GPIO0_41 */
+			AM62X_IOPAD(0x00ac, PIN_INPUT, 7) /* (L21) GPMC0_CSn1.GPIO0_42 */
+		>;
+	};
+
+	rpi_header_gpio1_pins_default: rpi-header-gpio1-default-pins{
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01d0, PIN_INPUT, 7) /* (A15) UART0_CTSn.GPIO1_22 */
+		>;
+	};
+
+	rpi_header_ehrpwm0_pins_default: rpi-header-ehrpwm0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01ac, PIN_OUTPUT, 6) /* (E19) MCASP0_AFSR.EHRPWM0_A */
+			AM62X_IOPAD(0x01b0, PIN_OUTPUT, 6) /* (A20) MCASP0_ACLKR.EHRPWM0_B */
+		>;
+	};
+
+	rpi_header_ehrpwm1_pins_default: rpi-header-ehrpwm1-default-pins{
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x019c, PIN_OUTPUT, 6) /* (B18) MCASP0_AXR1.EHRPWM1_A */
+			AM62X_IOPAD(0x01a0, PIN_OUTPUT, 6) /* (E18) MCASP0_AXR0.EHRPWM1_B */
+		>;
+	};
+};
+
+&main_uart1 {
+	/* Disable FW debug logs */
+	status = "disabled";
+};
+
+&main_i2c1 {
+	gpio@22 {
+		p05-hog {
+			/* P05 - EXP_PS_3V3_EN */
+			gpio-hog;
+			gpios = <5 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "EXP_PS_3V3_EN";
+		};
+
+		p06-hog {
+			/* P06 - EXP_PS_5V0_EN */
+			gpio-hog;
+			gpios = <6 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "EXP_PS_5V0_EN";
+		};
+
+		p25-hog {
+			/* P25 - UART1_FET_SEL */
+			gpio-hog;
+			gpios = <21 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "UART1_FET_SEL";
+		};
+	};
+};
+
+&epwm0 {
+	/* Pin 12/40 of J3 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&rpi_header_ehrpwm0_pins_default>;
+	status = "okay";
+};
+
+&epwm1 {
+	/* Pin 36/33 of J3 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&rpi_header_ehrpwm1_pins_default>;
+	status = "okay";
+};
+
+&main_gpio0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rpi_header_gpio0_pins_default>;
+};
+
+&main_gpio1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rpi_header_gpio1_pins_default>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-verdin-nonwifi-ivy.dts b/arch/arm64/boot/dts/ti/k3-am625-verdin-nonwifi-ivy.dts
--- a/arch/arm64/boot/dts/ti/k3-am625-verdin-nonwifi-ivy.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am625-verdin-nonwifi-ivy.dts	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2024 Toradex
+ *
+ * https://www.toradex.com/computer-on-modules/verdin-arm-family/ti-am62
+ * https://www.toradex.com/products/carrier-board/ivy-carrier-board
+ */
+
+/dts-v1/;
+
+#include "k3-am625.dtsi"
+#include "k3-am62-verdin.dtsi"
+#include "k3-am62-verdin-nonwifi.dtsi"
+#include "k3-am62-verdin-ivy.dtsi"
+
+/ {
+	model = "Toradex Verdin AM62 on Ivy Board";
+	compatible = "toradex,verdin-am62-nonwifi-ivy",
+		     "toradex,verdin-am62-nonwifi",
+		     "toradex,verdin-am62",
+		     "ti,am625";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am625-verdin-wifi-ivy.dts b/arch/arm64/boot/dts/ti/k3-am625-verdin-wifi-ivy.dts
--- a/arch/arm64/boot/dts/ti/k3-am625-verdin-wifi-ivy.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am625-verdin-wifi-ivy.dts	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2024 Toradex
+ *
+ * https://www.toradex.com/computer-on-modules/verdin-arm-family/ti-am62
+ * https://www.toradex.com/products/carrier-board/ivy-carrier-board
+ */
+
+/dts-v1/;
+
+#include "k3-am625.dtsi"
+#include "k3-am62-verdin.dtsi"
+#include "k3-am62-verdin-wifi.dtsi"
+#include "k3-am62-verdin-ivy.dtsi"
+
+/ {
+	model = "Toradex Verdin AM62 WB on Ivy Board";
+	compatible = "toradex,verdin-am62-wifi-ivy",
+		     "toradex,verdin-am62-wifi",
+		     "toradex,verdin-am62",
+		     "ti,am625";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a7.dtsi b/arch/arm64/boot/dts/ti/k3-am62a7.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62a7.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62a7.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -48,6 +48,8 @@
 			d-cache-line-size = <64>;
 			d-cache-sets = <128>;
 			next-level-cache = <&L2_0>;
+			operating-points-v2 = <&a53_opp_table>;
+			clocks = <&k3_clks 135 0>;
 		};
 
 		cpu1: cpu@1 {
@@ -62,6 +64,8 @@
 			d-cache-line-size = <64>;
 			d-cache-sets = <128>;
 			next-level-cache = <&L2_0>;
+			operating-points-v2 = <&a53_opp_table>;
+			clocks = <&k3_clks 136 0>;
 		};
 
 		cpu2: cpu@2 {
@@ -76,6 +80,8 @@
 			d-cache-line-size = <64>;
 			d-cache-sets = <128>;
 			next-level-cache = <&L2_0>;
+			operating-points-v2 = <&a53_opp_table>;
+			clocks = <&k3_clks 137 0>;
 		};
 
 		cpu3: cpu@3 {
@@ -90,6 +96,51 @@
 			d-cache-line-size = <64>;
 			d-cache-sets = <128>;
 			next-level-cache = <&L2_0>;
+			operating-points-v2 = <&a53_opp_table>;
+			clocks = <&k3_clks 138 0>;
+		};
+	};
+
+	a53_opp_table: opp-table {
+		compatible = "operating-points-v2-ti-cpu";
+		opp-shared;
+		syscon = <&opp_efuse_table>;
+
+		opp-200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+			opp-supported-hw = <0x01 0x0007>;
+			clock-latency-ns = <6000000>;
+		};
+
+		opp-400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x01 0x0007>;
+			clock-latency-ns = <6000000>;
+		};
+
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x01 0x0007>;
+			clock-latency-ns = <6000000>;
+		};
+
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-supported-hw = <0x01 0x0007>;
+			clock-latency-ns = <6000000>;
+		};
+
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-supported-hw = <0x01 0x0006>;
+			clock-latency-ns = <6000000>;
+		};
+
+		opp-1250000000 {
+			opp-hz = /bits/ 64 <1250000000>;
+			opp-supported-hw = <0x01 0x0004>;
+			clock-latency-ns = <6000000>;
+			opp-suspend;
 		};
 	};
 
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a7-phyboard-lyra-rdk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-phyboard-lyra-rdk.dts
--- a/arch/arm64/boot/dts/ti/k3-am62a7-phyboard-lyra-rdk.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-phyboard-lyra-rdk.dts	2025-10-23 09:30:40.282462115 -0400
@@ -16,3 +16,7 @@
 		     "phytec,am62a-phycore-som", "ti,am62a7";
 	model = "PHYTEC phyBOARD-Lyra AM62A7";
 };
+
+&cpsw3g_phy3 {
+	ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a7-sk-csi2-ox05b1s.dtso b/arch/arm64/boot/dts/ti/k3-am62a7-sk-csi2-ox05b1s.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk-csi2-ox05b1s.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk-csi2-ox05b1s.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OX05B1S Camera Module
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_ox05b1s_fixed: ox05b1s-xclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&main_i2c2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	i2c-switch@71 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x71>;
+
+		/* CAM port */
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+
+			ox05b1s: camera@36 {
+				compatible = "ovti,ox05b";
+				reg = <0x36>;
+
+				clocks = <&clk_ox05b1s_fixed>;
+				clock-names = "inck";
+
+				pwdn-gpios = <&exp1 13 GPIO_ACTIVE_LOW>;
+
+				port {
+					csi2_cam0: endpoint {
+						remote-endpoint = <&csi2rx0_in_sensor>;
+						link-frequencies = /bits/ 64 <480000000>;
+						clock-lanes = <0>;
+						data-lanes = <1 2 3 4>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx0_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam0>;
+				bus-type = <4>; /* CSI2 DPHY. */
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts	2025-10-23 09:30:40.282462115 -0400
@@ -12,16 +12,23 @@
 #include <dt-bindings/net/ti-dp83867.h>
 #include "k3-am62a7.dtsi"
 
+#include "k3-timesync-router.h"
+
 / {
 	compatible = "ti,am62a7-sk", "ti,am62a7";
 	model = "Texas Instruments AM62A7 SK";
 
 	aliases {
 		serial0 = &wkup_uart0;
+		serial1 = &mcu_uart0;
 		serial2 = &main_uart0;
 		serial3 = &main_uart1;
 		mmc0 = &sdhci0;
 		mmc1 = &sdhci1;
+		rtc0 = &wkup_rtc0;
+		rtc1 = &tps659312;
+		ethernet0 = &cpsw_port1;
+		spi0 = &ospi0;
 	};
 
 	chosen {
@@ -49,6 +56,42 @@
 			linux,cma-default;
 		};
 
+		c7x_0_dma_memory_region: c7x-dma-memory@99800000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x99800000 0x00 0x100000>;
+			no-map;
+		};
+
+		c7x_0_memory_region: c7x-memory@99900000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x99900000 0x00 0xf00000>;
+			no-map;
+		};
+
+		mcu_r5fss0_core0_dma_memory_region: r5f-dma-memory@9b800000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9b800000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_r5fss0_core0_memory_region: r5f-dma-memory@9b900000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9b900000 0x00 0xf00000>;
+			no-map;
+		};
+
+		wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@9c800000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9c800000 0x00 0x100000>;
+			no-map;
+		};
+
+		wkup_r5fss0_core0_memory_region: r5f-dma-memory@9c900000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9c900000 0x00 0x1e00000>;
+			no-map;
+		};
+
 		secure_tfa_ddr: tfa@9e780000 {
 			reg = <0x00 0x9e780000 0x00 0x80000>;
 			alignment = <0x1000>;
@@ -61,13 +104,22 @@
 			no-map;
 		};
 
-		wkup_r5fss0_core0_memory_region: r5f-dma-memory@9c900000 {
+		rtos_ipc_memory_region: ipc-memories@a0000000 {
 			compatible = "shared-dma-pool";
-			reg = <0x00 0x9c900000 0x00 0x01e00000>;
+			reg = <0x00 0xa0000000 0x00 0x01000000>;
 			no-map;
 		};
 	};
 
+	opp-table {
+		/* Requires VDD_CORE at 0v85 */
+		opp-1400000000 {
+			opp-hz = /bits/ 64 <1400000000>;
+			opp-supported-hw = <0x01 0x0004>;
+			clock-latency-ns = <6000000>;
+		};
+	};
+
 	vmain_pd: regulator-0 {
 		/* TPS25750 PD CONTROLLER OUTPUT */
 		compatible = "regulator-fixed";
@@ -288,6 +340,7 @@
 	};
 
 	main_mmc0_pins_default: main-mmc0-default-pins {
+		bootph-all;
 		pinctrl-single,pins = <
 			AM62AX_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */
 			AM62AX_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLKLB */
@@ -371,6 +424,23 @@
 			AM62AX_IOPAD(0x07c, PIN_OUTPUT, 7) /* (M19) GPMC0_CLK.GPIO0_31 */
 		>;
 	};
+
+	ospi0_pins_default: ospi0-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x0000, PIN_OUTPUT, 0) /* (L22) OSPI0_CLK */
+			AM62AX_IOPAD(0x002c, PIN_OUTPUT, 0) /* (H21) OSPI0_CSn0 */
+			AM62AX_IOPAD(0x000c, PIN_INPUT, 0) /* (J21) OSPI0_D0 */
+			AM62AX_IOPAD(0x0010, PIN_INPUT, 0) /* (J18) OSPI0_D1 */
+			AM62AX_IOPAD(0x0014, PIN_INPUT, 0) /* (J19) OSPI0_D2 */
+			AM62AX_IOPAD(0x0018, PIN_INPUT, 0) /* (H18) OSPI0_D3 */
+			AM62AX_IOPAD(0x001c, PIN_INPUT, 0) /* (K21) OSPI0_D4 */
+			AM62AX_IOPAD(0x0020, PIN_INPUT, 0) /* (H19) OSPI0_D5 */
+			AM62AX_IOPAD(0x0024, PIN_INPUT, 0) /* (J20) OSPI0_D6 */
+			AM62AX_IOPAD(0x0028, PIN_INPUT, 0) /* (J22) OSPI0_D7 */
+			AM62AX_IOPAD(0x0008, PIN_INPUT, 0) /* (L21) OSPI0_DQS */
+		>;
+	};
 };
 
 &mcu_pmx0 {
@@ -598,6 +668,7 @@
 
 &sdhci0 {
 	/* eMMC */
+	bootph-all;
 	status = "okay";
 	non-removable;
 	pinctrl-names = "default";
@@ -631,6 +702,9 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_uart0_pins_default>;
+	interrupts-extended = <&gic500 GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>,
+			<&main_pmx0 0x1c8>; /* (D14) UART0_RXD PADCONFIG114 */
+	interrupt-names = "irq", "wakeup";
 };
 
 /* Main UART1 is used for TIFS firmware logs */
@@ -640,6 +714,11 @@
 	status = "reserved";
 };
 
+/* main_timer2 is used by C7x DSP */
+&main_timer2 {
+	status = "reserved";
+};
+
 &usbss0 {
 	status = "okay";
 	ti,vbus-divider;
@@ -669,6 +748,11 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_rgmii1_pins_default>;
+
+	cpts@3d000 {
+		/* MAP HW3_TS_PUSH to GENF1 */
+		ti,pps = <2 1>;
+	};
 };
 
 &cpsw_port1 {
@@ -694,6 +778,74 @@
 	};
 };
 
+&fss {
+	status = "okay";
+};
+
+&ospi0 {
+	bootph-all;
+	pinctrl-names = "default";
+	pinctrl-0 = <&ospi0_pins_default>;
+
+	flash@0{
+		compatible = "spi-nand";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <2>;
+		cdns,phy-mode;
+		bootph-all;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			bootph-all;
+
+			partition@0 {
+				label = "ospi_nand.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition@80000 {
+				label = "ospi_nand.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition@280000 {
+				label = "ospi_nand.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition@680000 {
+				label = "ospi_nand.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition@6c0000 {
+				label = "ospi_nand.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition@2000000 {
+				label = "ospi_nand.rootfs";
+				reg = <0x2000000 0x5fc0000>;
+			};
+
+			partition@7fc0000 {
+				label = "ospi_nand.phypattern";
+				reg = <0x7fc0000 0x40000>;
+				bootph-all;
+			};
+		};
+	};
+};
+
 &mcasp1 {
 	status = "okay";
 	#sound-dai-cells = <0>;
@@ -720,7 +872,7 @@
 
 &dss_ports {
 	/* VP2: DPI Output */
-	port@1 {
+	hdmi0_dss: port@1 {
 		reg = <1>;
 
 		dpi1_out: endpoint {
@@ -728,3 +880,65 @@
 		};
 	};
 };
+
+&mailbox0_cluster0 {
+	mbox_r5_0: mbox-r5-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&mailbox0_cluster1 {
+	mbox_c7x_0: mbox-c7x-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&mailbox0_cluster2 {
+	mbox_mcu_r5_0: mbox-mcu-r5-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&wkup_r5fss0 {
+	status = "okay";
+};
+
+&wkup_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster0>, <&mbox_r5_0>;
+	memory-region = <&wkup_r5fss0_core0_dma_memory_region>,
+			<&wkup_r5fss0_core0_memory_region>;
+};
+
+&mcu_r5fss0 {
+	status = "okay";
+};
+
+&mcu_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster2>, <&mbox_mcu_r5_0>;
+	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
+			<&mcu_r5fss0_core0_memory_region>;
+};
+
+&c7x_0 {
+	mboxes = <&mailbox0_cluster1>, <&mbox_c7x_0>;
+	memory-region = <&c7x_0_dma_memory_region>,
+			<&c7x_0_memory_region>;
+	status = "okay";
+};
+
+/* main_rti4 is used by C7x DSP */
+&main_rti4 {
+	status = "reserved";
+};
+
+&timesync_router {
+	/* Use Time Sync Router to map GENF1 input to HW3_TS_PUSH output */
+	mux-reg-masks-state = <
+		/* pps [cpsw cpts genf1] in17 -> out12 [cpsw cpts hw3_push] */
+		K3_TS_OFFSET(12, 0x0001ffff, 17)
+		>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a7-sk-e3-max-opp.dtso b/arch/arm64/boot/dts/ti/k3-am62a7-sk-e3-max-opp.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk-e3-max-opp.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk-e3-max-opp.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay to run AM62A7-SK Rev E3 board at maximum performance
+ * Requires VDD_CORE to be at 0.85V
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	opp-table {
+		/*
+		 * Add 1.4GHz and disable lower OPPs for max A53 performance
+		 * Only for AM62A7-SK Rev E3 board
+		 * Requires VDD_CORE to be at 0.85V
+		 */
+		opp-200000000 {
+			status = "disabled";
+		};
+
+		opp-400000000 {
+			status = "disabled";
+		};
+
+		opp-600000000 {
+			status = "disabled";
+		};
+
+		opp-800000000 {
+			status = "disabled";
+		};
+
+		opp-1000000000 {
+			status = "disabled";
+		};
+
+		opp-1250000000 {
+			status = "disabled";
+		};
+
+		opp-1400000000 {
+			opp-hz = /bits/ 64 <1400000000>;
+			opp-supported-hw = <0x01 0x0004>;
+			clock-latency-ns = <6000000>;
+		};
+	};
+};
+
+&c7x_0 {
+	/*
+	 * Override C7x frequency to 1 GHz for max performance
+	 * Only for AM62A7-SK Rev E3 board
+	 * Requires VDD_CORE to be at 0.85V
+	 */
+	clocks = <&k3_clks 208 0>;
+	assigned-clocks = <&k3_clks 208 0>;
+	assigned-clock-rates = <1000000000>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a7-sk-edgeai.dtso b/arch/arm64/boot/dts/ti/k3-am62a7-sk-edgeai.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk-edgeai.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk-edgeai.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT overlay for AM62A edgeAI carveouts
+ * Copyright (C) 2023-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+&{/reserved-memory} {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	ranges;
+
+	edgeai_memory_region: edgeai-dma-memory@a1000000 {
+		compatible = "shared-dma-pool";
+		reg = <0x00 0xa1000000 0x00 0x02000000>;
+		no-map;
+	};
+
+	edgeai_shared_region: edgeai_shared-memories {
+		compatible = "dma-heap-carveout";
+		reg = <0x00 0xa3000000 0x00 0x0ac00000>;
+	};
+
+	edgeai_core_heaps: edgeai-core-heap-memory@adc00000 {
+		compatible = "shared-dma-pool";
+		reg = <0x00 0xadc00000 0x00 0x12400000>;
+		no-map;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a7-sk-ethernet-dc01.dtso b/arch/arm64/boot/dts/ti/k3-am62a7-sk-ethernet-dc01.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk-ethernet-dc01.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk-ethernet-dc01.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT Overlay for second CPSW3G port in RGMII mode using SK-ETHERNET-DC01
+ * Add-On Daughtercard with AM62A7-SK.
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	aliases {
+		ethernet1 = "/bus@f0000/ethernet@8000000/ethernet-ports/port@2";
+	};
+};
+
+&cpsw3g {
+	pinctrl-0 = <&main_rgmii1_pins_default>, <&main_rgmii2_pins_default>;
+};
+
+&cpsw_port2 {
+	status = "okay";
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&cpsw3g_phy1>;
+};
+
+&cpsw3g_mdio {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	cpsw3g_phy1: ethernet-phy@1 {
+		reg = <1>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		ti,min-output-impedance;
+	};
+};
+
+&main_pmx0 {
+	main_rgmii2_pins_default: main-rgmii2-default-pins {
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x0184, PIN_INPUT, 0) /* (AA21) RGMII2_RD0 */
+			AM62AX_IOPAD(0x0188, PIN_INPUT, 0) /* (Y20) RGMII2_RD1 */
+			AM62AX_IOPAD(0x018c, PIN_INPUT, 0) /* (AB21) RGMII2_RD2 */
+			AM62AX_IOPAD(0x0190, PIN_INPUT, 0) /* (AB20) RGMII2_RD3 */
+			AM62AX_IOPAD(0x0180, PIN_INPUT, 0) /* (AA20) RGMII2_RXC */
+			AM62AX_IOPAD(0x017c, PIN_INPUT, 0) /* (W18) RGMII2_RX_CTL */
+			AM62AX_IOPAD(0x016c, PIN_INPUT, 0) /* (AA19) RGMII2_TD0 */
+			AM62AX_IOPAD(0x0170, PIN_INPUT, 0) /* (Y18) RGMII2_TD1 */
+			AM62AX_IOPAD(0x0174, PIN_INPUT, 0) /* (AA18) RGMII2_TD2 */
+			AM62AX_IOPAD(0x0178, PIN_INPUT, 0) /* (W17) RGMII2_TD3 */
+			AM62AX_IOPAD(0x0168, PIN_INPUT, 0) /* (AB19) RGMII2_TXC */
+			AM62AX_IOPAD(0x0164, PIN_INPUT, 0) /* (Y19) RGMII2_TX_CTL */
+		>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a7-sk-fusion-2.dtso b/arch/arm64/boot/dts/ti/k3-am62a7-sk-fusion-2.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk-fusion-2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk-fusion-2.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * DT Overlay for Fusion 2 (FPD-Link IV) board on SK-AM62A
+ * https://www.ti.com/tool/J7EXPA01EVM
+ *
+ * Copyright (C) 2024 D3 Embedded - https://www.d3embedded.com
+ */
+
+ /dts-v1/;
+ /plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_fusion2_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&exp2 {
+	p9-hog {
+		/* P9 - CSI_RSTz */
+		gpio-hog;
+		gpios = <9 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI_RSTz";
+	};
+
+	p19-hog {
+		/* P19 -CSI_SEL2 */
+		gpio-hog;
+		gpios = <19 GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "CSI_SEL2";
+	};
+};
+
+&main_i2c2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	i2c-switch@71 {
+		compatible = "nxp,pca9543";
+		reg = <0x71>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			deser@3d {
+				compatible = "ti,ds90ub9702-q1";
+				reg = <0x3d>;
+
+				clock-names = "refclk";
+				clocks = <&clk_fusion2_25M_fixed>;
+
+				i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+				deserializer_0_ports: ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					/* CSI-2 TX */
+					port@4 {
+						reg = <4>;
+						ds90ub9702_0_csi_out: endpoint {
+							data-lanes = <1 2 3 4>;
+							clock-lanes = <0>;
+							link-frequencies = /bits/ 64 <800000000>;
+							remote-endpoint = <&csi2_phy0>;
+						};
+					};
+				};
+
+				deserializer_0_links: links {
+					#address-cells = <1>;
+					#size-cells = <0>;
+				};
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub9702_0_csi_out>;
+				data-lanes = <1 2 3 4>;
+				clock-lanes = <0>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a7-sk-fusion.dtso b/arch/arm64/boot/dts/ti/k3-am62a7-sk-fusion.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk-fusion.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk-fusion.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Fusion (FPD-Link III) board on SK-AM62A
+ * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&exp2 {
+	p19-hog {
+		/* P19 - CSI_SEL2 */
+		gpio-hog;
+		gpios = <19 GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "CSI_SEL2";
+	};
+};
+
+&main_i2c2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	i2c-switch@71 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x71>;
+
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+
+			deser@3d {
+				compatible = "ti,ds90ub960-q1";
+				reg = <0x3d>;
+
+				clock-names = "refclk";
+				clocks = <&clk_fusion_25M_fixed>;
+
+				i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+				deserializer_0_ports: ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					/* CSI-2 TX */
+					port@4 {
+						reg = <4>;
+						ds90ub960_0_csi_out: endpoint {
+							data-lanes = <1 2 3 4>;
+							clock-lanes = <0>;
+							link-frequencies = /bits/ 64 <800000000>;
+							remote-endpoint = <&csi2_phy0>;
+						};
+					};
+				};
+
+				deserializer_0_links: links {
+					#address-cells = <1>;
+					#size-cells = <0>;
+				};
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub960_0_csi_out>;
+				data-lanes = <1 2 3 4>;
+				clock-lanes = <0>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a7-sk-m2-cc3351.dtso b/arch/arm64/boot/dts/ti/k3-am62a7-sk-m2-cc3351.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk-m2-cc3351.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk-m2-cc3351.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * DT Overlay for M.2-CC3351 board to connect to the M.2 connector on AM625-SK.
+ *
+ * Product page for board: https://www.ti.com/tool/M2-CC3351
+ * CC3351 Datasheet: https://www.ti.com/lit/ds/symlink/cc3351.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	wlan_lten: regulator-30 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan_lten";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vdd_mmc1>;
+		gpios = <&exp1 11 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	wlan_en: regulator-31 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan_en";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&wlan_lten>;
+		enable-active-high;
+		gpios = <&main_gpio0 71 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wlan_en_pins_default>;
+	};
+};
+
+&main_pmx0 {
+	wlan_en_pins_default: wlan-en-pins-default {
+		pinctrl-single,pins = <
+				AM62X_IOPAD(0x124, PIN_OUTPUT, 7) /* (A23) MMC2_SDCD.GPIO0_71 */
+		>;
+	};
+
+	main_mmc2_pins_default: main-mmc2-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x120, PIN_INPUT, 0) /* (C24) MMC2_CMD */
+			AM62X_IOPAD(0x118, PIN_INPUT, 0) /* (D25) MMC2_CLK */
+			AM62X_IOPAD(0x114, PIN_INPUT, 0) /* (B24) MMC2_DAT0 */
+			AM62X_IOPAD(0x110, PIN_INPUT, 0) /* (C25) MMC2_DAT1 */
+			AM62X_IOPAD(0x10c, PIN_INPUT, 0) /* (E23) MMC2_DAT2 */
+			AM62X_IOPAD(0x108, PIN_INPUT, 0) /* (D24) MMC2_DAT3 */
+			AM62X_IOPAD(0x11c, PIN_INPUT, 0) /* (#N/A) MMC2_CLKB */
+		>;
+	};
+
+	main_wlirq_pins_default: main-wlirq-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x128, PIN_INPUT, 7) /* (B23) MMC2_SDWP.GPIO0_72 */
+		>;
+	};
+};
+
+&sdhci2 {
+	status = "okay";
+	bootph-all;
+	vmmc-supply = <&wlan_en>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc2_pins_default>;
+	bus-width = <4>;
+	non-removable;
+	ti,fails-without-test-cd;
+	cap-power-off-card;
+	keep-power-in-suspend;
+	ti,driver-strength-ohm = <50>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	wifi: cc33xx@2 {
+		compatible = "ti,cc3300";
+		reg = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_wlirq_pins_default>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <72 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a7-sk-rpi-hdr-ehrpwm.dtso b/arch/arm64/boot/dts/ti/k3-am62a7-sk-rpi-hdr-ehrpwm.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk-rpi-hdr-ehrpwm.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk-rpi-hdr-ehrpwm.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT Overlay for enabling RPi header with GPIOs and ePWMs on AM62A-SK
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+	rpi_header_gpio0_pins_default: rpi-header-gpio0-default-pins {
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x0038, PIN_INPUT, 7) /* (G20) OSPI0_CSn3.GPIO0_14 */
+			AM62AX_IOPAD(0x0088, PIN_INPUT, 7) /* (L17) GPMC0_OEn_REn.GPIO0_33 */
+			AM62AX_IOPAD(0x0094, PIN_INPUT, 7) /* (M18) GPMC0_BE1n.GPIO0_36 */
+			AM62AX_IOPAD(0x009c, PIN_INPUT, 7) /* (R17) GPMC0_WAIT1.GPIO0_38 */
+			AM62AX_IOPAD(0x00a0, PIN_INPUT, 7) /* (K17) GPMC0_WPn.GPIO0_39 */
+			AM62AX_IOPAD(0x00a4, PIN_INPUT, 7) /* (K18) GPMC0_DIR.GPIO0_40 */
+			AM62AX_IOPAD(0x00a8, PIN_INPUT, 7) /* (M19) GPMC0_CSn0.GPIO0_41 */
+			AM62AX_IOPAD(0x00ac, PIN_INPUT, 7) /* (M21) GPMC0_CSn1.GPIO0_42 */
+		>;
+	};
+
+	rpi_header_gpio1_pins_default: rpi-header-gpio1-default-pins{
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x0194, PIN_INPUT, 7) /* (C19) MCASP0_AXR3.GPIO1_7 */
+			AM62AX_IOPAD(0x0198, PIN_INPUT, 7) /* (B19) MCASP0_AXR2.GPIO1_8 */
+			AM62AX_IOPAD(0x01a4, PIN_INPUT, 7) /* (A19) MCASP0_ACLKX.GPIO1_11 */
+			AM62AX_IOPAD(0x01b4, PIN_INPUT, 7) /* (D16) SPI0_CS0.GPIO1_15 */
+			AM62AX_IOPAD(0x01b8, PIN_INPUT, 7) /* (C16) SPI0_CS1.GPIO1_16 */
+			AM62AX_IOPAD(0x01bc, PIN_INPUT, 7) /* (A17) SPI0_CLK.GPIO1_17 */
+			AM62AX_IOPAD(0x01c0, PIN_INPUT, 7) /* (B15) SPI0_D0.GPIO1_18 */
+			AM62AX_IOPAD(0x01c4, PIN_INPUT, 7) /* (E15) SPI0_D1.GPIO1_19 */
+			AM62AX_IOPAD(0x01d0, PIN_INPUT, 7) /* (F14) UART0_CTSn.GPIO1_22 */
+			AM62AX_IOPAD(0x01d8, PIN_INPUT, 7) /* (B17) MCAN0_TX.GPIO1_24 */
+			AM62AX_IOPAD(0x01dc, PIN_INPUT, 7) /* (C18) MCAN0_RX.GPIO1_25 */
+		>;
+	};
+
+	rpi_header_ehrpwm0_pins_default: rpi-header-ehrpwm0-default-pins {
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x01ac, PIN_OUTPUT, 6) /* (B21) MCASP0_AFSR.EHRPWM0_A */
+			AM62AX_IOPAD(0x01b0, PIN_OUTPUT, 6) /* (A21) MCASP0_ACLKR.EHRPWM0_B */
+		>;
+	};
+
+	rpi_header_ehrpwm1_pins_default: rpi-header-ehrpwm1-default-pins {
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x019c, PIN_OUTPUT, 6) /* (B18) MCASP0_AXR1.EHRPWM1_A */
+			AM62AX_IOPAD(0x01a0, PIN_OUTPUT, 6) /* (B20) MCASP0_AXR0.EHRPWM1_B */
+		>;
+	};
+};
+
+&main_uart1 {
+	/* Disable FW debug logs */
+	status = "disabled";
+};
+
+&main_i2c1 {
+	gpio@22 {
+		p05-hog {
+			/* P05 - EXP_PS_3V3_EN */
+			gpio-hog;
+			gpios = <5 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "EXP_PS_3V3_EN";
+		};
+
+		p06-hog {
+			/* P06 - EXP_PS_5V0_EN */
+			gpio-hog;
+			gpios = <6 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "EXP_PS_5V0_EN";
+		};
+
+		p25-hog {
+			/* P25 - UART1_FET_SEL */
+			gpio-hog;
+			gpios = <21 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "UART1_FET_SEL";
+		};
+	};
+};
+
+&epwm0 {
+	/* Pin 35/12 of J3 */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rpi_header_ehrpwm0_pins_default>;
+};
+
+&epwm1 {
+	/* Pin 36/33 of J3 */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rpi_header_ehrpwm1_pins_default>;
+};
+
+&main_gpio0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rpi_header_gpio0_pins_default>;
+};
+
+&main_gpio1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rpi_header_gpio1_pins_default>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a7-sk-ub954-evm.dtso b/arch/arm64/boot/dts/ti/k3-am62a7-sk-ub954-evm.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk-ub954-evm.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk-ub954-evm.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for DS90UB954-Q1EVM FPDLink-III deserializer board on SK-AM62A
+ * https://www.ti.com/tool/DS90UB954-Q1EVM
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&exp2 {
+	p19-hog {
+		/* P19 - CSI_SEL2 */
+		gpio-hog;
+		gpios = <19 GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "CSI_SEL2";
+	};
+};
+
+&main_i2c2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	i2c-switch@71 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x71>;
+
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+
+			deser@3d {
+				compatible = "ti,ds90ub954-q1";
+				reg = <0x3d>;
+
+				clock-names = "refclk";
+				clocks = <&clk_fusion_25M_fixed>;
+
+				i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+				deserializer_0_ports: ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					/* CSI-2 TX */
+					port@2 {
+						reg = <2>;
+						ds90ub960_0_csi_out: endpoint {
+							data-lanes = <1 2 3 4>;
+							clock-lanes = <0>;
+							link-frequencies = /bits/ 64 <800000000>;
+							remote-endpoint = <&csi2_phy0>;
+						};
+					};
+				};
+
+				deserializer_0_links: links {
+					#address-cells = <1>;
+					#size-cells = <0>;
+				};
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub960_0_csi_out>;
+				data-lanes = <1 2 3 4>;
+				clock-lanes = <0>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a.dtsi b/arch/arm64/boot/dts/ti/k3-am62a.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62a.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62a.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -50,6 +50,7 @@
 		compatible = "simple-bus";
 		#address-cells = <2>;
 		#size-cells = <2>;
+		bootph-all;
 
 		ranges = <0x00 0x000f0000 0x00 0x000f0000 0x00 0x00030000>, /* Main MMRs */
 			 <0x00 0x00420000 0x00 0x00420000 0x00 0x00001000>, /* ESM0 */
@@ -67,6 +68,7 @@
 			 <0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */
 			 <0x00 0x30101000 0x00 0x30101000 0x00 0x00010100>, /* CSI window */
 			 <0x00 0x30200000 0x00 0x30200000 0x00 0x00010000>, /* DSS */
+			 <0x00 0x30300000 0x00 0x30300000 0x00 0x00001000>, /* MCRC64 */
 			 <0x00 0x30210000 0x00 0x30210000 0x00 0x00010000>, /* VPU */
 			 <0x00 0x31000000 0x00 0x31000000 0x00 0x00050000>, /* USB0 DWC3 Core window */
 			 <0x00 0x31100000 0x00 0x31100000 0x00 0x00050000>, /* USB1 DWC3 Core window */
@@ -104,6 +106,7 @@
 				 <0x00 0x79020000 0x00 0x79020000 0x00 0x00008000>, /* MCU R5 BTCM */
 				 <0x00 0x79100000 0x00 0x79100000 0x00 0x00040000>, /* MCU IRAM0 */
 				 <0x00 0x79140000 0x00 0x79140000 0x00 0x00040000>; /* MCU IRAM1 */
+			bootph-all;
 		};
 
 		cbass_wakeup: bus@b00000 {
@@ -115,6 +118,7 @@
 				 <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>, /* WKUP CTRL MMR */
 				 <0x00 0x78000000 0x00 0x78000000 0x00 0x00008000>, /* DM R5 ATCM*/
 				 <0x00 0x78100000 0x00 0x78100000 0x00 0x00008000>; /* DM R5 BTCM*/
+			bootph-all;
 		};
 	};
 
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -51,6 +51,7 @@
 			compatible = "ti,am654-phy-gmii-sel";
 			reg = <0x4044 0x8>;
 			#phy-cells = <1>;
+			bootph-all;
 		};
 
 		epwm_tbclk: clock-controller@4130 {
@@ -84,6 +85,7 @@
 		#size-cells = <2>;
 		dma-ranges;
 		ranges = <0x00 0x48000000 0x00 0x48000000 0x00 0x06000000>;
+		bootph-all;
 
 		ti,sci-dev-id = <25>;
 
@@ -96,6 +98,7 @@
 			#mbox-cells = <1>;
 			interrupt-names = "rx_012";
 			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+			bootph-all;
 		};
 
 		inta_main_dmss: interrupt-controller@48000000 {
@@ -131,6 +134,7 @@
 			ti,sci-rm-range-bchan = <0x20>; /* BLOCK_COPY_CHAN */
 			ti,sci-rm-range-rchan = <0x21>; /* SPLIT_TR_RX_CHAN */
 			ti,sci-rm-range-tchan = <0x22>; /* SPLIT_TR_TX_CHAN */
+			bootph-all;
 		};
 
 		main_pktdma: dma-controller@485c0000 {
@@ -167,6 +171,7 @@
 						<0x2c>, /* FLOW_CPSW_RX_CHAN */
 						<0x2e>, /* FLOW_SAUL_RX_0/1_CHAN */
 						<0x32>; /* FLOW_SAUL_RX_2/3_CHAN */
+			bootph-all;
 		};
 	};
 
@@ -216,20 +221,24 @@
 		mbox-names = "rx", "tx";
 		mboxes = <&secure_proxy_main 12>,
 			 <&secure_proxy_main 13>;
+		bootph-all;
 
 		k3_pds: power-controller {
 			compatible = "ti,sci-pm-domain";
 			#power-domain-cells = <2>;
+			bootph-all;
 		};
 
 		k3_clks: clock-controller {
 			compatible = "ti,k2g-sci-clk";
 			#clock-cells = <2>;
+			bootph-all;
 		};
 
 		k3_reset: reset-controller {
 			compatible = "ti,sci-reset";
 			#reset-cells = <2>;
+			bootph-all;
 		};
 	};
 
@@ -241,6 +250,13 @@
 		dma-names = "tx", "rx1", "rx2";
 	};
 
+	crc: crc@30300000 {
+		compatible = "ti,am62-mcrc64";
+		reg = <0x00 0x30300000 0x00 0x1000>;
+		clocks = <&k3_clks 116 0>;
+		power-domains = <&k3_pds 116 TI_SCI_PD_EXCLUSIVE>;
+	};
+
 	secure_proxy_sa3: mailbox@43600000 {
 		compatible = "ti,am654-secure-proxy";
 		#mbox-cells = <1>;
@@ -254,14 +270,29 @@
 		 * firmware on non-MPU processors
 		 */
 		status = "disabled";
+		bootph-all;
 	};
 
 	main_pmx0: pinctrl@f4000 {
-		compatible = "pinctrl-single";
-		reg = <0x00 0xf4000 0x00 0x2ac>;
+		compatible = "ti,am654-padconf", "pinctrl-single";
+		reg = <0x00 0xf4000 0x00 0x25c>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
 		pinctrl-single,function-mask = <0xffffffff>;
+		/*
+		 * pinctrl IP DOES NOT give any functional IRQs when a
+		 * system is in active state. This IRQ is only a dummy IRQ
+		 * that is being used to trick Linux into thinking that
+		 * GIC can potentially recieve an interrupt from this IP.
+		 * This helps us setup the IO daisychain wakeups for deep
+		 * sleep via chained wake IRQs.
+		 * Please feel free to assign a different number here as
+		 * long as it is unused if 99 conflicts with another use case.
+		 */
+		interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		bootph-all;
 	};
 
 	main_esm: esm@420000 {
@@ -282,6 +313,7 @@
 		assigned-clock-parents = <&k3_clks 36 3>;
 		power-domains = <&k3_pds 36 TI_SCI_PD_EXCLUSIVE>;
 		ti,timer-pwm;
+		bootph-all;
 	};
 
 	main_timer1: timer@2410000 {
@@ -653,6 +685,7 @@
 			dr_mode = "otg";
 			snps,usb2-gadget-lpm-disable;
 			snps,usb2-lpm-disable;
+			bootph-all;
 		};
 	};
 
@@ -698,6 +731,7 @@
 			cdns,fifo-depth = <256>;
 			cdns,fifo-width = <4>;
 			cdns,trigger-address = <0x0>;
+			cdns,phase-detect-selector = <2>;
 			clocks = <&k3_clks 75 7>;
 			assigned-clocks = <&k3_clks 75 7>;
 			assigned-clock-parents = <&k3_clks 75 8>;
@@ -745,6 +779,7 @@
 				phys = <&phy_gmii_sel 1>;
 				mac-address = [00 00 00 00 00 00];
 				ti,syscon-efuse = <&cpsw_mac_syscon 0x0>;
+				bootph-all;
 			};
 
 			cpsw_port2: port@2 {
@@ -764,6 +799,7 @@
 			clocks = <&k3_clks 13 0>;
 			clock-names = "fck";
 			bus_freq = <1000000>;
+			bootph-all;
 		};
 
 		cpts@3d000 {
@@ -778,6 +814,13 @@
 		};
 	};
 
+	timesync_router: mux-controller@a40000 {
+		compatible = "reg-mux";
+		reg = <0x0 0xa40000 0x0 0x800>;
+		#mux-control-cells = <1>;
+		status = "disabled";
+	};
+
 	hwspinlock: spinlock@2a000000 {
 		compatible = "ti,am64-hwspinlock";
 		reg = <0x00 0x2a000000 0x00 0x1000>;
@@ -940,6 +983,33 @@
 		status = "disabled";
 	};
 
+	eqep0: counter@23200000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23200000 0x00 0x100>;
+		power-domains = <&k3_pds 59 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 59 0>;
+		interrupts = <GIC_SPI 116 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
+	eqep1: counter@23210000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23210000 0x00 0x100>;
+		power-domains = <&k3_pds 60 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 60 0>;
+		interrupts = <GIC_SPI 117 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
+	eqep2: counter@23220000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23220000 0x00 0x100>;
+		power-domains = <&k3_pds 62 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 62 0>;
+		interrupts = <GIC_SPI 118 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
 	mcasp0: audio-controller@2b00000 {
 		compatible = "ti,am33xx-mcasp-audio";
 		reg = <0x00 0x02b00000 0x00 0x2000>,
@@ -1002,8 +1072,10 @@
 
 	ti_csi2rx0: ticsi2rx@30102000 {
 		compatible = "ti,j721e-csi2rx-shim";
-		dmas = <&main_bcdma_csi 0 0x5000 0>;
-		dma-names = "rx0";
+		dmas = <&main_bcdma_csi 0 0x5000 0>, <&main_bcdma_csi 0 0x5001 0>,
+			<&main_bcdma_csi 0 0x5002 0>, <&main_bcdma_csi 0 0x5003 0>,
+			<&main_bcdma_csi 0 0x5004 0>, <&main_bcdma_csi 0 0x5005 0>;
+		dma-names = "rx0", "rx1", "rx2", "rx3", "rx4", "rx5";
 		reg = <0x00 0x30102000 0x00 0x1000>;
 		power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
 		#address-cells = <2>;
@@ -1014,6 +1086,9 @@
 		cdns_csi2rx0: csi-bridge@30101000 {
 			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
 			reg = <0x00 0x30101000 0x00 0x1000>;
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
 			clocks = <&k3_clks 182 0>, <&k3_clks 182 3>, <&k3_clks 182 0>,
 				<&k3_clks 182 0>, <&k3_clks 182 4>, <&k3_clks 182 4>;
 			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
@@ -1092,6 +1167,19 @@
 		reg = <0x00 0x30210000 0x00 0x10000>;
 		clocks = <&k3_clks 204 2>;
 		power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>;
+		sram = <&oc_sram>;
+	};
+
+	c7x_0: dsp@7e000000 {
+		compatible = "ti,am62a-c7xv-dsp";
+		reg = <0x00 0x7e000000 0x00 0x00100000>;
+		reg-names = "l2sram";
+		ti,sci = <&dmsc>;
+		ti,sci-dev-id = <208>;
+		ti,sci-proc-ids = <0x04 0xff>;
+		resets = <&k3_reset 208 1>;
+		firmware-name = "am62a-c71_0-fw";
+		status = "disabled";
 	};
 
 	e5010: jpeg-encoder@fd20000 {
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -6,13 +6,25 @@
  */
 
 &cbass_mcu {
+	mcu_ram: sram@79100000 {
+		compatible = "mmio-sram";
+		reg = <0x00 0x79100000 0x00 0x80000>;
+		ranges = <0x00 0x00 0x79100000 0x80000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		mcu1-sram@0 {
+			reg = <0x0 0x80000>;
+		};
+	};
+
 	mcu_pmx0: pinctrl@4084000 {
 		compatible = "pinctrl-single";
 		reg = <0x00 0x04084000 0x00 0x88>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
 		pinctrl-single,function-mask = <0xffffffff>;
-		status = "disabled";
+		bootph-all;
 	};
 
 	mcu_esm: esm@4100000 {
@@ -161,6 +173,7 @@
 		clocks = <&k3_clks 188 6>, <&k3_clks 188 1>;
 		clock-names = "hclk", "cclk";
 		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		wakeup-source = "suspend", "poweroff";
 		status = "disabled";
 	};
 
@@ -173,6 +186,33 @@
 		clocks = <&k3_clks 189 6>, <&k3_clks 189 1>;
 		clock-names = "hclk", "cclk";
 		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		wakeup-source = "suspend", "poweroff";
 		status = "disabled";
 	};
+
+	mcu_r5fss0: r5fss@79000000 {
+		compatible = "ti,am62-r5fss";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x79000000 0x00 0x79000000 0x8000>,
+			 <0x79020000 0x00 0x79020000 0x8000>;
+		power-domains = <&k3_pds 7 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		mcu_r5fss0_core0: r5f@79000000 {
+			compatible = "ti,am62-r5f";
+			reg = <0x79000000 0x00008000>,
+			      <0x79020000 0x00008000>;
+			reg-names = "atcm", "btcm";
+			ti,sci = <&dmsc>;
+			ti,sci-dev-id = <9>;
+			ti,sci-proc-ids = <0x03 0xff>;
+			resets = <&k3_reset 9 1>;
+			firmware-name = "am62a-mcu-r5f0_0-fw";
+			ti,atcm-enable = <0>;
+			ti,btcm-enable = <1>;
+			ti,loczrama = <0>;
+			sram = <&mcu_ram>;
+		};
+	};
 };
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -2,19 +2,28 @@
 /*
  * Device Tree Source for AM62A SoC Family Wakeup Domain peripherals
  *
- * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2025 Texas Instruments Incorporated - https://www.ti.com/
  */
 
+#include <dt-bindings/bus/ti-sysc.h>
+
 &cbass_wakeup {
 	wkup_conf: bus@43000000 {
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges = <0x00 0x00 0x43000000 0x20000>;
+		bootph-all;
 
 		chipid: chipid@14 {
 			compatible = "ti,am654-chipid";
 			reg = <0x14 0x4>;
+			bootph-all;
+		};
+
+		opp_efuse_table: syscon@18 {
+			compatible = "ti,am62-opp-efuse-table", "syscon";
+			reg = <0x18 0x4>;
 		};
 
 		cpsw_mac_syscon: ethernet-mac-syscon@200 {
@@ -31,16 +40,49 @@
 			compatible = "ti,am62-usb-phy-ctrl", "syscon";
 			reg = <0x4018 0x4>;
 		};
+
+		ddr_pmctrl: syscon@80d0 {
+			compatible = "ti,am62-ddr-pmctrl", "syscon";
+			reg = <0x80d0 0x4>;
+			bootph-pre-ram;
+		};
+
+		canuart_wake: syscon@18300 {
+			compatible = "ti,am62-canuart-wake", "syscon";
+			reg = <0x18300 0x44>;
+			bootph-pre-ram;
+		};
 	};
 
-	wkup_uart0: serial@2b300000 {
-		compatible = "ti,am64-uart", "ti,am654-uart";
-		reg = <0x00 0x2b300000 0x00 0x100>;
-		interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+	wkup_uart_conf: target-module@2b300050 {
+		compatible = "ti,sysc-omap2", "ti,sysc";
+		reg = <0 0x2b300050 0 0x4>,
+		      <0 0x2b300054 0 0x4>,
+		      <0 0x2b300058 0 0x4>;
+		reg-names = "rev", "sysc", "syss";
+		ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+				 SYSC_OMAP2_SOFTRESET |
+				 SYSC_OMAP2_AUTOIDLE)>;
+		ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+				<SYSC_IDLE_NO>,
+				<SYSC_IDLE_SMART>,
+				<SYSC_IDLE_SMART_WKUP>;
+		ti,syss-mask = <1>;
+		ti,no-reset-on-init;
 		power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 114 0>;
-		clock-names = "fclk";
-		status = "disabled";
+		clock-names = "fck";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0 0x2b300000 0x100000>;
+
+		wkup_uart0: serial@0 {
+			compatible = "ti,am64-uart", "ti,am654-uart";
+			reg = <0 0x100>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+			bootph-pre-ram;
+	       };
 	};
 
 	wkup_i2c0: i2c@2b200000 {
@@ -76,6 +118,31 @@
 		status = "reserved";
 	};
 
+	wkup_r5fss0: r5fss@78000000 {
+		compatible = "ti,am62-r5fss";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x78000000 0x00 0x78000000 0x8000>,
+			 <0x78100000 0x00 0x78100000 0x8000>;
+		power-domains = <&k3_pds 119 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		wkup_r5fss0_core0: r5f@78000000 {
+			compatible = "ti,am62-r5f";
+			reg = <0x78000000 0x00008000>,
+			      <0x78100000 0x00008000>;
+			reg-names = "atcm", "btcm";
+			ti,sci = <&dmsc>;
+			ti,sci-dev-id = <121>;
+			ti,sci-proc-ids = <0x01 0xff>;
+			resets = <&k3_reset 121 1>;
+			firmware-name = "am62a-wkup-r5f0_0-fw";
+			ti,atcm-enable = <1>;
+			ti,btcm-enable = <1>;
+			ti,loczrama = <1>;
+		};
+	};
+
 	wkup_vtm0: temperature-sensor@b00000 {
 		compatible = "ti,j7200-vtm";
 		reg = <0x00 0xb00000 0x00 0x400>,
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62d2-evm.dts b/arch/arm64/boot/dts/ti/k3-am62d2-evm.dts
--- a/arch/arm64/boot/dts/ti/k3-am62d2-evm.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62d2-evm.dts	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,675 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * AM62D2 EVM: https://www.ti.com/lit/zip/sprcal5
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include "k3-am62a7.dtsi"
+
+/ {
+	compatible = "ti,am62d2-evm", "ti,am62d2";
+	model = "Texas Instruments AM62D2 EVM";
+
+	aliases {
+		serial0 = &wkup_uart0;
+		serial1 = &mcu_uart0;
+		serial2 = &main_uart0;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+		rtc0 = &wkup_rtc0;
+		ethernet0 = &cpsw_port1;
+		ethernet1 = &cpsw_port2;
+	};
+
+	chosen {
+		stdout-path = &main_uart0;
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		/* 4G RAM */
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+		      <0x00000008 0x80000000 0x00000000 0x80000000>;
+		bootph-all;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		bootph-pre-ram;
+
+		/* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x2000000>;
+			alloc-ranges = <0x00 0xc0000000 0x00 0x2000000>;
+			linux,cma-default;
+		};
+
+		secure_tfa_ddr: tfa@80000000 {
+			reg = <0x00 0x80000000 0x00 0x80000>;
+			alignment = <0x1000>;
+			no-map;
+		};
+
+		c7x_0_dma_memory_region: c7x-dma-memory@99800000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x99800000 0x00 0x100000>;
+			no-map;
+		};
+
+		c7x_0_memory_region: c7x-memory@99900000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x99900000 0x00 0xf00000>;
+			no-map;
+		};
+
+		mcu_r5fss0_core0_dma_memory_region: r5f-dma-memory@9b800000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9b800000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_r5fss0_core0_memory_region: r5f-dma-memory@9b900000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9b900000 0x00 0xf00000>;
+			no-map;
+		};
+
+		wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@9c800000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9c800000 0x00 0x100000>;
+			no-map;
+		};
+
+		wkup_r5fss0_core0_memory_region: r5f-dma-memory@9c900000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9c900000 0x00 0xf00000>;
+			no-map;
+			bootph-pre-ram;
+		};
+
+		secure_ddr: optee@9e800000 {
+			reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
+			alignment = <0x1000>;
+			no-map;
+		};
+
+		rtos_ipc_memory_region: ipc-memories@a0000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0000000 0x00 0x01000000>;
+			no-map;
+		};
+	};
+
+	opp-table {
+		/* Requires VDD_CORE at 0v85 */
+		opp-1400000000 {
+			opp-hz = /bits/ 64 <1400000000>;
+			opp-supported-hw = <0x01 0x0004>;
+			clock-latency-ns = <6000000>;
+		};
+	};
+
+	vout_pd: regulator-1 {
+		/* TPS65988 PD CONTROLLER OUTPUT */
+		compatible = "regulator-fixed";
+		regulator-name = "vout_pd";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+		bootph-all;
+	};
+
+	vmain_pd: load-switch {
+		/* Output of TPS22811 */
+		compatible = "regulator-fixed";
+		regulator-name = "vmain_pd";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vout_pd>;
+		regulator-always-on;
+		regulator-boot-on;
+		bootph-all;
+	};
+
+	vcc_5v0: regulator-2 {
+		/* Output of TPS630702RNMR */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_5v0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vmain_pd>;
+		regulator-always-on;
+		regulator-boot-on;
+		bootph-all;
+	};
+
+	vdd_mmc1: regulator-3 {
+		/* TPS22918DBVR */
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_mmc1";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		enable-active-high;
+		gpio = <&exp1 3 GPIO_ACTIVE_HIGH>;
+		bootph-all;
+	};
+
+	vddshv_sdio: regulator-4 {
+		compatible = "regulator-gpio";
+		regulator-name = "vddshv_sdio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&vddshv_sdio_pins_default>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		gpios = <&main_gpio1 31 GPIO_ACTIVE_HIGH>;
+		states = <1800000 0x0>,
+			 <3300000 0x1>;
+		bootph-all;
+	};
+
+	codec_audio: sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "AM62D2-EVM";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&sound_master1>;
+		simple-audio-card,frame-master = <&sound_master1>;
+		simple-audio-card,bitclock-inversion;
+
+		sound_master1: simple-audio-card,cpu {
+			sound-dai = <&mcasp2>;
+			system-clock-direction-out;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&tad5212>;
+		};
+	};
+};
+
+&mcu_pmx0 {
+	wkup_uart0_pins_default: wkup-uart0-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_MCU_IOPAD(0x0024, PIN_INPUT, 0) /* (C9) WKUP_UART0_RXD */
+			AM62DX_MCU_IOPAD(0x0028, PIN_OUTPUT, 0) /* (E9) WKUP_UART0_TXD */
+			AM62DX_MCU_IOPAD(0x002c, PIN_INPUT, 0) /* (C10) WKUP_UART0_CTSn */
+			AM62DX_MCU_IOPAD(0x0030, PIN_OUTPUT, 0) /* (C8) WKUP_UART0_RTSn */
+		>;
+		bootph-all;
+	};
+};
+
+/* WKUP UART0 is used for DM firmware logs */
+&wkup_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_uart0_pins_default>;
+	status = "reserved";
+	bootph-all;
+};
+
+&main_pmx0 {
+	main_uart0_pins_default: main-uart0-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_IOPAD(0x01c8, PIN_INPUT, 0) /* (E14) UART0_RXD */
+			AM62DX_IOPAD(0x01cc, PIN_OUTPUT, 0) /* (D15) UART0_TXD */
+		>;
+		bootph-all;
+	};
+
+	main_i2c0_pins_default: main-i2c0-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (D17) I2C0_SCL */
+			AM62DX_IOPAD(0x01e4, PIN_INPUT_PULLUP, 0) /* (E16) I2C0_SDA */
+		>;
+		bootph-all;
+	};
+
+	main_i2c1_pins_default: main-i2c1-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_IOPAD(0x01e8, PIN_INPUT_PULLUP, 0) /* (C17) I2C1_SCL */
+			AM62DX_IOPAD(0x01ec, PIN_INPUT_PULLUP, 0) /* (E17) I2C1_SDA */
+		>;
+		bootph-all;
+	};
+
+	main_i2c2_pins_default: main-i2c2-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_IOPAD(0x00b0, PIN_INPUT_PULLUP, 1) /* (M22) GPMC0_CSn2.I2C2_SCL */
+			AM62DX_IOPAD(0x00b4, PIN_INPUT_PULLUP, 1) /* (M20) GPMC0_CSn3.I2C2_SDA */
+		>;
+	};
+
+	main_mmc0_pins_default: main-mmc0-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_IOPAD(0x0220, PIN_INPUT_PULLUP, 0) /* (Y6) MMC0_CMD */
+			AM62DX_IOPAD(0x0218, PIN_OUTPUT, 0) /* (AB7) MMC0_CLK */
+			AM62DX_IOPAD(0x0214, PIN_INPUT_PULLUP, 0) /* (AA6) MMC0_DAT0 */
+			AM62DX_IOPAD(0x0210, PIN_INPUT_PULLUP, 0) /* (AB6) MMC0_DAT1 */
+			AM62DX_IOPAD(0x020c, PIN_INPUT_PULLUP, 0) /* (Y7) MMC0_DAT2 */
+			AM62DX_IOPAD(0x0208, PIN_INPUT_PULLUP, 0) /* (AA7) MMC0_DAT3 */
+			AM62DX_IOPAD(0x0204, PIN_INPUT_PULLUP, 0) /* (Y8) MMC0_DAT4 */
+			AM62DX_IOPAD(0x0200, PIN_INPUT_PULLUP, 0) /* (W7) MMC0_DAT5 */
+			AM62DX_IOPAD(0x01fc, PIN_INPUT_PULLUP, 0) /* (W9) MMC0_DAT6 */
+			AM62DX_IOPAD(0x01f8, PIN_INPUT_PULLUP, 0) /* (AB8) MMC0_DAT7 */
+		>;
+		bootph-all;
+	};
+
+	main_mmc1_pins_default: main-mmc1-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_IOPAD(0x023c, PIN_INPUT, 0) /* (C21) MMC1_CMD */
+			AM62DX_IOPAD(0x0234, PIN_OUTPUT, 0) /* (E22) MMC1_CLK */
+			AM62DX_IOPAD(0x0230, PIN_INPUT, 0) /* (B22) MMC1_DAT0 */
+			AM62DX_IOPAD(0x022c, PIN_INPUT_PULLUP, 0) /* (D21) MMC1_DAT1 */
+			AM62DX_IOPAD(0x0228, PIN_INPUT_PULLUP, 0) /* (C22) MMC1_DAT2 */
+			AM62DX_IOPAD(0x0224, PIN_INPUT_PULLUP, 0) /* (D22) MMC1_DAT3 */
+			AM62DX_IOPAD(0x0240, PIN_INPUT, 0) /* (E18) MMC1_SDCD */
+			AM62DX_IOPAD(0x0244, PIN_INPUT, 0) /* (D18) MMC1_SDWP */
+		>;
+		bootph-all;
+	};
+
+	main_mdio0_pins_default: main-mdio0-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_IOPAD(0x160, PIN_OUTPUT, 0) /* (V12) MDIO0_MDC */
+			AM62DX_IOPAD(0x15c, PIN_INPUT, 0) /* (V13) MDIO0_MDIO */
+		>;
+		bootph-all;
+	};
+
+	main_rgmii1_pins_default: main-rgmii1-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_IOPAD(0x14c, PIN_INPUT, 0) /* (AB16) RGMII1_RD0 */
+			AM62DX_IOPAD(0x150, PIN_INPUT, 0) /* (V15) RGMII1_RD1 */
+			AM62DX_IOPAD(0x154, PIN_INPUT, 0) /* (W15) RGMII1_RD2 */
+			AM62DX_IOPAD(0x158, PIN_INPUT, 0) /* (V14) RGMII1_RD3 */
+			AM62DX_IOPAD(0x148, PIN_INPUT, 0) /* (AA16) RGMII1_RXC */
+			AM62DX_IOPAD(0x144, PIN_INPUT, 0) /* (AA15) RGMII1_RX_CTL */
+			AM62DX_IOPAD(0x134, PIN_INPUT, 0) /* (Y17) RGMII1_TD0 */
+			AM62DX_IOPAD(0x138, PIN_INPUT, 0) /* (V16) RGMII1_TD1 */
+			AM62DX_IOPAD(0x13c, PIN_INPUT, 0) /* (Y16) RGMII1_TD2 */
+			AM62DX_IOPAD(0x140, PIN_INPUT, 0) /* (AA17) RGMII1_TD3 */
+			AM62DX_IOPAD(0x0130, PIN_OUTPUT, 0) /* (AB17) RGMII1_TXC */
+			AM62DX_IOPAD(0x012c, PIN_OUTPUT, 0) /* (W16) RGMII1_TX_CTL */
+		>;
+		bootph-all;
+	};
+
+	main_rgmii2_pins_default: main-rgmii2-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_IOPAD(0x0184, PIN_INPUT, 0) /* (AA21) RGMII2_RD0 */
+			AM62DX_IOPAD(0x0188, PIN_INPUT, 0) /* (Y20) RGMII2_RD1 */
+			AM62DX_IOPAD(0x018c, PIN_INPUT, 0) /* (AB21) RGMII2_RD2 */
+			AM62DX_IOPAD(0x0190, PIN_INPUT, 0) /* (AB20) RGMII2_RD3 */
+			AM62DX_IOPAD(0x0180, PIN_INPUT, 0) /* (AA20) RGMII2_RXC */
+			AM62DX_IOPAD(0x017c, PIN_INPUT, 0) /* (W18) RGMII2_RX_CTL */
+			AM62DX_IOPAD(0x016c, PIN_INPUT, 0) /* (AA19) RGMII2_TD0 */
+			AM62DX_IOPAD(0x0170, PIN_INPUT, 0) /* (Y18) RGMII2_TD1 */
+			AM62DX_IOPAD(0x0174, PIN_INPUT, 0) /* (AA18) RGMII2_TD2 */
+			AM62DX_IOPAD(0x0178, PIN_INPUT, 0) /* (W17) RGMII2_TD3 */
+			AM62DX_IOPAD(0x0168, PIN_OUTPUT, 0) /* (AB19) RGMII2_TXC */
+			AM62DX_IOPAD(0x0164, PIN_OUTPUT, 0) /* (Y19) RGMII2_TX_CTL */
+		>;
+		bootph-all;
+	};
+
+	main_mcasp2_pins_default: main-mcasp2-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_IOPAD(0x0070, PIN_INPUT, 3) /* (R21) GPMC0_AD13.MCASP2_ACLKX */
+			AM62DX_IOPAD(0x006c, PIN_INPUT, 3) /* (T22) GPMC0_AD12.MCASP2_AFSX */
+			AM62DX_IOPAD(0x005C, PIN_INPUT, 3) /* (P22) GPMC0_AD8.MCASP2_AXR0 */
+			AM62DX_IOPAD(0x0060, PIN_INPUT, 3) /* (R19) GPMC0_AD9.MCASP2_AXR1 */
+			AM62DX_IOPAD(0x0068, PIN_INPUT, 3) /* (R22) GPMC0_AD11.MCASP2_AXR3 */
+			AM62DX_IOPAD(0x003c, PIN_INPUT, 3) /* (N21) GPMC0_AD0.MCASP2_AXR4 */
+		>;
+	};
+
+	main_gpio1_ioexp_intr_pins_default: main-gpio1-ioexp-intr-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_IOPAD(0x01d4, PIN_INPUT, 7) /* (C15) UART0_RTSn.GPIO1_23 */
+		>;
+	};
+
+	main_usb1_pins_default: main-usb1-default-pins {
+			pinctrl-single,pins = <
+			AM62DX_IOPAD(0x0280, PIN_OUTPUT, 0) /* (D19) USB1_DRVVBUS */
+		>;
+	};
+
+	vddshv_sdio_pins_default: vddshv-sdio-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_IOPAD(0x1F4, PIN_OUTPUT, 7) /* (M19) GPMC0_CLK.GPIO1_31 */
+		>;
+		bootph-all;
+	};
+};
+
+&mcu_pmx0 {
+	status = "okay";
+
+	pmic_irq_pins_default: pmic-irq-default-pins {
+		pinctrl-single,pins = <
+			AM62DX_MCU_IOPAD(0x000, PIN_INPUT, 7) /* (E11) MCU_GPIO0_0 */
+		>;
+	};
+};
+
+&mcu_gpio0 {
+	status = "okay";
+};
+
+&main_i2c0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+	bootph-all;
+
+	typec_pd0: usb-power-controller@3f {
+		compatible = "ti,tps6598x";
+		reg = <0x3f>;
+
+		connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			self-powered;
+			data-role = "dual";
+			power-role = "sink";
+			port {
+				usb_con_hs: endpoint {
+					remote-endpoint = <&usb0_hs_ep>;
+				};
+			};
+		};
+	};
+
+	exp1: gpio@22 {
+		compatible = "ti,tca6424";
+		reg = <0x22>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&main_gpio1>;
+		interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_gpio1_ioexp_intr_pins_default>;
+		bootph-all;
+
+		gpio-line-names = "GPIO_CPSW2_RST", "GPIO_CPSW1_RST",
+			"MMC1_SD_EN", "VPP_EN",
+			"GPIO_DIX_RST", "IO_EXP_OPT_EN",
+			"DIX_INT", "GPIO_eMMC_RSTn",
+			"CPLD2_DONE", "CPLD2_INTN",
+			"CPLD1_DONE", "CPLD1_INTN",
+			"USB_TYPEA_OC_INDICATION", "PCM1_INT",
+			"PCM2_INT", "GPIO_PCM1_RST",
+			"TEST_GPIO2", "GPIO_PCM2_RST",
+			"IO_MCAN0_STB", "IO_MCAN1_STB",
+			"PD_I2C_IRQ", "IO_EXP_TEST_LED";
+	};
+
+	exp2: gpio@20 {
+		compatible = "ti,tca6416";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		gpio-line-names = "", "DAC_LAT_CTRL",
+			"CPLD1_JTAGENB", "CPLD1_PROGRAMN",
+			"CPLD2_JTAGENB", "CPLD2_PROGRAMN",
+			"", "",
+			"", "",
+			"", "",
+			"", "",
+			"", "",
+			"", "",
+			"SoC_I2C0_SCL", "SoC_I2C0_SDA";
+	};
+
+	tad5212: dac@50 {
+		compatible = "ti,tad5212";
+		reg = <0x50>, <0x51>, <0x52>, <0x53>;
+		sound-name-prefix = "tad5212_04";
+		#sound-dai-cells = <0>;
+	};
+};
+
+&main_i2c1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	clock-frequency = <100000>;
+};
+
+&main_i2c2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c2_pins_default>;
+	clock-frequency = <400000>;
+};
+
+&mcasp2 {
+	status = "okay";
+	#sound-dai-cells = <0>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcasp2_pins_default>;
+
+	auxclk-fs-ratio = <2177>;
+	op-mode = <0>;          /* MCASP_IIS_MODE */
+	tdm-slots = <2>;
+	slot-width = <32>;
+	serial-dir = <
+	       1 1 0 1
+	       1 0 0 0
+	       0 0 0 0
+	       0 0 0 0
+	>;
+};
+
+&sdhci0 {
+	/* eMMC */
+	bootph-all;
+	status = "okay";
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc0_pins_default>;
+	disable-wp;
+};
+
+&sdhci1 {
+	/* SD/MMC */
+	status = "okay";
+	vmmc-supply = <&vdd_mmc1>;
+	vqmmc-supply = <&vddshv_sdio>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc1_pins_default>;
+	disable-wp;
+	bootph-all;
+};
+
+&main_gpio0 {
+	bootph-all;
+	status = "okay";
+};
+
+&main_gpio1 {
+	bootph-all;
+	status = "okay";
+};
+
+&main_gpio_intr {
+	status = "okay";
+};
+
+&main_uart0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart0_pins_default>;
+	bootph-all;
+};
+
+&usbss0 {
+	status = "okay";
+	ti,vbus-divider;
+};
+
+&usb0 {
+	usb-role-switch;
+
+	port {
+		usb0_hs_ep: endpoint {
+			remote-endpoint = <&usb_con_hs>;
+		};
+	};
+};
+
+&usbss1 {
+	status = "okay";
+};
+
+&usb1 {
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_usb1_pins_default>;
+};
+
+&mailbox0_cluster0 {
+	status = "okay";
+
+	mbox_r5_0: mbox-r5-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&mailbox0_cluster1 {
+	status = "okay";
+
+	mbox_c7x_0: mbox-c7x-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&mailbox0_cluster2 {
+	status = "okay";
+
+	mbox_mcu_r5_0: mbox-mcu-r5-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&wkup_r5fss0 {
+	status = "okay";
+};
+
+&wkup_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster0 &mbox_r5_0>;
+	memory-region = <&wkup_r5fss0_core0_dma_memory_region>,
+			<&wkup_r5fss0_core0_memory_region>;
+	bootph-pre-ram;
+};
+
+&mcu_r5fss0 {
+	status = "okay";
+};
+
+&mcu_r5fss0_core0 {
+	status = "okay";
+
+	mboxes = <&mailbox0_cluster2 &mbox_mcu_r5_0>;
+	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
+			<&mcu_r5fss0_core0_memory_region>;
+	firmware-name = "am62d-mcu-r5f0_0-fw";
+};
+
+&c7x_0 {
+	status = "okay";
+
+	mboxes = <&mailbox0_cluster1 &mbox_c7x_0>;
+	memory-region = <&c7x_0_dma_memory_region>,
+			<&c7x_0_memory_region>;
+	firmware-name = "am62d-c71_0-fw";
+};
+
+&cpsw3g {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_rgmii1_pins_default &main_rgmii2_pins_default>;
+
+	cpts@3d000 {
+		/* MAP HW3_TS_PUSH to GENF1 */
+		ti,pps = <2 1>;
+	};
+};
+
+&cpsw_port1 {
+	status = "okay";
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&cpsw3g_phy0>;
+};
+
+&cpsw_port2 {
+	status = "okay";
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&cpsw3g_phy1>;
+};
+
+&cpsw3g_mdio {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mdio0_pins_default>;
+
+	cpsw3g_phy0: ethernet-phy@0 {
+		reg = <0>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		ti,min-output-impedance;
+	};
+
+	cpsw3g_phy1: ethernet-phy@3 {
+		reg = <3>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		ti,min-output-impedance;
+	};
+};
+
+/* main_rti4 is used by C7x DSP */
+&main_rti4 {
+	status = "reserved";
+};
+
+/* main_timer2 is used by C7x DSP */
+&main_timer2 {
+	status = "reserved";
+};
+
+&vpu {
+	status = "disabled";
+};
+
+&e5010 {
+	status = "disabled";
+};
+
+&wkup_uart_conf{
+	status = "disabled";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62.dtsi b/arch/arm64/boot/dts/ti/k3-am62.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -66,6 +66,7 @@
 			 <0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */
 			 <0x00 0x30101000 0x00 0x30101000 0x00 0x00010100>, /* CSI window */
 			 <0x00 0x30200000 0x00 0x30200000 0x00 0x00010000>, /* DSS */
+			 <0x00 0x30300000 0x00 0x30300000 0x00 0x00001000>, /* MCRC64 */
 			 <0x00 0x31000000 0x00 0x31000000 0x00 0x00050000>, /* USB0 DWC3 Core window */
 			 <0x00 0x31100000 0x00 0x31100000 0x00 0x00050000>, /* USB1 DWC3 Core window */
 			 <0x00 0x3b000000 0x00 0x3b000000 0x00 0x00000400>, /* GPMC0_CFG */
@@ -86,7 +87,9 @@
 			 /* Wakeup Domain Range */
 			 <0x00 0x00b00000 0x00 0x00b00000 0x00 0x00002400>, /* VTM */
 			 <0x00 0x2b000000 0x00 0x2b000000 0x00 0x00300400>,
-			 <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>;
+			 <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>,
+			 <0x00 0x78000000 0x00 0x78000000 0x00 0x00008000>, /* DM R5 ATCM*/
+			 <0x00 0x78100000 0x00 0x78100000 0x00 0x00008000>; /* DM R5 BTCM*/
 
 		cbass_mcu: bus@4000000 {
 			bootph-all;
@@ -103,7 +106,9 @@
 			#size-cells = <2>;
 			ranges = <0x00 0x00b00000 0x00 0x00b00000 0x00 0x00002400>, /* VTM */
 				 <0x00 0x2b000000 0x00 0x2b000000 0x00 0x00300400>, /* Peripheral Window */
-				 <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>;
+				 <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>,
+				 <0x00 0x78000000 0x00 0x78000000 0x00 0x00008000>, /* DM R5 ATCM*/
+				 <0x00 0x78100000 0x00 0x78100000 0x00 0x00008000>; /* DM R5 BTCM*/
 		};
 	};
 
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l3.dtsi b/arch/arm64/boot/dts/ti/k3-am62l3.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62l3.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l3.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-only or MIT
+/*
+ * Device Tree file for the AM62L3 SoC family (Dual Core A53)
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Technical Reference Manual: https://www.ti.com/lit/pdf/sprujb4
+ */
+
+/dts-v1/;
+
+#include "k3-am62l.dtsi"
+
+/ {
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0: cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+			};
+		};
+
+		cpu0: cpu@0 {
+			compatible = "arm,cortex-a53";
+			reg = <0x000>;
+			device_type = "cpu";
+			enable-method = "psci";
+			i-cache-size = <0x8000>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu1: cpu@1 {
+			compatible = "arm,cortex-a53";
+			reg = <0x001>;
+			device_type = "cpu";
+			enable-method = "psci";
+			i-cache-size = <0x8000>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_0>;
+		};
+	};
+
+	l2_0: l2-cache0 {
+		compatible = "cache";
+		cache-unified;
+		cache-level = <2>;
+		cache-size = <0x40000>;
+		cache-line-size = <64>;
+		cache-sets = <256>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l3-evm-dsi-rpi-7inch-panel.dtso b/arch/arm64/boot/dts/ti/k3-am62l3-evm-dsi-rpi-7inch-panel.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62l3-evm-dsi-rpi-7inch-panel.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l3-evm-dsi-rpi-7inch-panel.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * DT Overlay for RPi 7inch touchscreen panel interfaced with DSI on
+ * AM62L3 EVM.
+ *
+ * RPi DSI Panel: https://www.raspberrypi.com/products/raspberry-pi-touch-display/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "k3-pinctrl.h"
+
+&{/} {
+	bridge_reg: bridge-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "bridge-reg";
+		gpio = <&display_reg 0 0>;
+		vin-supply = <&display_reg>;
+		enable-active-high;
+	};
+
+	panel0 {
+		compatible = "raspberrypi,7inch-dsi", "simple-panel";
+		backlight = <&display_reg>;
+		power-supply = <&display_reg>;
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&panel_bridge_out>;
+			};
+		};
+	};
+};
+
+&main_i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	display_reg: regulator@45 {
+		compatible = "raspberrypi,7inch-touchscreen-panel-regulator";
+		reg = <0x45>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	touch-controller@38 {
+		compatible = "edt,edt-ft5406";
+		reg = <0x38>;
+
+		touchscreen-size-x = < 800 >;
+		touchscreen-size-y = < 480 >;
+
+		vcc-supply = <&display_reg>;
+		reset-gpio = <&display_reg 1 1>;
+
+		touchscreen-inverted-x;
+		touchscreen-inverted-y;
+	};
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+
+		dpi_out: endpoint {
+			remote-endpoint = <&dsi0_in>;
+		};
+	};
+};
+
+&dsi0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			dsi0_out: endpoint {
+				remote-endpoint = <&panel_bridge_in>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			dsi0_in: endpoint {
+				remote-endpoint = <&dpi_out>;
+			};
+		};
+	};
+
+	bridge@0 {
+		compatible = "toshiba,tc358762";
+		reg = <0>;
+		vddc-supply = <&bridge_reg>;
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				panel_bridge_in: endpoint {
+					remote-endpoint = <&dsi0_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				panel_bridge_out: endpoint {
+					remote-endpoint = <&panel_in>;
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l3-evm.dts b/arch/arm64/boot/dts/ti/k3-am62l3-evm.dts
--- a/arch/arm64/boot/dts/ti/k3-am62l3-evm.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l3-evm.dts	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,996 @@
+// SPDX-License-Identifier: GPL-2.0-only or MIT
+/*
+ * Device Tree file for the AM62L3 Evaluation Module
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Technical Reference Manual: https://www.ti.com/lit/pdf/sprujb4
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include "k3-am62l3.dtsi"
+#include "k3-pinctrl.h"
+
+/ {
+	compatible = "ti,am62l3-evm", "ti,am62l3";
+	model = "Texas Instruments AM62L3 Evaluation Module";
+
+	aliases {
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+	};
+
+	chosen {
+		stdout-path = &main_uart0;
+	};
+
+	memory@80000000 {
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
+		device_type = "memory";
+		bootph-all;
+	};
+
+	hdmi0: connector-hdmi {
+		compatible = "hdmi-connector";
+		label = "hdmi";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&sii9022_out>;
+			};
+		};
+	};
+
+	gpio_keys: gpio-keys {
+		compatible = "gpio-keys";
+		autorepeat;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usr_button_pins_default>;
+
+		usr: button-usr {
+			label = "User Key";
+			linux,code = <BTN_0>;
+			gpios = <&main_gpio0 90 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&usr_led_pins_default>;
+
+		led-0 {
+			label = "am62-sk:green:heartbeat";
+			gpios = <&main_gpio0 123 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+			function = LED_FUNCTION_HEARTBEAT;
+			default-state = "on";
+		};
+	};
+
+	vmain_pd: regulator-0 {
+		/* TPS65988 PD CONTROLLER OUTPUT */
+		bootph-all;
+		compatible = "regulator-fixed";
+		regulator-name = "vmain_pd";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vcc_3v3_sys: regulator-1 {
+		/* output of LM61460-Q1 */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3_sys";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vmain_pd>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vdd_mmc1: regulator-2 {
+		/* TPS22918DBVR */
+		bootph-all;
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_mmc1";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		enable-active-high;
+		vin-supply = <&vcc_3v3_sys>;
+		gpio = <&exp1 3 GPIO_ACTIVE_HIGH>;
+	};
+
+	vcc_1v8: regulator-3 {
+		/* output of TPS6282518DMQ */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_3v3_sys>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	tlv320_mclk: clk-0 {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <12288000>;
+	};
+
+	codec_audio: sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "AM62L-SKEVM";
+		simple-audio-card,widgets =
+			"Headphone",	"Headphone Jack",
+			"Line",		"Line In",
+			"Microphone",	"Microphone Jack";
+		simple-audio-card,routing =
+			"Headphone Jack",	"HPLOUT",
+			"Headphone Jack",	"HPROUT",
+			"LINE1L",		"Line In",
+			"LINE1R",		"Line In",
+			"MIC3R",		"Microphone Jack",
+			"Microphone Jack",	"Mic Bias";
+		simple-audio-card,format = "dsp_b";
+		simple-audio-card,bitclock-master = <&sound_master>;
+		simple-audio-card,frame-master = <&sound_master>;
+		simple-audio-card,bitclock-inversion;
+
+		simple-audio-card,cpu {
+			sound-dai = <&mcasp0>;
+		};
+
+		sound_master: simple-audio-card,codec {
+			sound-dai = <&tlv320aic3106>;
+			clocks = <&tlv320_mclk>;
+		};
+	};
+};
+
+&pmx0 {
+	main_uart0_pins_default: main-uart0-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01b4, PIN_INPUT, 0)	/* (D13) UART0_RXD */
+			AM62LX_IOPAD(0x01b8, PIN_OUTPUT, 0)	/* (C13) UART0_TXD */
+		>;
+		bootph-all;
+	};
+
+	main_uart1_pins_default: main-uart1-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0180, PIN_INPUT, 2) /* (A8) MCASP0_AXR3.UART1_CTSn */
+			AM62LX_IOPAD(0x0184, PIN_OUTPUT, 2) /* (B10) MCASP0_AXR2.UART1_RTSn */
+			AM62LX_IOPAD(0x0198, PIN_INPUT, 2) /* (C11) MCASP0_AFSR.UART1_RXD */
+			AM62LX_IOPAD(0x019c, PIN_OUTPUT, 2) /* (A12) MCASP0_ACLKR.UART1_TXD */
+		>;
+		bootph-all;
+	};
+
+	main_i2c0_pins_default: main-i2c0-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01cc, PIN_INPUT_PULLUP, 0) /* (B7) I2C0_SCL */
+			AM62LX_IOPAD(0x01d0, PIN_INPUT_PULLUP, 0) /* (A7) I2C0_SDA */
+		>;
+		bootph-all;
+	};
+
+	main_i2c1_pins_default: main-i2c1-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01d4, PIN_INPUT_PULLUP, 0) /* (D7) I2C1_SCL */
+			AM62LX_IOPAD(0x01d8, PIN_INPUT_PULLUP, 0) /* (A6) I2C1_SDA */
+		>;
+		bootph-all;
+	};
+
+	main_i2c2_pins_default: main-i2c2-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01dc, PIN_INPUT_PULLUP, 0) /* (B8) I2C2_SCL */
+			AM62LX_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (D8) I2C2_SDA */
+		>;
+	};
+
+	ospi0_pins_default: ospi0-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x003c, PIN_OUTPUT, 0) /* (D22) OSPI0_CLK */
+			AM62LX_IOPAD(0x0068, PIN_OUTPUT, 0) /* (C20) OSPI0_CSn0 */
+			AM62LX_IOPAD(0x0074, PIN_OUTPUT, 0) /* (C23) OSPI0_CSn3 */
+			AM62LX_IOPAD(0x0048, PIN_INPUT, 0) /* (C22) OSPI0_D0 */
+			AM62LX_IOPAD(0x004c, PIN_INPUT, 0) /* (D21) OSPI0_D1 */
+			AM62LX_IOPAD(0x0050, PIN_INPUT, 0) /* (E23) OSPI0_D2 */
+			AM62LX_IOPAD(0x0054, PIN_INPUT, 0) /* (D23) OSPI0_D3 */
+			AM62LX_IOPAD(0x0058, PIN_INPUT, 0) /* (F21) OSPI0_D4 */
+			AM62LX_IOPAD(0x005c, PIN_INPUT, 0) /* (F19) OSPI0_D5 */
+			AM62LX_IOPAD(0x0060, PIN_INPUT, 0) /* (G20) OSPI0_D6 */
+			AM62LX_IOPAD(0x0064, PIN_INPUT, 0) /* (F20) OSPI0_D7 */
+			AM62LX_IOPAD(0x0044, PIN_INPUT, 0) /* (E22) OSPI0_DQS */
+			AM62LX_IOPAD(0x0040, PIN_INPUT, 0) /* (E18) OSPI0_LBCLKO */
+		>;
+	};
+
+	main_gpio0_ioexp_intr_pins_default: main-gpio0-ioexp-intr-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01b0, PIN_INPUT, 7) /* (B12) SPI0_D1.GPIO0_91 */
+		>;
+		bootph-all;
+	};
+
+	usr_led_pins_default: usr-led-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0238, PIN_OUTPUT, 7) /* (D24) MMC1_SDWP.GPIO0_123 */
+		>;
+	};
+
+	usr_button_pins_default: usr-button-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01ac, PIN_INPUT, 7) /* (E12) SPI0_D0.GPIO0_90 */
+		>;
+	};
+
+	main_mmc0_pins_default: main-mmc0-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0214, PIN_INPUT_PULLUP, 0) /* (D2) MMC0_CMD */
+			AM62LX_IOPAD(0x020c, PIN_OUTPUT, 0) /* (B2) MMC0_CLK */
+			AM62LX_IOPAD(0x0208, PIN_INPUT_PULLUP, 0) /* (D3) MMC0_DAT0 */
+			AM62LX_IOPAD(0x0204, PIN_INPUT_PULLUP, 0) /* (D4) MMC0_DAT1 */
+			AM62LX_IOPAD(0x0200, PIN_INPUT_PULLUP, 0) /* (C1) MMC0_DAT2 */
+			AM62LX_IOPAD(0x01fc, PIN_INPUT_PULLUP, 0) /* (C2) MMC0_DAT3 */
+			AM62LX_IOPAD(0x01f8, PIN_INPUT_PULLUP, 0) /* (C4) MMC0_DAT4 */
+			AM62LX_IOPAD(0x01f4, PIN_INPUT_PULLUP, 0) /* (B3) MMC0_DAT5 */
+			AM62LX_IOPAD(0x01f0, PIN_INPUT_PULLUP, 0) /* (A3) MMC0_DAT6 */
+			AM62LX_IOPAD(0x01ec, PIN_INPUT_PULLUP, 0) /* (B4) MMC0_DAT7 */
+		>;
+		bootph-all;
+	};
+
+	main_mmc1_pins_default: main-mmc1-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0230, PIN_INPUT, 0) /* (Y3) MMC1_CMD */
+			AM62LX_IOPAD(0x0228, PIN_OUTPUT, 0) /* (Y2) MMC1_CLK */
+			AM62LX_IOPAD(0x0224, PIN_INPUT, 0) /* (AA1) MMC1_DAT0 */
+			AM62LX_IOPAD(0x0220, PIN_INPUT_PULLUP, 0) /* (Y4) MMC1_DAT1 */
+			AM62LX_IOPAD(0x021c, PIN_INPUT_PULLUP, 0) /* (AA2) MMC1_DAT2 */
+			AM62LX_IOPAD(0x0218, PIN_INPUT_PULLUP, 0) /* (AB2) MMC1_DAT3 */
+			AM62LX_IOPAD(0x0234, PIN_INPUT, 0) /* (B6) MMC1_SDCD */
+		>;
+		bootph-all;
+	};
+
+	main_dpi_pins_default: main-dpi-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x00e4, PIN_OUTPUT, 1) /* (L20) GPMC0_CSn0.VOUT0_VSYNC */
+			AM62LX_IOPAD(0x00dc, PIN_OUTPUT, 1) /* (N21) GPMC0_WPn.VOUT0_HSYNC */
+			AM62LX_IOPAD(0x00e8, PIN_OUTPUT, 1) /* (L19) GPMC0_CSn1.VOUT0_PCLK */
+			AM62LX_IOPAD(0x00e0, PIN_OUTPUT, 1) /* (M21) GPMC0_DIR.VOUT0_DE */
+			AM62LX_IOPAD(0x0078, PIN_OUTPUT, 1) /* (L22) GPMC0_AD0.VOUT0_DATA0 */
+			AM62LX_IOPAD(0x007c, PIN_OUTPUT, 1) /* (L23) GPMC0_AD1.VOUT0_DATA1 */
+			AM62LX_IOPAD(0x0080, PIN_OUTPUT, 1) /* (K22) GPMC0_AD2.VOUT0_DATA2 */
+			AM62LX_IOPAD(0x0084, PIN_OUTPUT, 1) /* (J23) GPMC0_AD3.VOUT0_DATA3 */
+			AM62LX_IOPAD(0x0088, PIN_OUTPUT, 1) /* (K23) GPMC0_AD4.VOUT0_DATA4 */
+			AM62LX_IOPAD(0x008c, PIN_OUTPUT, 1) /* (H22) GPMC0_AD5.VOUT0_DATA5 */
+			AM62LX_IOPAD(0x0090, PIN_OUTPUT, 1) /* (H23) GPMC0_AD6.VOUT0_DATA6 */
+			AM62LX_IOPAD(0x0094, PIN_OUTPUT, 1) /* (J22) GPMC0_AD7.VOUT0_DATA7 */
+			AM62LX_IOPAD(0x0098, PIN_OUTPUT, 1) /* (H19) GPMC0_AD8.VOUT0_DATA8 */
+			AM62LX_IOPAD(0x009c, PIN_OUTPUT, 1) /* (H20) GPMC0_AD9.VOUT0_DATA9 */
+			AM62LX_IOPAD(0x00a0, PIN_OUTPUT, 1) /* (H21) GPMC0_AD10.VOUT0_DATA10 */
+			AM62LX_IOPAD(0x00a4, PIN_OUTPUT, 1) /* (H18) GPMC0_AD11.VOUT0_DATA11 */
+			AM62LX_IOPAD(0x00a8, PIN_OUTPUT, 1) /* (G23) GPMC0_AD12.VOUT0_DATA12 */
+			AM62LX_IOPAD(0x00ac, PIN_OUTPUT, 1) /* (G22) GPMC0_AD13.VOUT0_DATA13 */
+			AM62LX_IOPAD(0x00b0, PIN_OUTPUT, 1) /* (F22) GPMC0_AD14.VOUT0_DATA14 */
+			AM62LX_IOPAD(0x00b4, PIN_OUTPUT, 1) /* (F23) GPMC0_AD15.VOUT0_DATA15 */
+			AM62LX_IOPAD(0x00b8, PIN_OUTPUT, 1) /* (L21) GPMC0_CLK.VOUT0_DATA16 */
+			AM62LX_IOPAD(0x00c0, PIN_OUTPUT, 1) /* (N19) GPMC0_ADVn_ALE.VOUT0_DATA17 */
+			AM62LX_IOPAD(0x00c4, PIN_OUTPUT, 1) /* (N20) GPMC0_OEn_REn.VOUT0_DATA18 */
+			AM62LX_IOPAD(0x00c8, PIN_OUTPUT, 1) /* (M19) GPMC0_WEn.VOUT0_DATA19 */
+			AM62LX_IOPAD(0x00cc, PIN_OUTPUT, 1) /* (P23) GPMC0_BE0n_CLE.VOUT0_DATA20 */
+			AM62LX_IOPAD(0x00d0, PIN_OUTPUT, 1) /* (P22) GPMC0_BE1n.VOUT0_DATA21 */
+			AM62LX_IOPAD(0x00d4, PIN_OUTPUT, 1) /* (N23) GPMC0_WAIT0.VOUT0_DATA22 */
+			AM62LX_IOPAD(0x00d8, PIN_OUTPUT, 1) /* (N22) GPMC0_WAIT1.VOUT0_DATA23 */
+			AM62LX_IOPAD(0x00ec, PIN_OUTPUT, 5) /* (M23) GPMC0_CSn2.VOUT0_EXTPCLKIN */
+		>;
+		bootph-all;
+	};
+
+	main_mcan0_pins_default: main-mcan0-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01c8, PIN_INPUT, 0) /* (B15) MCAN0_RX */
+			AM62LX_IOPAD(0x01c4, PIN_OUTPUT, 0) /* (B16) MCAN0_TX */
+		>;
+	};
+
+	main_mcan2_pins_default: main-mcan2-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01bc, PIN_INPUT, 6) /* (B14) UART0_CTSn.MCAN2_RX */
+			AM62LX_IOPAD(0x01c0, PIN_OUTPUT, 6) /* (B13) UART0_RTSn.MCAN2_TX */
+		>;
+	};
+
+	gpmc0_pins_default: gpmc0-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0078, PIN_INPUT, 0) /* (L22) GPMC0_AD0 */
+			AM62LX_IOPAD(0x007c, PIN_INPUT, 0) /* (L23) GPMC0_AD1 */
+			AM62LX_IOPAD(0x0080, PIN_INPUT, 0) /* (K22) GPMC0_AD2 */
+			AM62LX_IOPAD(0x0084, PIN_INPUT, 0) /* (J23) GPMC0_AD3 */
+			AM62LX_IOPAD(0x0088, PIN_INPUT, 0) /* (K23) GPMC0_AD4 */
+			AM62LX_IOPAD(0x008c, PIN_INPUT, 0) /* (H22) GPMC0_AD5 */
+			AM62LX_IOPAD(0x0090, PIN_INPUT, 0) /* (H23) GPMC0_AD6 */
+			AM62LX_IOPAD(0x0094, PIN_INPUT, 0) /* (J22) GPMC0_AD7 */
+			AM62LX_IOPAD(0x00d4, PIN_INPUT, 0) /* (N23) GPMC0_WAIT0 */
+			AM62LX_IOPAD(0x00e4, PIN_OUTPUT, 0) /* (L20) GPMC0_CSn0 */
+			AM62LX_IOPAD(0x00c0, PIN_OUTPUT, 0) /* (N19) GPMC0_ADVn_ALE */
+			AM62LX_IOPAD(0x00c4, PIN_OUTPUT, 0) /* (N20) GPMC0_OEn_REn */
+			AM62LX_IOPAD(0x00c8, PIN_OUTPUT, 0) /* (M19) GPMC0_WEn */
+			AM62LX_IOPAD(0x00cc, PIN_OUTPUT, 0) /* (P23) GPMC0_BE0n_CLE */
+			AM62LX_IOPAD(0x00dc, PIN_OUTPUT, 0) /* (N21) GPMC0_WPn */
+		>;
+	};
+
+	rgmii1_pins_default: rgmii1-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x0138, PIN_INPUT, 0) /* (Y8) RGMII1_RD0 */
+			AM62PX_IOPAD(0x013c, PIN_INPUT, 0) /* (AA6) RGMII1_RD1 */
+			AM62PX_IOPAD(0x0140, PIN_INPUT, 0) /* (AA8) RGMII1_RD2 */
+			AM62PX_IOPAD(0x0144, PIN_INPUT, 0) /* (W8) RGMII1_RD3 */
+			AM62PX_IOPAD(0x0134, PIN_INPUT, 0) /* (Y7) RGMII1_RXC */
+			AM62PX_IOPAD(0x0130, PIN_INPUT, 0) /* (Y6) RGMII1_RX_CTL */
+			AM62PX_IOPAD(0x0120, PIN_OUTPUT, 0) /* (AC10) RGMII1_TD0 */
+			AM62PX_IOPAD(0x0124, PIN_OUTPUT, 0) /* (W13) RGMII1_TD1 */
+			AM62PX_IOPAD(0x0128, PIN_OUTPUT, 0) /* (Y11) RGMII1_TD2 */
+			AM62PX_IOPAD(0x012c, PIN_OUTPUT, 0) /* (AA11) RGMII1_TD3 */
+			AM62PX_IOPAD(0x011c, PIN_OUTPUT, 0) /* (W11) RGMII1_TXC */
+			AM62PX_IOPAD(0x0118, PIN_OUTPUT, 0) /* (AB11) RGMII1_TX_CTL */
+		>;
+	};
+
+	rgmii2_pins_default: rgmii2-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x0170, PIN_INPUT, 0) /* (AB9) RGMII2_RD0 */
+			AM62PX_IOPAD(0x0174, PIN_INPUT, 0) /* (AC9) RGMII2_RD1 */
+			AM62PX_IOPAD(0x0178, PIN_INPUT, 0) /* (AB10) RGMII2_RD2 */
+			AM62PX_IOPAD(0x017c, PIN_INPUT, 0) /* (AB8) RGMII2_RD3 */
+			AM62PX_IOPAD(0x016c, PIN_INPUT, 0) /* (AC7) RGMII2_RXC */
+			AM62PX_IOPAD(0x0168, PIN_INPUT, 0) /* (AC8) RGMII2_RX_CTL */
+			AM62PX_IOPAD(0x0158, PIN_OUTPUT, 0) /* (AC12) RGMII2_TD0 */
+			AM62PX_IOPAD(0x015c, PIN_OUTPUT, 0) /* (AB13) RGMII2_TD1 */
+			AM62PX_IOPAD(0x0160, PIN_OUTPUT, 0) /* (AA12) RGMII2_TD2 */
+			AM62PX_IOPAD(0x0164, PIN_OUTPUT, 0) /* (AA13) RGMII2_TD3 */
+			AM62PX_IOPAD(0x0154, PIN_OUTPUT, 0) /* (Y13) RGMII2_TXC */
+			AM62PX_IOPAD(0x0150, PIN_OUTPUT, 0) /* (AB12) RGMII2_TX_CTL */
+		>;
+	};
+
+	mdio1_pins_default: mdio1-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x014c, PIN_OUTPUT, 0) /* (AC15) MDIO0_MDC */
+			AM62PX_IOPAD(0x0148, PIN_INPUT, 0) /* (AC13) MDIO0_MDIO */
+		>;
+	};
+
+	main_usb1_default_pins: main-usb1-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0248, PIN_INPUT | PIN_DS_PULLUD_ENABLE | PIN_DS_PULL_UP, 0) /* (A5) USB1_DRVVBUS */
+		>;
+	};
+
+	main_mcasp0_pins_default: main-mcasp0-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x0190, PIN_INPUT, 0) /* (A11) MCASP0_ACLKX */
+			AM62PX_IOPAD(0x0194, PIN_INPUT, 0) /* (B11) MCASP0_AFSX */
+			AM62PX_IOPAD(0x018c, PIN_INPUT, 0) /* (B9) MCASP0_AXR0 */
+			AM62PX_IOPAD(0x0188, PIN_INPUT, 0) /* (A9) MCASP0_AXR1 */
+		>;
+	};
+
+	pmic_irq_pins_default: pmic-irq-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01e8, PIN_INPUT, 0) /* (C8) EXTINTn */
+		>;
+	};
+
+	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0010, PIN_INPUT_PULLUP, 0) /* (AB22) WKUP_I2C0_SCL */
+			AM62LX_IOPAD(0x0014, PIN_INPUT_PULLUP, 0) /* (AA22) WKUP_I2C0_SDA */
+		>;
+	};
+};
+
+&main_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart0_pins_default>;
+	status = "okay";
+	bootph-all;
+};
+
+&main_uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart1_pins_default>;
+	status = "okay";
+	bootph-all;
+};
+
+&main_i2c0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+	bootph-all;
+
+	eeprom@51 {
+		/* AT24C512C-MAHM-T or M24512-DFMC6TG */
+		compatible = "atmel,24c512";
+		reg = <0x51>;
+	};
+};
+
+&main_i2c1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	clock-frequency = <100000>;
+	bootph-all;
+
+	exp1: gpio@22 {
+		compatible = "ti,tca6424";
+		reg = <0x22>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "", "",
+				   "UART1_FET_SEL", "MMC1_SD_EN",
+				   "VPP_EN", "EXP_PS_3V3_EN",
+				   "UART1_FET_BUF_EN", "",
+				   "DSI_GPIO0", "DSI_GPIO1",
+				   "", "BT_UART_WAKE_SOC_3V3",
+				   "USB_TYPEA_OC_INDICATION", "",
+				   "", "WLAN_ALERTn",
+				   "HDMI_INTn", "TEST_GPIO2",
+				   "MCASP0_FET_EN", "MCASP0_BUF_BT_EN",
+				   "MCASP0_FET_SEL", "DSI_EDID",
+				   "PD_I2C_IRQ", "IO_EXP_TEST_LED";
+
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <91 IRQ_TYPE_EDGE_FALLING>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_gpio0_ioexp_intr_pins_default>;
+		bootph-all;
+	};
+
+	exp2: gpio@23 {
+		compatible = "ti,tca6424";
+		reg = <0x23>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "BT_EN_SOC", "VOUT0_FET_SEL0",
+				   "", "",
+				   "", "",
+				   "", "",
+				   "WL_LT_EN", "EXP_PS_5V0_EN",
+				   "TP45", "TP48",
+				   "TP46", "TP49",
+				   "TP47", "TP50",
+				   "GPIO_QSPI_NAND_RSTn", "GPIO_HDMI_RSTn",
+				   "GPIO_CPSW1_RST", "GPIO_CPSW2_RST",
+				   "", "GPIO_AUD_RSTn",
+				   "GPIO_eMMC_RSTn", "SoC_WLAN_SDIO_RST";
+		bootph-all;
+	};
+
+	sii9022: bridge-hdmi@3b {
+		compatible = "sil,sii9022";
+		reg = <0x3b>;
+		interrupt-parent = <&exp1>;
+		interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
+		#sound-dai-cells = <0>;
+		sil,i2s-data-lanes = < 0 >;
+		bootph-all;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				sii9022_in: endpoint {
+					remote-endpoint = <&dpi_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				sii9022_out: endpoint {
+					remote-endpoint = <&hdmi_connector_in>;
+				};
+			};
+		};
+	};
+
+	tlv320aic3106: audio-codec@1b {
+		#sound-dai-cells = <0>;
+		compatible = "ti,tlv320aic3106";
+		reg = <0x1b>;
+		ai3x-micbias-vg = <1>;	/* 2.0V */
+
+		/* Regulators */
+		AVDD-supply = <&vcc_3v3_sys>;
+		IOVDD-supply = <&vcc_3v3_sys>;
+		DRVDD-supply = <&vcc_3v3_sys>;
+		DVDD-supply = <&vcc_1v8>;
+	};
+};
+
+&main_i2c2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c2_pins_default>;
+	clock-frequency = <400000>;
+
+	typec_pd0: tps6598x@3f {
+		compatible = "ti,tps6598x";
+		reg = <0x3f>;
+
+		connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			self-powered;
+			data-role = "dual";
+			power-role = "sink";
+			port {
+				usb_con_hs: endpoint {
+					remote-endpoint = <&usb0_hs_ep>;
+				};
+			};
+		};
+	};
+};
+
+&wkup_i2c0 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_i2c0_pins_default>;
+	status = "okay";
+
+	tps65214: pmic@30 {
+		compatible = "ti,tps65214";
+		reg = <0x30>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-0 = <&pmic_irq_pins_default>;
+		ti,power-button;
+
+		buck1-supply = <&vmain_pd>;
+		buck2-supply = <&vmain_pd>;
+		buck3-supply = <&vmain_pd>;
+		ldo1-supply = <&vmain_pd>;
+		ldo2-supply = <&vmain_pd>;
+
+		regulators {
+			buck1_reg: buck1 {
+				regulator-name = "VDD_CORE";
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			buck2_reg: buck2 {
+				regulator-name = "DVDD_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			buck3_reg: buck3 {
+				regulator-name = "VDD_LPDDR4";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			ldo1_reg: ldo1 {
+				regulator-name = "VDD_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			ldo2_reg: ldo2 {
+				regulator-name = "VDDA_V75";
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+		};
+	};
+};
+
+&main_gpio0 {
+	status = "okay";
+	bootph-all;
+};
+
+&main_gpio2 {
+	status = "okay";
+	bootph-all;
+};
+
+&sdhci0 {
+	/* eMMC */
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc0_pins_default>;
+	status = "okay";
+	bootph-all;
+};
+
+&sdhci1 {
+	/* SD/MMC */
+	vmmc-supply = <&vdd_mmc1>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc1_pins_default>;
+	status = "okay";
+	bootph-all;
+	disable-wp;
+};
+
+&ospi0 {
+	bootph-all;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&ospi0_pins_default>;
+
+	ospi0_nor: flash@0 {
+		bootph-all;
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <4>;
+		cdns,phy-mode;
+
+		partitions {
+			bootph-all;
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "ospi.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition@80000 {
+				label = "ospi.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition@280000 {
+				label = "ospi.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition@680000 {
+				label = "ospi.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition@6c0000 {
+				label = "ospi.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition@800000 {
+				label = "ospi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition@3fc0000 {
+				bootph-all;
+				label = "ospi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
+	};
+
+	ospi0_nand: flash@3 {
+		bootph-all;
+		compatible = "spi-nand";
+		reg = <0x3>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <2>;
+		cdns,phy-mode;
+
+		partitions {
+			bootph-all;
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "ospi_nand.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition@80000 {
+				label = "ospi_nand.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition@280000 {
+				label = "ospi_nand.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition@680000 {
+				label = "ospi_nand.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition@6c0000 {
+				label = "ospi_nand.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition@2000000 {
+				label = "ospi_nand.rootfs";
+				reg = <0x2000000 0x5fe0000>;
+			};
+
+			partition@7fe0000 {
+				bootph-all;
+				label = "ospi_nand.phypattern";
+				reg = <0x7fe0000 0x20000>;
+			};
+		};
+	};
+};
+
+&dss {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_dpi_pins_default>;
+	bootph-all;
+};
+
+&dss_ports {
+	/* VP1: DPI Output */
+	port@0 {
+		reg = <0>;
+
+		dpi_out: endpoint {
+			remote-endpoint = <&sii9022_in>;
+		};
+	};
+};
+
+&dphy_tx0 {
+	status = "okay";
+	bootph-all;
+};
+
+&dsi0 {
+	status = "okay";
+	bootph-all;
+};
+
+&main_mcan0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan0_pins_default>;
+	status = "okay";
+};
+
+&main_mcan2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan2_pins_default>;
+	status = "okay";
+};
+
+&tscadc0 {
+	status = "okay";
+
+	adc {
+		ti,adc-channels = <0 1 2 3>;
+	};
+};
+
+&cpsw3g {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins_default>,
+		    <&rgmii2_pins_default>;
+};
+
+&cpsw_port1 {
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&cpsw3g_phy0>;
+};
+
+&cpsw_port2 {
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&cpsw3g_phy1>;
+};
+
+&cpsw3g_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio1_pins_default>;
+	status = "okay";
+
+	cpsw3g_phy0: ethernet-phy@0 {
+		reg = <0>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		ti,min-output-impedance;
+	};
+
+	cpsw3g_phy1: ethernet-phy@1 {
+		reg = <1>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		ti,min-output-impedance;
+	};
+};
+
+&elm0 {
+	/*
+	 * status = "okay";
+	 * disable dss when enabling this
+	 */
+};
+
+&gpmc0 {
+	/*
+	 * status = "okay";
+	 * disable dss when enabling this
+	 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpmc0_pins_default>;
+	#address-cells = <2>;
+	#size-cells = <1>;
+	ranges = <0 0 0x00 0x51000000 0x01000000>; /* CS0 space. Min partition = 16MB */
+
+	nand@0,0 {
+		compatible = "ti,am64-nand";
+		reg = <0 0 64>;		/* device IO registers */
+		interrupt-parent = <&gpmc0>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc0 0 GPIO_ACTIVE_HIGH>;	/* gpmc_wait0 */
+		ti,nand-xfer-type = "prefetch-polled";
+		ti,nand-ecc-opt = "bch8";	/* BCH8: Bootrom limitation */
+		ti,elm-id = <&elm0>;
+		nand-bus-width = <8>;
+		gpmc,device-width = <1>;
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <40>;
+		gpmc,cs-wr-off-ns = <40>;
+		gpmc,adv-on-ns = <0>;
+		gpmc,adv-rd-off-ns = <25>;
+		gpmc,adv-wr-off-ns = <25>;
+		gpmc,we-on-ns = <0>;
+		gpmc,we-off-ns = <20>;
+		gpmc,oe-on-ns = <3>;
+		gpmc,oe-off-ns = <30>;
+		gpmc,access-ns = <30>;
+		gpmc,rd-cycle-ns = <40>;
+		gpmc,wr-cycle-ns = <40>;
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-delay-ns = <0>;
+		gpmc,clk-activation-ns = <0>;
+		gpmc,wr-access-ns = <40>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "NAND.tiboot3";
+				reg = <0x00000000 0x00080000>;	/* 512KB */
+			};
+			partition@80000 {
+				label = "NAND.tispl";
+				reg = <0x80000 0x180000>; /* 1.5M */
+			};
+			partition@200000 {
+				label = "NAND.u-boot";
+				reg = <0x00200000 0x00200000>;	/* 2M */
+			};
+			partition@400000 {
+				label = "NAND.tiboot3.backup";	/* 512KB */
+				reg = <0x00400000 0x00080000>;	/* BootROM looks at 4M */
+			};
+			partition@480000 {
+				label = "NAND.tispl.bin.backup";
+				reg = <0x00480000 0x180000>; /* 1.5M */
+			};
+			partition@600000 {
+				label = "NAND.u-boot.backup";
+				reg = <0x00600000 0x00200000>;	/* 2M */
+			};
+			partition@800000 {
+				label = "NAND.u-boot-env";
+				reg = <0x00800000 0x00040000>;	/* 256K */
+			};
+			partition@840000 {
+				label = "NAND.u-boot-env.backup";
+				reg = <0x00840000 0x00040000>;	/* 256K */
+			};
+			partition@880000 {
+				label = "NAND.file-system";
+				reg = <0x00880000 0x1f780000>;
+			};
+		};
+	};
+};
+
+&usbss0 {
+	status = "okay";
+	ti,vbus-divider;
+};
+
+&usb0 {
+	usb-role-switch;
+
+	port {
+		usb0_hs_ep: endpoint {
+			remote-endpoint = <&usb_con_hs>;
+		};
+	};
+};
+
+&usbss1 {
+	status = "okay";
+	ti,vbus-divider;
+};
+
+&usb1 {
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_usb1_default_pins>;
+};
+
+&mcasp0 {
+	status = "okay";
+	#sound-dai-cells = <0>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcasp0_pins_default>;
+
+	op-mode = <0>;          /* MCASP_IIS_MODE */
+	tdm-slots = <2>;
+
+	serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
+	       1 2 0 0
+	       0 0 0 0
+	       0 0 0 0
+	       0 0 0 0
+	>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l3-evm-ecap-capture.dtso b/arch/arm64/boot/dts/ti/k3-am62l3-evm-ecap-capture.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62l3-evm-ecap-capture.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l3-evm-ecap-capture.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for enabling ECAP in capture mode on AM62L3-EVM
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "k3-pinctrl.h"
+
+&pmx0 {
+	main_ecap2_capture_pins_default: main-ecap2-capture-pins-default {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0184, PIN_INPUT, 4) /* (B10) MCASP0_AXR2.ECAP2_IN_APWM_OUT */
+		>;
+	};
+};
+
+&main_uart1 {
+	status = "disabled";
+};
+
+&main_i2c1 {
+	gpio@22 {
+		fet_sel {
+			/* P02 - UART1_FET_SEL */
+			gpio-hog;
+			gpios = <2 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "UART1_FET_SEL";
+		};
+	};
+};
+
+&ecap2 {
+	/* ECAP in capture mode */
+	/* P2 of J6 */
+	compatible = "ti,am62-ecap-capture";
+	interrupt-parent = <&gic500>;
+	interrupts = <GIC_SPI 154 IRQ_TYPE_EDGE_RISING>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap2_capture_pins_default>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l3-evm-eqep.dtso b/arch/arm64/boot/dts/ti/k3-am62l3-evm-eqep.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62l3-evm-eqep.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l3-evm-eqep.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for enabling EQEP on AM62L3 EVM
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&pmx0 {
+	main_eqep0_pins_default: main-eqep0-pins-default {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x00cc, PIN_INPUT, 4) /* (P23) GPMC0_BE0n_CLE.EQEP0_A */
+			AM62LX_IOPAD(0x00d0, PIN_INPUT, 4) /* (P22) GPMC0_BE1n.EQEP0_B */
+			AM62LX_IOPAD(0x00d8, PIN_INPUT, 4) /* (N22) GPMC0_WAIT1.EQEP0_I */
+			AM62LX_IOPAD(0x00d4, PIN_INPUT, 4) /* (N23) GPMC0_WAIT0.EQEP0_S */
+		>;
+	};
+
+	main_eqep1_pins_default: main-eqep1-pins-default {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x00dc, PIN_INPUT, 4) /* (N21) GPMC0_WPn.EQEP1_A */
+			AM62LX_IOPAD(0x00e0, PIN_INPUT, 4) /* (M21) GPMC0_DIR.EQEP1_B */
+			AM62LX_IOPAD(0x00e4, PIN_INPUT, 4) /* (L20) GPMC0_CSn0.EQEP1_S */
+		>;
+	};
+};
+
+&dss {
+	status = "disabled";
+};
+
+&main_i2c1 {
+	gpio@23 {
+		fet_sel {
+			/* P01 - VOUT0_FET_SEL0 */
+			gpio-hog;
+			gpios = <1 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "VOUT0_FET_SEL0";
+		};
+	};
+};
+
+&eqep0 {
+	status = "okay";
+	/* A/B on pins 19/14 of J2 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_eqep0_pins_default>;
+};
+
+&eqep1 {
+	status = "okay";
+	/* A/B on pins 9/7 of J2 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_eqep1_pins_default>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l3-evm-lpmdemo.dts b/arch/arm64/boot/dts/ti/k3-am62l3-evm-lpmdemo.dts
--- a/arch/arm64/boot/dts/ti/k3-am62l3-evm-lpmdemo.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l3-evm-lpmdemo.dts	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0-only or MIT
+/*
+ * Low Power Mode Demo Device Tree file for the AM62L3 Starter Kit
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include "k3-am62l3.dtsi"
+#include "k3-pinctrl.h"
+
+/ {
+	compatible = "ti,am62l3-evm", "ti,am62l3";
+	model = "Texas Instruments AM62L3 EVM";
+
+	chosen {
+		stdout-path = &main_uart0;
+	};
+
+	memory@80000000 {
+		/* 2G RAM */
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
+		device_type = "memory";
+		bootph-all;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		secure_tfa_ddr: tfa@80000000 {
+			reg = <0x00 0x80000000 0x00 0x200000>;
+			no-map;
+			bootph-all;
+		};
+
+		secure_ddr: optee@80200000 {
+			reg = <0x00 0x80200000 0x00 0x800000>;
+			no-map;
+		};
+
+		tifs_ctx_ddr: tifs@80a00000 {
+			reg = <0x00 0x80a00000 0x00 0x800000>;
+			no-map;
+			bootph-all;
+		};
+	};
+
+	gpio_keys: gpio-keys {
+		compatible = "gpio-keys";
+		autorepeat;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usr_button_pins_default>;
+
+		usr: button-usr {
+			label = "User Key";
+			linux,code = <BTN_0>;
+			gpios = <&main_gpio0 90 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&usr_led_pins_default>;
+
+		led-0 {
+			label = "am62-sk:green:heartbeat";
+			gpios = <&main_gpio0 123 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+			function = LED_FUNCTION_HEARTBEAT;
+			default-state = "on";
+		};
+	};
+
+	vmain_pd: regulator-0 {
+		/* TPS65988 PD CONTROLLER OUTPUT */
+		bootph-all;
+		compatible = "regulator-fixed";
+		regulator-name = "vmain_pd";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vcc_3v3_sys: regulator-1 {
+		/* output of LM61460-Q1 */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3_sys";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vmain_pd>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vcc_1v8: regulator-3 {
+		/* output of TPS6282518DMQ */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_3v3_sys>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&pmx0 {
+	main_uart0_pins_default: main-uart0-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01b4, PIN_INPUT, 0)	/* (D13) UART0_RXD */
+			AM62LX_IOPAD(0x01b8, PIN_OUTPUT, 0)	/* (C13) UART0_TXD */
+		>;
+		bootph-all;
+	};
+
+	main_uart1_pins_default: main-uart1-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0180, PIN_INPUT, 2) /* (A8) MCASP0_AXR3.UART1_CTSn */
+			AM62LX_IOPAD(0x0184, PIN_OUTPUT, 2) /* (B10) MCASP0_AXR2.UART1_RTSn */
+			AM62LX_IOPAD(0x0198, PIN_INPUT, 2) /* (C11) MCASP0_AFSR.UART1_RXD */
+			AM62LX_IOPAD(0x019c, PIN_OUTPUT, 2) /* (A12) MCASP0_ACLKR.UART1_TXD */
+		>;
+		bootph-all;
+	};
+
+	main_i2c0_pins_default: main-i2c0-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01cc, PIN_INPUT_PULLUP, 0) /* (B7) I2C0_SCL */
+			AM62LX_IOPAD(0x01d0, PIN_INPUT_PULLUP, 0) /* (A7) I2C0_SDA */
+		>;
+		bootph-all;
+	};
+
+	main_i2c2_pins_default: main-i2c2-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01dc, PIN_INPUT_PULLUP, 0) /* (B8) I2C2_SCL */
+			AM62LX_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (D8) I2C2_SDA */
+		>;
+	};
+
+	main_gpio0_ioexp_intr_pins_default: main-gpio0-ioexp-intr-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01b0, PIN_INPUT, 7) /* (B12) SPI0_D1.GPIO0_91 */
+		>;
+		bootph-all;
+	};
+
+	usr_led_pins_default: usr-led-pins-default {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0238, PIN_OUTPUT, 7) /* (D24) MMC1_SDWP.GPIO0_123 */
+		>;
+	};
+
+	usr_button_pins_default: usr-button-pins-default {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x01ac, PIN_INPUT, 7) /* (E12) SPI0_D0.GPIO0_90 */
+		>;
+	};
+
+	main_mmc0_pins_default: main-mmc0-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0214, PIN_INPUT_PULLUP, 0) /* (D2) MMC0_CMD */
+			AM62LX_IOPAD(0x020c, PIN_OUTPUT, 0) /* (B2) MMC0_CLK */
+			AM62LX_IOPAD(0x0208, PIN_INPUT_PULLUP, 0) /* (D3) MMC0_DAT0 */
+			AM62LX_IOPAD(0x0204, PIN_INPUT_PULLUP, 0) /* (D4) MMC0_DAT1 */
+			AM62LX_IOPAD(0x0200, PIN_INPUT_PULLUP, 0) /* (C1) MMC0_DAT2 */
+			AM62LX_IOPAD(0x01fc, PIN_INPUT_PULLUP, 0) /* (C2) MMC0_DAT3 */
+			AM62LX_IOPAD(0x01f8, PIN_INPUT_PULLUP, 0) /* (C4) MMC0_DAT4 */
+			AM62LX_IOPAD(0x01f4, PIN_INPUT_PULLUP, 0) /* (B3) MMC0_DAT5 */
+			AM62LX_IOPAD(0x01f0, PIN_INPUT_PULLUP, 0) /* (A3) MMC0_DAT6 */
+			AM62LX_IOPAD(0x01ec, PIN_INPUT_PULLUP, 0) /* (B4) MMC0_DAT7 */
+		>;
+		bootph-all;
+	};
+
+	main_mmc1_pins_default: main-mmc1-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0230, PIN_INPUT, 0) /* (Y3) MMC1_CMD */
+			AM62LX_IOPAD(0x0228, PIN_OUTPUT, 0) /* (Y2) MMC1_CLK */
+			AM62LX_IOPAD(0x0224, PIN_INPUT, 0) /* (AA1) MMC1_DAT0 */
+			AM62LX_IOPAD(0x0220, PIN_INPUT_PULLUP, 0) /* (Y4) MMC1_DAT1 */
+			AM62LX_IOPAD(0x021c, PIN_INPUT_PULLUP, 0) /* (AA2) MMC1_DAT2 */
+			AM62LX_IOPAD(0x0218, PIN_INPUT_PULLUP, 0) /* (AB2) MMC1_DAT3 */
+			AM62LX_IOPAD(0x0234, PIN_INPUT, 0) /* (B6) MMC1_SDCD */
+		>;
+		bootph-all;
+	};
+
+};
+
+&main_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart0_pins_default>;
+	status = "okay";
+	bootph-all;
+};
+
+&main_uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart1_pins_default>;
+	status = "okay";
+	bootph-all;
+};
+
+&main_i2c0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+	bootph-all;
+
+	eeprom@51 {
+		/* AT24C512C-MAHM-T or M24512-DFMC6TG */
+		compatible = "atmel,24c512";
+		reg = <0x51>;
+	};
+};
+
+&main_i2c2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c2_pins_default>;
+	clock-frequency = <400000>;
+};
+
+&main_gpio0 {
+	status = "okay";
+	bootph-all;
+};
+
+&main_gpio2 {
+	status = "okay";
+	bootph-all;
+};
+
+&sdhci0 {
+	/* eMMC */
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc0_pins_default>;
+	status = "okay";
+	bootph-all;
+};
+
+&sdhci1 {
+	/* SD/MMC */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc1_pins_default>;
+	status = "okay";
+	bootph-all;
+};
+
+/delete-node/ &main_rti1;
+/delete-node/ &main_bcdma;
+/delete-node/ &mcasp0;
+/delete-node/ &mcasp1;
+/delete-node/ &mcasp2;
+/delete-node/ &crypto;
+/delete-node/ &main_uart1;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l3-evm-m2-cc3351.dtso b/arch/arm64/boot/dts/ti/k3-am62l3-evm-m2-cc3351.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62l3-evm-m2-cc3351.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l3-evm-m2-cc3351.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * DT Overlay for M.2-CC3351 board to connect to the M.2 connector on AM62L-EVM.
+ *
+ * Product page for board: https://www.ti.com/tool/M2-CC3351
+ * CC3351 Datasheet: https://www.ti.com/lit/ds/symlink/cc3351.pdf
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	wlan_lten: regulator-30 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan_lten";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpios = <&exp2 8 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	wlan_en: regulator-31 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan_en";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&wlan_lten>;
+		enable-active-high;
+		gpios = <&main_gpio0 51 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wlan_en_pins_default>;
+	};
+};
+
+&pmx0 {
+	main_mmc2_pins_default: main-mmc2-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x010c, PIN_INPUT, 0) /* (U23) MMC2_CMD */
+			AM62LX_IOPAD(0x0104, PIN_OUTPUT, 0) /* (R23) MMC2_CLK */
+			AM62LX_IOPAD(0x0108, PIN_INPUT, 0) /* () MMC2_CLKLB */
+			AM62LX_IOPAD(0x0100, PIN_INPUT, 0) /* (U22) MMC2_DAT0 */
+			AM62LX_IOPAD(0x00fc, PIN_INPUT, 0) /* (T22) MMC2_DAT1 */
+			AM62LX_IOPAD(0x00f8, PIN_INPUT, 0) /* (T23) MMC2_DAT2 */
+			AM62LX_IOPAD(0x00f4, PIN_INPUT, 0) /* (R22) MMC2_DAT3 */
+		>;
+	};
+
+	wlan_en_pins_default: wlan-en-pins-default {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0110, PIN_OUTPUT, 7) /* (T20) MMC2_SDCD.GPIO0_51 */
+		>;
+	};
+
+	main_wlirq_pins_default: main-wlirq-pins-default {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0114, PIN_INPUT, 7) /* (T21) MMC2_SDWP.GPIO0_52 */
+		>;
+	};
+};
+
+&sdhci2 {
+	bootph-all;
+	vmmc-supply = <&wlan_en>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc2_pins_default>;
+	bus-width = <4>;
+	non-removable;
+	ti,fails-without-test-cd;
+	cap-power-off-card;
+	keep-power-in-suspend;
+	ti,driver-strength-ohm = <50>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	wlcore: wlcore@2 {
+		compatible = "ti,cc3300";
+		reg = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_wlirq_pins_default>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <52 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l3-evm-nand.dtso b/arch/arm64/boot/dts/ti/k3-am62l3-evm-nand.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62l3-evm-nand.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l3-evm-nand.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "k3-pinctrl.h"
+
+&dss {
+	status = "disabled";
+};
+
+&pmx0 {
+	gpmc0_pins_default: gpmc0-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0078, PIN_INPUT, 0) /* (L22) GPMC0_AD0 */
+			AM62LX_IOPAD(0x007c, PIN_INPUT, 0) /* (L23) GPMC0_AD1 */
+			AM62LX_IOPAD(0x0080, PIN_INPUT, 0) /* (K22) GPMC0_AD2 */
+			AM62LX_IOPAD(0x0084, PIN_INPUT, 0) /* (J23) GPMC0_AD3 */
+			AM62LX_IOPAD(0x0088, PIN_INPUT, 0) /* (K23) GPMC0_AD4 */
+			AM62LX_IOPAD(0x008c, PIN_INPUT, 0) /* (H22) GPMC0_AD5 */
+			AM62LX_IOPAD(0x0090, PIN_INPUT, 0) /* (H23) GPMC0_AD6 */
+			AM62LX_IOPAD(0x0094, PIN_INPUT, 0) /* (J22) GPMC0_AD7 */
+			AM62LX_IOPAD(0x00d4, PIN_INPUT, 0) /* (N23) GPMC0_WAIT0 */
+			AM62LX_IOPAD(0x00e4, PIN_OUTPUT, 0) /* (L20) GPMC0_CSn0 */
+			AM62LX_IOPAD(0x00c0, PIN_OUTPUT, 0) /* (N19) GPMC0_ADVn_ALE */
+			AM62LX_IOPAD(0x00c4, PIN_OUTPUT, 0) /* (N20) GPMC0_OEn_REn */
+			AM62LX_IOPAD(0x00c8, PIN_OUTPUT, 0) /* (M19) GPMC0_WEn */
+			AM62LX_IOPAD(0x00cc, PIN_OUTPUT, 0) /* (P23) GPMC0_BE0n_CLE */
+			AM62LX_IOPAD(0x00dc, PIN_OUTPUT, 0) /* (N21) GPMC0_WPn */
+		>;
+		bootph-all;
+	};
+};
+
+&elm0 {
+	status = "okay";
+	bootph-all;
+};
+
+&gpmc0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpmc0_pins_default>;
+	#address-cells = <2>;
+	#size-cells = <1>;
+	ranges = <0 0 0x00 0x51000000 0x01000000>; /* CS0 space. Min partition = 16MB */
+
+	nand@0,0 {
+		compatible = "ti,am64-nand";
+		reg = <0 0 64>;		/* device IO registers */
+		interrupt-parent = <&gpmc0>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc0 0 GPIO_ACTIVE_HIGH>;	/* gpmc_wait0 */
+		ti,nand-xfer-type = "prefetch-polled";
+		ti,nand-ecc-opt = "bch8";	/* BCH8: Bootrom limitation */
+		ti,elm-id = <&elm0>;
+		nand-bus-width = <8>;
+		gpmc,device-width = <1>;
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <40>;
+		gpmc,cs-wr-off-ns = <40>;
+		gpmc,adv-on-ns = <0>;
+		gpmc,adv-rd-off-ns = <25>;
+		gpmc,adv-wr-off-ns = <25>;
+		gpmc,we-on-ns = <0>;
+		gpmc,we-off-ns = <20>;
+		gpmc,oe-on-ns = <3>;
+		gpmc,oe-off-ns = <30>;
+		gpmc,access-ns = <30>;
+		gpmc,rd-cycle-ns = <40>;
+		gpmc,wr-cycle-ns = <40>;
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-delay-ns = <0>;
+		gpmc,clk-activation-ns = <0>;
+		gpmc,wr-access-ns = <40>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+		bootph-all;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "NAND.tiboot3";
+				reg = <0x00000000 0x00080000>;	/* 512KB */
+			};
+			partition@80000 {
+				label = "NAND.tispl";
+				reg = <0x80000 0x180000>; /* 1.5M */
+			};
+			 partition@200000 {
+				label = "NAND.u-boot";
+				reg = <0x00200000 0x00200000>;  /* 2M */
+			};
+			partition@400000 {
+				label = "NAND.tiboot3.backup";	/* 512KB */
+				reg = <0x00400000 0x00080000>;	/* BootROM looks at 4M */
+			};
+			partition@480000 {
+				label = "NAND.tispl.backup";
+				reg = <0x00480000 0x180000>; /* 1.5M */
+			};
+			partition@600000 {
+				label = "NAND.u-boot.backup";
+				reg = <0x00600000 0x00200000>;  /* 2M */
+			};
+			partition@800000 {
+				label = "NAND.u-boot-env";
+				reg = <0x00800000 0x00040000>;  /* 256K */
+			};
+			partition@840000 {
+				label = "NAND.u-boot-env.backup";
+				reg = <0x00840000 0x00040000>;  /* 256K */
+			};
+			partition@880000 {
+				label = "NAND.file-system";
+				reg = <0x00880000 0x1f780000>;
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l3-evm-pwm.dtso b/arch/arm64/boot/dts/ti/k3-am62l3-evm-pwm.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62l3-evm-pwm.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l3-evm-pwm.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ *
+ * DT Overlay for enabling PWM output on user expansion connector for AM62L3 EVM
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&pmx0 {
+	main_epwm0_pins_default: main-epwm0-pins-default {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x00ac, PIN_OUTPUT, 4) /* (G22) GPMC0_AD13.EHRPWM0_A */
+			AM62LX_IOPAD(0x00b0, PIN_OUTPUT, 4) /* (F22) GPMC0_AD14.EHRPWM0_B */
+		>;
+	};
+
+	main_epwm1_pins_default: main-epwm1-pins-default {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x00b4, PIN_OUTPUT, 4) /* (F23) GPMC0_AD15.EHRPWM1_A */
+			AM62LX_IOPAD(0x00b8, PIN_OUTPUT, 4) /* (L21) GPMC0_CLK.EHRPWM1_B */
+		>;
+	};
+
+	main_epwm2_pins_default: main-epwm2-pins-default {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x00c4, PIN_OUTPUT, 4) /* (N20) GPMC0_OEn_REn.EHRPWM2_A */
+			AM62LX_IOPAD(0x00c8, PIN_OUTPUT, 4) /* (M19) GPMC0_WEn.EHRPWM2_B */
+		>;
+	};
+
+	main_ecap0_pins_default: main-ecap0-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x0078, PIN_OUTPUT, 5) /* (L22) GPMC0_AD0.ECAP0_IN_APWM_OUT */
+		>;
+	};
+
+	main_ecap1_pins_default: main_ecap1-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x007c, PIN_OUTPUT, 5) /* (L23) GPMC0_AD1.ECAP1_IN_APWM_OUT */
+		>;
+	};
+
+	main_ecap2_pins_default: main-ecap2-default-pins {
+		pinctrl-single,pins = <
+			AM62LX_IOPAD(0x009c, PIN_OUTPUT, 5) /* (H20) GPMC0_AD9.ECAP2_IN_APWM_OUT */
+		>;
+	};
+};
+
+&main_i2c1 {
+	gpio@23 {
+		fet_sel {
+			/* P01 - VOUT0_FET_SEL0 */
+			gpio-hog;
+			gpios = <1 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "VOUT0_FET_SEL0";
+		};
+	};
+};
+
+&dss {
+	status = "disabled";
+};
+
+&epwm0 {
+	/* P18 on J2 & P7 on J3 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm0_pins_default>;
+	status = "okay";
+};
+
+&epwm1 {
+	/* P10 on J2 & P5 on J2 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm1_pins_default>;
+	status = "okay";
+};
+
+&epwm2 {
+	/* P4 on J2 & P1 on J2 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm2_pins_default>;
+	status = "okay";
+};
+
+&ecap0 {
+	/* ECAP0 in APWM mode */
+	/* P24 on J2 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap0_pins_default>;
+	status = "okay";
+};
+
+&ecap1 {
+	/* ECAP1 in APWM mode */
+	/* P26 on J2 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap1_pins_default>;
+	status = "okay";
+};
+
+&ecap2 {
+	/* ECAP2 in APWM mode */
+	/* P9 on J3 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap2_pins_default>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l.dtsi b/arch/arm64/boot/dts/ti/k3-am62l.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62l.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0-only or MIT
+/*
+ * Device Tree Source for AM62L SoC Family
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Technical Reference Manual: https://www.ti.com/lit/pdf/sprujb4
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "k3-pinctrl.h"
+
+/ {
+	model = "Texas Instruments K3 AM62L3 SoC";
+	compatible = "ti,am62l3";
+	interrupt-parent = <&gic500>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	firmware {
+		optee {
+			compatible = "linaro,optee-tz";
+			method = "smc";
+		};
+
+		psci: psci {
+			compatible = "arm,psci-1.0";
+			method = "smc";
+		};
+
+		scmi: scmi {
+			compatible = "arm,scmi-smc";
+			arm,smc-id = <0x82004000>;
+			shmem = <&scmi_shmem>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			scmi_clk: protocol@14 {
+				reg = <0x14>;
+				#clock-cells = <1>;
+				bootph-all;
+			};
+
+			scmi_pds: protocol@11 {
+				reg = <0x11>;
+				#power-domain-cells = <1>;
+				bootph-all;
+			};
+		};
+	};
+
+	a53_timer0: timer-cl0-cpu0 {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* cntpsirq */
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* cntpnsirq */
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* cntvirq */
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* cnthpirq */
+	};
+
+	pmu: pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	cbass_main: bus@f0000 {
+		compatible = "simple-bus";
+		ranges = <0x00 0x00600000 0x00 0x00600000 0x00 0x00010100>, /* GPIO */
+			 <0x00 0x00a40000 0x00 0x00a40000 0x00 0x00000800>, /* Timesync router */
+			 <0x00 0x00a80000 0x00 0x00a80000 0x00 0x00040000>, /* GTC */
+			 <0x00 0x01000000 0x00 0x01000000 0x00 0x01b28400>, /* First peripheral window */
+			 <0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* CPSW */
+			 <0x00 0x09000000 0x00 0x09000000 0x00 0x00400000>, /* CTRL MMRs */
+			 <0x00 0x0e000000 0x00 0x0e000000 0x00 0x01d20000>, /* Second peripheral window */
+			 <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */
+			 <0x00 0x301C0000 0x00 0x301C0000 0x00 0x00001000>, /* DPHY-TX */
+			 <0x00 0x30200000 0x00 0x30200000 0x00 0x00400000>, /* DSS */
+			 <0x00 0x30270000 0x00 0x30270000 0x00 0x00010000>, /* DSI Wrapper */
+			 <0x00 0x30500000 0x00 0x30500000 0x00 0x00100000>, /* DSI Config */
+			 <0x00 0x31000000 0x00 0x31000000 0x00 0x00050000>, /* USB0 DWC3 Core window */
+			 <0x00 0x31100000 0x00 0x31100000 0x00 0x00050000>, /* USB1 DWC3 Core window */
+			 <0x00 0x3b000000 0x00 0x3b000000 0x00 0x00001000>, /* GPMC0 */
+			 <0x00 0x47000000 0x00 0x47000000 0x00 0x02000000>, /* DMSS */
+			 <0x00 0x50000000 0x00 0x50000000 0x00 0x08000000>, /* GPMC DATA */
+			 <0x00 0x60000000 0x00 0x60000000 0x00 0x08000000>, /* FSS0 DAT1 */
+			 <0x00 0x70800000 0x00 0x70800000 0x00 0x00010000>, /* OCSRAM */
+			 <0x01 0x00000000 0x01 0x00000000 0x00 0x00310000>, /* A53 PERIPHBASE */
+			 <0x05 0x00000000 0x05 0x00000000 0x01 0x00000000>, /* FSS0 DAT3 */
+
+			 /* Wakeup Domain Range */
+			 <0x00 0x00b00000 0x00 0x00b00000 0x00 0x00001400>, /* VTM */
+			 <0x00 0x04080000 0x00 0x04080000 0x00 0x00008000>, /* PDCFG */
+			 <0x00 0x04201000 0x00 0x04201000 0x00 0x00000100>, /* GPIO */
+			 <0x00 0x2b100000 0x00 0x2b100000 0x00 0x00200200>, /* Peripheral window */
+			 <0x00 0x40800000 0x00 0x40800000 0x00 0x00014000>, /* DMA */
+			 <0x00 0x43000000 0x00 0x43000000 0x00 0x00080000>; /* CTRL MMRs */
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		cbass_wakeup:  bus@43000000 {
+			compatible = "simple-bus";
+			ranges = <0x00 0x00b00000 0x00 0x00b00000 0x00 0x00001400>, /* VTM */
+				 <0x00 0x04080000 0x00 0x04080000 0x00 0x00008000>, /* PDCFG */
+				 <0x00 0x04201000 0x00 0x04201000 0x00 0x00000100>, /* GPIO */
+				 <0x00 0x2b100000 0x00 0x2b100000 0x00 0x00200200>, /* Peripheral window */
+				 <0x00 0x40800000 0x00 0x40800000 0x00 0x00014000>, /* DMA */
+				 <0x00 0x43000000 0x00 0x43000000 0x00 0x00080000>; /* CTRL MMRs */
+			#address-cells = <2>;
+			#size-cells = <2>;
+			bootph-all;
+		};
+	};
+
+	#include "k3-am62l-thermal.dtsi"
+};
+
+/* Now include peripherals for each bus segment */
+#include "k3-am62l-main.dtsi"
+#include "k3-am62l-wakeup.dtsi"
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62l-main.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62l-main.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l-main.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,941 @@
+// SPDX-License-Identifier: GPL-2.0-only or MIT
+/*
+ * Device Tree file for the AM62L main domain peripherals
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Technical Reference Manual: https://www.ti.com/lit/pdf/sprujb4
+ */
+
+&cbass_main {
+	gic500: interrupt-controller@1800000 {
+		compatible = "arm,gic-v3";
+		reg = <0x00 0x01800000 0x00 0x10000>,	/* GICD */
+		      <0x00 0x01840000 0x00 0xc0000>,	/* GICR */
+		      <0x01 0x00000000 0x00 0x2000>,    /* GICC */
+		      <0x01 0x00010000 0x00 0x1000>,    /* GICH */
+		      <0x01 0x00020000 0x00 0x2000>;    /* GICV */
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		/*
+		 * vcpumntirq:
+		 * virtual CPU interface maintenance interrupt
+		 */
+		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+		gic_its: msi-controller@1820000 {
+			compatible = "arm,gic-v3-its";
+			reg = <0x00 0x01820000 0x00 0x10000>;
+			socionext,synquacer-pre-its = <0x1000000 0x400000>;
+			msi-controller;
+			#msi-cells = <1>;
+		};
+	};
+
+	main_gpio0: gpio@600000 {
+		compatible = "ti,am64-gpio", "ti,keystone-gpio";
+		reg = <0x00 0x00600000 0x00 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 260 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 261 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 262 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 263 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 264 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 265 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 266 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 267 IRQ_TYPE_EDGE_RISING>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <126>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&scmi_pds 34>;
+		clocks = <&scmi_clk 140>;
+		clock-names = "gpio";
+		status = "disabled";
+	};
+
+	main_gpio2: gpio@610000 {
+		compatible = "ti,am64-gpio", "ti,keystone-gpio";
+		reg = <0x00 0x00610000 0x00 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 280 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 281 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 282 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 283 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 284 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 285 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 286 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 287 IRQ_TYPE_EDGE_RISING>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <79>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&scmi_pds 35>;
+		clocks = <&scmi_clk 141>;
+		clock-names = "gpio";
+		status = "disabled";
+	};
+
+	main_timer0: timer@2400000 {
+		compatible = "ti,am654-timer";
+		reg = <0x00 0x2400000 0x00 0x400>;
+		interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&scmi_clk 47>;
+		clock-names = "fck";
+		power-domains = <&scmi_pds 15>;
+		ti,timer-pwm;
+	};
+
+	main_timer1: timer@2410000 {
+		compatible = "ti,am654-timer";
+		reg = <0x00 0x2410000 0x00 0x400>;
+		interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&scmi_clk 61>;
+		clock-names = "fck";
+		power-domains = <&scmi_pds 16>;
+		ti,timer-pwm;
+	};
+
+	main_timer2: timer@2420000 {
+		compatible = "ti,am654-timer";
+		reg = <0x00 0x2420000 0x00 0x400>;
+		interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&scmi_clk 66>;
+		clock-names = "fck";
+		power-domains = <&scmi_pds 17>;
+		ti,timer-pwm;
+	};
+
+	main_timer3: timer@2430000 {
+		compatible = "ti,am654-timer";
+		reg = <0x00 0x2430000 0x00 0x400>;
+		interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&scmi_clk 80>;
+		clock-names = "fck";
+		power-domains = <&scmi_pds 18>;
+		ti,timer-pwm;
+	};
+
+	main_uart0: serial@2800000 {
+		compatible = "ti,am64-uart", "ti,am654-uart";
+		reg = <0x00 0x02800000 0x00 0x100>;
+		interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&scmi_pds 89>;
+		clocks = <&scmi_clk 358>;
+		clock-names = "fclk";
+		status = "disabled";
+	};
+
+	main_uart1: serial@2810000 {
+		compatible = "ti,am64-uart", "ti,am654-uart";
+		reg = <0x00 0x02810000 0x00 0x100>;
+		interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&scmi_pds 77>;
+		clocks = <&scmi_clk 312>;
+		clock-names = "fclk";
+		status = "disabled";
+	};
+
+	main_uart2: serial@2820000 {
+		compatible = "ti,am64-uart", "ti,am654-uart";
+		reg = <0x00 0x02820000 0x00 0x100>;
+		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&scmi_pds 78>;
+		clocks = <&scmi_clk 314>;
+		clock-names = "fclk";
+		status = "disabled";
+	};
+
+	main_uart3: serial@2830000 {
+		compatible = "ti,am64-uart", "ti,am654-uart";
+		reg = <0x00 0x02830000 0x00 0x100>;
+		interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&scmi_pds 79>;
+		clocks = <&scmi_clk 316>;
+		clock-names = "fclk";
+		status = "disabled";
+	};
+
+	main_uart4: serial@2840000 {
+		compatible = "ti,am64-uart", "ti,am654-uart";
+		reg = <0x00 0x02840000 0x00 0x100>;
+		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&scmi_pds 80>;
+		clocks = <&scmi_clk 318>;
+		clock-names = "fclk";
+		status = "disabled";
+	};
+
+	main_uart5: serial@2850000 {
+		compatible = "ti,am64-uart", "ti,am654-uart";
+		reg = <0x00 0x02850000 0x00 0x100>;
+		interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&scmi_pds 81>;
+		clocks = <&scmi_clk 320>;
+		clock-names = "fclk";
+		status = "disabled";
+	};
+
+	main_uart6: serial@2860000 {
+		compatible = "ti,am64-uart", "ti,am654-uart";
+		reg = <0x00 0x02860000 0x00 0x100>;
+		interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&scmi_pds 82>;
+		clocks = <&scmi_clk 322>;
+		clock-names = "fclk";
+		status = "disabled";
+	};
+
+	main_conf: bus@9000000 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x00 0x09000000 0x400000>;
+
+		phy_gmii_sel: phy@1be000 {
+			compatible = "ti,am654-phy-gmii-sel";
+			reg = <0x1be000 0x8>;
+			#phy-cells = <1>;
+		};
+
+		epwm_tbclk: clock-controller@1e9100 {
+			compatible = "ti,am62-epwm-tbclk";
+			reg = <0x1e9100 0x4>;
+			#clock-cells = <1>;
+		};
+	};
+
+	main_rti0: watchdog@e000000 {
+		compatible = "ti,am62l-rti-wdt";
+		reg = <0x00 0x0e000000 0x00 0x100>;
+		clocks = <&scmi_clk 273>;
+		power-domains = <&scmi_pds 60>;
+		assigned-clocks = <&scmi_clk 273>;
+		assigned-clock-parents = <&scmi_clk 1>;
+	};
+
+	main_rti1: watchdog@e010000 {
+		compatible = "ti,am62l-rti-wdt";
+		reg = <0x00 0x0e010000 0x00 0x100>;
+		clocks = <&scmi_clk 279>;
+		power-domains = <&scmi_pds 61>;
+		assigned-clocks = <&scmi_clk 279>;
+		assigned-clock-parents = <&scmi_clk 1>;
+	};
+
+	fss: bus@fc00000 {
+		compatible = "simple-bus";
+		reg = <0x00 0x0fc00000 0x00 0x70000>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		ospi0: spi@fc40000 {
+			compatible = "ti,am654-ospi", "cdns,qspi-nor";
+			reg = <0x00 0x0fc40000 0x00 0x100>,
+			      <0x05 0x00000000 0x01 0x00000000>;
+			interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
+			cdns,fifo-depth = <256>;
+			cdns,fifo-width = <4>;
+			cdns,trigger-address = <0x0>;
+			cdns,phase-detect-selector = <2>;
+			clocks = <&scmi_clk 134>;
+			assigned-clocks = <&scmi_clk 134>;
+			assigned-clock-rates = <166666666>;
+			power-domains = <&scmi_pds 32>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+	};
+
+	usbss0: dwc3-usb@f900000 {
+		compatible = "ti,am62-usb";
+		reg = <0x00 0x0f900000 0x00 0x800>,
+		      <0x00 0x0f908000 0x00 0x400>;
+		clocks = <&scmi_clk 329>;
+		clock-names = "ref";
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		power-domains = <&scmi_pds 95>;
+		ranges;
+		status = "disabled";
+
+		usb0: usb@31000000 {
+			compatible = "snps,dwc3";
+			reg = <0x00 0x31000000 0x00 0x50000>;
+			interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+				     <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+			interrupt-names = "host", "peripheral";
+			maximum-speed = "high-speed";
+			dr_mode = "otg";
+			bootph-all;
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
+		};
+	};
+
+	usbss1: dwc3-usb@f910000 {
+		compatible = "ti,am62-usb";
+		reg = <0x00 0x0f910000 0x00 0x800>,
+		      <0x00 0x0f918000 0x00 0x400>;
+		clocks = <&scmi_clk 336>;
+		clock-names = "ref";
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		power-domains = <&scmi_pds 96>;
+		ranges;
+		status = "disabled";
+
+		usb1: usb@31100000 {
+			compatible = "snps,dwc3";
+			reg = <0x00 0x31100000 0x00 0x50000>;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+				     <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+			interrupt-names = "host", "peripheral";
+			maximum-speed = "high-speed";
+			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
+		};
+	};
+
+	sdhci0: mmc@fa10000 {
+		compatible = "ti,am62-sdhci";
+		reg = <0x00 0xfa10000 0x00 0x1000>, <0x00 0xfa18000 0x00 0x400>;
+		interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&scmi_pds 28>;
+		clocks = <&scmi_clk 122>, <&scmi_clk 123>;
+		clock-names = "clk_ahb", "clk_xin";
+		assigned-clocks = <&scmi_clk 123>;
+		assigned-clock-parents = <&scmi_clk 0>;
+		bus-width = <8>;
+		mmc-hs200-1_8v;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-mmc-hs = <0x0>;
+		ti,otap-del-sel-hs200 = <0x6>;
+		status = "disabled";
+	};
+
+	sdhci1: mmc@fa00000 {
+		compatible = "ti,j721e-sdhci-4bit";
+		reg = <0x00 0x0fa00000 0x00 0x1000>, <0x00 0x0fa08000 0x00 0x400>;
+		interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&scmi_pds 26>;
+		clocks = <&scmi_clk 106>, <&scmi_clk 107>;
+		clock-names = "clk_ahb", "clk_xin";
+		assigned-clocks = <&scmi_clk 107>;
+		assigned-clock-parents = <&scmi_clk 0>;
+		bus-width = <4>;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
+		status = "disabled";
+	};
+
+	sdhci2: mmc@fa20000 {
+		compatible = "ti,am62-sdhci";
+		reg = <0x00 0x0fa20000 0x00 0x1000>, <0x00 0x0fa28000 0x00 0x400>;
+		interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&scmi_pds 27>;
+		clocks = <&scmi_clk 114>, <&scmi_clk 115>;
+		clock-names = "clk_ahb", "clk_xin";
+		assigned-clocks = <&scmi_clk 115>;
+		assigned-clock-parents = <&scmi_clk 0>;
+		bus-width = <4>;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
+		status = "disabled";
+	};
+
+	main_i2c0: i2c@20000000 {
+		compatible = "ti,am64-i2c", "ti,omap4-i2c";
+		reg = <0x00 0x20000000 0x00 0x100>;
+		interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		power-domains = <&scmi_pds 53>;
+		clocks = <&scmi_clk 246>;
+		clock-names = "fck";
+		status = "disabled";
+	};
+
+	main_i2c1: i2c@20010000 {
+		compatible = "ti,am64-i2c", "ti,omap4-i2c";
+		reg = <0x00 0x20010000 0x00 0x100>;
+		interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		power-domains = <&scmi_pds 54>;
+		clocks = <&scmi_clk 250>;
+		clock-names = "fck";
+		status = "disabled";
+	};
+
+	main_i2c2: i2c@20020000 {
+		compatible = "ti,am64-i2c", "ti,omap4-i2c";
+		reg = <0x00 0x20020000 0x00 0x100>;
+		interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		power-domains = <&scmi_pds 55>;
+		clocks = <&scmi_clk 254>;
+		clock-names = "fck";
+		status = "disabled";
+	};
+
+	main_i2c3: i2c@20030000 {
+		compatible = "ti,am64-i2c", "ti,omap4-i2c";
+		reg = <0x00 0x20030000 0x00 0x100>;
+		interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		power-domains = <&scmi_pds 56>;
+		clocks = <&scmi_clk 258>;
+		clock-names = "fck";
+		status = "disabled";
+	};
+
+	main_mcan0: can@20701000 {
+		compatible = "bosch,m_can";
+		reg = <0x00 0x20701000 0x00 0x200>,
+		      <0x00 0x20708000 0x00 0x8000>;
+		reg-names = "m_can", "message_ram";
+		power-domains = <&scmi_pds 47>;
+		clocks = <&scmi_clk 179>, <&scmi_clk 174>;
+		clock-names = "hclk", "cclk";
+		interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "int0", "int1";
+		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		status = "disabled";
+	};
+
+	main_mcan1: can@20711000 {
+		compatible = "bosch,m_can";
+		reg = <0x00 0x20711000 0x00 0x200>,
+		      <0x00 0x20718000 0x00 0x8000>;
+		reg-names = "m_can", "message_ram";
+		power-domains = <&scmi_pds 48>;
+		clocks = <&scmi_clk 185>, <&scmi_clk 180>;
+		clock-names = "hclk", "cclk";
+		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "int0", "int1";
+		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		status = "disabled";
+	};
+
+	main_mcan2: can@20721000 {
+		compatible = "bosch,m_can";
+		reg = <0x00 0x20721000 0x00 0x200>,
+		      <0x00 0x20728000 0x00 0x8000>;
+		reg-names = "m_can", "message_ram";
+		power-domains = <&scmi_pds 49>;
+		clocks = <&scmi_clk 191>, <&scmi_clk 186>;
+		clock-names = "hclk", "cclk";
+		interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "int0", "int1";
+		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		status = "disabled";
+	};
+
+	main_spi0: spi@20100000 {
+		compatible = "ti,am654-mcspi", "ti,omap4-mcspi";
+		reg = <0x00 0x20100000 0x00 0x400>;
+		interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		power-domains = <&scmi_pds 72>;
+		clocks = <&scmi_clk 299>;
+		status = "disabled";
+	};
+
+	main_spi1: spi@20110000 {
+		compatible = "ti,am654-mcspi","ti,omap4-mcspi";
+		reg = <0x00 0x20110000 0x00 0x400>;
+		interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		power-domains = <&scmi_pds 73>;
+		clocks = <&scmi_clk 302>;
+		status = "disabled";
+	};
+
+	main_spi2: spi@20120000 {
+		compatible = "ti,am654-mcspi","ti,omap4-mcspi";
+		reg = <0x00 0x20120000 0x00 0x400>;
+		interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		power-domains = <&scmi_pds 74>;
+		clocks = <&scmi_clk 305>;
+		status = "disabled";
+	};
+
+	main_spi3: spi@20130000 {
+		compatible = "ti,am654-mcspi","ti,omap4-mcspi";
+		reg = <0x00 0x20130000 0x00 0x400>;
+		interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		power-domains = <&scmi_pds 75>;
+		clocks = <&scmi_clk 308>;
+		status = "disabled";
+	};
+
+	epwm0: pwm@23000000 {
+		compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
+		#pwm-cells = <3>;
+		reg = <0x00 0x23000000 0x00 0x100>;
+		power-domains = <&scmi_pds 40>;
+		clocks = <&epwm_tbclk 0>, <&scmi_clk 164>;
+		clock-names = "tbclk", "fck";
+		status = "disabled";
+	};
+
+	epwm1: pwm@23010000 {
+		compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
+		#pwm-cells = <3>;
+		reg = <0x00 0x23010000 0x00 0x100>;
+		power-domains = <&scmi_pds 41>;
+		clocks = <&epwm_tbclk 1>, <&scmi_clk 165>;
+		clock-names = "tbclk", "fck";
+		status = "disabled";
+	};
+
+	epwm2: pwm@23020000 {
+		compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
+		#pwm-cells = <3>;
+		reg = <0x00 0x23020000 0x00 0x100>;
+		power-domains = <&scmi_pds 42>;
+		clocks = <&epwm_tbclk 2>, <&scmi_clk 166>;
+		clock-names = "tbclk", "fck";
+		status = "disabled";
+	};
+
+	ecap0: pwm@23100000 {
+		compatible = "ti,am3352-ecap";
+		#pwm-cells = <3>;
+		reg = <0x00 0x23100000 0x00 0x100>;
+		power-domains = <&scmi_pds 23>;
+		clocks = <&scmi_clk 99>;
+		clock-names = "fck";
+		status = "disabled";
+	};
+
+	ecap1: pwm@23110000 {
+		compatible = "ti,am3352-ecap";
+		#pwm-cells = <3>;
+		reg = <0x00 0x23110000 0x00 0x100>;
+		power-domains = <&scmi_pds 24>;
+		clocks = <&scmi_clk 100>;
+		clock-names = "fck";
+		status = "disabled";
+	};
+
+	ecap2: pwm@23120000 {
+		compatible = "ti,am3352-ecap";
+		#pwm-cells = <3>;
+		reg = <0x00 0x23120000 0x00 0x100>;
+		power-domains = <&scmi_pds 25>;
+		clocks = <&scmi_clk 101>;
+		clock-names = "fck";
+		status = "disabled";
+	};
+
+	eqep0: counter@23200000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23200000 0x00 0x100>;
+		power-domains = <&scmi_pds 29>;
+		clocks = <&scmi_clk 127>;
+		interrupts = <GIC_SPI 162 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
+	eqep1: counter@23210000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23210000 0x00 0x100>;
+		power-domains = <&scmi_pds 30>;
+		clocks = <&scmi_clk 128>;
+		interrupts = <GIC_SPI 163 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
+	eqep2: counter@23220000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23220000 0x00 0x100>;
+		power-domains = <&scmi_pds 31>;
+		clocks = <&scmi_clk 129>;
+		interrupts = <GIC_SPI 164 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
+	elm0: ecc@25010000 {
+		compatible = "ti,am64-elm";
+		reg = <0x00 0x25010000 0x00 0x2000>;
+		interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&scmi_pds 25>;
+		clocks = <&scmi_clk 102>;
+		clock-names = "fck";
+		status = "disabled";
+	};
+
+	tscadc0: tscadc@28001000 {
+		compatible = "ti,am654-tscadc", "ti,am3359-tscadc";
+		reg = <0x00 0x28001000 0x00 0x1000>;
+		interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&scmi_pds 0>;
+		clocks = <&scmi_clk 0>;
+		assigned-clocks = <&scmi_clk 0>;
+		assigned-clock-parents = <&scmi_clk 2>;
+		assigned-clock-rates = <60000000>;
+		clock-names = "fck";
+		status = "disabled";
+
+		adc {
+			#io-channel-cells = <1>;
+			compatible = "ti,am654-adc", "ti,am3359-adc";
+		};
+	};
+
+	dphy_tx0: phy@301c0000 {
+		compatible = "ti,j721e-dphy";
+		reg = <0x0 0x301c0000 0x0 0x1000>;
+		clocks = <&scmi_clk 348>, <&scmi_clk 341>;
+		clock-names = "psm", "pll_ref";
+		#phy-cells = <0>;
+		power-domains = <&scmi_pds 86>;
+		assigned-clocks = <&scmi_clk 341>;
+		assigned-clock-parents = <&scmi_clk 0>;
+		assigned-clock-rates = <25000000>;
+		status = "disabled";
+	};
+
+	dss: dss@30200000 {
+		compatible = "ti,am62l-dss";
+		reg = <0x00 0x30200000 0x00 0x1000>, /* common */
+		      <0x00 0x30202000 0x00 0x1000>, /* vidl1 */
+		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
+		      <0x00 0x3020a000 0x00 0x1000>, /* vp1 */
+		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
+		reg-names = "common", "vidl1", "ovr1", "vp1", "common1";
+		power-domains = <&scmi_pds 39>;
+		clocks = <&scmi_clk 162>,
+			 <&scmi_clk 159>;
+		clock-names = "fck", "vp1";
+		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+
+		dss_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	dsi0: dsi@30500000 {
+		compatible = "ti,j721e-dsi";
+		reg = <0x0 0x30500000 0x0 0x100000>, <0x0 0x30270000 0x0 0x100>;
+		clocks = <&scmi_clk 155>, <&scmi_clk 158>;
+		clock-names = "dsi_p_clk", "dsi_sys_clk";
+		power-domains = <&scmi_pds 38>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+		phys = <&dphy_tx0>;
+		phy-names = "dphy";
+		status = "disabled";
+	};
+
+	gpmc0: memory-controller@3b000000 {
+		compatible = "ti,am64-gpmc";
+		power-domains = <&scmi_pds 37>;
+		clocks = <&scmi_clk 147>;
+		clock-names = "fck";
+		reg = <0x00 0x3b000000 0x00 0x400>,
+		      <0x00 0x50000000 0x00 0x8000000>;
+		reg-names = "cfg", "data";
+		interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;
+		gpmc,num-cs = <3>;
+		gpmc,num-waitpins = <2>;
+		#address-cells = <2>;
+		#size-cells = <1>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		status = "disabled";
+	};
+
+	oc_sram: sram@70800000 {
+		compatible = "mmio-sram";
+		reg = <0x00 0x70800000 0x00 0x10000>;
+		ranges = <0x0 0x00 0x70800000 0x10000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		scmi_shmem: sram@0 {
+			compatible = "arm,scmi-shmem";
+			reg = <0x0 0x100>;
+			bootph-all;
+		};
+	};
+
+	main_bcdma: dma-controller@485c4000 {
+		compatible = "ti,am62l-dmss-bcdma";
+		reg = <0x00 0x485c4000 0x00 0x4000>,
+			<0x00 0x48880000 0x00 0x10000>,
+			<0x00 0x48800000 0x00 0x80000>,
+			<0x00 0x47000000 0x00 0x200000>;
+		reg-names = "gcfg", "bchanrt", "chanrt", "ringrt";
+		#address-cells = <2>;
+		#interrupt-cells = <1>;
+		#dma-cells = <4>;
+		interrupt-map = <0 0 0 &gic500 0 0 GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 1 &gic500 0 0 GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 2 &gic500 0 0 GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 3 &gic500 0 0 GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 4 &gic500 0 0 GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 5 &gic500 0 0 GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 6 &gic500 0 0 GIC_SPI 364 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 7 &gic500 0 0 GIC_SPI 365 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 8 &gic500 0 0 GIC_SPI 368 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 9 &gic500 0 0 GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 10 &gic500 0 0 GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 11 &gic500 0 0 GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 12 &gic500 0 0 GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 13 &gic500 0 0 GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 16 &gic500 0 0 GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 17 &gic500 0 0 GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 24 &gic500 0 0 GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 25 &gic500 0 0 GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 32 &gic500 0 0 GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 33 &gic500 0 0 GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 40 &gic500 0 0 GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 41 &gic500 0 0 GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 48 &gic500 0 0 GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 49 &gic500 0 0 GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 50 &gic500 0 0 GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 51 &gic500 0 0 GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 52 &gic500 0 0 GIC_SPI 388 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 53 &gic500 0 0 GIC_SPI 389 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 64 &gic500 0 0 GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 65 &gic500 0 0 GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 66 &gic500 0 0 GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 80 &gic500 0 0 GIC_SPI 482 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 67 &gic500 0 0 GIC_SPI 548 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 128 &gic500 0 0 GIC_SPI 516 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 129 &gic500 0 0 GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 130 &gic500 0 0 GIC_SPI 518 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 131 &gic500 0 0 GIC_SPI 519 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 132 &gic500 0 0 GIC_SPI 520 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 133 &gic500 0 0 GIC_SPI 521 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 134 &gic500 0 0 GIC_SPI 522 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 135 &gic500 0 0 GIC_SPI 523 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 136 &gic500 0 0 GIC_SPI 524 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 137 &gic500 0 0 GIC_SPI 525 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 138 &gic500 0 0 GIC_SPI 526 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 139 &gic500 0 0 GIC_SPI 527 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 140 &gic500 0 0 GIC_SPI 528 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 141 &gic500 0 0 GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 142 &gic500 0 0 GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 143 &gic500 0 0 GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	main_pktdma: dma-controller@485c0000 {
+		compatible = "ti,am62l-dmss-pktdma";
+		reg = <0x00 0x485c0000 0x00 0x4000>,
+			<0x00 0x48900000 0x00 0x80000>,
+			<0x00 0x47200000 0x00 0x100000>;
+		reg-names = "gcfg", "chanrt", "ringrt";
+		#address-cells = <2>;
+		#dma-cells = <2>;
+		#interrupt-cells = <1>;
+		interrupt-map = <0 0 0 &gic500 0 0 GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 1 &gic500 0 0 GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 2 &gic500 0 0 GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 3 &gic500 0 0 GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 4 &gic500 0 0 GIC_SPI 362 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 5 &gic500 0 0 GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 6 &gic500 0 0 GIC_SPI 366 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 7 &gic500 0 0 GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 8 &gic500 0 0 GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 9 &gic500 0 0 GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 10 &gic500 0 0 GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 11 &gic500 0 0 GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 12 &gic500 0 0 GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 13 &gic500 0 0 GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 64 &gic500 0 0 GIC_SPI 500 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 65 &gic500 0 0 GIC_SPI 501 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 66 &gic500 0 0 GIC_SPI 502 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 67 &gic500 0 0 GIC_SPI 503 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 68 &gic500 0 0 GIC_SPI 504 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 69 &gic500 0 0 GIC_SPI 505 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 70 &gic500 0 0 GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 71 &gic500 0 0 GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 72 &gic500 0 0 GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 73 &gic500 0 0 GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 74 &gic500 0 0 GIC_SPI 510 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 75 &gic500 0 0 GIC_SPI 511 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 76 &gic500 0 0 GIC_SPI 512 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 77 &gic500 0 0 GIC_SPI 513 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 78 &gic500 0 0 GIC_SPI 514 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 79 &gic500 0 0 GIC_SPI 515 IRQ_TYPE_LEVEL_HIGH>,
+			<0 0 96 &gic500 0 0 GIC_SPI 484 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	cpsw3g: ethernet@8000000 {
+		compatible = "ti,am642-cpsw-nuss";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		reg = <0x00 0x08000000 0x00 0x200000>;
+		reg-names = "cpsw_nuss";
+		ranges = <0x00 0x00 0x00 0x08000000 0x00 0x200000>;
+		clocks = <&scmi_clk 9>;
+		clock-names = "fck";
+		power-domains = <&scmi_pds 3>;
+		dmas = <&main_pktdma 0xc600 15>,
+			   <&main_pktdma 0xc601 15>,
+			   <&main_pktdma 0xc602 15>,
+			   <&main_pktdma 0xc603 15>,
+			   <&main_pktdma 0xc604 15>,
+			   <&main_pktdma 0xc605 15>,
+			   <&main_pktdma 0xc606 15>,
+			   <&main_pktdma 0xc607 15>,
+			   <&main_pktdma 0x4600 15>;
+		dma-names = "tx0", "tx1", "tx2", "tx3", "tx4", "tx5", "tx6",
+					"tx7", "rx";
+
+		ethernet-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			cpsw_port1: port@1 {
+				reg = <1>;
+				ti,mac-only;
+				label = "port1";
+				phys = <&phy_gmii_sel 1>;
+				ti,syscon-efuse = <&cpsw_mac_syscon 0x0>;
+				mac-address = [00 00 00 00 00 00];
+			};
+
+			cpsw_port2: port@2 {
+				reg = <2>;
+				ti,mac-only;
+				label = "port2";
+				phys = <&phy_gmii_sel 2>;
+				mac-address = [00 00 00 00 00 00];
+			};
+		};
+
+		cpsw3g_mdio: mdio@f00 {
+			compatible = "ti,cpsw-mdio","ti,davinci_mdio";
+			reg = <0x00 0xf00 0x00 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&scmi_clk 9>;
+			clock-names = "fck";
+			bus_freq = <1000000>;
+			status = "disabled";
+		};
+
+		cpts@3d000 {
+			compatible = "ti,j721e-cpts";
+			reg = <0x00 0x3d000 0x00 0x400>;
+			clocks = <&scmi_clk 10>;
+			clock-names = "cpts";
+			interrupts-extended = <&gic500 GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "cpts";
+			ti,cpts-ext-ts-inputs = <4>;
+			ti,cpts-periodic-outputs = <2>;
+		};
+	};
+
+	mcasp0: audio-controller@2b00000 {
+		compatible = "ti,am33xx-mcasp-audio";
+		reg = <0x00 0x02b00000 0x00 0x2000>,
+				<0x00 0x02b08000 0x00 0x400>;
+		reg-names = "mpu", "dat";
+		interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "tx", "rx";
+
+		clocks = <&scmi_clk 192>;
+		clock-names = "fck";
+		assigned-clocks = <&scmi_clk 192>;
+		assigned-clock-parents = <&scmi_clk 1>;
+		dmas = <&main_bcdma 0 0 0xc500 0>, <&main_bcdma 0 0 0x4500 0>;
+		dma-names = "tx", "rx";
+		power-domains = <&scmi_pds 50>;
+
+		status = "disabled";
+	};
+
+	mcasp1: audio-controller@2b10000 {
+		compatible = "ti,am33xx-mcasp-audio";
+		reg = <0x00 0x02b10000 0x00 0x2000>,
+				<0x00 0x02b18000 0x00 0x400>;
+		reg-names = "mpu", "dat";
+		interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "tx", "rx";
+
+		clocks = <&scmi_clk 216>;
+		clock-names = "fck";
+		assigned-clocks = <&scmi_clk 216>;
+		dmas = <&main_bcdma 0 0 0xc501 0>, <&main_bcdma 0 0 0x4501 0>;
+		dma-names = "tx", "rx";
+		power-domains = <&scmi_pds 51>;
+
+		status = "disabled";
+	};
+
+	mcasp2: audio-controller@2b20000 {
+		compatible = "ti,am33xx-mcasp-audio";
+		reg = <0x00 0x02b20000 0x00 0x2000>,
+				<0x00 0x02b28000 0x00 0x400>;
+		reg-names = "mpu", "dat";
+		interrupts = <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "tx", "rx";
+
+		clocks = <&scmi_clk 230>;
+		clock-names = "fck";
+		assigned-clocks = <&scmi_clk 230>;
+		dmas = <&main_bcdma 0 0 0xc502 0>, <&main_bcdma 0 0 0x4502 0>;
+		dma-names = "tx", "rx";
+		power-domains = <&scmi_pds 52>;
+
+		status = "disabled";
+	};
+
+	crypto: crypto@40800000 {
+		compatible = "ti,am62l-dthev2";
+		reg = <0x00 0x40800000 0x00 0x14000>;
+
+		dmas = <&main_bcdma 0 0 0x4700 0>,
+		       <&main_bcdma 0 0 0xc701 0>,
+		       <&main_bcdma 0 0 0xc700 0>;
+		dma-names = "rx", "tx1", "tx2";
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts b/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts
--- a/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts	2025-10-23 09:30:40.282462115 -0400
@@ -7,57 +7,22 @@
 
 /dts-v1/;
 
+#include "k3-am625.dtsi"
 #include "k3-am62x-sk-common.dtsi"
 
 / {
 	compatible = "ti,am62-lp-sk", "ti,am625";
 	model = "Texas Instruments AM62x LP SK";
 
-	vmain_pd: regulator-0 {
-		/* TPS65988 PD CONTROLLER OUTPUT */
-		compatible = "regulator-fixed";
-		regulator-name = "vmain_pd";
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		regulator-always-on;
-		regulator-boot-on;
-	};
-
-	vcc_5v0: regulator-1 {
-		/* Output of TPS630702RNMR */
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_5v0";
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		vin-supply = <&vmain_pd>;
-		regulator-always-on;
-		regulator-boot-on;
-	};
-
-	vcc_3v3_sys: regulator-2 {
-		/* output of LM61460-Q1 */
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_3v3_sys";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		vin-supply = <&vmain_pd>;
-		regulator-always-on;
-		regulator-boot-on;
-	};
-
-	vdd_mmc1: regulator-3 {
-		/* TPS22918DBVR */
-		compatible = "regulator-fixed";
-		regulator-name = "vdd_mmc1";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		regulator-boot-on;
-		enable-active-high;
-		vin-supply = <&vcc_3v3_sys>;
-		gpio = <&exp1 3 GPIO_ACTIVE_HIGH>;
+	memory@80000000 {
+		bootph-pre-ram;
+		device_type = "memory";
+		/* 2G RAM */
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
 	};
 
 	vddshv_sdio: regulator-4 {
+		bootph-all;
 		compatible = "regulator-gpio";
 		regulator-name = "vddshv_sdio";
 		pinctrl-names = "default";
@@ -73,13 +38,31 @@
 };
 
 &main_pmx0 {
+	main_mmc0_pins_default: main-mmc0-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (V3) MMC0_CMD */
+			AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (Y1) MMC0_CLK */
+			AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (V2) MMC0_DAT0 */
+			AM62X_IOPAD(0x210, PIN_INPUT, 0) /* (V1) MMC0_DAT1 */
+			AM62X_IOPAD(0x20c, PIN_INPUT, 0) /* (W2) MMC0_DAT2 */
+			AM62X_IOPAD(0x208, PIN_INPUT, 0) /* (W1) MMC0_DAT3 */
+			AM62X_IOPAD(0x204, PIN_INPUT, 0) /* (Y2) MMC0_DAT4 */
+			AM62X_IOPAD(0x200, PIN_INPUT, 0) /* (W3) MMC0_DAT5 */
+			AM62X_IOPAD(0x1fc, PIN_INPUT, 0) /* (W4) MMC0_DAT6 */
+			AM62X_IOPAD(0x1f8, PIN_INPUT, 0) /* (V4) MMC0_DAT7 */
+		>;
+	};
+
 	vddshv_sdio_pins_default: vddshv-sdio-default-pins {
+		bootph-all;
 		pinctrl-single,pins = <
 			AM62X_IOPAD(0x07c, PIN_OUTPUT, 7) /* (M19) GPMC0_CLK.GPIO0_31 */
 		>;
 	};
 
 	main_gpio1_ioexp_intr_pins_default: main-gpio1-ioexp-intr-default-pins {
+		bootph-all;
 		pinctrl-single,pins = <
 			AM62X_IOPAD(0x01d4, PIN_INPUT, 7) /* (C13) UART0_RTSn.GPIO1_23 */
 		>;
@@ -94,6 +77,7 @@
 
 &main_i2c1 {
 	exp1: gpio@22 {
+		bootph-all;
 		compatible = "ti,tca6424";
 		reg = <0x22>;
 		gpio-controller;
@@ -140,6 +124,14 @@
 	};
 };
 
+&sdhci0 {
+	bootph-all;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc0_pins_default>;
+	disable-wp;
+};
+
 &sdhci1 {
 	vmmc-supply = <&vdd_mmc1>;
 	vqmmc-supply = <&vddshv_sdio>;
@@ -229,6 +221,127 @@
 	DVDD-supply = <&buck2_reg>;
 };
 
+&main_gpio0 {
+	bootph-all;
+};
+
+&main_gpio1 {
+	bootph-all;
+};
+
+&ospi0 {
+
+	flash@0 {
+		compatible = "spi-nand";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <2>;
+		cdns,phy-mode;
+		bootph-all;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			bootph-all;
+
+			partition@0 {
+				label = "ospi_nand.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition@80000 {
+				label = "ospi_nand.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition@280000 {
+				label = "ospi_nand.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition@680000 {
+				label = "ospi_nand.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition@6c0000 {
+				label = "ospi_nand.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition@2000000 {
+				label = "ospi_nand.rootfs";
+				reg = <0x2000000 0x5fc0000>;
+			};
+
+			partition@7fc0000 {
+				label = "ospi_nand.phypattern";
+				reg = <0x7fc0000 0x40000>;
+				bootph-all;
+			};
+		};
+	};
+};
+
 &gpmc0 {
 	ranges = <0 0 0x00 0x51000000 0x01000000>; /* CS0 space. Min partition = 16MB */
 };
+
+&mcu_mcan0 {
+	pinctrl-names = "default", "wakeup";
+	pinctrl-0 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_default>;
+	pinctrl-1 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_wakeup>;
+	status = "okay";
+};
+
+&mcu_mcan1 {
+	pinctrl-names = "default", "wakeup";
+	pinctrl-0 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_default>;
+	pinctrl-1 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_wakeup>;
+	status = "okay";
+};
+
+&mcu_pmx0 {
+	mcu_mcan0_tx_pins_default: mcu-mcan0-tx-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x034, PIN_OUTPUT, 0) /* (D6) MCU_MCAN0_TX */
+		>;
+	};
+
+	mcu_mcan0_rx_pins_default: mcu-mcan0-rx-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x038, PIN_INPUT, 0) /* (B3) MCU_MCAN0_RX */
+		>;
+	};
+
+	mcu_mcan0_rx_pins_wakeup: mcu-mcan0-rx-wakeup-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x038, PIN_INPUT | WKUP_EN, 0) /* (B3) MCU_MCAN0_RX */
+		>;
+	};
+
+	mcu_mcan1_tx_pins_default: mcu-mcan1-tx-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x03c, PIN_OUTPUT, 0) /* (E5) MCU_MCAN1_TX */
+		>;
+	};
+
+	mcu_mcan1_rx_pins_default: mcu-mcan1-rx-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x040, PIN_INPUT, 0) /* (D4) MCU_MCAN1_RX */
+		>;
+	};
+
+	mcu_mcan1_rx_pins_wakeup: mcu-mcan1-rx-wakeup-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x040, PIN_INPUT | WKUP_EN, 0) /* (D4) MCU_MCAN1_RX */
+		>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-lp-sk-lincolntech-lcd185-panel.dtso b/arch/arm64/boot/dts/ti/k3-am62-lp-sk-lincolntech-lcd185-panel.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62-lp-sk-lincolntech-lcd185-panel.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62-lp-sk-lincolntech-lcd185-panel.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0-or-late OR MIT
+/**
+ * Lincoln tech Solutions OLDI panel (LCD185-101CT) and touch DT overlay for AM62-LP-SK
+ *
+ * AM62-LP SKEVM: https://www.ti.com/tool/SK-AM62-LP
+ * Panel datasheet: https://lincolntechsolutions.com/wp-content/uploads/2023/04/LCD185-101CTL1ARNTT_DS_R1.3.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&{/} {
+	display {
+		compatible = "lincolntech,lcd185-101ct", "panel-simple";
+		/*
+		* Note that the OLDI TX 0 transmits the odd set of pixels
+		* while the OLDI TX 1 transmits the even set. This is a
+		* fixed configuration in the IP integration and is not
+		* changeable. The properties, "dual-lvds-odd-pixels" and
+		* "dual-lvds-even-pixels" have been used to merely
+		* identify if a Dual Link configuration is required.
+		* Swapping them will cause an error in the dss oldi driver.
+		*/
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				dual-lvds-odd-pixels;
+				lcd_in0: endpoint {
+					remote-endpoint = <&oldi_0_out>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				dual-lvds-even-pixels;
+				lcd_in1: endpoint {
+					remote-endpoint = <&oldi_1_out>;
+				};
+			};
+		};
+	};
+};
+
+&dss {
+	status = "okay";
+};
+
+&oldi0 {
+	status = "okay";
+	ti,companion-oldi = <&oldi1>;
+};
+
+&oldi1 {
+	status = "okay";
+	ti,secondary-oldi;
+};
+
+&oldi0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		oldi_0_in: endpoint {
+			remote-endpoint = <&dpi0_out0>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		oldi_0_out: endpoint {
+			remote-endpoint = <&lcd_in0>;
+		};
+	};
+};
+
+&oldi1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		oldi_1_in: endpoint {
+			remote-endpoint = <&dpi0_out1>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		oldi_1_out: endpoint {
+			remote-endpoint = <&lcd_in1>;
+		};
+	};
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* VP1: Output to OLDI */
+	port@0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dpi0_out0: endpoint@0 {
+			reg = <0>;
+			remote-endpoint = <&oldi_0_in>;
+		};
+		dpi0_out1: endpoint@1 {
+			reg = <1>;
+			remote-endpoint = <&oldi_1_in>;
+		};
+	};
+};
+
+&main_i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	eeprom@57 {
+		compatible = "atmel,24c256";
+		reg = <0x57>;
+	};
+
+	touchscreen@5d {
+		compatible = "goodix,gt928";
+		reg = <0x5d>;
+		interrupt-parent = <&exp1>;
+		interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+		irq-gpios = <&exp1 15 GPIO_ACTIVE_LOW>;
+		reset-gpios = <&exp2 18 GPIO_ACTIVE_LOW>;
+		touchscreen-size-x = <1920>;
+		touchscreen-size-y = <1200>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-lp-sk-microtips-mf101hie-panel.dtso b/arch/arm64/boot/dts/ti/k3-am62-lp-sk-microtips-mf101hie-panel.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62-lp-sk-microtips-mf101hie-panel.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62-lp-sk-microtips-mf101hie-panel.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * Microtips integrated OLDI panel (MF-101HIEBCAF0) and touch DT overlay for AM62 LP-SK
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "k3-pinctrl.h"
+
+&{/} {
+	display {
+		compatible = "microtips,mf-101hiebcaf0", "panel-simple";
+		/*
+		* Note that the OLDI TX 0 transmits the odd set of pixels
+		* while the OLDI TX 1 transmits the even set. This is a
+		* fixed configuration in the IP integration and is not
+		* changeable. The properties, "dual-lvds-odd-pixels" and
+		* "dual-lvds-even-pixels" have been used to merely
+		* identify if a Dual Link configuration is required.
+		* Swapping them will cause an error in the dss oldi driver.
+		*/
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				dual-lvds-odd-pixels;
+				lcd_in0: endpoint {
+					remote-endpoint = <&oldi_0_out>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				dual-lvds-even-pixels;
+				lcd_in1: endpoint {
+					remote-endpoint = <&oldi_1_out>;
+				};
+			};
+		};
+	};
+};
+
+&dss {
+	status = "okay";
+};
+
+&oldi0 {
+	status = "okay";
+	ti,companion-oldi = <&oldi1>;
+};
+
+&oldi1 {
+	status = "okay";
+	ti,secondary-oldi;
+};
+
+&oldi0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		oldi_0_in: endpoint {
+			remote-endpoint = <&dpi0_out0>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		oldi_0_out: endpoint {
+			remote-endpoint = <&lcd_in0>;
+		};
+	};
+};
+
+&oldi1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		oldi_1_in: endpoint {
+			remote-endpoint = <&dpi0_out1>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		oldi_1_out: endpoint {
+			remote-endpoint = <&lcd_in1>;
+		};
+	};
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* VP1: Output to OLDI */
+	port@0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dpi0_out0: endpoint@0 {
+			reg = <0>;
+			remote-endpoint = <&oldi_0_in>;
+		};
+		dpi0_out1: endpoint@1 {
+			reg = <1>;
+			remote-endpoint = <&oldi_1_in>;
+		};
+	};
+};
+
+&main_i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	touchscreen@41 {
+		compatible = "ilitek,ili251x";
+		reg = <0x41>;
+		interrupt-parent = <&exp1>;
+		interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&exp2 18 GPIO_ACTIVE_LOW>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-am62l-thermal.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62l-thermal.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l-thermal.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <dt-bindings/thermal/thermal.h>
+
+thermal_zones: thermal-zones {
+	main0_thermal: main0-thermal {
+		polling-delay-passive = <250>;	/* milliSeconds */
+		polling-delay = <500>;		/* milliSeconds */
+		thermal-sensors = <&wkup_vtm0 0>;
+
+		trips {
+			main0_crit: main0-crit {
+				temperature = <125000>;	/* milliCelsius */
+				hysteresis = <2000>;	/* milliCelsius */
+				type = "critical";
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62l-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62l-wakeup.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62l-wakeup.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62l-wakeup.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0-only or MIT
+/*
+ * Device Tree file for the AM62L wakeup domain peripherals
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Technical Reference Manual: https://www.ti.com/lit/pdf/sprujb4
+ */
+
+#include <dt-bindings/bus/ti-sysc.h>
+
+&cbass_wakeup {
+	wkup_vtm0: temperature-sensor@b00000 {
+		compatible = "ti,j7200-vtm";
+		reg = <0x00 0xb00000 0x00 0x400>,
+		      <0x00 0xb01000 0x00 0x400>;
+		power-domains = <&scmi_pds 46>;
+		#thermal-sensor-cells = <1>;
+	};
+
+	pmx0: pinctrl@4084000 {
+		compatible = "pinctrl-single";
+		reg = <0x00 0x4084000 0x00 0x8000>;
+		pinctrl-single,register-width = <32>;
+		pinctrl-single,function-mask = <0xffffffff>;
+		#pinctrl-cells = <1>;
+		bootph-all;
+	};
+
+	wkup_gpio0: gpio@4201000 {
+		compatible = "ti,am64-gpio", "ti,keystone-gpio";
+		reg = <0x00 0x04201000 0x00 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 276 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 704 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 705 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 706 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 707 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 708 IRQ_TYPE_EDGE_RISING>,
+			     <GIC_SPI 709 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 710 IRQ_TYPE_EDGE_RISING>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <7>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&scmi_pds 36>;
+		clocks = <&scmi_clk 142>;
+		clock-names = "gpio";
+		status = "disabled";
+	};
+
+	wkup_timer0: timer@2b100000 {
+		compatible = "ti,am654-timer";
+		reg = <0x00 0x2b100000 0x00 0x400>;
+		interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&scmi_clk 85>;
+		clock-names = "fck";
+		power-domains = <&scmi_pds 19>;
+		ti,timer-pwm;
+	};
+
+	wkup_timer1: timer@2b110000 {
+		compatible = "ti,am654-timer";
+		reg = <0x00 0x2b110000 0x00 0x400>;
+		interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&scmi_clk 96>;
+		clock-names = "fck";
+		power-domains = <&scmi_pds 20>;
+		ti,timer-pwm;
+	};
+
+	wkup_i2c0: i2c@2b200000 {
+		compatible = "ti,am64-i2c", "ti,omap4-i2c";
+		reg = <0x00 0x2b200000 0x00 0x100>;
+		interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		power-domains = <&scmi_pds 57>;
+		clocks = <&scmi_clk 262>;
+		clock-names = "fck";
+		status = "disabled";
+	};
+
+	target-module@2b300050 {
+		compatible = "ti,sysc-omap2", "ti,sysc";
+		reg = <0x00 0x2b300050 0x00 0x4>,
+		      <0x00 0x2b300054 0x00 0x4>,
+		      <0x00 0x2b300058 0x00 0x4>;
+		reg-names = "rev", "sysc", "syss";
+		ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+				 SYSC_OMAP2_SOFTRESET |
+				 SYSC_OMAP2_AUTOIDLE)>;
+		ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+				<SYSC_IDLE_NO>,
+				<SYSC_IDLE_SMART>,
+				<SYSC_IDLE_SMART_WKUP>;
+		ti,syss-mask = <1>;
+		ti,no-reset-on-init;
+		power-domains = <&scmi_pds 83>;
+		clocks = <&scmi_clk 324>;
+		clock-names = "fck";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x00 0x2b300000 0x100000>;
+		status = "disabled";
+
+		wkup_uart0: serial@0 {
+			compatible = "ti,am64-uart", "ti,am654-uart";
+			reg = <0x0 0x100>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&scmi_clk 324>;
+			assigned-clocks = <&scmi_clk 324>;
+			clock-names = "fck";
+			status = "disabled";
+		};
+	};
+
+	wkup_conf: bus@43000000 {
+		compatible = "simple-bus";
+		ranges = <0x0 0x00 0x43000000 0x80000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		chipid: chipid@14 {
+			compatible = "ti,am654-chipid";
+			reg = <0x14 0x4>;
+			bootph-all;
+		};
+
+		cpsw_mac_syscon: ethernet-mac-syscon@2000 {
+			compatible = "ti,am62p-cpsw-mac-efuse", "syscon";
+			reg = <0x2000 0x8>;
+		};
+
+		usb0_phy_ctrl: syscon@45000 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x45000 0x4>;
+			bootph-all;
+		};
+
+		usb1_phy_ctrl: syscon@45004 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x45004 0x4>;
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -76,6 +76,11 @@
 			assigned-clock-parents = <&k3_clks 157 18>;
 			#clock-cells = <0>;
 		};
+
+		dss_oldi_io_ctrl: oldi-io-controller@8600 {
+			compatible = "ti,am625-dss-oldi-io-ctrl", "syscon";
+			reg = <0x8600 0x200>;
+		};
 	};
 
 	dmss: bus@48000000 {
@@ -211,6 +216,13 @@
 		dma-names = "tx", "rx1", "rx2";
 	};
 
+	crc: crc@30300000 {
+		compatible = "ti,am62-mcrc64";
+		reg = <0x00 0x30300000 0x00 0x1000>;
+		clocks = <&k3_clks 116 0>;
+		power-domains = <&k3_pds 116 TI_SCI_PD_EXCLUSIVE>;
+	};
+
 	secure_proxy_sa3: mailbox@43600000 {
 		bootph-pre-ram;
 		compatible = "ti,am654-secure-proxy";
@@ -229,11 +241,24 @@
 
 	main_pmx0: pinctrl@f4000 {
 		bootph-all;
-		compatible = "pinctrl-single";
+		compatible = "ti,am654-padconf", "pinctrl-single";
 		reg = <0x00 0xf4000 0x00 0x2ac>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
 		pinctrl-single,function-mask = <0xffffffff>;
+		/*
+		 * pinctrl IP DOES NOT give any functional IRQs when a
+		 * system is in active state. This IRQ is only a dummy IRQ
+		 * that is being used to trick Linux into thinking that
+		 * GIC can potentially recieve an interrupt from this IP.
+		 * This helps us setup the IO daisychain wakeups for deep
+		 * sleep via chained wake IRQs.
+		 * Please feel free to assign a different number here as
+		 * long as it is unused if 98 conflicts with another use case.
+		 */
+		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
 	};
 
 	main_esm: esm@420000 {
@@ -553,15 +578,13 @@
 		clocks = <&k3_clks 57 5>, <&k3_clks 57 6>;
 		clock-names = "clk_ahb", "clk_xin";
 		bus-width = <8>;
-		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-mmc-hs = <0x0>;
-		ti,otap-del-sel-ddr52 = <0x5>;
-		ti,otap-del-sel-hs200 = <0x5>;
-		ti,itap-del-sel-legacy = <0xa>;
-		ti,itap-del-sel-mmc-hs = <0x1>;
+		ti,otap-del-sel-hs200 = <0x6>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-mmc-hs = <0x0>;
 		status = "disabled";
 	};
 
@@ -574,17 +597,17 @@
 		clock-names = "clk_ahb", "clk_xin";
 		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
-		ti,otap-del-sel-legacy = <0x8>;
+		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
-		ti,otap-del-sel-sdr12 = <0x0>;
-		ti,otap-del-sel-sdr25 = <0x0>;
-		ti,otap-del-sel-sdr50 = <0x8>;
-		ti,otap-del-sel-sdr104 = <0x7>;
-		ti,otap-del-sel-ddr50 = <0x4>;
-		ti,itap-del-sel-legacy = <0xa>;
-		ti,itap-del-sel-sd-hs = <0x1>;
-		ti,itap-del-sel-sdr12 = <0xa>;
-		ti,itap-del-sel-sdr25 = <0x1>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
 		status = "disabled";
 	};
 
@@ -597,17 +620,17 @@
 		clock-names = "clk_ahb", "clk_xin";
 		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
-		ti,otap-del-sel-legacy = <0x8>;
+		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
-		ti,otap-del-sel-sdr12 = <0x0>;
-		ti,otap-del-sel-sdr25 = <0x0>;
-		ti,otap-del-sel-sdr50 = <0x8>;
-		ti,otap-del-sel-sdr104 = <0x7>;
-		ti,otap-del-sel-ddr50 = <0x8>;
-		ti,itap-del-sel-legacy = <0xa>;
-		ti,itap-del-sel-sd-hs = <0xa>;
-		ti,itap-del-sel-sdr12 = <0xa>;
-		ti,itap-del-sel-sdr25 = <0x1>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
 		status = "disabled";
 	};
 
@@ -678,6 +701,7 @@
 			cdns,fifo-depth = <256>;
 			cdns,fifo-width = <4>;
 			cdns,trigger-address = <0x0>;
+			cdns,phase-detect-selector = <2>;
 			clocks = <&k3_clks 75 7>;
 			assigned-clocks = <&k3_clks 75 7>;
 			assigned-clock-parents = <&k3_clks 75 8>;
@@ -690,12 +714,14 @@
 	};
 
 	gpu: gpu@fd00000 {
-		compatible = "ti,am62-gpu", "img,img-axe";
+		compatible = "ti,am62-gpu", "img,img-axe-1-16m", "img,img-axe",
+			     "img,img-rogue";
 		reg = <0x00 0x0fd00000 0x00 0x20000>;
 		clocks = <&k3_clks 187 0>;
 		clock-names = "core";
 		interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 		power-domains = <&k3_pds 187 TI_SCI_PD_EXCLUSIVE>;
+		power-domain-names = "a";
 	};
 
 	cpsw3g: ethernet@8000000 {
@@ -788,12 +814,51 @@
 		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
 		status = "disabled";
 
+		oldi-transmitters {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			oldi0: oldi@0 {
+				reg = <0>;
+				clocks = <&k3_clks 186 0>;
+				clock-names = "serial";
+				ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+				status = "disabled";
+
+				oldi0_ports: ports {
+				};
+			};
+
+			/*
+			 * OLDI1 in AM625 SoC can only act as a secondary OLDI, if
+			 * required, hence the clock and io-ctrl properties are not
+			 * required at the moment.
+			 */
+			oldi1: oldi@1 {
+				reg = <1>;
+				clocks = <&k3_clks 186 0>;
+				clock-names = "serial";
+				ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+				status = "disabled";
+
+				oldi1_ports: ports {
+				};
+			};
+		};
+
 		dss_ports: ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
 		};
 	};
 
+	timesync_router: mux-controller@a40000 {
+		compatible = "reg-mux";
+		reg = <0x0 0xa40000 0x0 0x800>;
+		#mux-control-cells = <1>;
+		status = "disabled";
+	};
+
 	hwspinlock: spinlock@2a000000 {
 		compatible = "ti,am64-hwspinlock";
 		reg = <0x00 0x2a000000 0x00 0x1000>;
@@ -840,6 +905,33 @@
 		status = "disabled";
 	};
 
+	eqep0: counter@23200000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23200000 0x00 0x100>;
+		power-domains = <&k3_pds 59 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 59 0>;
+		interrupts = <GIC_SPI 116 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
+	eqep1: counter@23210000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23210000 0x00 0x100>;
+		power-domains = <&k3_pds 60 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 60 0>;
+		interrupts = <GIC_SPI 117 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
+	eqep2: counter@23220000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23220000 0x00 0x100>;
+		power-domains = <&k3_pds 62 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 62 0>;
+		interrupts = <GIC_SPI 118 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
 	main_mcan0: can@20701000 {
 		compatible = "bosch,m_can";
 		reg = <0x00 0x20701000 0x00 0x200>,
@@ -992,8 +1084,9 @@
 
 	ti_csi2rx0: ticsi2rx@30102000 {
 		compatible = "ti,j721e-csi2rx-shim";
-		dmas = <&main_bcdma 0 0x4700 0>;
-		dma-names = "rx0";
+		dmas = <&main_bcdma 0 0x4700 0>, <&main_bcdma 0 0x4701 0>,
+		       <&main_bcdma 0 0x4702 0>, <&main_bcdma 0 0x4703 0>;
+		dma-names = "rx0", "rx1", "rx2", "rx3";
 		reg = <0x00 0x30102000 0x00 0x1000>;
 		power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
 		#address-cells = <2>;
@@ -1004,6 +1097,9 @@
 		cdns_csi2rx0: csi-bridge@30101000 {
 			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
 			reg = <0x00 0x30101000 0x00 0x1000>;
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
 			clocks = <&k3_clks 182 0>, <&k3_clks 182 3>, <&k3_clks 182 0>,
 				<&k3_clks 182 0>, <&k3_clks 182 4>, <&k3_clks 182 4>;
 			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
@@ -1051,6 +1147,105 @@
 		status = "disabled";
 	};
 
+	pruss: pruss@30040000 {
+		compatible = "ti,am625-pruss";
+		reg = <0x00 0x30040000 0x00 0x80000>;
+		power-domains = <&k3_pds 81 TI_SCI_PD_EXCLUSIVE>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x00 0x30040000 0x80000>;
+
+		pruss_mem: memories@0 {
+			reg = <0x0 0x2000>,
+			      <0x2000 0x2000>,
+			      <0x10000 0x10000>;
+			reg-names = "dram0", "dram1", "shrdram2";
+		};
+
+		pruss_cfg: cfg@26000 {
+			compatible = "ti,pruss-cfg", "syscon";
+			reg = <0x26000 0x200>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x26000 0x2000>;
+
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				pruss_coreclk_mux: coreclk-mux@3c {
+					reg = <0x3c>;
+					#clock-cells = <0>;
+					clocks = <&k3_clks 81 0>,  /* pruss_core_clk */
+						 <&k3_clks 81 14>; /* pruss_iclk */
+					assigned-clocks = <&pruss_coreclk_mux>;
+					assigned-clock-parents = <&k3_clks 81 14>;
+				};
+
+				pruss_iepclk_mux: iepclk-mux@30 {
+					reg = <0x30>;
+					#clock-cells = <0>;
+					clocks = <&k3_clks 81 3>,	/* pruss_iep_clk */
+						 <&pruss_coreclk_mux>;	/* pruss_coreclk_mux */
+					assigned-clocks = <&pruss_iepclk_mux>;
+					assigned-clock-parents = <&pruss_coreclk_mux>;
+				};
+			};
+		};
+
+		pruss_intc: interrupt-controller@20000 {
+			compatible = "ti,pruss-intc";
+			reg = <0x20000 0x2000>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "host_intr0", "host_intr1",
+					  "host_intr2", "host_intr3",
+					  "host_intr4", "host_intr5",
+					  "host_intr6", "host_intr7";
+		};
+
+		pruss_uart: serial@28000 {
+			compatible = "ti,pruss-uart";
+			reg = <0x28000 0x40>;
+			clocks = <&k3_clks 81 13>; /* pruss_uart_clk */
+			interrupt-parent = <&pruss_intc>;
+			interrupts = <6 4 4>;
+			status = "disabled";
+		};
+
+		pru0: pru@34000 {
+			compatible = "ti,am625-pru";
+			reg = <0x34000 0x3000>,
+			      <0x22000 0x100>,
+			      <0x22400 0x100>;
+			reg-names = "iram", "control", "debug";
+			firmware-name = "am62x-pru0-fw";
+			interrupt-parent = <&pruss_intc>;
+			interrupts = <16 2 2>;
+			interrupt-names = "vring";
+		};
+
+		pru1: pru@38000 {
+			compatible = "ti,am625-pru";
+			reg = <0x38000 0x3000>,
+			      <0x24000 0x100>,
+			      <0x24400 0x100>;
+			reg-names = "iram", "control", "debug";
+			firmware-name = "am62x-pru1-fw";
+			interrupt-parent = <&pruss_intc>;
+			interrupts = <18 3 3>;
+			interrupt-names = "vring";
+		};
+	};
+
 	gpmc0: memory-controller@3b000000 {
 		compatible = "ti,am64-gpmc";
 		power-domains = <&k3_pds 80 TI_SCI_PD_EXCLUSIVE>;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -160,6 +160,7 @@
 		clocks = <&k3_clks 188 6>, <&k3_clks 188 1>;
 		clock-names = "hclk", "cclk";
 		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		wakeup-source = "suspend", "poweroff";
 		status = "disabled";
 	};
 
@@ -172,6 +173,20 @@
 		clocks = <&k3_clks 189 6>, <&k3_clks 189 1>;
 		clock-names = "hclk", "cclk";
 		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		wakeup-source = "suspend", "poweroff";
+		status = "disabled";
+	};
+
+	mcu_m4fss: m4fss@5000000 {
+		compatible = "ti,am64-m4fss";
+		reg = <0x00 0x5000000 0x00 0x30000>,
+		      <0x00 0x5040000 0x00 0x10000>;
+		reg-names = "iram", "dram";
+		resets = <&k3_reset 9 1>;
+		firmware-name = "am62-mcu-m4f0_0-fw";
+		ti,sci = <&dmsc>;
+		ti,sci-dev-id = <9>;
+		ti,sci-proc-ids = <0x18 0xff>;
 		status = "disabled";
 	};
 };
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5.dtsi b/arch/arm64/boot/dts/ti/k3-am62p5.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62p5.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62p5.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -47,6 +47,7 @@
 			d-cache-line-size = <64>;
 			d-cache-sets = <128>;
 			next-level-cache = <&l2_0>;
+			operating-points-v2 = <&a53_opp_table>;
 			clocks = <&k3_clks 135 0>;
 		};
 
@@ -62,6 +63,7 @@
 			d-cache-line-size = <64>;
 			d-cache-sets = <128>;
 			next-level-cache = <&l2_0>;
+			operating-points-v2 = <&a53_opp_table>;
 			clocks = <&k3_clks 136 0>;
 		};
 
@@ -77,6 +79,7 @@
 			d-cache-line-size = <64>;
 			d-cache-sets = <128>;
 			next-level-cache = <&l2_0>;
+			operating-points-v2 = <&a53_opp_table>;
 			clocks = <&k3_clks 137 0>;
 		};
 
@@ -92,10 +95,54 @@
 			d-cache-line-size = <64>;
 			d-cache-sets = <128>;
 			next-level-cache = <&l2_0>;
+			operating-points-v2 = <&a53_opp_table>;
 			clocks = <&k3_clks 138 0>;
 		};
 	};
 
+	a53_opp_table: opp-table {
+		compatible = "operating-points-v2-ti-cpu";
+		opp-shared;
+		syscon = <&opp_efuse_table>;
+
+		opp-200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+			opp-supported-hw = <0x01 0x0007>;
+			clock-latency-ns = <6000000>;
+		};
+
+		opp-400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x01 0x0007>;
+			clock-latency-ns = <6000000>;
+		};
+
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x01 0x0007>;
+			clock-latency-ns = <6000000>;
+		};
+
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-supported-hw = <0x01 0x0007>;
+			clock-latency-ns = <6000000>;
+		};
+
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-supported-hw = <0x01 0x0006>;
+			clock-latency-ns = <6000000>;
+		};
+
+		opp-1250000000 {
+			opp-hz = /bits/ 64 <1250000000>;
+			opp-supported-hw = <0x01 0x0004>;
+			clock-latency-ns = <6000000>;
+			opp-suspend;
+		};
+	};
+
 	l2_0: l2-cache0 {
 		compatible = "cache";
 		cache-unified;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5-sk-dsi-rpi-7inch-panel.dtso b/arch/arm64/boot/dts/ti/k3-am62p5-sk-dsi-rpi-7inch-panel.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk-dsi-rpi-7inch-panel.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk-dsi-rpi-7inch-panel.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * DT Overlay for RPi 7inch touchscreen panel interfaced with DSI on
+ * AM62P5-SK EVM.
+ *
+ * RPi DSI Panel: https://www.raspberrypi.com/products/raspberry-pi-touch-display/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "k3-pinctrl.h"
+
+&{/} {
+	panel0 {
+		compatible = "raspberrypi,7inch-dsi", "simple-panel";
+		backlight = <&display_reg>;
+		power-supply = <&display_reg>;
+
+		port {
+
+			panel_in: endpoint {
+				remote-endpoint = <&panel_bridge_out>;
+			};
+		};
+	};
+
+	bridge_reg: bridge-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "bridge-reg";
+		gpio = <&display_reg 0 0>;
+		vin-supply = <&display_reg>;
+		enable-active-high;
+	};
+};
+
+&dphy_tx0 {
+	status = "okay";
+};
+
+&main_i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	display_reg: regulator@45 {
+		compatible = "raspberrypi,7inch-touchscreen-panel-regulator";
+		reg = <0x45>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&dss1 {
+	status = "okay";
+};
+
+&dss1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* DSS1-VP1: DSI Output */
+	port@1 {
+		reg = <1>;
+
+		dss1_dpi1_out: endpoint {
+			remote-endpoint = <&dsi0_in>;
+		};
+	};
+};
+
+&dsi0 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+
+			dsi0_out: endpoint {
+				remote-endpoint = <&panel_bridge_in>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+
+			dsi0_in: endpoint {
+				remote-endpoint = <&dss1_dpi1_out>;
+			};
+		};
+	};
+
+	bridge@0 {
+		status = "okay";
+		compatible = "toshiba,tc358762";
+		reg = <0>;
+		vddc-supply = <&bridge_reg>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				panel_bridge_in: endpoint {
+					remote-endpoint = <&dsi0_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				panel_bridge_out: endpoint {
+					remote-endpoint = <&panel_in>;
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5-sk-dss-shared-mode.dtso b/arch/arm64/boot/dts/ti/k3-am62p5-sk-dss-shared-mode.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk-dss-shared-mode.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk-dss-shared-mode.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * DT overlay to enable display sharing mode for AM62P DSS0
+ * This is compatible with AM62P Device Manager firmware labelled as
+ * "dss_display_share.wkup-r5f0_0.release.strip.out"
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+&dss0 {
+	ti,dss-shared-mode;
+	ti,dss-shared-mode-vp = "vp1";
+	ti,dss-shared-mode-vp-owned = <0>;
+	ti,dss-shared-mode-common = "common1";
+	ti,dss-shared-mode-planes = "vid";
+	ti,dss-shared-mode-plane-zorder = <0>;
+	interrupt-parent = <&gic500>;
+	interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&reserved_memory {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	rtos_framebuffer_memory_region: rtos-framebuffer-memory@93500000 {
+		reg = <0x00 0x93500000 0x00 0x08000000>;
+		no-map;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts	2025-10-23 09:30:40.282462115 -0400
@@ -19,6 +19,7 @@
 
 	aliases {
 		serial0 = &wkup_uart0;
+		serial1 = &mcu_uart0;
 		serial2 = &main_uart0;
 		serial3 = &main_uart1;
 		mmc0 = &sdhci0;
@@ -32,7 +33,21 @@
 	};
 
 	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
 		stdout-path = &main_uart0;
+
+		framebuffer0: framebuffer@0 {
+			compatible = "simple-framebuffer";
+			power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
+			clocks = <&k3_clks 186 6>,
+				 <&dss0_vp1_clk>,
+				 <&k3_clks 186 2>;
+			display = <&dss0>;
+			status = "disabled";
+		};
 	};
 
 	memory@80000000 {
@@ -43,24 +58,55 @@
 		bootph-pre-ram;
 	};
 
-	reserved-memory {
+	reserved_memory: reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
 		ranges;
 
-		secure_tfa_ddr: tfa@9e780000 {
-			reg = <0x00 0x9e780000 0x00 0x80000>;
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x24000000>;
+			linux,cma-default;
+		};
+
+		rtos_ipc_memory_region: rtos-ipc-memory@9b500000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9b500000 0x00 0x00300000>;
 			no-map;
 		};
 
-		secure_ddr: optee@9e800000 {
-			reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
+		mcu_r5fss0_core0_dma_memory_region: mcu-r5fss-dma-memory-region@9b800000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9b800000 0x00 0x100000>;
 			no-map;
 		};
 
-		wkup_r5fss0_core0_memory_region: r5f-dma-memory@9c900000 {
+		mcu_r5fss0_core0_memory_region: mcu-r5fss-memory-region@9b900000 {
 			compatible = "shared-dma-pool";
-			reg = <0x00 0x9c900000 0x00 0x01e00000>;
+			reg = <0x00 0x9b900000 0x00 0xf00000>;
+			no-map;
+		};
+
+		wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@9c800000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9c800000 0x00 0x100000>;
+			no-map;
+		};
+
+		wkup_r5fss0_core0_memory_region: r5f-memory@9c900000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9c900000 0x00 0x1e00000>;
+			no-map;
+		};
+
+		secure_tfa_ddr: tfa@9e780000 {
+			reg = <0x00 0x9e780000 0x00 0x80000>;
+			no-map;
+		};
+
+		secure_ddr: optee@9e800000 {
+			reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
 			no-map;
 		};
 	};
@@ -128,6 +174,15 @@
 		};
 	};
 
+	opp-table {
+		/* Requires VDD_CORE at 0v85 */
+		opp-1400000000 {
+			opp-hz = /bits/ 64 <1400000000>;
+			opp-supported-hw = <0x01 0x0004>;
+			clock-latency-ns = <6000000>;
+		};
+	};
+
 	tlv320_mclk: clk-0 {
 		#clock-cells = <0>;
 		compatible = "fixed-clock";
@@ -162,6 +217,17 @@
 			clocks = <&tlv320_mclk>;
 		};
 	};
+
+	hdmi0: connector-hdmi {
+		compatible = "hdmi-connector";
+		label = "hdmi";
+		type = "a";
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&sii9022_out>;
+			};
+		};
+	};
 };
 
 &main_gpio0 {
@@ -217,6 +283,7 @@
 			AM62PX_IOPAD(0x0160, PIN_OUTPUT, 0) /* (F17) MDIO0_MDC */
 			AM62PX_IOPAD(0x015c, PIN_INPUT, 0) /* (F16) MDIO0_MDIO */
 		>;
+		bootph-all;
 	};
 
 	main_mmc1_pins_default: main-mmc1-default-pins {
@@ -301,7 +368,7 @@
 
 	main_usb1_pins_default: main-usb1-default-pins {
 		pinctrl-single,pins = <
-			AM62PX_IOPAD(0x0258, PIN_INPUT, 0) /* (G21) USB1_DRVVBUS */
+			AM62PX_IOPAD(0x0258, PIN_INPUT | PIN_DS_PULLUD_ENABLE | PIN_DS_PULL_UP, 0) /* (G21) USB1_DRVVBUS */
 		>;
 	};
 
@@ -346,6 +413,66 @@
 			AM62PX_IOPAD(0x0124, PIN_INPUT, 7) /* (J25) MMC2_SDCD.GPIO0_71 */
 		>;
 	};
+
+	main_dpi_pins_default: main-dpi-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x0100, PIN_OUTPUT, 0) /* (W20) VOUT0_VSYNC */
+			AM62PX_IOPAD(0x00f8, PIN_OUTPUT, 0) /* (AC20) VOUT0_HSYNC */
+			AM62PX_IOPAD(0x0104, PIN_OUTPUT, 0) /* (Y21) VOUT0_PCLK */
+			AM62PX_IOPAD(0x00fc, PIN_OUTPUT, 0) /* (W21) VOUT0_DE */
+			AM62PX_IOPAD(0x00b8, PIN_OUTPUT, 0) /* (AE24) VOUT0_DATA0 */
+			AM62PX_IOPAD(0x00bc, PIN_OUTPUT, 0) /* (W23) VOUT0_DATA1 */
+			AM62PX_IOPAD(0x00c0, PIN_OUTPUT, 0) /* (AA23) VOUT0_DATA2 */
+			AM62PX_IOPAD(0x00c4, PIN_OUTPUT, 0) /* (Y23) VOUT0_DATA3 */
+			AM62PX_IOPAD(0x00c8, PIN_OUTPUT, 0) /* (AB23) VOUT0_DATA4 */
+			AM62PX_IOPAD(0x00cc, PIN_OUTPUT, 0) /* (AD23) VOUT0_DATA5 */
+			AM62PX_IOPAD(0x00d0, PIN_OUTPUT, 0) /* (AC23) VOUT0_DATA6 */
+			AM62PX_IOPAD(0x00d4, PIN_OUTPUT, 0) /* (AE23) VOUT0_DATA7 */
+			AM62PX_IOPAD(0x00d8, PIN_OUTPUT, 0) /* (AE22) VOUT0_DATA8 */
+			AM62PX_IOPAD(0x00dc, PIN_OUTPUT, 0) /* (AC22) VOUT0_DATA9 */
+			AM62PX_IOPAD(0x00e0, PIN_OUTPUT, 0) /* (W22) VOUT0_DATA10 */
+			AM62PX_IOPAD(0x00e4, PIN_OUTPUT, 0) /* (AE21) VOUT0_DATA11 */
+			AM62PX_IOPAD(0x00e8, PIN_OUTPUT, 0) /* (AD21) VOUT0_DATA12 */
+			AM62PX_IOPAD(0x00ec, PIN_OUTPUT, 0) /* (AC21) VOUT0_DATA13 */
+			AM62PX_IOPAD(0x00f0, PIN_OUTPUT, 0) /* (AA20) VOUT0_DATA14 */
+			AM62PX_IOPAD(0x00f4, PIN_OUTPUT, 0) /* (Y20) VOUT0_DATA15 */
+			AM62PX_IOPAD(0x005c, PIN_OUTPUT, 1) /* (AC25) GPMC0_AD8.VOUT0_DATA16 */
+			AM62PX_IOPAD(0x0060, PIN_OUTPUT, 1) /* (AB25) GPMC0_AD9.VOUT0_DATA17 */
+			AM62PX_IOPAD(0x0064, PIN_OUTPUT, 1) /* (AA25) GPMC0_AD10.VOUT0_DATA18 */
+			AM62PX_IOPAD(0x0068, PIN_OUTPUT, 1) /* (W24) GPMC0_AD11.VOUT0_DATA19 */
+			AM62PX_IOPAD(0x006c, PIN_OUTPUT, 1) /* (Y24) GPMC0_AD12.VOUT0_DATA20 */
+			AM62PX_IOPAD(0x0070, PIN_OUTPUT, 1) /* (AD25) GPMC0_AD13.VOUT0_DATA21 */
+			AM62PX_IOPAD(0x0074, PIN_OUTPUT, 1) /* (AB24) GPMC0_AD14.VOUT0_DATA22 */
+			AM62PX_IOPAD(0x0078, PIN_OUTPUT, 1) /* (AC24) GPMC0_AD15.VOUT0_DATA23 */
+			AM62PX_IOPAD(0x009c, PIN_OUTPUT, 1) /* (AD24) GPMC0_WAIT1.VOUT0_EXTPCLKIN */
+		>;
+	};
+
+	main_epwm0_pins_default: main_epwm0-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x01b4, PIN_OUTPUT, 2) /* (D20) SPI0_CS0.EHRPWM0_A */
+			AM62PX_IOPAD(0x01b8, PIN_OUTPUT, 2) /* (E20) SPI0_CS1.EHRPWM0_B */
+		>;
+	};
+
+	main_epwm1_pins_default: main_epwm1-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x01bc, PIN_OUTPUT, 2) /* (B21) SPI0_CLK.EHRPWM1_A */
+			AM62PX_IOPAD(0x01c0, PIN_OUTPUT, 2) /* (B20) SPI0_D0.EHRPWM1_B */
+		>;
+	};
+
+	main_ecap1_pins_default: main_ecap1-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x019c, PIN_OUTPUT, 2) /* (E24) MCASP0_AXR1.ECAP1_IN_APWM_OUT */
+		>;
+	};
+
+	main_ecap2_pins_default: main-ecap2-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x01a4, PIN_OUTPUT, 2) /* (F24) MCASP0_ACLKX.ECAP2_IN_APWM_OUT */
+		>;
+	};
 };
 
 &main_i2c0 {
@@ -433,6 +560,41 @@
 				   "GPIO_OLDI_RSTn", "GPIO_AUD_RSTn",
 				   "GPIO_eMMC_RSTn", "SoC_WLAN_SDIO_RST";
 	};
+
+	sii9022: bridge-hdmi@3b {
+		compatible = "sil,sii9022";
+		reg = <0x3b>;
+		interrupt-parent = <&exp1>;
+		interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
+		#sound-dai-cells = <0>;
+		sil,i2s-data-lanes = < 0 >;
+
+		hdmi_tx_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/*
+			 * HDMI can be serviced with 3 potential VPs -
+			 * (DSS0 VP1 / DSS1 VP0 / DSS1 VP1).
+			 * For now, we will service it with DSS0 VP1.
+			 */
+			port@0 {
+				reg = <0>;
+
+				sii9022_in: endpoint {
+					remote-endpoint = <&dss0_dpi1_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				sii9022_out: endpoint {
+					remote-endpoint = <&hdmi_connector_in>;
+				};
+			};
+		};
+	};
 };
 
 &main_i2c2 {
@@ -486,6 +648,7 @@
 
 	cpsw3g_phy0: ethernet-phy@0 {
 		reg = <0>;
+		bootph-all;
 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
 		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
 		ti,min-output-impedance;
@@ -564,6 +727,7 @@
 		cdns,tchsh-ns = <60>;
 		cdns,tslch-ns = <60>;
 		cdns,read-delay = <4>;
+		cdns,phy-mode;
 		bootph-all;
 
 		partitions {
@@ -612,6 +776,8 @@
 };
 
 &mailbox0_cluster0 {
+	status = "okay";
+
 	mbox_r5_0: mbox-r5-0 {
 		ti,mbox-rx = <0 0 0>;
 		ti,mbox-tx = <1 0 0>;
@@ -619,15 +785,40 @@
 };
 
 &mailbox0_cluster1 {
+	status = "okay";
+
 	mbox_mcu_r5_0: mbox-mcu-r5-0 {
 		ti,mbox-rx = <0 0 0>;
 		ti,mbox-tx = <1 0 0>;
 	};
 };
 
+&wkup_r5fss0 {
+	status = "okay";
+};
+
+&wkup_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster0 &mbox_r5_0>;
+	memory-region = <&wkup_r5fss0_core0_dma_memory_region>,
+			<&wkup_r5fss0_core0_memory_region>;
+};
+
+&mcu_r5fss0 {
+	status = "okay";
+};
+
+&mcu_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster1 &mbox_mcu_r5_0>;
+	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
+			<&mcu_r5fss0_core0_memory_region>;
+};
+
 &main_uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_uart0_pins_default>;
+	interrupts-extended = <&gic500 GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>,
+			<&main_pmx0 0x1c8>; /* (D14) UART0_RXD PADCONFIG114 */
+	interrupt-names = "irq", "wakeup";
 	status = "okay";
 	bootph-all;
 };
@@ -668,3 +859,55 @@
 &mcu_gpio_intr {
 	status = "reserved";
 };
+
+&dss_oldi_io_ctrl {
+	bootph-all;
+};
+
+&dss0 {
+	bootph-all;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_dpi_pins_default>;
+};
+
+&dss0_ports {
+	/* DSS0-VP2: DPI/HDMI Output */
+	hdmi0_dss: port@1 {
+		reg = <1>;
+
+		dss0_dpi1_out: endpoint {
+			remote-endpoint = <&sii9022_in>;
+		};
+	};
+};
+
+&epwm0 {
+	/* Pin 24/26 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm0_pins_default>;
+	status = "okay";
+};
+
+&epwm1 {
+	/* Pin 23/19 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm1_pins_default>;
+	status = "okay";
+};
+
+&ecap1 {
+	/* ECAP1 in APWM mode */
+	/* Pin 36 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap1_pins_default>;
+	status = "okay";
+};
+
+&ecap2 {
+	/* ECAP2 in APWM mode */
+	/* Pin 11 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap2_pins_default>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5-sk-ecap-capture.dtso b/arch/arm64/boot/dts/ti/k3-am62p5-sk-ecap-capture.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk-ecap-capture.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk-ecap-capture.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for enabling ECAP in capture mode on AM62P5-SK
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+	main_ecap1_capture_pins_default: main-ecap1-capture-pins-default {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x019c, PIN_INPUT, 2) /* (E24) MCASP0_AXR1.ECAP1_IN_APWM_OUT */
+		>;
+	};
+
+	main_ecap2_capture_pins_default: main-ecap2-capture-pins-default {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x01a4, PIN_INPUT, 2) /* (F24) MCASP0_ACLKX.ECAP2_IN_APWM_OUT */
+		>;
+	};
+};
+
+&ecap1 {
+	/* ECAP in capture mode */
+	/* Pin 36 of J4 */
+	compatible = "ti,am62-ecap-capture";
+	interrupt-parent = <&gic500>;
+	interrupts = <GIC_SPI 114 IRQ_TYPE_EDGE_RISING>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap1_capture_pins_default>;
+	status = "okay";
+};
+
+&ecap2 {
+	/* ECAP in capture mode */
+	/* Pin 11 of J4 */
+	compatible = "ti,am62-ecap-capture";
+	interrupt-parent = <&gic500>;
+	interrupts = <GIC_SPI 115 IRQ_TYPE_EDGE_RISING>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap2_capture_pins_default>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5-sk-eqep.dtso b/arch/arm64/boot/dts/ti/k3-am62p5-sk-eqep.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk-eqep.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk-eqep.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for enabling EQEP on AM62P5-SK
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+	main_eqep0_pins_default: main-eqep0-pins-default {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x0194, PIN_INPUT, 8) /* (D25) MCASP0_AXR3.EQEP0_A */
+			AM62PX_IOPAD(0x0198, PIN_INPUT, 8) /* (E25) MCASP0_AXR2.EQEP0_B */
+			AM62PX_IOPAD(0x01a0, PIN_INPUT, 8) /* (F23) MCASP0_AXR0.EQEP0_I */
+			AM62PX_IOPAD(0x019c, PIN_INPUT, 8) /* (E24) MCASP0_AXR1.EQEP0_S */
+		>;
+	};
+};
+
+&main_i2c1 {
+	gpio@22 {
+		p02-hog {
+			/* P02 - UART1_FET_SEL */
+			gpio-hog;
+			gpios = <2 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "UART1_FET_SEL";
+		};
+	};
+};
+
+&ecap1 {
+	/* MCASP0_AXR1 pinmux conflict  */
+	status = "disabled";
+};
+
+&main_uart1 {
+	/* Disable FW debug logs */
+	status = "disabled";
+};
+
+&eqep0 {
+	status = "okay";
+	/* A/B on pins 40/38 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_eqep0_pins_default>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5-sk-ethfw.dtso b/arch/arm64/boot/dts/ti/k3-am62p5-sk-ethfw.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk-ethfw.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk-ethfw.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for CPSW3G functionality with Ethernet Switch Firmware (EthFw)
+ * and CPSW Proxy Client driver.
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+/* Mark CPSW3G reserved for EthFw. */
+&cpsw3g {
+	status = "reserved";
+};
+
+/* Reserve shared memory for inter-core network communication. */
+&reserved_memory {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	wkup_r5fss0_core0_shared_memory_queue_region:r5f-virtual-eth-queues@a4000000 {
+		compatible = "shared-dma-pool";
+		reg = <0x00 0xa4000000 0x00 0x200000>;
+		no-map;
+	};
+
+	wkup_r5fss0_core0_shared_memory_bufpool_region:r5f-virtual-eth-buffers@a4200000 {
+		compatible = "shared-dma-pool";
+		reg = <0x00 0xa4200000 0x00 0x1e00000>;
+		no-map;
+	};
+};
+
+&wkup_r5fss0_core0 {
+	memory-region = <&wkup_r5fss0_core0_dma_memory_region>,
+			<&wkup_r5fss0_core0_memory_region>,
+			<&wkup_r5fss0_core0_shared_memory_queue_region>,
+			<&wkup_r5fss0_core0_shared_memory_bufpool_region>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5-sk-m2-cc3351.dtso b/arch/arm64/boot/dts/ti/k3-am62p5-sk-m2-cc3351.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk-m2-cc3351.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk-m2-cc3351.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * DT Overlay for M.2-CC3351 board to connect to the M.2 connector on AM625-SK.
+ *
+ * Product page for board: https://www.ti.com/tool/M2-CC3351
+ * CC3351 Datasheet: https://www.ti.com/lit/ds/symlink/cc3351.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	wlan_lten: regulator-30 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan_lten";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vdd_mmc1>;
+		gpios = <&exp1 11 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	wlan_en: regulator-31 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan_en";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&wlan_lten>;
+		enable-active-high;
+		gpios = <&main_gpio0 71 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wlan_en_pins_default>;
+	};
+};
+
+&main_pmx0 {
+	wlan_en_pins_default: wlan-en-pins-default {
+		pinctrl-single,pins = <
+				AM62X_IOPAD(0x124, PIN_OUTPUT, 7) /* (A23) MMC2_SDCD.GPIO0_71 */
+		>;
+	};
+
+	main_mmc2_pins_default: main-mmc2-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x120, PIN_INPUT, 0) /* (C24) MMC2_CMD */
+			AM62X_IOPAD(0x118, PIN_INPUT, 0) /* (D25) MMC2_CLK */
+			AM62X_IOPAD(0x114, PIN_INPUT, 0) /* (B24) MMC2_DAT0 */
+			AM62X_IOPAD(0x110, PIN_INPUT, 0) /* (C25) MMC2_DAT1 */
+			AM62X_IOPAD(0x10c, PIN_INPUT, 0) /* (E23) MMC2_DAT2 */
+			AM62X_IOPAD(0x108, PIN_INPUT, 0) /* (D24) MMC2_DAT3 */
+			AM62X_IOPAD(0x11c, PIN_INPUT, 0) /* (#N/A) MMC2_CLKB */
+		>;
+	};
+
+	main_wlirq_pins_default: main-wlirq-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x128, PIN_INPUT, 7) /* (B23) MMC2_SDWP.GPIO0_72 */
+		>;
+	};
+};
+
+&sdhci2 {
+	status = "okay";
+	bootph-all;
+	vmmc-supply = <&wlan_en>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc2_pins_default>;
+	bus-width = <4>;
+	non-removable;
+	ti,fails-without-test-cd;
+	cap-power-off-card;
+	keep-power-in-suspend;
+	ti,driver-strength-ohm = <50>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	wifi: cc3300@2 {
+		compatible = "ti,cc3300";
+		reg = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_wlirq_pins_default>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <72 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5-sk-mcan.dtso b/arch/arm64/boot/dts/ti/k3-am62p5-sk-mcan.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk-mcan.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk-mcan.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT overlay for enabling MCAN for AM62P-SK
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	transceiver1: can-phy0 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
+	transceiver2: can-phy1 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
+	transceiver3: can-phy2 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
+	transceiver4: can-phy3 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+};
+
+&main_pmx0 {
+	main_mcan0_pins_default: main-mcan0-pins-default {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x01dc, PIN_INPUT, 0) /* (F20) MCAN0_RX */
+			AM62PX_IOPAD(0x01d8, PIN_OUTPUT, 0) /* (B23) MCAN0_TX */
+		>;
+	};
+
+	main_mcan1_pins_default: main-mcan1-pins-default {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x00b4, PIN_INPUT, 5) /* (U25) GPMC0_CSn3.MCAN1_RX */
+			AM62PX_IOPAD(0x00b0, PIN_OUTPUT, 5) /* (T22) GPMC0_CSn2.MCAN1_TX */
+		>;
+	};
+};
+
+&mcu_pmx0 {
+	mcu_mcan0_pins_default: mcu-mcan0-pins-default {
+		pinctrl-single,pins = <
+			AM62PX_MCU_IOPAD(0x0038, PIN_INPUT, 0) /* (D6) MCU_MCAN0_RX */
+			AM62PX_MCU_IOPAD(0x0034, PIN_OUTPUT, 0) /* (E8) MCU_MCAN0_TX */
+		>;
+	};
+
+	mcu_mcan1_pins_default: mcu-mcan1-pins-default {
+		pinctrl-single,pins = <
+			AM62PX_MCU_IOPAD(0x0040, PIN_INPUT, 0) /* (E7) MCU_MCAN1_RX */
+			AM62PX_MCU_IOPAD(0x003c, PIN_OUTPUT, 0) /* (F8) MCU_MCAN1_TX */
+		>;
+	};
+};
+
+&main_i2c2{
+	/*
+	* main_i2c2 is using (U25) and (T22)
+	* so disable to use main_mcan1
+	*/
+	status = "disabled";
+};
+
+&main_i2c1 {
+	/*
+	* Unset GPIO SoC_I2C2_MCAN_SEL to
+	* route MCAN1 signals to MCAN1 HDR
+	*/
+	gpio@23 {
+		p20-hog {
+		/* P20 - SoC_I2C2_MCAN_SEL */
+		gpio-hog;
+		gpios = <16 GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "SoC_I2C2_MCAN_SEL";
+		};
+	};
+};
+
+&main_mcan0 {
+	/* RX pin 8 & TX pin 10 of J3 */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan0_pins_default>;
+	phys = <&transceiver1>;
+};
+
+&main_mcan1 {
+	/* RX pin 2 & TX pin 1 of J1 */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan1_pins_default>;
+	phys = <&transceiver2>;
+};
+
+&mcu_mcan0 {
+	/* RX pin 22 & TX pin 16 of J11 */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mcan0_pins_default>;
+	phys = <&transceiver3>;
+};
+
+&mcu_mcan1 {
+	/* RX pin 11 & TX pin 10 of J11 */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mcan1_pins_default>;
+	phys = <&transceiver4>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5-sk-microtips-mf070zima-lcd3.dtso b/arch/arm64/boot/dts/ti/k3-am62p5-sk-microtips-mf070zima-lcd3.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk-microtips-mf070zima-lcd3.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk-microtips-mf070zima-lcd3.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * Microtips integrated DSI panel (MF-070ZIMACAA0) and touch DT overlay for AM62P5-SK
+ *
+ * AM62P5-SK EVM: https://www.ti.com/tool/SK-AM62P-LP
+ * Panel: https://simplespec.microtipsusa.com/uploads/spec/datasheetFile/3004/13-070ZIMACAA0-S_V1.1_20231120.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&dphy_tx0 {
+	status = "okay";
+};
+
+&dss1 {
+	status = "okay";
+};
+
+&dss1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* DSS1-VP1: DSI Output */
+	port@1 {
+		reg = <1>;
+
+		dss1_dpi1_out: endpoint {
+			remote-endpoint = <&dsi0_in>;
+		};
+	};
+};
+
+&dsi0 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+
+			dsi0_out: endpoint {
+				remote-endpoint = <&panel_in>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+
+			dsi0_in: endpoint {
+				remote-endpoint = <&dss1_dpi1_out>;
+			};
+		};
+	};
+
+	dsi_panel0: panel-dsi@0 {
+		compatible = "microtips,mf-070zimacaa0", "ilitek,ili9881c";
+		reg = <0>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&dsi0_out>;
+			};
+		};
+	};
+};
+
+&main_i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	touchscreen@41 {
+		compatible = "ilitek,ili251x";
+		reg = <0x41>;
+		reset-gpios = <&exp1 8 GPIO_ACTIVE_LOW>;
+		interrupt-parent = <&exp1>;
+		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5-sk-microtips-mf101hie-panel.dtso b/arch/arm64/boot/dts/ti/k3-am62p5-sk-microtips-mf101hie-panel.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk-microtips-mf101hie-panel.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk-microtips-mf101hie-panel.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * Microtips integrated OLDI panel (MF-101HIEBCAF0) and touch DT overlay for AM62P5-SK
+ *
+ * Panel datasheet: https://simplespec.microtipsusa.com/uploads/spec/datasheetFile/2588/13-101HIEBCAF0-S_V1.1_20221104.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&{/} {
+	display {
+		compatible = "microtips,mf-101hiebcaf0", "panel-simple";
+
+		/*
+		* Note that the OLDI TX 0 transmits the odd set of pixels
+		* while the OLDI TX 1 transmits the even set. This is a
+		* fixed configuration in the IP integration and is not
+		* changeable. The properties, "dual-lvds-odd-pixels" and
+		* "dual-lvds-even-pixels" have been used to merely
+		* identify if a Dual Link configuration is required.
+		* Swapping them will cause an error in the dss oldi driver.
+		*/
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				dual-lvds-odd-pixels;
+
+				lcd_in0: endpoint {
+					remote-endpoint = <&oldi0_dss0_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				dual-lvds-even-pixels;
+
+				lcd_in1: endpoint {
+					remote-endpoint = <&oldi1_dss0_out>;
+				};
+			};
+		};
+	};
+};
+
+&dss0 {
+	status = "okay";
+};
+
+&oldi0_dss0 {
+	status = "okay";
+};
+
+&oldi1_dss0 {
+	status = "okay";
+};
+
+&oldi0_dss0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+
+		oldi0_dss0_in: endpoint {
+			remote-endpoint = <&dss0_dpi0_out0>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+
+		oldi0_dss0_out: endpoint {
+			remote-endpoint = <&lcd_in0>;
+		};
+	};
+};
+
+&oldi1_dss0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+
+		oldi1_dss0_in: endpoint {
+			remote-endpoint = <&dss0_dpi0_out1>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+
+		oldi1_dss0_out: endpoint {
+			remote-endpoint = <&lcd_in1>;
+		};
+	};
+};
+
+&dss0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* VP1: Output to OLDI */
+	port@0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dss0_dpi0_out0: endpoint@0 {
+			reg = <0>;
+			remote-endpoint = <&oldi0_dss0_in>;
+		};
+
+		dss0_dpi0_out1: endpoint@1 {
+			reg = <1>;
+			remote-endpoint = <&oldi1_dss0_in>;
+		};
+	};
+};
+
+&main_i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	touchscreen@41 {
+		compatible = "ilitek,ili251x";
+		reg = <0x41>;
+		interrupt-parent = <&exp1>;
+		interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&exp2 20 GPIO_ACTIVE_LOW>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5-sk-microtips-mf103hie-lcd2.dtso b/arch/arm64/boot/dts/ti/k3-am62p5-sk-microtips-mf103hie-lcd2.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk-microtips-mf103hie-lcd2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk-microtips-mf103hie-lcd2.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * Microtips integrated OLDI panel (MF-103HIEB0GA0) (SK-LCD2) DT overlay for AM62PS5-SK
+ *
+ * Panel datasheet: https://simplespec.microtipsusa.com/uploads/spec/datasheetFile/2660/13-103HIEB0GA0-S_V1.0_20211206.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&{/} {
+	display {
+		compatible = "microtips,mf-103hieb0ga0", "panel-simple";
+
+		/*
+		* Note that the OLDI TX 0 transmits the odd set of pixels
+		* while the OLDI TX 1 transmits the even set. This is a
+		* fixed configuration in the IP integration and is not
+		* changeable. The properties, "dual-lvds-odd-pixels" and
+		* "dual-lvds-even-pixels" have been used to merely
+		* identify if a Dual Link configuration is required.
+		* Swapping them will cause an error in the dss oldi driver.
+		*/
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				dual-lvds-odd-pixels;
+
+				lcd_in0: endpoint {
+					remote-endpoint = <&oldi0_dss0_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				dual-lvds-even-pixels;
+
+				lcd_in1: endpoint {
+					remote-endpoint = <&oldi1_dss0_out>;
+				};
+			};
+		};
+	};
+};
+
+&dss0 {
+	status = "okay";
+};
+
+&oldi0_dss0 {
+	status = "okay";
+};
+
+&oldi1_dss0 {
+	status = "okay";
+};
+
+&oldi0_dss0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+
+		oldi0_dss0_in: endpoint {
+			remote-endpoint = <&dss0_dpi0_out0>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+
+		oldi0_dss0_out: endpoint {
+			remote-endpoint = <&lcd_in0>;
+		};
+	};
+};
+
+&oldi1_dss0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+
+		oldi1_dss0_in: endpoint {
+			remote-endpoint = <&dss0_dpi0_out1>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+
+		oldi1_dss0_out: endpoint {
+			remote-endpoint = <&lcd_in1>;
+		};
+	};
+};
+
+&dss0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* VP1: Output to OLDI */
+	port@0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dss0_dpi0_out0: endpoint@0 {
+			reg = <0>;
+			remote-endpoint = <&oldi0_dss0_in>;
+		};
+
+		dss0_dpi0_out1: endpoint@1 {
+			reg = <1>;
+			remote-endpoint = <&oldi1_dss0_in>;
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p5-sk-rpi-hdr-ehrpwm.dtso b/arch/arm64/boot/dts/ti/k3-am62p5-sk-rpi-hdr-ehrpwm.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk-rpi-hdr-ehrpwm.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk-rpi-hdr-ehrpwm.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT Overlay for enabling RPi header with GPIOs and ePWMs on AM62P-SK
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+	rpi_header_gpio0_pins_default: rpi-header-gpio0-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x0038, PIN_INPUT, 7) /* (L23) OSPI0_CSn3.GPIO0_14 */
+			AM62PX_IOPAD(0x0088, PIN_INPUT, 7) /* (R24) GPMC0_OEn_REn.GPIO0_33 */
+			AM62PX_IOPAD(0x0094, PIN_INPUT, 7) /* (T24) GPMC0_BE1n.GPIO0_36 */
+			AM62PX_IOPAD(0x009c, PIN_INPUT, 7) /* (AD24) GPMC0_WAIT1.GPIO0_38 */
+			AM62PX_IOPAD(0x00a0, PIN_INPUT, 7) /* (P24) GPMC0_WPn.GPIO0_39 */
+			AM62PX_IOPAD(0x00a4, PIN_INPUT, 7) /* (P25) GPMC0_DIR.GPIO0_40 */
+			AM62PX_IOPAD(0x00a8, PIN_INPUT, 7) /* (T23) GPMC0_CSn0.GPIO0_41 */
+			AM62PX_IOPAD(0x00ac, PIN_INPUT, 7) /* (U23) GPMC0_CSn1.GPIO0_42 */
+		>;
+	};
+
+	rpi_header_gpio1_pins_default: rpi-header-gpio1-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x01a4, PIN_INPUT, 7) /* (F24) MCASP0_ACLKX.GPIO1_11 */
+			AM62PX_IOPAD(0x01bc, PIN_INPUT, 7) /* (B21) SPI0_CLK.GPIO1_17 */
+			AM62PX_IOPAD(0x01c0, PIN_INPUT, 7) /* (B20) SPI0_D0.GPIO1_18 */
+			AM62PX_IOPAD(0x01c4, PIN_INPUT, 7) /* (C21) SPI0_D1.GPIO1_19 */
+			AM62PX_IOPAD(0x01d0, PIN_INPUT, 7) /* (A23) UART0_CTSn.GPIO1_22 */
+			AM62PX_IOPAD(0x01d8, PIN_INPUT, 7) /* (B23) MCAN0_TX.GPIO1_24 */
+			AM62PX_IOPAD(0x01dc, PIN_INPUT, 7) /* (F20) MCAN0_RX.GPIO1_25 */
+		>;
+	};
+
+	rpi_header_ehrpwm0_pins_default: rpi-header-ehrpwm0-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x01b4, PIN_OUTPUT, 2) /* (D20) SPI0_CS0.EHRPWM0_A */
+			AM62PX_IOPAD(0x01b8, PIN_OUTPUT, 2) /* (E20) SPI0_CS1.EHRPWM0_B */
+		>;
+	};
+
+	rpi_header_ehrpwm1_pins_default: rpi-header-ehrpwm1-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x01bc, PIN_OUTPUT, 2) /* (B21) SPI0_CLK.EHRPWM1_A */
+			AM62PX_IOPAD(0x01c0, PIN_OUTPUT, 2) /* (B20) SPI0_D0.EHRPWM1_B */
+		>;
+	};
+};
+
+&main_i2c1 {
+	gpio@22 {
+		p02-hog {
+			/* P02 - UART1_FET_SEL */
+			gpio-hog;
+			gpios = <2 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "UART1_FET_SEL";
+		};
+
+		p05-hog {
+			/* P05 - EXP_PS_3V3_EN */
+			gpio-hog;
+			gpios = <5 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "EXP_PS_3V3_EN";
+		};
+	};
+
+	gpio@23 {
+		p01-hog {
+			/* P01 - EXP_PS_5V0_EN */
+			gpio-hog;
+			gpios = <1 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "EXP_PS_5V0_EN";
+		};
+	};
+};
+
+&dss0 {
+	/* Conflict with GPIO0_38 */
+	status = "disabled";
+};
+
+&epwm0 {
+	/* Pin 24/26 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&rpi_header_ehrpwm0_pins_default>;
+	status = "okay";
+};
+
+&epwm1 {
+	/* Pin 23/19 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&rpi_header_ehrpwm1_pins_default>;
+	status = "okay";
+};
+
+&main_gpio0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rpi_header_gpio0_pins_default>;
+};
+
+&main_gpio1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rpi_header_gpio1_pins_default>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -59,12 +59,17 @@
 			 <0x00 0x01000000 0x00 0x01000000 0x00 0x01b28400>, /* First peripheral window */
 			 <0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* Main CPSW */
 			 <0x00 0x0e000000 0x00 0x0e000000 0x00 0x01d20000>, /* Second peripheral window */
-			 <0x00 0x0fd00000 0x00 0x0fd00000 0x00 0x00020000>, /* GPU */
+			 <0x00 0x0fd80000 0x00 0x0fd80000 0x00 0x00080000>, /* GPU */
 			 <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */
 			 <0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */
 			 <0x00 0x30101000 0x00 0x30101000 0x00 0x00010100>, /* CSI window */
+			 <0x00 0x301C0000 0x00 0x301C0000 0x00 0x00001000>, /* DPHY-TX */
 			 <0x00 0x30200000 0x00 0x30200000 0x00 0x00010000>, /* DSS */
 			 <0x00 0x30210000 0x00 0x30210000 0x00 0x00010000>, /* VPU */
+			 <0x00 0x30220000 0x00 0x30220000 0x00 0x00010000>, /* DSS1 */
+			 <0x00 0x30270000 0x00 0x30270000 0x00 0x00010000>, /* DSI Wrapper */
+			 <0x00 0x30300000 0x00 0x30300000 0x00 0x00001000>, /* MCRC64 */
+			 <0x00 0x30500000 0x00 0x30500000 0x00 0x00100000>, /* DSI Config */
 			 <0x00 0x31000000 0x00 0x31000000 0x00 0x00050000>, /* USB0 DWC3 Core window */
 			 <0x00 0x31100000 0x00 0x31100000 0x00 0x00050000>, /* USB1 DWC3 Core window */
 			 <0x00 0x40900000 0x00 0x40900000 0x00 0x00030000>, /* SA3UL */
@@ -116,6 +121,22 @@
 		};
 	};
 
+	dss0_vp1_clk: clock-divider-oldi-dss0 {
+		compatible = "fixed-factor-clock";
+		clocks = <&k3_clks 186 0>;
+		#clock-cells = <0>;
+		clock-div = <7>;
+		clock-mult = <1>;
+	};
+
+	dss1_vp1_clk: clock-divider-oldi-dss1 {
+		compatible = "fixed-factor-clock";
+		clocks = <&k3_clks 232 0>;
+		#clock-cells = <0>;
+		clock-div = <7>;
+		clock-mult = <1>;
+	};
+
 	#include "k3-am62p-j722s-common-thermal.dtsi"
 };
 
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -45,6 +45,18 @@
 			pmsg-size = <0x8000>;
 		};
 
+		mcu_m4fss_dma_memory_region: m4f-dma-memory@9cb00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9cb00000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_m4fss_memory_region: m4f-memory@9cc00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9cc00000 0x00 0xe00000>;
+			no-map;
+		};
+
 		secure_tfa_ddr: tfa@9e780000 {
 			reg = <0x00 0x9e780000 0x00 0x80000>;
 			alignment = <0x1000>;
@@ -83,6 +95,16 @@
 		regulator-boot-on;
 	};
 
+	vddshv_3v3: regulator-vddshv-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDSHV0";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vdd_3v3>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -173,6 +195,13 @@
 	};
 };
 
+&a53_opp_table {
+	opp-1400000000 {
+		opp-hz = /bits/ 64 <1400000000>;
+		opp-supported-hw = <0x01 0x0004>;
+	};
+};
+
 &cpsw3g {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_rgmii1_pins_default>;
@@ -196,6 +225,13 @@
 	};
 };
 
+&mailbox0_cluster0 {
+	mbox_m4_0: mbox-m4-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
 &main_i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_i2c0_pins_default>;
@@ -226,8 +262,8 @@
 		regulators {
 			vdd_core: buck1 {
 				regulator-name = "VDD_CORE";
-				regulator-min-microvolt = <750000>;
-				regulator-max-microvolt = <750000>;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
 				regulator-boot-on;
 				regulator-always-on;
 			};
@@ -287,6 +323,7 @@
 		compatible = "atmel,24c32";
 		pagesize = <32>;
 		reg = <0x50>;
+		vcc-supply = <&vddshv_3v3>;
 	};
 
 	i2c_som_rtc: rtc@52 {
@@ -295,6 +332,13 @@
 	};
 };
 
+&mcu_m4fss {
+	mboxes = <&mailbox0_cluster0 &mbox_m4_0>;
+	memory-region = <&mcu_m4fss_dma_memory_region>,
+			<&mcu_m4fss_memory_region>;
+	status = "okay";
+};
+
 &ospi0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ospi0_pins_default>;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -50,6 +50,7 @@
 			compatible = "ti,am654-phy-gmii-sel";
 			reg = <0x4044 0x8>;
 			#phy-cells = <1>;
+			bootph-all;
 		};
 
 		epwm_tbclk: clock-controller@4130 {
@@ -57,6 +58,11 @@
 			reg = <0x4130 0x4>;
 			#clock-cells = <1>;
 		};
+
+		dss_oldi_io_ctrl: dss-oldi-io-ctrl@8600 {
+			compatible = "syscon";
+			reg = <0x8600 0x200>;
+		};
 	};
 
 	dmss: bus@48000000 {
@@ -232,6 +238,13 @@
 		dma-names = "tx", "rx1", "rx2";
 	};
 
+	crc: crc@30300000 {
+		compatible = "ti,am62-mcrc64";
+		reg = <0x00 0x30300000 0x00 0x1000>;
+		clocks = <&k3_clks 116 0>;
+		power-domains = <&k3_pds 116 TI_SCI_PD_EXCLUSIVE>;
+	};
+
 	secure_proxy_sa3: mailbox@43600000 {
 		compatible = "ti,am654-secure-proxy";
 		#mbox-cells = <1>;
@@ -249,11 +262,24 @@
 	};
 
 	main_pmx0: pinctrl@f4000 {
-		compatible = "pinctrl-single";
+		compatible = "ti,am654-padconf", "pinctrl-single";
 		reg = <0x00 0xf4000 0x00 0x2ac>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
 		pinctrl-single,function-mask = <0xffffffff>;
+		/*
+		 * pinctrl IP DOES NOT give any functional IRQs when a
+		 * system is in active state. This IRQ is only a dummy IRQ
+		 * that is being used to trick Linux into thinking that
+		 * GIC can potentially recieve an interrupt from this IP.
+		 * This helps us setup the IO daisychain wakeups for deep
+		 * sleep via chained wake IRQs.
+		 * Please feel free to assign a different number here as
+		 * long as it is unused if 98 conflicts with another use case.
+		 */
+		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
 		bootph-all;
 	};
 
@@ -567,15 +593,12 @@
 		bus-width = <8>;
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
-		mmc-hs400-1_8v;
 		ti,clkbuf-sel = <0x7>;
-		ti,strobe-sel = <0x77>;
 		ti,trm-icp = <0x8>;
 		ti,otap-del-sel-legacy = <0x1>;
 		ti,otap-del-sel-mmc-hs = <0x1>;
 		ti,otap-del-sel-ddr52 = <0x6>;
 		ti,otap-del-sel-hs200 = <0x8>;
-		ti,otap-del-sel-hs400 = <0x5>;
 		ti,itap-del-sel-legacy = <0x10>;
 		ti,itap-del-sel-mmc-hs = <0xa>;
 		ti,itap-del-sel-ddr52 = <0x3>;
@@ -649,6 +672,7 @@
 			interrupt-names = "host", "peripheral";
 			maximum-speed = "high-speed";
 			dr_mode = "otg";
+			bootph-all;
 			snps,usb2-gadget-lpm-disable;
 			snps,usb2-lpm-disable;
 		};
@@ -669,6 +693,7 @@
 			cdns,fifo-depth = <256>;
 			cdns,fifo-width = <4>;
 			cdns,trigger-address = <0x0>;
+			cdns,phase-detect-selector = <0>;
 			clocks = <&k3_clks 75 7>;
 			assigned-clocks = <&k3_clks 75 7>;
 			assigned-clock-parents = <&k3_clks 75 8>;
@@ -718,6 +743,7 @@
 				mac-address = [00 00 00 00 00 00];
 				ti,syscon-efuse = <&cpsw_mac_syscon 0x0>;
 				status = "disabled";
+				bootph-all;
 			};
 
 			cpsw_port2: port@2 {
@@ -739,6 +765,7 @@
 			clock-names = "fck";
 			bus_freq = <1000000>;
 			status = "disabled";
+			bootph-all;
 		};
 
 		cpts@3d000 {
@@ -753,6 +780,19 @@
 		};
 	};
 
+	gpu: gpu@fd80000 {
+		compatible = "ti,am62p-pvr", "img,pvr-bxs64";
+		reg = <0x00 0x0fd80000 0x00 0x80000>;
+		interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&k3_pds 237 TI_SCI_PD_EXCLUSIVE>,
+		                <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>;
+		assigned-clocks = <&k3_clks 237 3>;
+		assigned-clock-rates = <800000000>;
+		power-domain-names = "firmware", "dust";
+		clocks = <&k3_clks 237 3>;
+		clock-names = "core";
+	};
+
 	hwspinlock: spinlock@2a000000 {
 		compatible = "ti,am64-hwspinlock";
 		reg = <0x00 0x2a000000 0x00 0x1000>;
@@ -766,6 +806,7 @@
 		#mbox-cells = <1>;
 		ti,mbox-num-users = <4>;
 		ti,mbox-num-fifos = <16>;
+		status = "disabled";
 	};
 
 	mailbox0_cluster1: mailbox@29010000 {
@@ -775,6 +816,7 @@
 		#mbox-cells = <1>;
 		ti,mbox-num-users = <4>;
 		ti,mbox-num-fifos = <16>;
+		status = "disabled";
 	};
 
 	mailbox0_cluster2: mailbox@29020000 {
@@ -784,6 +826,7 @@
 		#mbox-cells = <1>;
 		ti,mbox-num-users = <4>;
 		ti,mbox-num-fifos = <16>;
+		status = "disabled";
 	};
 
 	mailbox0_cluster3: mailbox@29030000 {
@@ -793,6 +836,7 @@
 		#mbox-cells = <1>;
 		ti,mbox-num-users = <4>;
 		ti,mbox-num-fifos = <16>;
+		status = "disabled";
 	};
 
 	ecap0: pwm@23100000 {
@@ -825,6 +869,33 @@
 		status = "disabled";
 	};
 
+	eqep0: counter@23200000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23200000 0x00 0x100>;
+		power-domains = <&k3_pds 59 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 59 0>;
+		interrupts = <GIC_SPI 116 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
+	eqep1: counter@23210000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23210000 0x00 0x100>;
+		power-domains = <&k3_pds 60 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 60 0>;
+		interrupts = <GIC_SPI 117 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
+	eqep2: counter@23220000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23220000 0x00 0x100>;
+		power-domains = <&k3_pds 62 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 62 0>;
+		interrupts = <GIC_SPI 118 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
 	main_mcan0: can@20701000 {
 		compatible = "bosch,m_can";
 		reg = <0x00 0x20701000 0x00 0x200>,
@@ -996,14 +1067,19 @@
 		ranges;
 		#address-cells = <2>;
 		#size-cells = <2>;
-		dmas = <&main_bcdma_csi 0 0x5000 0>;
-		dma-names = "rx0";
+		dmas = <&main_bcdma_csi 0 0x5000 0>, <&main_bcdma_csi 0 0x5001 0>,
+		       <&main_bcdma_csi 0 0x5002 0>, <&main_bcdma_csi 0 0x5003 0>,
+		       <&main_bcdma_csi 0 0x5004 0>, <&main_bcdma_csi 0 0x5005 0>;
+		dma-names = "rx0", "rx1", "rx2", "rx3", "rx4", "rx5";
 		power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 
 		cdns_csi2rx0: csi-bridge@30101000 {
 			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
 			reg = <0x00 0x30101000 0x00 0x1000>;
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
 			clocks = <&k3_clks 182 0>, <&k3_clks 182 3>, <&k3_clks 182 0>,
 				<&k3_clks 182 0>, <&k3_clks 182 4>, <&k3_clks 182 4>;
 			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
@@ -1051,11 +1127,166 @@
 		status = "disabled";
 	};
 
+	dphy0: phy@30110000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x30110000 0x00 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 185 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dss0: dss@30200000 {
+		compatible = "ti,am62p51-dss";
+		reg = <0x00 0x30200000 0x00 0x1000>, /* common */
+		      <0x00 0x30202000 0x00 0x1000>, /* vidl1 */
+		      <0x00 0x30206000 0x00 0x1000>, /* vid */
+		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
+		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
+		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Used for OLDI */
+		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
+		reg-names = "common", "vidl1", "vid",
+			    "ovr1", "ovr2", "vp1", "vp2", "common1";
+		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>,	/* DSS0 */
+				<&k3_pds 243 TI_SCI_PD_EXCLUSIVE>,	/* OLDI0 */
+				<&k3_pds 244 TI_SCI_PD_EXCLUSIVE>;	/* OLDI1 */
+		clocks = <&k3_clks 186 6>,
+			 <&dss0_vp1_clk>,
+			 <&k3_clks 186 2>;
+		clock-names = "fck", "vp1", "vp2";
+		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+
+		oldi-transmitters {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			oldi0_dss0: oldi@0 {
+				reg = <0>;
+				clocks = <&k3_clks 186 0>;
+				clock-names = "serial";
+				ti,companion-oldi = <&oldi1_dss0>;
+				ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+				status = "disabled";
+
+				oldi0_dss0_ports: ports {
+				};
+			};
+
+			oldi1_dss0: oldi@1 {
+				reg = <1>;
+				ti,secondary-oldi;
+				status = "disabled";
+
+				oldi1_dss0_ports: ports {
+				};
+			};
+		};
+
+		dss0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	dss1: dss@30220000 {
+		compatible = "ti,am62p52-dss";
+		reg = <0x00 0x30220000 0x00 0x1000>, /* common */
+		      <0x00 0x30222000 0x00 0x1000>, /* vidl1 */
+		      <0x00 0x30226000 0x00 0x1000>, /* vid */
+		      <0x00 0x30227000 0x00 0x1000>, /* ovr1 */
+		      <0x00 0x30228000 0x00 0x1000>, /* ovr2 */
+		      <0x00 0x3022a000 0x00 0x1000>, /* vp1: Used for OLDI */
+		      <0x00 0x3022b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+		      <0x00 0x30221000 0x00 0x1000>; /* common1 */
+		reg-names = "common", "vidl1", "vid",
+			    "ovr1", "ovr2", "vp1", "vp2", "common1";
+		power-domains = <&k3_pds 232 TI_SCI_PD_EXCLUSIVE>,	/* DSS0 */
+				<&k3_pds 244 TI_SCI_PD_EXCLUSIVE>;	/* OLDI1 */
+		clocks = <&k3_clks 232 8>,
+			 <&dss1_vp1_clk>,
+			 <&k3_clks 232 4>;
+		clock-names = "fck", "vp1", "vp2";
+		interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+
+		oldi-transmitters {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			oldi1_dss1: oldi@1 {
+				reg = <0>;
+				clocks = <&k3_clks 232 0>;
+				clock-names = "serial";
+				ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+				status = "disabled";
+
+				oldi1_dss1_ports: ports {
+				};
+			};
+		};
+
+		dss1_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	dphy_tx0: phy@301c0000 {
+		compatible = "ti,j721e-dphy";
+		reg = <0x0 0x301c0000 0x0 0x1000>;
+		clocks = <&k3_clks 238 16>, <&k3_clks 238 1>;
+		clock-names = "psm", "pll_ref";
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 238 TI_SCI_PD_EXCLUSIVE>;
+		assigned-clocks = <&k3_clks 238 1>;
+		assigned-clock-parents = <&k3_clks 238 2>;
+		assigned-clock-rates = <25000000>;
+		status = "disabled";
+	};
+
+	dsi0: dsi@30500000 {
+		compatible = "ti,j721e-dsi";
+		reg = <0x0 0x30500000 0x0 0x100000>, <0x0 0x30270000 0x0 0x100>;
+		clocks = <&k3_clks 231 2>, <&k3_clks 231 5>;
+		clock-names = "dsi_p_clk", "dsi_sys_clk";
+		power-domains = <&k3_pds 231 TI_SCI_PD_EXCLUSIVE>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+		phys = <&dphy_tx0>;
+		phy-names = "dphy";
+		status = "disabled";
+	};
+
 	vpu: video-codec@30210000 {
 		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
 		reg = <0x00 0x30210000 0x00 0x10000>;
 		interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&k3_clks 204 2>;
 		power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>;
+		sram = <&oc_sram>;
+		operating-points-v2 = <&vpu_opp_table>;
+		vpu_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-20000000 {
+				opp-hz = /bits/ 64 <20000000>;
+			};
+
+			opp-100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+			};
+
+			opp-200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+			};
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+			};
+
+			opp-500000000 {
+				opp-hz = /bits/ 64 <500000000>;
+			};
+		};
 	};
 };
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -6,6 +6,18 @@
  */
 
 &cbass_mcu {
+	mcu_ram: sram@79100000 {
+		compatible = "mmio-sram";
+		reg = <0x00 0x79100000 0x00 0x80000>;
+		ranges = <0x00 0x00 0x79100000 0x80000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		mcu_sram1@0 {
+			reg = <0x0 0x80000>;
+		};
+	};
+
 	mcu_pmx0: pinctrl@4084000 {
 		compatible = "pinctrl-single";
 		reg = <0x00 0x04084000 0x00 0x88>;
@@ -173,6 +185,7 @@
 		interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "int0", "int1";
+		wakeup-source = "suspend", "poweroff";
 		status = "disabled";
 	};
 
@@ -188,6 +201,7 @@
 		interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "int0", "int1";
+		wakeup-source = "suspend", "poweroff";
 		status = "disabled";
 	};
 
@@ -213,6 +227,7 @@
 			ti,atcm-enable = <0>;
 			ti,btcm-enable = <1>;
 			ti,loczrama = <0>;
+			sram = <&mcu_ram>;
 		};
 	};
 };
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-wakeup.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-wakeup.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-wakeup.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -5,6 +5,8 @@
  * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
  */
 
+#include <dt-bindings/bus/ti-sysc.h>
+
 &cbass_wakeup {
 	wkup_conf: bus@43000000 {
 		compatible = "simple-bus";
@@ -20,6 +22,11 @@
 			bootph-all;
 		};
 
+		opp_efuse_table: syscon@18 {
+			compatible = "ti,am62-opp-efuse-table", "syscon";
+			reg = <0x18 0x4>;
+		};
+
 		cpsw_mac_syscon: ethernet-mac-syscon@200 {
 			compatible = "ti,am62p-cpsw-mac-efuse", "syscon";
 			reg = <0x200 0x8>;
@@ -34,16 +41,46 @@
 			compatible = "ti,am62-usb-phy-ctrl", "syscon";
 			reg = <0x4018 0x4>;
 		};
+
+		ddr_pmctrl: syscon@80d0 {
+			compatible = "ti,am62-ddr-pmctrl", "syscon";
+			reg = <0x80d0 0x4>;
+		};
+
+		canuart_wake: syscon@18300 {
+			compatible = "ti,am62-canuart-wake", "syscon";
+			reg = <0x18300 0x44>;
+		};
 	};
 
-	wkup_uart0: serial@2b300000 {
-		compatible = "ti,am64-uart", "ti,am654-uart";
-		reg = <0x00 0x2b300000 0x00 0x100>;
-		interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+	target-module@2b300050 {
+		compatible = "ti,sysc-omap2", "ti,sysc";
+		reg = <0 0x2b300050 0 0x4>,
+		      <0 0x2b300054 0 0x4>,
+		      <0 0x2b300058 0 0x4>;
+		reg-names = "rev", "sysc", "syss";
+		ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+				 SYSC_OMAP2_SOFTRESET |
+				 SYSC_OMAP2_AUTOIDLE)>;
+		ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+				<SYSC_IDLE_NO>,
+				<SYSC_IDLE_SMART>,
+				<SYSC_IDLE_SMART_WKUP>;
+		ti,syss-mask = <1>;
+		ti,no-reset-on-init;
 		power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 114 0>;
-		clock-names = "fclk";
-		status = "disabled";
+		clock-names = "fck";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0 0x2b300000 0x100000>;
+
+		wkup_uart0: serial@0 {
+			compatible = "ti,am64-uart", "ti,am654-uart";
+			reg = <0 0x100>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
 	};
 
 	wkup_i2c0: i2c@2b200000 {
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -56,6 +56,26 @@
 	};
 };
 
+&main_conf {
+	audio_refclk0: clock-controller@82e0 {
+		compatible = "ti,am62-audio-refclk";
+		reg = <0x82e0 0x4>;
+		clocks = <&k3_clks 157 0>;
+		assigned-clocks = <&k3_clks 157 0>;
+		assigned-clock-parents = <&k3_clks 157 16>;
+		#clock-cells = <0>;
+	};
+
+	audio_refclk1: clock-controller@82e4 {
+		compatible = "ti,am62-audio-refclk";
+		reg = <0x82e4 0x4>;
+		clocks = <&k3_clks 157 18>;
+		assigned-clocks = <&k3_clks 157 18>;
+		assigned-clock-parents = <&k3_clks 157 34>;
+		#clock-cells = <0>;
+	};
+};
+
 &main_gpio0 {
 	gpio-ranges = <&main_pmx0 0 0 32>, <&main_pmx0 32 33 38>,
 			<&main_pmx0 70 72 22>;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-ardupilot-cape.dtso b/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-ardupilot-cape.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-ardupilot-cape.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-ardupilot-cape.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 BeagleBoard.org - https://beagleboard.org/
+ *
+ * https://docs.beagleboard.io/latest/boards/capes/cape-interface-spec.html#i2c
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		PB2-ARDUPILOT.kernel = __TIMESTAMP__;
+	};
+};
+
+// many definitions from pinmux/board/pocketbeagle2/pocketbeagle2-pinmux.dts
+&main_pmx0 {
+	main_spi0_pins: main-spi0-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01bc, PIN_INPUT_PULLUP, 0) /* P2.25 (A14) SPI0_CLK */
+			AM62X_IOPAD(0x01c0, PIN_INPUT_PULLUP, 0) /* P2.27v(B13) SPI0_D0 */
+			AM62X_IOPAD(0x01c4, PIN_OUTPUT_PULLUP, 0) /* P2.29 SPI0_D1 */
+			AM62X_IOPAD(0x01b4, PIN_OUTPUT_PULLUP, 0) /* P2.31 (A13) SPI0_CS0 */
+			AM62X_IOPAD(0x01B8, PIN_OUTPUT_PULLUP, 0) /* P2.36 (C13) SPI0_CS1 */
+		>;
+	};
+	main_can0_pins: main-can0-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01D8, PIN_OUTPUT, 0) /* P2.05 (C15) MCAN0_TX */
+			AM62X_IOPAD(0x01DC, PIN_INPUT, 0) /*  P2.07 (E15) MCAN0_RX */
+		>;
+	};
+	main_i2c2_pins: main-i2c2-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00B4, PIN_INPUT_PULLUP, 1) /* P1.26 (K24) I2C2_SDA */
+			AM62X_IOPAD(0x00B0, PIN_INPUT_PULLUP, 1) /* P1.28 (K22) I2C2_SCL */
+		>;
+	};
+        main_i2c3_pins: main-i2c3-pins {
+                pinctrl-single,pins = <
+                        AM62X_IOPAD(0x01D0, PIN_INPUT_PULLUP, 2) /* P2.09 (A15) I2C3_SCL */
+                        AM62X_IOPAD(0x01D4, PIN_INPUT_PULLUP, 2) /* P2.11 (B15) I2C3_SCL */
+                >;
+        };
+
+	main_uart1_pins_default: main-uart1-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01ac, PIN_INPUT, 2) /* P1.06 (E19/D15) MCASP0_AFSR.UART1_RXD */
+			AM62X_IOPAD(0x01b0, PIN_OUTPUT, 2) /* P1.08 (A20/D16) MCASP0_ACLKR.UART1_TXD */
+		>;
+	};
+	main_uart3_pins_default: main-uart3-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00C0, PIN_INPUT, 4) /* P2.06 (W25) UART3_RXD */
+			AM62X_IOPAD(0x00C4, PIN_OUTPUT, 4) /* P2.08 (W24) UART3_TXD */
+		>;
+	};
+	main_uart4_pins_default: main-uart4-default-pins {
+		pinctrl-single,pins = <
+		AM62X_IOPAD(0x00C8, PIN_INPUT, 4) /* P2.20 (Y25) UART4_RXD */
+		AM62X_IOPAD(0x00CC, PIN_OUTPUT, 4) /* P1.20(Y24) UART4_TXD */
+		>;
+	};
+        main_uart5_pins_default: main-uart5-default-pins {
+                pinctrl-single,pins = <
+                AM62X_IOPAD(0x00D0, PIN_INPUT, 4) /* P2.24 (Y23) UART5_RXD */
+                AM62X_IOPAD(0x00D4, PIN_OUTPUT, 4) /* P2.33(AA25) UART5_TXD */
+                >;
+        };
+
+	main_prus_pins: main-prus-pins {
+		pinctrl-single,pins = <
+		AM62X_IOPAD(0x00FC, PIN_OUTPUT_PULLDOWN, 5) /* P1.29 - RCOUT 1*/
+		AM62X_IOPAD(0x00F0, PIN_OUTPUT_PULLDOWN, 5) /* P1.31 - RCOUT 2*/
+		AM62X_IOPAD(0x00E4, PIN_OUTPUT_PULLDOWN, 5) /* P1.33A - RCOUT 3*/
+		AM62X_IOPAD(0x00F4, PIN_OUTPUT_PULLDOWN, 5) /* P2.34 - RCOUT 4*/
+
+		AM62X_IOPAD(0x0104, PIN_INPUT_PULLUP, 8) /* P2.17 - RCINPUT*/
+		>;
+	};
+};
+
+&main_spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_spi0_pins>;
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	ti,spi-num-cs = <3>;
+
+	channel@0 {
+		compatible = "rohm,dh2228fv";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		symlink = "spi/0.0";
+		reg = <0>;
+		spi-max-frequency = <24000000>;
+		spi-cpha;
+	};
+        channel@1 {
+                compatible = "rohm,dh2228fv";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		symlink = "spi/0.1";
+		reg = <1>;
+                spi-max-frequency = <24000000>;
+        };
+
+};
+&main_mcan0 {
+    pinctrl-names = "default";
+    pinctrl-0 = <&main_can0_pins>;
+    status = "okay";
+};
+
+&main_i2c2 {
+    pinctrl-names = "default";
+    pinctrl-0 = <&main_i2c2_pins>;
+    status = "okay";
+};
+
+&main_i2c3 {
+    pinctrl-names = "default";
+    pinctrl-0 = <&main_i2c3_pins>;
+    status = "okay";
+};
+
+&wkup_i2c0 {
+    status = "disabled";
+};
+
+&main_i2c1 {
+    status = "disabled";
+};
+
+
+&main_uart1 {
+        pinctrl-names = "default";
+        pinctrl-0 = <&main_uart1_pins_default>;
+        bootph-all;
+        status = "okay";
+};
+
+&main_uart3 {
+        pinctrl-names = "default";
+        pinctrl-0 = <&main_uart3_pins_default>;
+        bootph-all;
+        status = "okay";
+};
+
+&main_uart4 {
+        pinctrl-names = "default";
+        pinctrl-0 = <&main_uart4_pins_default>;
+        bootph-all;
+        status = "okay";
+};
+
+&main_uart5 {
+        pinctrl-names = "default";
+        pinctrl-0 = <&main_uart5_pins_default>;
+        bootph-all;
+        status = "okay";
+};
+
+&pruss {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_prus_pins>;
+	status = "okay";
+};
+&main_gpio0 {
+	/* pinctrl-names = "default"; */
+	/* pinctrl-0 = <&main_gpio_pins>; */
+	status = "okay";
+};
+&main_gpio1 {
+	status = "okay";
+};
+&ecap0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2.dts b/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2.dts
--- a/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2.dts	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,531 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * https://www.beagleboard.org/boards/pocketbeagle-2
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2025 Robert Nelson, BeagleBoard.org Foundation
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "k3-am625.dtsi"
+#include "k3-am62-pocketbeagle2-pinmux.dtsi"
+
+/ {
+	compatible = "beagle,am62-pocketbeagle2", "ti,am625";
+	model = "BeagleBoard.org PocketBeagle2";
+
+	aliases {
+		serial0 = &wkup_uart0;
+		serial1 = &main_uart1;
+		serial2 = &main_uart6;
+		serial3 = &main_uart3;
+		serial4 = &main_uart4;
+		serial5 = &main_uart5;
+		serial6 = &main_uart2;
+		serial7 = &main_uart0;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+		usb0 = &usb0;
+		usb1 = &usb1;
+		i2c0 = &main_i2c0;
+		i2c1 = &main_i2c1;
+		i2c2 = &main_i2c2;
+		i2c3 = &wkup_i2c0;
+		spi0 = &main_spi0;
+		spi2 = &main_spi2;
+	};
+
+	chosen {
+		stdout-path = &main_uart6;
+		base_dtb = "k3-am62-pocketbeagle2.dts";
+	};
+
+	memory@80000000 {
+		/* 512MB RAM */
+		reg = <0x00000000 0x80000000 0x00000000 0x20000000>;
+		device_type = "memory";
+		bootph-pre-ram;
+	};
+
+	reserved_memory: reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x8000000>;
+			linux,cma-default;
+		};
+
+		mcu_m4fss_dma_memory_region: m4f-dma-memory@9cb00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9cb00000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_m4fss_memory_region: m4f-memory@9cc00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9cc00000 0x00 0xe00000>;
+			no-map;
+		};
+
+		secure_tfa_ddr: tfa@9e780000 {
+			reg = <0x00 0x9e780000 0x00 0x80000>;
+			alignment = <0x1000>;
+			no-map;
+		};
+
+		secure_ddr: optee@9e800000 {
+			reg = <0x00 0x9e800000 0x00 0x01800000>;
+			alignment = <0x1000>;
+			no-map;
+		};
+
+		wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@9db00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9db00000 0x00 0xc00000>;
+			no-map;
+		};
+	};
+
+	vsys_5v0: regulator-1 {
+		compatible = "regulator-fixed";
+		regulator-name = "vsys_5v0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+		bootph-all;
+	};
+
+	vdd_3v3: regulator-2 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vsys_5v0>;
+		regulator-always-on;
+		regulator-boot-on;
+		bootph-all;
+	};
+
+	vdd_mmc1: regulator-3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_mmc1";
+		pinctrl-names = "default";
+		pinctrl-0 = <&vdd_3v3_sd_pins_default>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		enable-active-high;
+		regulator-always-on;
+		vin-supply = <&vdd_3v3>;
+		gpio = <&main_gpio0 0 GPIO_ACTIVE_HIGH>;
+		bootph-all;
+	};
+
+	vdd_sd_dv: regulator-4 {
+		compatible = "regulator-gpio";
+		regulator-name = "sd_hs200_switch";
+		pinctrl-names = "default";
+		pinctrl-0 = <&vdd_sd_dv_pins_default>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		vin-supply = <&vdd_3v3>;
+		gpios = <&main_gpio1 49 GPIO_ACTIVE_HIGH>;
+		states = <1800000 0x0>,
+			 <3300000 0x1>;
+		bootph-all;
+	};
+
+	adc_vref: regulator-5 {
+		compatible = "regulator-fixed";
+		regulator-name = "default";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins_default>;
+		bootph-all;
+
+		led-1 {
+			function = LED_FUNCTION_HEARTBEAT;
+			color = <LED_COLOR_ID_GREEN>;
+			linux,default-trigger = "heartbeat";
+			gpios = <&main_gpio0 6 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+			bootph-all;
+		};
+
+		led-2 {
+			function = LED_FUNCTION_DISK_ACTIVITY;
+			color = <LED_COLOR_ID_GREEN>;
+			linux,default-trigger = "mmc1";
+			gpios = <&main_gpio0 5 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+			bootph-all;
+		};
+
+		led-3 {
+			function = LED_FUNCTION_INDICATOR;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&main_gpio0 4 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			bootph-all;
+		};
+
+		led-4 {
+			function = LED_FUNCTION_INDICATOR;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&main_gpio0 3 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			bootph-all;
+		};
+	};
+};
+
+&main_pmx0 {
+	led_pins_default: led-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x000c, PIN_OUTPUT, 7) /* (E25) OSPI0_D0.GPIO0_3 */
+			AM62X_IOPAD(0x0010, PIN_OUTPUT, 7) /* (G24) OSPI0_D1.GPIO0_4 */
+			AM62X_IOPAD(0x0014, PIN_OUTPUT, 7) /* (F25) OSPI0_D2.GPIO0_5 */
+			AM62X_IOPAD(0x0018, PIN_OUTPUT, 7) /* (F24) OSPI0_D3.GPIO0_6 */
+		>;
+		bootph-all;
+	};
+
+	main_i2c0_pins_default: main-i2c0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (B16) I2C0_SCL */
+			AM62X_IOPAD(0x01e4, PIN_INPUT_PULLUP, 0) /* (A16) I2C0_SDA */
+		>;
+		bootph-all;
+	};
+
+	main_i2c2_pins_default: main-i2c2-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00b0, PIN_INPUT_PULLUP, 1) /* (K22) GPMC0_CSn2.I2C2_SCL */
+			AM62X_IOPAD(0x00b4, PIN_INPUT_PULLUP, 1) /* (K24) GPMC0_CSn3.I2C2_SDA */
+		>;
+		bootph-all;
+	};
+
+	main_uart0_pins_default: main-uart0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x1c8, PIN_INPUT, 0) /* (D14/A13) UART0_RXD */
+			AM62X_IOPAD(0x1cc, PIN_OUTPUT, 0) /* (E14/E11) UART0_TXD */
+		>;
+		bootph-all;
+	};
+
+	main_uart1_pins_default: main-uart1-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x194, PIN_INPUT, 2) /* (B19/B18) MCASP0_AXR3.UART1_CTSn */
+			AM62X_IOPAD(0x198, PIN_OUTPUT, 2) /* (A19/B17) MCASP0_AXR2.UART1_RTSn */
+			AM62X_IOPAD(0x1ac, PIN_INPUT, 2) /* (E19/D15) MCASP0_AFSR.UART1_RXD */
+			AM62X_IOPAD(0x1b0, PIN_OUTPUT, 2) /* (A20/D16) MCASP0_ACLKR.UART1_TXD */
+		>;
+		bootph-all;
+	};
+
+	main_uart6_pins_default: main-uart6-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x001c, PIN_INPUT, 3) /* (J23) OSPI0_D4.UART6_RXD */
+			AM62X_IOPAD(0x0020, PIN_OUTPUT, 3) /* (J25) OSPI0_D5.UART6_TXD */
+		>;
+	};
+
+	main_mmc1_pins_default: main-mmc1-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x23c, PIN_INPUT, 0) /* (A21/C18) MMC1_CMD */
+			AM62X_IOPAD(0x234, PIN_INPUT, 0) /* (B22/A20) MMC1_CLK */
+			AM62X_IOPAD(0x230, PIN_INPUT, 0) /* (A22/A19) MMC1_DAT0 */
+			AM62X_IOPAD(0x22c, PIN_INPUT, 0) /* (B21/B19) MMC1_DAT1 */
+			AM62X_IOPAD(0x228, PIN_INPUT, 0) /* (C21/B20) MMC1_DAT2 */
+			AM62X_IOPAD(0x224, PIN_INPUT, 0) /* (D22/C19) MMC1_DAT3 */
+			AM62X_IOPAD(0x240, PIN_INPUT, 7) /* (D17/C15) MMC1_SDCD.GPIO1_48 */
+		>;
+		bootph-all;
+	};
+
+	vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0244, PIN_OUTPUT, 7) /* (P25) GPMC0_CLK.GPIO1_49 */
+		>;
+		bootph-all;
+	};
+
+	pmic_irq_pins_default: pmic-irq-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01f4, PIN_INPUT_PULLUP, 0) /* (D16) EXTINTn */
+		>;
+		bootph-all;
+	};
+
+	vdd_3v3_sd_pins_default: vdd-3v3-sd-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0000, PIN_OUTPUT, 7) /* (H24) OSPI0_CLK.GPIO0_0 */
+		>;
+		bootph-all;
+	};
+
+	usb1_pins_default: usb1-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0258, PIN_INPUT, 0) /* (F18) USB1_DRVVBUS */
+		>;
+		bootph-all;
+	};
+
+	epwm2_pins_default: epwm2-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01e8, PIN_OUTPUT, 8) /* (B17) I2C1_SCL.EHRPWM2_A */
+		>;
+	};
+};
+
+&epwm2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&epwm2_pins_default>;
+};
+
+&mailbox0_cluster0 {
+	mbox_m4_0: mbox-m4-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&main_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart0_pins_default>;
+	bootph-all;
+	status = "okay";
+};
+
+&main_uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart1_pins_default>;
+	bootph-pre-ram;
+	status = "reserved";
+};
+
+&main_uart6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart6_pins_default>;
+	bootph-all;
+	status = "okay";
+};
+
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+	bootph-all;
+	status = "okay";
+
+	ad7291: adc@20 {
+		/* Emulated with MSPM0L1105 */
+		compatible = "adi,ad7291";
+		reg = <0x20>;
+		vref-supply = <&adc_vref>;
+	};
+
+	eeprom: eeprom@50 {
+		/* Emulated with MSPM0L1105 */
+		compatible = "atmel,24c32";
+		reg = <0x50>;
+	};
+};
+
+&main_i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c2_pins_default>;
+	clock-frequency = <400000>;
+	bootph-all;
+	status = "okay";
+};
+
+&mcu_m4fss {
+	mboxes = <&mailbox0_cluster0 &mbox_m4_0>;
+	memory-region = <&mcu_m4fss_dma_memory_region>,
+			<&mcu_m4fss_memory_region>;
+	status = "okay";
+};
+
+&mcu_pmx0 {
+	wkup_uart0_pins_default: wkup-uart0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x02c, PIN_INPUT, 0)	/* (C6/A7) WKUP_UART0_CTSn */
+			AM62X_MCU_IOPAD(0x030, PIN_OUTPUT, 0)	/* (A4/B4) WKUP_UART0_RTSn */
+			AM62X_MCU_IOPAD(0x024, PIN_INPUT, 0)	/* (B4/B5) WKUP_UART0_RXD */
+			AM62X_MCU_IOPAD(0x028, PIN_OUTPUT, 0)	/* (C5/C6) WKUP_UART0_TXD */
+		>;
+		bootph-all;
+	};
+
+	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x004c, PIN_INPUT_PULLUP, 0)	/* (B9) WKUP_I2C0_SCL */
+			AM62X_MCU_IOPAD(0x0050, PIN_INPUT_PULLUP, 0)	/* (A9) WKUP_I2C0_SDA */
+		>;
+		bootph-all;
+	};
+};
+
+&sdhci1 {
+	/* SD/MMC */
+	vmmc-supply = <&vdd_mmc1>;
+	vqmmc-supply = <&vdd_sd_dv>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc1_pins_default>;
+	disable-wp;
+	cd-gpios = <&main_gpio1 48 GPIO_ACTIVE_LOW>;
+	cd-debounce-delay-ms = <100>;
+	bootph-all;
+	ti,fails-without-test-cd;
+	status = "okay";
+};
+
+&usbss0 {
+	bootph-all;
+	ti,vbus-divider;
+	status = "okay";
+};
+
+&usb0 {
+	/* This is a Type-C socket, but wired as USB 2.0 */
+	dr_mode = "peripheral";
+	bootph-all;
+};
+
+&usbss1 {
+	ti,vbus-divider;
+	status = "okay";
+};
+
+&usb1 {
+	/*
+	 * Default set here is compatible with original PocketBeagle,
+	 * Expansion boards assumed this was pre-setup as host.
+	 */
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb1_pins_default>;
+};
+
+&wkup_uart0 {
+	/* WKUP UART0 is used by Device Manager firmware */
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_uart0_pins_default>;
+	bootph-all;
+	status = "reserved";
+};
+
+&wkup_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_i2c0_pins_default>;
+	clock-frequency = <100000>;
+	bootph-all;
+	status = "okay";
+
+	tps65219: pmic@30 {
+		compatible = "ti,tps65219";
+		reg = <0x30>;
+		buck1-supply = <&vsys_5v0>;
+		buck2-supply = <&vsys_5v0>;
+		buck3-supply = <&vsys_5v0>;
+		ldo1-supply = <&vdd_3v3>;
+		ldo2-supply = <&buck2_reg>;
+		ldo3-supply = <&vdd_3v3>;
+		ldo4-supply = <&vdd_3v3>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_irq_pins_default>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		bootph-all;
+		system-power-controller;
+		ti,power-button;
+
+		regulators {
+			buck1_reg: buck1 {
+				regulator-name = "VDD_CORE";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck2_reg: buck2 {
+				regulator-name = "VDD_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck3_reg: buck3 {
+				regulator-name = "VDD_1V2";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo1_reg: ldo1 {
+				/*
+				 * Regulator is left as is unused, vdd_sd
+				 * is controlled via GPIO with bypass config
+				 * as per the NVM configuration
+				 */
+				regulator-name = "VDD_SD_3V3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-allow-bypass;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo2_reg: ldo2 {
+				regulator-name = "VDDA_0V85";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo3_reg: ldo3 {
+				regulator-name = "VDDA_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo4_reg: ldo4 {
+				regulator-name = "VDD_2V5";
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-leds-off.dtso b/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-leds-off.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-leds-off.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-leds-off.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,41 @@
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/leds/common.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		k3-am62-pocketbeagle2-leds-off.kernel = __TIMESTAMP__;
+	};
+};
+
+&{/} {
+	leds {
+		led-1 {
+			function = LED_FUNCTION_INDICATOR;
+			default-state = "off";
+			linux,default-trigger = "none";
+		};
+
+		led-2 {
+			function = LED_FUNCTION_INDICATOR;
+			default-state = "off";
+			linux,default-trigger = "none";
+		};
+
+		led-3 {
+			function = LED_FUNCTION_INDICATOR;
+			default-state = "off";
+			linux,default-trigger = "none";
+		};
+
+		led-4 {
+			function = LED_FUNCTION_INDICATOR;
+			default-state = "off";
+			linux,default-trigger = "none";
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-pinmux.dtsi b/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-pinmux.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-pinmux.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-pinmux.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,672 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * https://www.beagleboard.org/boards/pocketbeagle-2
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2025 Robert Nelson, BeagleBoard.org Foundation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/*
+ * Everything in this file is our staging ground, anything heading to mainline or rejected...
+ */
+
+/ {
+	chosen {
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
+
+	leds {
+		led-1 {
+			label = "beaglebone:green:usr1";
+		};
+
+		led-2 {
+			label = "beaglebone:green:usr2";
+		};
+
+		led-3 {
+			label = "beaglebone:green:usr3";
+			function = LED_FUNCTION_ACTIVITY;
+			linux,default-trigger = "activity";
+		};
+
+		led-4 {
+			label = "beaglebone:green:usr4";
+		};
+	};
+};
+
+&a53_opp_table {
+	/* Requires VDD_CORE to be at 0.85V */
+	opp-1400000000 {
+		opp-hz = /bits/ 64 <1400000000>;
+		opp-supported-hw = <0x01 0x0004>;
+	};
+};
+
+&cpsw3g {
+	status = "disabled";
+};
+
+&cpsw_port1 {
+	status = "disabled";
+};
+
+&cpsw_port2 {
+	status = "disabled";
+};
+
+&main_pmx0 {
+	main_mmc0_pins_default: main-mmc0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (Y3/V3) MMC0_CMD */
+			AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (AB1/Y1) MMC0_CLK */
+			AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (AA2/V2) MMC0_DAT0 */
+			AM62X_IOPAD(0x210, PIN_INPUT, 0) /* (AA1/V1) MMC0_DAT1 */
+			AM62X_IOPAD(0x20c, PIN_INPUT, 0) /* (AA3/W2) MMC0_DAT2 */
+			AM62X_IOPAD(0x208, PIN_INPUT, 0) /* (Y4/W1) MMC0_DAT3 */
+			AM62X_IOPAD(0x204, PIN_INPUT, 0) /* (AB2/Y2) MMC0_DAT4 */
+			AM62X_IOPAD(0x200, PIN_INPUT, 0) /* (AC1/W3) MMC0_DAT5 */
+			AM62X_IOPAD(0x1fc, PIN_INPUT, 0) /* (AD2/W4) MMC0_DAT6 */
+			AM62X_IOPAD(0x1f8, PIN_INPUT, 0) /* (AC2/V4) MMC0_DAT7 */
+		>;
+		bootph-all;
+	};
+
+	main_gpio0_pins_default: main-gpio0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00c8, PIN_INPUT, 7) /* (Y25) VOUT0_DATA4.GPIO0_49 */
+			AM62X_IOPAD(0x00cc, PIN_INPUT, 7) /* (Y24) VOUT0_DATA5.GPIO0_50 */
+			AM62X_IOPAD(0x00d0, PIN_INPUT, 7) /* (Y23) VOUT0_DATA6.GPIO0_51 */
+			AM62X_IOPAD(0x00d4, PIN_INPUT, 7) /* (AA25) VOUT0_DATA7.GPIO0_52 */
+			AM62X_IOPAD(0x00d8, PIN_INPUT, 7) /* (V21) VOUT0_DATA8.GPIO0_53 */
+			AM62X_IOPAD(0x0100, PIN_INPUT, 7) /* (AC25) VOUT0_VSYNC.GPIO0_63 */
+		>;
+	};
+
+	main_gpio1_pins_default: main-gpio1-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01a0, PIN_INPUT, 7) /* (E18) MCASP0_AXR0.GPIO1_10 */
+			AM62X_IOPAD(0x01a8, PIN_INPUT, 7) /* (D20) MCASP0_AFSX.GPIO1_12 */
+			AM62X_IOPAD(0x0180, PIN_INPUT, 7) /* (AD23) RGMII2_RXC.GPIO1_2 */
+		>;
+	};
+
+	main_spi2_pins_gpio: main-spi2-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0194, PIN_INPUT, 7) /* (B19) MCASP0_AXR3.GPIO1_7 */
+			AM62X_IOPAD(0x0198, PIN_INPUT, 7) /* (A19) MCASP0_AXR2.GPIO1_8 */
+			AM62X_IOPAD(0x01ac, PIN_INPUT, 7) /* (E19) MCASP0_AFSR.GPIO1_13 */
+			AM62X_IOPAD(0x01b0, PIN_INPUT, 7) /* (A20) MCASP0_ACLKR.GPIO1_14 */
+		>;
+	};
+
+
+	ecap2_pins_default: ecap2-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01a4, PIN_INPUT, 2) /* (B20) MCASP0_ACLKX.ECAP2_IN_APWM_OUT */
+			AM62X_IOPAD(0x0160, PIN_DISABLE, 7) /* (AD24) MDIO0_MDC.GPIO0_86 */
+		>;
+	};
+
+	main_spi0_pins_default: main-spi0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01bc, PIN_INPUT, 0) /* (A14) SPI0_CLK */
+			AM62X_IOPAD(0x01c0, PIN_OUTPUT, 0) /* (B13) SPI0_D0 */
+			AM62X_IOPAD(0x01c4, PIN_INPUT, 0) /* (B14) SPI0_D1 */
+			AM62X_IOPAD(0x01b4, PIN_OUTPUT, 0) /* (A13) SPI0_CS0 */
+		>;
+	};
+
+	mspm0_nrst_pins_default: mspm0-nrst-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0254, PIN_INPUT, 7) /* (C20) USB0_DRVVBUS.GPIO1_50 */
+		>;
+	};
+
+	P1_02_E18_gpio: P1-02-E18-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01A0, PIN_INPUT, 7) /* (E18) MCASP0_AXR0.GPIO1_10 */
+			AM62X_IOPAD(0x0164, PIN_INPUT, 7) /* (AA19) RGMII2_TX_CTL.GPIO0_87 */
+		>;
+	};
+
+	P1_02_AA19_gpio: P1-02-AA19-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0164, PIN_INPUT, 7) /* (AA19) RGMII2_TX_CTL.GPIO0_87 */
+			AM62X_IOPAD(0x01A0, PIN_DISABLE, 7) /* (E18) MCASP0_AXR0.GPIO1_10 */
+		>;
+	};
+
+	P1_04_D20_gpio: P1-04-D20-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01A8, PIN_INPUT, 7) /* (D20) MCASP0_AFSX.GPIO1_12 */
+			AM62X_IOPAD(0x016C, PIN_DISABLE, 7) /* (Y18) RGMII2_TD0.GPIO0_89 */
+		>;
+	};
+
+	P1_04_Y18_gpio: P1-04-Y18-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x016C, PIN_INPUT, 7) /* (Y18) RGMII2_TD0.GPIO0_89 */
+			AM62X_IOPAD(0x01A8, PIN_DISABLE, 7) /* (D20) MCASP0_AFSX.GPIO1_12 */
+		>;
+	};
+
+	P1_06_E19_gpio: P1-06-E19-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01AC, PIN_INPUT, 7) /* (E19) MCASP0_AFSR.GPIO1_13 */
+			AM62X_IOPAD(0x0140, PIN_DISABLE, 7) /* (AD18) RGMII1_TD3.GPIO0_78 */
+		>;
+	};
+
+	P1_06_AD18_gpio: P1-06-AD18-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0140, PIN_INPUT, 7) /* (AD18) RGMII1_TD3.GPIO0_78 */
+			AM62X_IOPAD(0x01AC, PIN_DISABLE, 7) /* (E19) MCASP0_AFSR.GPIO1_13 */
+		>;
+	};
+
+	P1_08_gpio: P1-08-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01B0, PIN_INPUT, 7) /* (A20) MCASP0_ACLKR.GPIO1_14 */
+		>;
+	};
+
+	P1_10_A18_gpio: P1-10-A18-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01F0, PIN_INPUT, 7) /* (A18) EXT_REFCLK1.GPIO1_30 */
+			AM62X_IOPAD(0x0194, PIN_DISABLE, 7) /* (B19) MCASP0_AXR3.GPIO1_7 */
+		>;
+	};
+
+	P1_10_B19_gpio: P1-10-B19-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0194, PIN_INPUT, 7) /* (B19) MCASP0_AXR3.GPIO1_7 */
+			AM62X_IOPAD(0x01F0, PIN_DISABLE, 7) /* (A18) EXT_REFCLK1.GPIO1_30 */
+		>;
+	};
+
+	P1_12_A19_gpio: P1-12-A19-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0198, PIN_INPUT, 7) /* (A19) MCASP0_AXR2.GPIO1_8 */
+			AM62X_IOPAD(0x013C, PIN_DISABLE, 7) /* (AE18) RGMII1_TD2.GPIO0_77 */
+		>;
+	};
+
+	P1_12_AE18_gpio: P1-12-AE18-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x013C, PIN_INPUT, 7) /* (AE18) RGMII1_TD2.GPIO0_77 */
+			AM62X_IOPAD(0x0198, PIN_DISABLE, 7) /* (A19) MCASP0_AXR2.GPIO1_8 */
+		>;
+	};
+
+	P1_19_gpio: P1-19-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x017C, PIN_INPUT, 7) /* (AD22) RGMII2_RX_CTL.GPIO1_1 */
+		>;
+	};
+
+	P1_20_gpio: P1-20-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00CC, PIN_INPUT, 7) /* (Y24) VOUT0_DATA5.GPIO0_50 */
+		>;
+	};
+
+	P1_21_gpio: P1-21-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0190, PIN_INPUT, 7) /* (AE22) RGMII2_RD3.GPIO1_6 */
+		>;
+	};
+
+	P1_23_gpio: P1-23-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x018C, PIN_INPUT, 7) /* (AC21) RGMII2_RD2.GPIO1_5 */
+		>;
+	};
+
+	P1_25_gpio: P1-25-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0188, PIN_INPUT, 7) /* (AB20) RGMII2_RD1.GPIO1_4 */
+		>;
+	};
+
+	P1_26_K24_gpio: P1-26-K24-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00B4, PIN_INPUT, 7) /* (K24) GPMC0_CSn3.GPIO0_44 */
+		>;
+	};
+
+	P1_27_gpio: P1-27-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0184, PIN_INPUT, 7) /* (AE23) RGMII2_RD0.GPIO1_3 */
+		>;
+	};
+
+	P1_28_K22_gpio: P1-28-K22-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00B0, PIN_INPUT, 7) /* (K22) GPMC0_CSn2.GPIO0_43 */
+		>;
+	};
+
+	P1_29_gpio: P1-29-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00FC, PIN_INPUT, 7) /* (Y20) VOUT0_DE.GPIO0_62 */
+		>;
+	};
+
+	P1_30_gpio: P1-30-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01CC, PIN_INPUT, 7) /* (E14) UART0_TXD.GPIO1_21 */
+		>;
+	};
+
+	P1_31_gpio: P1-31-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00F0, PIN_INPUT, 7) /* (Y22) VOUT0_DATA14.GPIO0_59 */
+		>;
+	};
+
+	P1_32_gpio: P1-32-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01C8, PIN_INPUT, 7) /* (D14) UART0_RXD.GPIO1_20 */
+		>;
+	};
+
+	P1_33_A17_gpio: P1-33-A17-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01EC, PIN_INPUT, 7) /* (A17) I2C1_SDA.GPIO1_29 */
+			AM62X_IOPAD(0x00E4, PIN_DISABLE, 7) /* (AA23) VOUT0_DATA11.GPIO0_56 */
+		>;
+	};
+
+	P1_33_A17_pwm: P1-33-A15-pwm-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01EC, PIN_INPUT, 8) /* (A17) I2C1_SDA.EHRPWM2_B */
+			AM62X_IOPAD(0x00E4, PIN_DISABLE, 7) /* (AA23) VOUT0_DATA11.GPIO0_56 */
+		>;
+	};
+
+	P1_33_AA23_gpio: P1-33-AA23-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00E4, PIN_INPUT, 7) /* (AA23) VOUT0_DATA11.GPIO0_56 */
+			AM62X_IOPAD(0x01EC, PIN_DISABLE, 7) /* (A17) I2C1_SDA.GPIO1_29 */
+		>;
+	};
+
+	P1_34_gpio: P1-34-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0180, PIN_INPUT, 7) /* (AD23) RGMII2_RXC.GPIO1_2 */
+		>;
+	};
+
+	P1_35_gpio: P1-35-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0168, PIN_INPUT, 7) /* (AE21) RGMII2_TXC.GPIO0_88 */
+		>;
+	};
+
+	P1_36_V20_gpio: P1-36-V20-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00E0, PIN_INPUT, 7) /* (V20) VOUT0_DATA10.GPIO0_55 */
+			AM62X_IOPAD(0x01E8, PIN_DISABLE, 7) /* (B17) I2C1_SCL.GPIO1_28 */
+		>;
+	};
+
+	P1_36_B17_gpio: P1-36-B17-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01E8, PIN_INPUT, 7) /* (B17) I2C1_SCL.GPIO1_28 */
+			AM62X_IOPAD(0x00E0, PIN_DISABLE, 7) /* (V20) VOUT0_DATA10.GPIO0_55 */
+		>;
+	};
+
+	P2_01_AD24_gpio: P2-01-AD24-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0160, PIN_INPUT, 7) /* (AD24) MDIO0_MDC.GPIO0_86 */
+			AM62X_IOPAD(0x01A4, PIN_DISABLE, 7) /* (B20) MCASP0_ACLKX.GPIO1_11 */
+		>;
+	};
+
+	P2_01_B20_gpio: P2-01-B20-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01A4, PIN_INPUT, 7) /* (B20) MCASP0_ACLKX.GPIO1_11 */
+			AM62X_IOPAD(0x0160, PIN_DISABLE, 7) /* (AD24) MDIO0_MDC.GPIO0_86 */
+		>;
+	};
+
+	P2_02_gpio: P2-02-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00B8, PIN_INPUT, 7) /* (U22) VOUT0_DATA0.GPIO0_45 */
+		>;
+	};
+
+	P2_03_AB22_gpio: P2-03-AB22-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x015C, PIN_INPUT, 7) /* (AB22) MDIO0_MDIO.GPIO0_85 */
+			AM62X_IOPAD(0x019C, PIN_DISABLE, 7) /* (B18) MCASP0_AXR1.GPIO1_9 */
+		>;
+	};
+
+	P2_03_B18_gpio: P2-03-B18-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x019C, PIN_INPUT, 7) /* (B18) MCASP0_AXR1.GPIO1_9 */
+			AM62X_IOPAD(0x015C, PIN_DISABLE, 7) /* (AB22) MDIO0_MDIO.GPIO0_85 */
+		>;
+	};
+
+	P2_04_gpio: P2-04-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00BC, PIN_INPUT, 7) /* (V24) VOUT0_DATA1.GPIO0_46 */
+		>;
+	};
+
+	P2_05_C15_gpio: P2-05-C15-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01D8, PIN_INPUT, 7) /* (C15) MCAN0_TX.GPIO1_24 */
+		>;
+	};
+
+	P2_06_gpio: P2-06-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00C0, PIN_INPUT, 7) /* (W25) VOUT0_DATA2.GPIO0_47 */
+		>;
+	};
+
+	P2_07_E15_gpio: P2-07-E15-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01DC, PIN_INPUT, 7) /* (E15) MCAN0_RX.GPIO1_25 */
+		>;
+	};
+
+	P2_08_gpio: P2-08-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00C4, PIN_INPUT, 7) /* (W24) VOUT0_DATA3.GPIO0_48 */
+		>;
+	};
+
+	P2_09_A15_gpio: P2-09-A15-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01D0, PIN_INPUT, 7) /* (A15) UART0_CTSn.GPIO1_22 */
+		>;
+	};
+
+	P2_10_gpio: P2-10-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0174, PIN_INPUT, 7) /* (AD21) RGMII2_TD2.GPIO0_91 */
+		>;
+	};
+
+	P2_11_B15_gpio: P2-11-B15-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01D4, PIN_INPUT, 7) /* (B15) UART0_RTSn.GPIO1_23 */
+		>;
+	};
+
+	P2_17_gpio: P2-17-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0104, PIN_INPUT, 7) /* (AC24) VOUT0_PCLK.GPIO0_64 */
+		>;
+	};
+
+	P2_18_gpio: P2-18-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00D8, PIN_INPUT, 7) /* (V21) VOUT0_DATA8.GPIO0_53 */
+		>;
+	};
+
+	P2_19_gpio: P2-19-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0178, PIN_INPUT, 7) /* (AC20) RGMII2_TD3.GPIO1_0 */
+		>;
+	};
+
+	P2_20_gpio: P2-20-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00C8, PIN_INPUT, 7) /* (Y25) VOUT0_DATA4.GPIO0_49 */
+		>;
+	};
+
+	P2_22_gpio: P2-22-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0100, PIN_INPUT, 7) /* (AC25) VOUT0_VSYNC.GPIO0_63 */
+		>;
+	};
+
+	P2_24_gpio: P2-24-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00D0, PIN_INPUT, 7) /* (Y23) VOUT0_DATA6.GPIO0_51 */
+		>;
+	};
+
+	P2_25_gpio: P2-25-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01C4, PIN_INPUT, 7) /* (B14) SPI0_D1.GPIO1_19 */
+		>;
+	};
+
+	P2_27_gpio: P2-27-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01C0, PIN_INPUT, 7) /* (B13) SPI0_D0.GPIO1_18 */
+		>;
+	};
+
+	P2_28_gpio: P2-28-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00F8, PIN_INPUT, 7) /* (AB24) VOUT0_HSYNC.GPIO0_61 */
+		>;
+	};
+
+	P2_29_A14_gpio: P2-29-A14-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01BC, PIN_INPUT, 7) /* (A14) SPI0_CLK.GPIO1_17 */
+			AM62X_IOPAD(0x00A4, PIN_DISABLE, 7) /* (M22) GPMC0_DIR.GPIO0_40 */
+		>;
+	};
+
+	P2_29_M22_gpio: P2-29-M22-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00A4, PIN_INPUT, 7) /* (M22) GPMC0_DIR.GPIO0_40 */
+			AM62X_IOPAD(0x01BC, PIN_DISABLE, 7) /* (A14) SPI0_CLK.GPIO1_17 */
+		>;
+	};
+
+	P2_30_gpio: P2-30-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00EC, PIN_INPUT, 7) /* (AA24) VOUT0_DATA13.GPIO0_58 */
+		>;
+	};
+
+	P2_31_A13_gpio: P2-31-A13-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01B4, PIN_INPUT, 7) /* (A13) SPI0_CS0.GPIO1_15 */
+			AM62X_IOPAD(0x0170, PIN_DISABLE, 7) /* (AA18) RGMII2_TD1.GPIO0_90 */
+		>;
+	};
+
+	P2_31_AA18_gpio: P2-31-AA18-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0170, PIN_INPUT, 7) /* (AA18) RGMII2_TD1.GPIO0_90 */
+			AM62X_IOPAD(0x01B4, PIN_DISABLE, 7) /* (A13) SPI0_CS0.GPIO1_15 */
+		>;
+	};
+
+	P2_32_gpio: P2-32-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00E8, PIN_INPUT, 7) /* (AB25) VOUT0_DATA12.GPIO0_57 */
+		>;
+	};
+
+	P2_33_gpio: P2-33-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00D4, PIN_INPUT, 7) /* (AA25) VOUT0_DATA7.GPIO0_52 */
+		>;
+	};
+
+	P2_34_gpio: P2-34-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00F4, PIN_INPUT, 7) /* (AA21) VOUT0_DATA15.GPIO0_60 */
+		>;
+	};
+
+	P2_35_gpio: P2-35-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x00DC, PIN_INPUT, 7) /* (W21) VOUT0_DATA9.GPIO0_54 */
+		>;
+	};
+
+	P2_36_gpio: P2-36-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01B8, PIN_INPUT, 7) /* (C13) SPI0_CS1.GPIO1_16 */
+		>;
+	};
+
+};
+
+&mcu_pmx0 {
+	mspm0_bsl_pins_default: mspm0-bsl-default-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x0004, PIN_INPUT, 7) /* (B8) MCU_SPI0_CS1.MCU_GPIO0_1 */
+		>;
+	};
+
+	P1_26_D6_gpio: P1-26-D6-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x0034, PIN_INPUT, 7) /* (D6) MCU_MCAN0_TX.MCU_GPIO0_13 */
+		>;
+	};
+
+	P1_28_B3_gpio: P1-28-B3-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x0038, PIN_INPUT, 7) /* (B3) MCU_MCAN0_RX.MCU_GPIO0_14 */
+		>;
+	};
+
+	P2_05_B5_gpio: P2-05-B5-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x0014, PIN_INPUT, 7) /* (B5) MCU_UART0_RXD.MCU_GPIO0_5 */
+		>;
+	};
+
+	P2_07_A5_gpio: P2-07-A5-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x0018, PIN_INPUT, 7) /* (A5) MCU_UART0_TXD.MCU_GPIO0_6 */
+		>;
+	};
+
+	P2_09_D4_gpio: P2-09-D4-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x0040, PIN_INPUT, 7) /* (D4) MCU_MCAN1_RX.MCU_GPIO0_16 */
+		>;
+	};
+
+	P2_11_E5_gpio: P2-11-E5-gpio-pins {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x003C, PIN_INPUT, 7) /* (E5) MCU_MCAN1_TX.MCU_GPIO0_15 */
+		>;
+	};
+};
+
+&main_gpio0 {
+	//pinctrl-names = "default";
+	//pinctrl-0 = <&main_gpio0_pins_default>;
+	gpio-line-names = "", "", "",	/* 0-2 */
+			  "USR_LED_4", "USR_LED_3", "USR_LED_2",	/* 3-5 */
+			  "USR_LED_1", "", "",	/* 6-8 */
+			  "", "", "",	/* 9-11 */
+			  "", "", "",	/* 12-14 */
+			  "", "", "",	/* 15-17 */
+			  "", "", "",	/* 18-20 */
+			  "", "", "",	/* 21-23 */
+			  "", "", "",	/* 24-26 */
+			  "", "", "",	/* 27-29 */
+			  "", "", "",	/* 30-32 */
+			  "", "", "",	/* 33-35 */
+			  "P1.13/USB_ID", "", "",	/* 36-38 */
+			  "", "P2.29(M22)", "",	/* 39-41 */
+			  "", "P1.28/I2C1_SCL(K22)", "P1.26/I2C1_SDA(K24)",	/* 42-44 */
+			  "P2.02/AIN6", "P2.04", "P2.06",	/* 45-47 */
+			  "P2.08", "P2.20", "P1.20",	/* 48-50 */
+			  "P2.24", "P2.33", "P2.18",	/* 51-53 */
+			  "P2.35/AIN5", "P1.36(V20)", "P1.33(AA23)",	/* 54-56 */
+			  "P2.32", "P2.30", "P1.31",	/* 57-59 */
+			  "P2.34", "P2.28", "P1.29",	/* 60-62 */
+			  "P2.22", "P2.17", "",	/* 63-65 */
+			  "", "", "",	/* 66-68 */
+			  "", "", "",	/* 69-71 */
+			  "", "", "",	/* 72-74 */
+			  "", "", "P1.12(AE18)",	/* 75-77 */
+			  "P1.06(AD18)", "", "",	/* 78-80 */
+			  "", "", "",	/* 81-83 */
+			  "", "P2.03(AB22)", "P2.01(AD24)",	/* 84-86 */
+			  "P1.02(AA19)", "P1.35", "P1.04(Y18)",	/* 87-89 */
+			  "P2.31(AA18)", "P2.10";	/* 90-91 */
+	status = "okay";
+};
+
+&main_gpio1 {
+	//pinctrl-names = "default";
+	//pinctrl-0 = <&main_gpio1_pins_default>;
+	gpio-line-names = "P2.19", "P1.19/AIN0", "P1.34",	/* 0-2 */
+			  "P1.27/AIN4", "P1.25/AIN3", "P1.23/AIN2",	/* 3-5 */
+			  "P1.21/AIN1", "P1.10(B19)", "P1.12(A19)",	/* 6-8 */
+			  "P2.03(B18)", "P1.02/AIN6(E18)", "P2.01(B20)",	/* 9-11 */
+			  "P1.04(D20)", "P1.06(E19)", "P1.08",	/* 12-14 */
+			  "P2.31(A13)", "P2.36/AIN7", "P2.29(A14)",	/* 15-17 */
+			  "P2.27", "P2.25", "P1.32",	/* 18-20 */
+			  "P1.30", "P2.09(A15)", "P2.11(B15)",	/* 21-23 */
+			  "P2.05(C15)", "P2.07(E15)", "",	/* 24-26 */
+			  "", "P1.36(B17)", "P1.33(A17)",	/* 27-29 */
+			  "P1.10(A18)", "";	/* 30-31 */
+	status = "okay";
+};
+
+&mcu_gpio0 {
+	pinctrl-names = "default";
+	gpio-line-names = "", "", "",   /* 0-2 */
+			  "", "", "P2.05(B5)",   /* 3-5 */
+			  "P2.07(A5)", "", "",   /* 6-8 */
+			  "", "", "",   /* 9-11 */
+			  "", "P1.26(D6)", "P1.28(B3)",   /* 12-14 */
+			  "P2.11(E5)", "P2.09(D4)", "",   /* 15-17 */
+			  "", "", "",   /* 18-20 */
+			  "", "", "";   /* 21-23 */
+	status = "okay";
+};
+
+&sdhci0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc0_pins_default>;
+	disable-wp;
+	bootph-all;
+	status = "okay";
+};
+
+&main_i2c0 {
+	mspm0l1105: mspm0l1105@48 {
+		compatible = "ti,mspm0l1105";
+		reg = <0x48>;
+		bootloader-backdoor-gpios = <&mcu_gpio0 1 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&main_gpio1 50 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mspm0_bsl_pins_default &mspm0_nrst_pins_default>;
+	};
+};
+
+&main_i2c1 {
+	clock-frequency = <400000>;
+	bootph-all;
+	status = "okay";
+};
+
+&main_spi0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_spi0_pins_default>;
+};
+
+&ecap2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&ecap2_pins_default>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-techlab-cape.dtso b/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-techlab-cape.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-techlab-cape.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2-techlab-cape.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,126 @@
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		k3-am62-pocketbeagle2-techlab-cape.kernel = __TIMESTAMP__;
+	};
+};
+
+&main_spi0 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	techlab_gpio: techlab-gpio@0 {
+		compatible = "microchip,mcp23s18";
+		reg = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		spi-max-frequency = <1000000>;
+		microchip,spi-present-mask = <1>;
+		gpio-line-names = "LD4", "LD7", "LD8",	  /* 0-2 */
+				  "LD6", "LD3", "LD2",    /* 3-5 */
+				  "LD5", "", "LD11",      /* 6-8 */
+				  "LD14", "LD15", "LD13", /* 9-11 */
+				  "LD10", "LD9", "LD12",  /* 12-14 */
+				  "";                     /* 15 */
+	};
+};
+
+&{/} {
+	techlab-led {
+		compatible = "pwm-leds-multicolor";
+		pinctrl-names = "default";
+		pinctrl-0 = <&P1_33_A17_pwm>;
+
+		multi-led {
+			led-red {
+				pwms = <&epwm2 1 255 0>;
+				color = <LED_COLOR_ID_RED>;
+			};
+
+			led-blue {
+				pwms = <&epwm2 0 255 0>;
+				color = <LED_COLOR_ID_BLUE>;
+			};
+
+			led-green {
+				pwms = <&ecap2 0 255 0>;
+				color = <LED_COLOR_ID_GREEN>;
+			};
+		};
+	};
+
+	seven-segments-left {
+		compatible = "gpio-7-segment";
+		segment-gpios = <&techlab_gpio 0 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 1 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 2 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 3 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 4 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 5 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 6 GPIO_ACTIVE_LOW>;
+	};
+
+	seven-segments-right {
+		compatible = "gpio-7-segment";
+		segment-gpios = <&techlab_gpio 8 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 9 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 10 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 11 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 12 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 13 GPIO_ACTIVE_LOW>,
+				<&techlab_gpio 14 GPIO_ACTIVE_LOW>;
+	};
+
+	buzzer_pwm: buzzer-pwm {
+		#pwm-cells = <3>;
+		compatible = "pwm-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&P2_30_gpio>;
+		gpios = <&main_gpio0 58 GPIO_ACTIVE_HIGH>;
+	};
+
+
+	buttons {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&P1_29_gpio &P2_33_gpio>;
+
+		left {
+			label = "GPIO Key Left";
+			gpios = <&main_gpio0 52 0>;
+			linux,code = <KEY_LEFT>;
+		};
+
+		right {
+			label = "GPIO Key Right";
+			gpios = <&main_gpio0 62 0>;
+			linux,code = <KEY_RIGHT>;
+		};
+	};
+
+	techlab-buzzer {
+		compatible = "pwm-beeper";
+		pwms = <&buzzer_pwm 0 50000 0>;
+	};
+};
+
+&main_i2c2 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+        accel@1c {
+		compatible = "fsl,mma8453";
+		reg = <0x1c>;
+        };
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -1131,6 +1131,11 @@
 		};
 	};
 
+	tpm@2e {
+		compatible = "st,st33ktpm2xi2c", "tcg,tpm-tis-i2c";
+		reg = <0x2e>;
+	};
+
 	pmic@30 {
 		compatible = "ti,tps65219";
 		reg = <0x30>;
@@ -1219,11 +1224,12 @@
 		reg = <0x48>;
 	};
 
-	adc@49 {
-		compatible = "ti,ads1015";
+	verdin_som_adc: adc@49 {
+		compatible = "ti,tla2024";
 		reg = <0x49>;
 		#address-cells = <1>;
 		#size-cells = <0>;
+		#io-channel-cells = <1>;
 
 		/* Verdin PMIC_I2C (ADC_4 - ADC_3) */
 		channel@0 {
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-verdin-ivy.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-ivy.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-ivy.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-ivy.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,655 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2024 Toradex
+ *
+ * Common dtsi for Verdin AM62 SoM on Ivy carrier board
+ *
+ * https://www.toradex.com/computer-on-modules/verdin-arm-family/ti-am62
+ * https://www.toradex.com/products/carrier-board/ivy-carrier-board
+ */
+
+#include <dt-bindings/mux/mux.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/net/ti-dp83867.h>
+
+/ {
+	/* AIN1 Voltage w/o AIN1_MODE gpio control */
+	ain1_voltage_unmanaged: voltage-divider-ain1 {
+		compatible = "voltage-divider";
+		#io-channel-cells = <1>;
+		io-channels = <&ivy_adc1 0>;
+		full-ohms = <19>;
+		output-ohms = <1>;
+	};
+
+	/* AIN1 Current w/o AIN1_MODE gpio control */
+	ain1_current_unmanaged: current-sense-shunt-ain1 {
+		compatible = "current-sense-shunt";
+		#io-channel-cells = <0>;
+		io-channels = <&ivy_adc1 1>;
+		shunt-resistor-micro-ohms = <100000000>;
+	};
+
+	/* AIN1_MODE - SODIMM 216 */
+	ain1_mode_mux_ctrl: mux-controller-0 {
+		compatible = "gpio-mux";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_5>;
+		#mux-control-cells = <0>;
+		mux-gpios = <&main_gpio0 40 GPIO_ACTIVE_HIGH>;
+	};
+
+	ain1-voltage {
+		compatible = "io-channel-mux";
+		channels = "ain1_voltage", "";
+		io-channels = <&ain1_voltage_unmanaged 0>;
+		io-channel-names = "parent";
+		mux-controls = <&ain1_mode_mux_ctrl>;
+		settle-time-us = <1000>;
+	};
+
+	ain1-current {
+		compatible = "io-channel-mux";
+		channels = "", "ain1_current";
+		io-channels = <&ain1_current_unmanaged>;
+		io-channel-names = "parent";
+		mux-controls = <&ain1_mode_mux_ctrl>;
+		settle-time-us = <1000>;
+	};
+
+	/* AIN2 Voltage w/o AIN2_MODE gpio control */
+	ain2_voltage_unmanaged: voltage-divider-ain2 {
+		compatible = "voltage-divider";
+		#io-channel-cells = <1>;
+		io-channels = <&ivy_adc2 0>;
+		full-ohms = <19>;
+		output-ohms = <1>;
+	};
+
+	/* AIN2 Current w/o AIN2_MODE gpio control */
+	ain2_current_unmanaged: current-sense-shunt-ain2 {
+		compatible = "current-sense-shunt";
+		#io-channel-cells = <0>;
+		io-channels = <&ivy_adc2 1>;
+		shunt-resistor-micro-ohms = <100000000>;
+	};
+
+	/* AIN2_MODE - SODIMM 218 */
+	ain2_mode_mux_ctrl: mux-controller-1 {
+		compatible = "gpio-mux";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_6>;
+		#mux-control-cells = <0>;
+		mux-gpios = <&main_gpio0 36 GPIO_ACTIVE_HIGH>;
+	};
+
+	ain2-voltage {
+		compatible = "io-channel-mux";
+		channels = "ain2_voltage", "";
+		io-channels = <&ain2_voltage_unmanaged 0>;
+		io-channel-names = "parent";
+		mux-controls = <&ain2_mode_mux_ctrl>;
+		settle-time-us = <1000>;
+	};
+
+	ain2-current {
+		compatible = "io-channel-mux";
+		channels = "", "ain2_current";
+		io-channels = <&ain2_current_unmanaged>;
+		io-channel-names = "parent";
+		mux-controls = <&ain2_mode_mux_ctrl>;
+		settle-time-us = <1000>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ivy_leds>;
+
+		/* D7 Blue - SODIMM 30 - LEDs.GPIO1 */
+		led-0 {
+			color = <LED_COLOR_ID_BLUE>;
+			default-state = "off";
+			function = LED_FUNCTION_STATUS;
+			function-enumerator = <1>;
+			gpios = <&main_gpio1 11 GPIO_ACTIVE_HIGH>;
+		};
+
+		/* D7 Green - SODIMM 32 - LEDs.GPIO2 */
+		led-1 {
+			color = <LED_COLOR_ID_GREEN>;
+			default-state = "off";
+			function = LED_FUNCTION_STATUS;
+			function-enumerator = <1>;
+			gpios = <&main_gpio1 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		/* D7 Red - SODIMM 34 - LEDs.GPIO3 */
+		led-2 {
+			color = <LED_COLOR_ID_RED>;
+			default-state = "off";
+			function = LED_FUNCTION_STATUS;
+			function-enumerator = <1>;
+			gpios = <&main_gpio1 10 GPIO_ACTIVE_HIGH>;
+		};
+
+		/* D8 Blue - SODIMM 36 - LEDs.GPIO4 */
+		led-3 {
+			color = <LED_COLOR_ID_BLUE>;
+			default-state = "off";
+			function = LED_FUNCTION_STATUS;
+			function-enumerator = <2>;
+			gpios = <&main_gpio1 9 GPIO_ACTIVE_HIGH>;
+		};
+
+		/* D8 Green - SODIMM 54 - LEDs.GPIO5 */
+		led-4 {
+			color = <LED_COLOR_ID_GREEN>;
+			default-state = "off";
+			function = LED_FUNCTION_STATUS;
+			function-enumerator = <2>;
+			gpios = <&main_gpio0 11 GPIO_ACTIVE_HIGH>;
+		};
+
+		/* D8 Red - SODIMM 44 - LEDs.GPIO6 */
+		led-5 {
+			color = <LED_COLOR_ID_RED>;
+			default-state = "off";
+			function = LED_FUNCTION_STATUS;
+			function-enumerator = <2>;
+			gpios = <&main_gpio0 37 GPIO_ACTIVE_HIGH>;
+		};
+
+		/* D9 Blue - SODIMM 46 - LEDs.GPIO7 */
+		led-6 {
+			color = <LED_COLOR_ID_BLUE>;
+			default-state = "off";
+			function = LED_FUNCTION_STATUS;
+			function-enumerator = <3>;
+			gpios = <&main_gpio0 34 GPIO_ACTIVE_HIGH>;
+		};
+
+		/* D9 Red - SODIMM 48 - LEDs.GPIO8 */
+		led-7 {
+			color = <LED_COLOR_ID_RED>;
+			default-state = "off";
+			function = LED_FUNCTION_STATUS;
+			function-enumerator = <3>;
+			gpios = <&main_gpio0 33 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	reg_3v2_ain1: regulator-3v2-ain1 {
+		compatible = "regulator-fixed";
+		regulator-max-microvolt = <3200000>;
+		regulator-min-microvolt = <3200000>;
+		regulator-name = "+3V2_AIN1";
+	};
+
+	reg_3v2_ain2: regulator-3v2-ain2 {
+		compatible = "regulator-fixed";
+		regulator-max-microvolt = <3200000>;
+		regulator-min-microvolt = <3200000>;
+		regulator-name = "+3V2_AIN2";
+	};
+
+	/* Ivy Power Supply Input Voltage */
+	ivy-input-voltage {
+		compatible = "voltage-divider";
+		/* Verdin ADC_1 */
+		io-channels = <&verdin_som_adc 7>;
+		full-ohms = <204700>; /* 200K + 4.7K */
+		output-ohms = <4700>;
+	};
+
+	ivy-5v-voltage {
+		compatible = "voltage-divider";
+		/* Verdin ADC_2 */
+		io-channels = <&verdin_som_adc 6>;
+		full-ohms = <39000>; /* 27K + 12K */
+		output-ohms = <12000>;
+	};
+
+	ivy-3v3-voltage {
+		compatible = "voltage-divider";
+		/* Verdin ADC_3 */
+		io-channels = <&verdin_som_adc 5>;
+		full-ohms = <54000>; /* 27K + 27K */
+		output-ohms = <27000>;
+	};
+
+	ivy-1v8-voltage {
+		compatible = "voltage-divider";
+		/* Verdin ADC_4 */
+		io-channels = <&verdin_som_adc 4>;
+		full-ohms = <39000>; /* 12K + 27K */
+		output-ohms = <27000>;
+	};
+};
+
+&main_pmx0 {
+	pinctrl_ivy_leds: ivy-leds-default-pins {
+		pinctrl-single,pins =
+			<AM62X_IOPAD(0x019c, PIN_INPUT, 7)>, /* (B18) MCASP0_AXR1.GPIO1_9    */ /* SODIMM 36 */
+			<AM62X_IOPAD(0x01a0, PIN_INPUT, 7)>, /* (B20) MCASP0_AXR0.GPIO1_10   */ /* SODIMM 34 */
+			<AM62X_IOPAD(0x01a4, PIN_INPUT, 7)>, /* (A19) MCASP0_ACLKX.GPIO1_11  */ /* SODIMM 30 */
+			<AM62X_IOPAD(0x01a8, PIN_INPUT, 7)>, /* (A20) MCASP0_AFSX.GPIO1_12   */ /* SODIMM 32 */
+			<AM62X_IOPAD(0x0088, PIN_INPUT, 7)>, /* (L17) GPMC0_OEn_REn.GPIO0_33 */ /* SODIMM 48 */
+			<AM62X_IOPAD(0x0098, PIN_INPUT, 7)>, /* (R18) GPMC0_WAIT0.GPIO0_37   */ /* SODIMM 44 */
+			<AM62X_IOPAD(0x008c, PIN_INPUT, 7)>, /* (L25) GPMC0_WEn.GPIO0_34     */ /* SODIMM 46 */
+			<AM62X_IOPAD(0x002c, PIN_INPUT, 7)>; /* (F23) OSPI0_CSn0.GPIO0_11    */ /* SODIMM 54 */
+	};
+};
+
+/* Verdin ETH */
+&cpsw3g {
+	status = "okay";
+};
+
+/* MDIO, shared by Verdin ETH_1 (On-module PHY) and Verdin ETH_2_RGMII */
+&cpsw3g_mdio {
+	status = "okay";
+
+	cpsw3g_phy1: ethernet-phy@2 {
+		reg = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_eth2_rgmii_int>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <38 IRQ_TYPE_EDGE_FALLING>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+	};
+};
+
+/* Verdin ETH_1*/
+&cpsw_port1 {
+	status = "okay";
+};
+
+/* Verdin ETH_2_RGMII */
+&cpsw_port2 {
+	phy-handle = <&cpsw3g_phy1>;
+	phy-mode = "rgmii-rxid";
+	status = "okay";
+};
+
+&main_gpio0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ctrl_sleep_moci>,
+		    <&pinctrl_qspi1_cs2_gpio>,
+		    <&pinctrl_qspi1_io0_gpio>,
+		    <&pinctrl_qspi1_io1_gpio>,
+		    <&pinctrl_qspi1_io2_gpio>,
+		    <&pinctrl_qspi1_io3_gpio>;
+	gpio-line-names =
+		"", /* 0 */
+		"",
+		"",
+		"DIGI_1", /* SODIMM 56 */
+		"DIGI_2", /* SODIMM 58 */
+		"REL1",   /* SODIMM 60 */
+		"REL2",   /* SODIMM 62 */
+		"",
+		"",
+		"",
+		"", /* 10 */
+		"",
+		"REL3", /* SODIMM 64 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 20 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 30 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 40 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 50 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 60 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 70 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 80 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"";
+};
+
+&main_gpio1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_qspi1_dqs_gpio>;
+	gpio-line-names =
+		"", /* 0 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 10 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"REL4", /* SODIMM 66 */
+		"",
+		"", /* 20 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 30 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 40 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 50 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 60 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 70 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"", /* 80 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"";
+};
+
+/* Verdin I2C_1 */
+&main_i2c1 {
+	status = "okay";
+
+	temperature-sensor@4f {
+		compatible = "ti,tmp1075";
+		reg = <0x4f>;
+	};
+
+	eeprom@57 {
+		compatible = "st,24c02", "atmel,24c02";
+		reg = <0x57>;
+		pagesize = <16>;
+	};
+};
+
+/* Verdin I2C_4 CSI */
+&main_i2c3 {
+	status = "okay";
+
+	ivy_adc1: adc@40 {
+		compatible = "ti,ads1119";
+		reg = <0x40>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_7>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <41 IRQ_TYPE_EDGE_FALLING>;
+		avdd-supply = <&reg_3v2_ain1>;
+		dvdd-supply = <&reg_3v2_ain1>;
+		vref-supply = <&reg_3v2_ain1>;
+		#address-cells = <1>;
+		#io-channel-cells = <1>;
+		#size-cells = <0>;
+
+		/* AIN1 0-33V Voltage Input */
+		channel@0 {
+			reg = <0>;
+			diff-channels = <0 1>;
+		};
+
+		/* AIN1 0-20mA Current Input */
+		channel@1 {
+			reg = <1>;
+			diff-channels = <2 3>;
+		};
+	};
+
+	ivy_adc2: adc@41 {
+		compatible = "ti,ads1119";
+		reg = <0x41>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_8>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <42 IRQ_TYPE_EDGE_FALLING>;
+		avdd-supply = <&reg_3v2_ain2>;
+		dvdd-supply = <&reg_3v2_ain2>;
+		vref-supply = <&reg_3v2_ain2>;
+		#address-cells = <1>;
+		#io-channel-cells = <1>;
+		#size-cells = <0>;
+
+		/* AIN2 0-33V Voltage Input */
+		channel@0 {
+			reg = <0>;
+			diff-channels = <0 1>;
+		};
+
+		/* AIN2 0-20mA Current Input */
+		channel@1 {
+			reg = <1>;
+			diff-channels = <2 3>;
+		};
+	};
+};
+
+/* Verdin CAN_1 */
+&main_mcan0 {
+	status = "okay";
+};
+
+/* Verdin SPI_1 */
+&main_spi1 {
+	pinctrl-0 = <&pinctrl_spi1>,
+		    <&pinctrl_spi1_cs0>,
+		    <&pinctrl_gpio_1>,
+		    <&pinctrl_gpio_4>;
+	cs-gpios = <0>,
+		   <&mcu_gpio0 1 GPIO_ACTIVE_LOW>,
+		   <&mcu_gpio0 4 GPIO_ACTIVE_LOW>;
+	status = "okay";
+
+	tpm@1 {
+		compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+		reg = <1>;
+		spi-max-frequency = <18500000>;
+	};
+
+	fram@2 {
+		compatible = "fujitsu,mb85rs256", "atmel,at25";
+		reg = <2>;
+		address-width = <16>;
+		size = <32768>;
+		spi-max-frequency = <33000000>;
+		pagesize = <1>;
+	};
+};
+
+/* Verdin UART_3 */
+&main_uart0 {
+	status = "okay";
+};
+
+/* Verdin UART_1 */
+&main_uart1 {
+	status = "okay";
+};
+
+&mcu_gpio0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpio_2>,
+		    <&pinctrl_gpio_3>,
+		    <&pinctrl_pcie_1_reset>;
+	gpio-line-names =
+		"",
+		"",
+		"GPIO2", /* Verdin GPIO_2 - SODIMM 208 */
+		"GPIO3", /* Verdin GPIO_3 - SODIMM 210 */
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"",
+		"";
+};
+
+/* Verdin CAN_2 */
+&mcu_mcan0 {
+	status = "okay";
+};
+
+/* Verdin SD_1 */
+&sdhci1 {
+	status = "okay";
+};
+
+/* Verdin USB_1*/
+&usbss0 {
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+};
+
+/* Verdin USB_2 */
+&usbss1 {
+	status = "okay";
+};
+
+&usb1 {
+	status = "okay";
+};
+
+/* Verdin PCIE_1_RESET# */
+&verdin_pcie_1_reset_hog {
+	status = "okay";
+};
+
+/* Verdin UART_2 */
+&wkup_uart0 {
+	linux,rs485-enabled-at-boot-time;
+	rs485-rts-active-low;
+	rs485-rx-during-tx;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -8,9 +8,9 @@
 #include <dt-bindings/bus/ti-sysc.h>
 
 &cbass_wakeup {
-	wkup_conf: syscon@43000000 {
+	wkup_conf: bus@43000000 {
 		bootph-all;
-		compatible = "syscon", "simple-mfd";
+		compatible = "simple-bus";
 		reg = <0x00 0x43000000 0x00 0x20000>;
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -22,6 +22,11 @@
 			reg = <0x14 0x4>;
 		};
 
+		opp_efuse_table: syscon@18 {
+			compatible = "ti,am62-opp-efuse-table", "syscon";
+			reg = <0x18 0x4>;
+		};
+
 		cpsw_mac_syscon: ethernet-mac-syscon@200 {
 			compatible = "ti,am62p-cpsw-mac-efuse", "syscon";
 			reg = <0x200 0x8>;
@@ -101,6 +106,31 @@
 		status = "reserved";
 	};
 
+	wkup_r5fss0: r5fss@78000000 {
+		compatible = "ti,am62-r5fss";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x78000000 0x00 0x78000000 0x8000>,
+			 <0x78100000 0x00 0x78100000 0x8000>;
+		power-domains = <&k3_pds 119 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		wkup_r5fss0_core0: r5f@78000000 {
+			compatible = "ti,am62-r5f";
+			reg = <0x78000000 0x00008000>,
+			      <0x78100000 0x00008000>;
+			reg-names = "atcm", "btcm";
+			ti,sci = <&dmsc>;
+			ti,sci-dev-id = <121>;
+			ti,sci-proc-ids = <0x01 0xff>;
+			resets = <&k3_reset 121 1>;
+			firmware-name = "am62-wkup-r5f0_0-fw";
+			ti,atcm-enable = <1>;
+			ti,btcm-enable = <1>;
+			ti,loczrama = <1>;
+		};
+	};
+
 	wkup_vtm0: temperature-sensor@b00000 {
 		compatible = "ti,j7200-vtm";
 		reg = <0x00 0xb00000 0x00 0x400>,
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -82,8 +82,8 @@
 		};
 
 		sound_master: simple-audio-card,codec {
-				sound-dai = <&audio_codec>;
-				clocks = <&audio_refclk1>;
+			sound-dai = <&audio_codec>;
+			clocks = <&audio_refclk1>;
 		};
 	};
 
@@ -112,6 +112,25 @@
 		regulator-boot-on;
 	};
 
+	vcc_3v3_hdmi: regulator-vcc-3v3-hdmi {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_3V3_HDMI";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_3v3_sw>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vcc_1v2_hdmi: regulator-vcc-1v2-hdmi {
+		compatible = "regulator-fixed";
+		regulator-name = "HDMI_CVCC";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
 	vcc_3v3_mmc: regulator-vcc-3v3-mmc {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3_MMC";
@@ -367,6 +386,9 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&hdmi_int_pins_default>;
 
+		iovcc-supply = <&vcc_3v3_hdmi>;
+		cvcc12-supply = <&vcc_1v2_hdmi>;
+
 		ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -376,6 +398,7 @@
 
 				sii9022_in: endpoint {
 					remote-endpoint = <&dpi1_out>;
+					bus-width = <16>;
 				};
 			};
 
@@ -393,6 +416,7 @@
 		compatible = "atmel,24c02";
 		pagesize = <16>;
 		reg = <0x51>;
+		vcc-supply = <&vcc_3v3_mmc>;
 	};
 };
 
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -8,10 +8,11 @@
 #include <dt-bindings/leds/common.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/net/ti-dp83867.h>
-#include "k3-am625.dtsi"
 
 / {
 	aliases {
+		serial0 = &wkup_uart0;
+		serial1 = &mcu_uart0;
 		serial2 = &main_uart0;
 		mmc0 = &sdhci0;
 		mmc1 = &sdhci1;
@@ -24,14 +25,21 @@
 	};
 
 	chosen {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
 		stdout-path = "serial2:115200n8";
-	};
 
-	memory@80000000 {
-		bootph-pre-ram;
-		device_type = "memory";
-		/* 2G RAM */
-		reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
+		framebuffer0: framebuffer@0 {
+			compatible = "simple-framebuffer";
+			power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
+			clocks = <&k3_clks 186 6>,
+				 <&dss_vp1_clk>,
+				 <&k3_clks 186 2>;
+			display = <&dss>;
+			status = "disabled";
+		};
 	};
 
 	reserved-memory {
@@ -39,9 +47,9 @@
 		#size-cells = <2>;
 		ranges;
 
-		ramoops@9ca00000 {
+		ramoops@9c700000 {
 			compatible = "ramoops";
-			reg = <0x00 0x9ca00000 0x00 0x00100000>;
+			reg = <0x00 0x9c700000 0x00 0x00100000>;
 			record-size = <0x8000>;
 			console-size = <0x8000>;
 			ftrace-size = <0x00>;
@@ -56,6 +64,36 @@
 			linux,cma-default;
 		};
 
+		rtos_ipc_memory_region: ipc-memories@9c800000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9c800000 0x00 0x00300000>;
+			no-map;
+		};
+
+		mcu_m4fss_dma_memory_region: m4f-dma-memory@9cb00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9cb00000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_m4fss_memory_region: m4f-memory@9cc00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9cc00000 0x00 0xe00000>;
+			no-map;
+		};
+
+		wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@9da00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9da00000 0x00 0x100000>;
+			no-map;
+		};
+
+		wkup_r5fss0_core0_memory_region: r5f-memory@9db00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0x9db00000 0x00 0xc00000>;
+			no-map;
+		};
+
 		secure_tfa_ddr: tfa@9e780000 {
 			reg = <0x00 0x9e780000 0x00 0x80000>;
 			alignment = <0x1000>;
@@ -68,11 +106,50 @@
 			no-map;
 		};
 
-		wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@9db00000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0x9db00000 0x00 0xc00000>;
-			no-map;
-		};
+	};
+
+	vmain_pd: regulator-0 {
+		/* TPS65988 PD CONTROLLER OUTPUT */
+		compatible = "regulator-fixed";
+		regulator-name = "vmain_pd";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vcc_5v0: regulator-1 {
+		/* Output of LM34936 */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_5v0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vmain_pd>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vcc_3v3_sys: regulator-2 {
+		/* output of LM61460-Q1 */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3_sys";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vmain_pd>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vdd_mmc1: regulator-3 {
+		/* TPS22918DBVR */
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_mmc1";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		enable-active-high;
+		vin-supply = <&vcc_3v3_sys>;
+		gpio = <&exp1 3 GPIO_ACTIVE_HIGH>;
 	};
 
 	leds {
@@ -182,22 +259,6 @@
 		>;
 	};
 
-	main_mmc0_pins_default: main-mmc0-default-pins {
-		bootph-all;
-		pinctrl-single,pins = <
-			AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (Y3/V3) MMC0_CMD */
-			AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (AB1/Y1) MMC0_CLK */
-			AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (AA2/V2) MMC0_DAT0 */
-			AM62X_IOPAD(0x210, PIN_INPUT, 0) /* (AA1/V1) MMC0_DAT1 */
-			AM62X_IOPAD(0x20c, PIN_INPUT, 0) /* (AA3/W2) MMC0_DAT2 */
-			AM62X_IOPAD(0x208, PIN_INPUT, 0) /* (Y4/W1) MMC0_DAT3 */
-			AM62X_IOPAD(0x204, PIN_INPUT, 0) /* (AB2/Y2) MMC0_DAT4 */
-			AM62X_IOPAD(0x200, PIN_INPUT, 0) /* (AC1/W3) MMC0_DAT5 */
-			AM62X_IOPAD(0x1fc, PIN_INPUT, 0) /* (AD2/W4) MMC0_DAT6 */
-			AM62X_IOPAD(0x1f8, PIN_INPUT, 0) /* (AC2/V4) MMC0_DAT7 */
-		>;
-	};
-
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
@@ -244,7 +305,7 @@
 
 	main_usb1_pins_default: main-usb1-default-pins {
 		pinctrl-single,pins = <
-			AM62X_IOPAD(0x0258, PIN_OUTPUT, 0) /* (F18/E16) USB1_DRVVBUS */
+			AM62X_IOPAD(0x0258, PIN_OUTPUT | PIN_DS_PULLUD_ENABLE | PIN_DS_PULL_UP, 0) /* (F18/E16) USB1_DRVVBUS */
 		>;
 	};
 
@@ -289,6 +350,30 @@
 			AM62X_IOPAD(0x078, PIN_OUTPUT, 1) /* (U24) GPMC0_AD15.VOUT0_DATA23 */
 		>;
 	};
+
+	ospi0_pins_default: ospi0-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x000, PIN_OUTPUT, 0) /* (H24/G19) OSPI0_CLK */
+			AM62X_IOPAD(0x02c, PIN_OUTPUT, 0) /* (F23/F19) OSPI0_CSn0 */
+			AM62X_IOPAD(0x00c, PIN_INPUT, 0) /* (E25/F18) OSPI0_D0 */
+			AM62X_IOPAD(0x010, PIN_INPUT, 0) /* (G24/G17) OSPI0_D1 */
+			AM62X_IOPAD(0x014, PIN_INPUT, 0) /* (F25/F21) OSPI0_D2 */
+			AM62X_IOPAD(0x018, PIN_INPUT, 0) /* (F24/F20) OSPI0_D3 */
+			AM62X_IOPAD(0x01c, PIN_INPUT, 0) /* (J23/G21) OSPI0_D4 */
+			AM62X_IOPAD(0x020, PIN_INPUT, 0) /* (J25/H21) OSPI0_D5 */
+			AM62X_IOPAD(0x024, PIN_INPUT, 0) /* (H25/G20) OSPI0_D6 */
+			AM62X_IOPAD(0x028, PIN_INPUT, 0) /* (J22/J21) OSPI0_D7 */
+			AM62X_IOPAD(0x008, PIN_INPUT, 0) /* (J24/H20) OSPI0_DQS */
+		>;
+	};
+
+	pruss_uart_pins: pruss-uart-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01d8, PIN_INPUT, 6) /* (C15) MCAN0_TX.PR0_UART0_RXD */
+			AM62X_IOPAD(0x01dc, PIN_OUTPUT, 6) /* (E15) MCAN0_RX.PR0_UART0_TXD */
+		>;
+	};
 };
 
 &mcu_pmx0 {
@@ -303,6 +388,10 @@
 	};
 };
 
+&cpsw_mac_syscon {
+	bootph-all;
+};
+
 &wkup_uart0 {
 	/* WKUP UART0 is used by DM firmware */
 	bootph-pre-ram;
@@ -316,6 +405,9 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_uart0_pins_default>;
+	interrupts-extended = <&gic500 GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>,
+			       <&main_pmx0 0x1c8>; /* (D14) UART0_RXD PADCONFIG114 */
+	interrupt-names = "irq", "wakeup";
 };
 
 &main_uart1 {
@@ -413,14 +505,6 @@
 	clock-frequency = <400000>;
 };
 
-&sdhci0 {
-	bootph-all;
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&main_mmc0_pins_default>;
-	disable-wp;
-};
-
 &sdhci1 {
 	/* SD/MMC */
 	bootph-all;
@@ -462,6 +546,28 @@
 		ti,mbox-rx = <0 0 0>;
 		ti,mbox-tx = <1 0 0>;
 	};
+
+	mbox_r5_0: mbox-r5-0 {
+		ti,mbox-rx = <2 0 0>;
+		ti,mbox-tx = <3 0 0>;
+	};
+};
+
+&mcu_m4fss {
+	mboxes = <&mailbox0_cluster0 &mbox_m4_0>;
+	memory-region = <&mcu_m4fss_dma_memory_region>,
+			<&mcu_m4fss_memory_region>;
+	status = "okay";
+};
+
+&wkup_r5fss0 {
+	status = "okay";
+};
+
+&wkup_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster0 &mbox_r5_0>;
+	memory-region = <&wkup_r5fss0_core0_dma_memory_region>,
+			<&wkup_r5fss0_core0_memory_region>;
 };
 
 &usbss0 {
@@ -510,7 +616,12 @@
 	>;
 };
 
+&dss_oldi_io_ctrl {
+	bootph-all;
+};
+
 &dss {
+	bootph-all;
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_dss0_pins_default>;
@@ -518,7 +629,7 @@
 
 &dss_ports {
 	/* VP2: DPI Output */
-	port@1 {
+	hdmi0_dss: port@1 {
 		reg = <1>;
 
 		dpi1_out: endpoint {
@@ -535,3 +646,16 @@
 &mcu_gpio_intr {
 	status = "reserved";
 };
+
+&ospi0 {
+	bootph-all;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&ospi0_pins_default>;
+};
+
+&pruss_uart {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pruss_uart_pins>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-v3link-fusion.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-v3link-fusion.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-v3link-fusion.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-v3link-fusion.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Arducam V3Link UC-A09 board
+ * https://www.arducam.com/fpd-link-3-cameras/
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&main_i2c2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	i2c-switch@71 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x71>;
+
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+
+			deser@30 {
+				compatible = "ti,ds90ub960-q1";
+				reg = <0x30>;
+
+				clock-names = "refclk";
+				clocks = <&clk_fusion_25M_fixed>;
+
+				i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+				deserializer_0_ports: ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					/* CSI-2 TX */
+					port@4 {
+						reg = <4>;
+						ds90ub960_0_csi_out: endpoint {
+							data-lanes = <1 2 3 4>;
+							clock-lanes = <0>;
+							link-frequencies = /bits/ 64 <800000000>;
+							remote-endpoint = <&csi2_phy0>;
+						};
+					};
+				};
+
+				deserializer_0_links: links {
+					#address-cells = <1>;
+					#size-cells = <0>;
+				};
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub960_0_csi_out>;
+				data-lanes = <1 2 3 4>;
+				clock-lanes = <0>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62x-sk-dmtimer-pwm.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-dmtimer-pwm.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-dmtimer-pwm.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-dmtimer-pwm.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay to enable DM timer in PWM mode on AM625-SK, AM62 LP-SK, and AM62A7-SK
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/leds/common.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	leds {
+		compatible = "pwm-leds";
+		pinctrl-names;
+		pinctrl-0;
+
+		led-0 {
+			pwms = <&main_pwm7 0 7812500 0>;
+			max-brightness = <255>;
+		};
+	};
+
+	main_pwm7: dmtimer-main-pwm-7 {
+		compatible = "ti,omap-dmtimer-pwm";
+		#pwm-cells = <3>;
+		ti,timers = <&main_timer7>;
+		pinctrl-0 = <&usr_led_pins_default>;
+		pinctrl-names = "default";
+	};
+
+	main_pwm3: dmtimer-main-pwm-3 {
+		/* dmtimer PWM output */
+		/* Pin 8 of J3 */
+		compatible = "ti,omap-dmtimer-pwm";
+		#pwm-cells = <3>;
+		ti,timers = <&main_timer3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_timer3_pins_default>;
+	};
+};
+
+&main_pmx0 {
+	usr_led_pins_default: usr-led-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x244, PIN_OUTPUT, 2) /* (C17) MMC1_SDWP.TIMER_IO7 */
+		>;
+	};
+
+	main_timer3_pins_default: main_timer3-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01dc, PIN_OUTPUT, 2) /* (A15) MCAN0_RX.TIMER_IO3 */
+		>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62x-sk-ecap-capture.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-ecap-capture.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-ecap-capture.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-ecap-capture.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for enabling ECAP in capture mode for AM625-SK, AM62 LP-SK, and AM62A7-SK
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+	main_ecap2_capture_pins_default: main-ecap2-capture-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01a4, PIN_INPUT, 2) /* (B20) MCASP0_ACLKX.ECAP2_IN_APWM_OUT */
+		>;
+	};
+};
+
+&ecap2 {
+	/* ECAP in capture mode */
+	/* P11 on J3 */
+	compatible = "ti,am62-ecap-capture";
+	interrupt-parent = <&gic500>;
+	interrupts = <GIC_SPI 115 IRQ_TYPE_EDGE_RISING>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap2_capture_pins_default>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62x-sk-eqep.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-eqep.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-eqep.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-eqep.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for enabling EQEP on AM625-SK, AM62 LP-SK, and AM62A7-SK
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+	main_eqep0_pins_default: main-eqep0-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0194, PIN_INPUT, 8) /* (B19/C19) MCASP0_AXR3.EQEP0_A */
+			AM62X_IOPAD(0x0198, PIN_INPUT, 8) /* (A19/B19) MCASP0_AXR2.EQEP0_B */
+			AM62X_IOPAD(0x01a0, PIN_INPUT, 8) /* (E18/B20) MCASP0_AXR0.EQEP0_I */
+			AM62X_IOPAD(0x019c, PIN_INPUT, 8) /* (B18/B18) MCASP0_AXR1.EQEP0_S */
+		>;
+	};
+};
+
+&main_i2c1 {
+	gpio@22 {
+		p25-hog {
+			/* P25 - UART1_FET_SEL */
+			gpio-hog;
+			gpios = <21 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "UART1_FET_SEL";
+		};
+	};
+};
+
+&main_uart1 {
+	/* Disable FW debug logs */
+	status = "disabled";
+};
+
+&eqep0 {
+	status = "okay";
+	/* A/B on pins 38/35 of J3 on AM625-SK & AM62 LP-SK */
+	/* A/B on pins 40/38 of J3 on AM62A7-SK */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_eqep0_pins_default>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62x-sk-fastboot-disable-hdmi.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-fastboot-disable-hdmi.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-fastboot-disable-hdmi.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-fastboot-disable-hdmi.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+* Overlay to remove HDMI support for TI K3 AM62* SK
+*
+* Copyright (C) 2025 Texas Instruments Incorporated - http://www.ti.com/
+*/
+
+/dts-v1/;
+/plugin/;
+
+&hdmi0 {
+	status = "disabled";
+};
+
+&sii9022 {
+	status = "disabled";
+};
+
+&hdmi0_dss {
+	status = "disabled";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62x-sk-lpm-io-ddr-wkup-sources.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-lpm-io-ddr-wkup-sources.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-lpm-io-ddr-wkup-sources.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-lpm-io-ddr-wkup-sources.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * AM62 family of devices can wakeup from I/O Only + DDR low power mode via
+ * multiple wakeup sources. This overlay enables mcu_mcan pins to be used
+ * as wakeup source.
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "k3-pinctrl.h"
+
+&mcu_pmx0 {
+        mcu_mcan0_tx_pins_default: mcu-mcan0-tx-pins-default {
+                pinctrl-single,pins = <
+                        AM62X_IOPAD(0x034, PIN_OUTPUT, 0) /* (D6) MCU_MCAN0_TX */
+                >;
+        };
+
+        mcu_mcan0_rx_pins_default: mcu-mcan0-rx-pins-default {
+                pinctrl-single,pins = <
+                        AM62X_IOPAD(0x038, PIN_INPUT, 0) /* (B3) MCU_MCAN0_RX */
+                >;
+        };
+
+        mcu_mcan0_rx_pins_wakeup: mcu-mcan0-rx-pins-wakeup {
+                pinctrl-single,pins = <
+                        AM62X_IOPAD(0x038, PIN_INPUT | WKUP_EN, 0) /* (B3) MCU_MCAN0_RX */
+                >;
+        };
+
+        mcu_mcan1_tx_pins_default: mcu-mcan1-tx-pins-default {
+                pinctrl-single,pins = <
+                        AM62X_IOPAD(0x03c, PIN_OUTPUT, 0) /* (E5) MCU_MCAN1_TX */
+                >;
+        };
+
+        mcu_mcan1_rx_pins_default: mcu-mcan1-rx-pins-default {
+                pinctrl-single,pins = <
+                        AM62X_IOPAD(0x040, PIN_INPUT, 0) /* (D4) MCU_MCAN1_RX */
+                >;
+        };
+
+        mcu_mcan1_rx_pins_wakeup: mcu-mcan1-rx-pins-wakeup {
+                pinctrl-single,pins = <
+                        AM62X_IOPAD(0x040, PIN_INPUT | WKUP_EN, 0) /* (D4) MCU_MCAN1_RX */
+                >;
+        };
+};
+
+&mcu_mcan0 {
+	pinctrl-names = "default", "wakeup";
+	pinctrl-0 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_default>;
+	pinctrl-1 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_wakeup>;
+	status = "okay";
+};
+
+&mcu_mcan1 {
+	pinctrl-names = "default", "wakeup";
+	pinctrl-0 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_default>;
+	pinctrl-1 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_wakeup>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62x-sk-lpm-wkup-sources.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-lpm-wkup-sources.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-lpm-wkup-sources.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-lpm-wkup-sources.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * AM62 family of devices can wakeup from Low Power Modes via
+ * multiple wakeup sources. This overlay enables MAIN GPIO, MCU GPIO,
+ * and MCU MCAN pins.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "k3-pinctrl.h"
+
+&{/} {
+	gpio_key {
+		compatible = "gpio-keys";
+		autorepeat;
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_gpio1_pins_default>;
+		switch {
+			label = "WKGPIO";
+			linux,code = <KEY_WAKEUP>;
+			interrupts-extended = <&main_gpio1 10 IRQ_TYPE_EDGE_RISING>,
+				<&main_pmx0 0x1a0>;
+			interrupt-names = "irq", "wakeup";
+		};
+	};
+
+	mcu_gpio_key {
+		compatible = "gpio-keys";
+			autorepeat;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wake_mcugpio1_pins_default>;
+		interrupt-parent = <&mcu_gpio0>;
+		interrupts = <4 IRQ_TYPE_EDGE_RISING>;
+		switch {
+			label = "MCUGPIO";
+			linux,code = <143>;
+			gpios = <&mcu_gpio0 4 GPIO_ACTIVE_LOW>;
+			wakeup-source;
+		};
+	};
+};
+
+&main_pmx0 {
+	main_gpio1_pins_default: main-gpio1-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x1a0, PIN_INPUT_PULLUP, 7) /* (E18) MCASP0_AXR0.EHRPWM1_B */
+		>;
+	};
+};
+
+&mcu_pmx0 {
+	wake_mcugpio1_pins_default: wake-mcugpio1-pins-default {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x0010, PIN_INPUT, 7) /* (D8) MCU_SPI0_D1.MCU_GPIO0_4 */
+		>;
+	};
+
+	mcu_mcan0_tx_pins_default: mcu-mcan0-tx-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x034, PIN_OUTPUT, 0) /* (D6) MCU_MCAN0_TX */
+		>;
+	};
+
+	mcu_mcan0_rx_pins_default: mcu-mcan0-rx-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x038, PIN_INPUT, 0) /* (B3) MCU_MCAN0_RX */
+		>;
+	};
+
+	mcu_mcan0_rx_pins_wakeup: mcu-mcan0-rx-pins-wakeup {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x038, PIN_INPUT | WKUP_EN, 0) /* (B3) MCU_MCAN0_RX */
+		>;
+	};
+
+	mcu_mcan1_tx_pins_default: mcu-mcan1-tx-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x03c, PIN_OUTPUT, 0) /* (E5) MCU_MCAN1_TX */
+		>;
+	};
+
+	mcu_mcan1_rx_pins_default: mcu-mcan1-rx-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x040, PIN_INPUT, 0) /* (D4) MCU_MCAN1_RX */
+		>;
+	};
+
+	mcu_mcan1_rx_pins_wakeup: mcu-mcan1-rx-pins-wakeup {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x040, PIN_INPUT | WKUP_EN, 0) /* (D4) MCU_MCAN1_RX */
+		>;
+	};
+};
+
+&mcu_gpio0 {
+	status = "okay";
+};
+
+&mcu_gpio_intr {
+	status = "okay";
+};
+
+&mcu_mcan0 {
+	pinctrl-names = "default", "wakeup";
+	pinctrl-0 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_default>;
+	pinctrl-1 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_wakeup>;
+	status = "okay";
+};
+
+&mcu_mcan1 {
+	pinctrl-names = "default", "wakeup";
+	pinctrl-0 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_default>;
+	pinctrl-1 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_wakeup>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62x-sk-mcan.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-mcan.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-mcan.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-mcan.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT overlay to enable MCAN on AM625-SK, AM62 LP-SK, and AM62A7-SK
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "k3-pinctrl.h"
+
+&{/} {
+	transceiver1: can-phy0 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
+	transceiver2: can-phy1 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
+	transceiver3: can-phy2 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+};
+
+&main_pmx0 {
+	main_mcan0_pins_default: main-mcan0-pins-default {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01dc, PIN_INPUT, 0) /* (E15) MCAN0_RX */
+			AM62X_IOPAD(0x01d8, PIN_OUTPUT, 0) /* (C15) MCAN0_TX */
+		>;
+	};
+};
+
+&mcu_pmx0 {
+	mcu_mcan0_pins_default: mcu-mcan0-pins-default {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x0038, PIN_INPUT, 0) /* (B3) MCU_MCAN0_RX */
+			AM62X_MCU_IOPAD(0x0034, PIN_OUTPUT, 0) /* (D6) MCU_MCAN0_TX */
+		>;
+	};
+
+	mcu_mcan1_pins_default: mcu-mcan1-pins-default {
+		pinctrl-single,pins = <
+			AM62X_MCU_IOPAD(0x0040, PIN_INPUT, 0) /* (D4) MCU_MCAN1_RX */
+			AM62X_MCU_IOPAD(0x003c, PIN_OUTPUT, 0) /* (E5) MCU_MCAN1_TX */
+		>;
+	};
+};
+
+&main_mcan0 {
+	/* RX pin 8 & TX pin 10 of J3 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan0_pins_default>;
+	phys = <&transceiver1>;
+	status = "okay";
+};
+
+&mcu_mcan0 {
+	/* RX pin 22 & TX pin 16 of J10 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mcan0_pins_default>;
+	phys = <&transceiver2>;
+	status = "okay";
+};
+
+&mcu_mcan1 {
+	/* RX pin 11 & TX pin 10 of J10 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mcan1_pins_default>;
+	phys = <&transceiver3>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62x-sk-microtips-mf103hie-lcd2.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-microtips-mf103hie-lcd2.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-microtips-mf103hie-lcd2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-microtips-mf103hie-lcd2.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * Microtips integrated OLDI panel (MF-103HIEB0GA0) (SK-LCD2) DT overlay for AM625-SK and AM62-LP SK
+ *
+ * AM625-SKEVM: https://www.ti.com/tool/SK-AM62
+ * AM62-LP SKEVM: https://www.ti.com/tool/SK-AM62-LP
+ * Panel datasheet: https://simplespec.microtipsusa.com/uploads/spec/datasheetFile/2660/13-103HIEB0GA0-S_V1.0_20211206.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&{/} {
+	display {
+		compatible = "microtips,mf-103hieb0ga0", "panel-simple";
+		/*
+		* Note that the OLDI TX 0 transmits the odd set of pixels
+		* while the OLDI TX 1 transmits the even set. This is a
+		* fixed configuration in the IP integration and is not
+		* changeable. The properties, "dual-lvds-odd-pixels" and
+		* "dual-lvds-even-pixels" have been used to merely
+		* identify if a Dual Link configuration is required.
+		* Swapping them will cause an error in the dss oldi driver.
+		*/
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				dual-lvds-odd-pixels;
+				lcd_in0: endpoint {
+					remote-endpoint = <&oldi_0_out>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				dual-lvds-even-pixels;
+				lcd_in1: endpoint {
+					remote-endpoint = <&oldi_1_out>;
+				};
+			};
+		};
+	};
+};
+
+&dss {
+	status = "okay";
+};
+
+&oldi0 {
+	status = "okay";
+	ti,companion-oldi = <&oldi1>;
+};
+
+&oldi1 {
+	status = "okay";
+	ti,secondary-oldi;
+};
+
+&oldi0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		oldi_0_in: endpoint {
+			remote-endpoint = <&dpi0_out0>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		oldi_0_out: endpoint {
+			remote-endpoint = <&lcd_in0>;
+		};
+	};
+};
+
+&oldi1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		oldi_1_in: endpoint {
+			remote-endpoint = <&dpi0_out1>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		oldi_1_out: endpoint {
+			remote-endpoint = <&lcd_in1>;
+		};
+	};
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* VP1: Output to OLDI */
+	port@0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dpi0_out0: endpoint@0 {
+			reg = <0>;
+			remote-endpoint = <&oldi_0_in>;
+		};
+		dpi0_out1: endpoint@1 {
+			reg = <1>;
+			remote-endpoint = <&oldi_1_in>;
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am62x-sk-pwm.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-pwm.dtso
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-pwm.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-pwm.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT Overlay for enabling PWM output on user expansion connector for AM625-SK, AM62 LP-SK, and AM62A7-SK
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+	main_epwm0_pins_default: main-epwm0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01ac, PIN_OUTPUT, 6) /* (E19) MCASP0_AFSR.EHRPWM0_A */
+			AM62X_IOPAD(0x01b0, PIN_OUTPUT, 6) /* (A20) MCASP0_ACLKR.EHRPWM0_B */
+		>;
+	};
+	main_epwm1_pins_default: main-epwm1-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x019c, PIN_OUTPUT, 6) /* (B18) MCASP0_AXR1.EHRPWM1_A */
+			AM62X_IOPAD(0x01a0, PIN_OUTPUT, 6) /* (E18) MCASP0_AXR0.EHRPWM1_B */
+		>;
+	};
+	main_ecap0_pins_default: main-ecap0-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01b8, PIN_OUTPUT, 3) /* (C13) SPI0_CS1.ECAP0_IN_APWM_OUT */
+		>;
+	};
+	main_ecap1_pins_default: main_ecap1-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0194, PIN_OUTPUT, 5) /* (B19) MCASP0_AXR3.ECAP1_IN_APWM_OUT */
+		>;
+	};
+	main_ecap2_pins_default: main-ecap2-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x01a4, PIN_OUTPUT, 2) /* (B20) MCASP0_ACLKX.ECAP2_IN_APWM_OUT */
+		>;
+	};
+};
+
+&main_i2c1 {
+	gpio@22 {
+		fet_sel {
+			gpio-hog;
+			gpios = <21 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "UART1_FET_SEL";
+		};
+	};
+};
+
+&main_uart1 {
+	/* Disable FW debug logs */
+	status = "disabled";
+};
+
+&epwm0 {
+	/* Pin 12/40 of J3 on AM625-SK & AM62 LP-SK */
+	/* Pin 35/12 of J3 on AM62A7-SK */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm0_pins_default>;
+	status = "okay";
+};
+
+&epwm1 {
+	/* Pin 36/33 of J3 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm1_pins_default>;
+	status = "okay";
+};
+
+&ecap0 {
+	/* ECAP0 in APWM mode */
+	/* Pin 26 of J3 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap0_pins_default>;
+	status = "okay";
+};
+
+&ecap1 {
+	/* ECAP1 in APWM mode */
+	/* Pin 38 of J3 on AM625-SK & AM62 LP-SK */
+	/* Pin 40 of J3 on AM62A7-SK */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap1_pins_default>;
+	status = "okay";
+};
+
+&ecap2 {
+	/* ECAP2 in APWM mode */
+	/* Pin 11 of J3 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap2_pins_default>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts	2025-10-23 09:30:40.282462115 -0400
@@ -12,6 +12,7 @@
 #include "k3-am642.dtsi"
 
 #include "k3-serdes.h"
+#include "k3-timesync-router.h"
 
 / {
 	compatible = "ti,am642-evm", "ti,am642";
@@ -101,6 +102,18 @@
 			no-map;
 		};
 
+		mcu_m4fss_dma_memory_region: m4f-dma-memory@a4000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa4000000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_m4fss_memory_region: m4f-memory@a4100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa4100000 0x00 0xf00000>;
+			no-map;
+		};
+
 		rtos_ipc_memory_region: ipc-memories@a5000000 {
 			reg = <0x00 0xa5000000 0x00 0x00800000>;
 			alignment = <0x1000>;
@@ -253,6 +266,7 @@
 		ti,mii-g-rt = <&icssg1_mii_g_rt>;
 		ti,mii-rt = <&icssg1_mii_rt>;
 		ti,iep = <&icssg1_iep0>,  <&icssg1_iep1>;
+		ti,pa-stats = <&icssg1_pa_stats>;
 		interrupt-parent = <&icssg1_intc>;
 		interrupts = <24 0 2>, <25 1 3>;
 		interrupt-names = "tx_ts0", "tx_ts1";
@@ -414,6 +428,7 @@
 			AM64X_IOPAD(0x0028, PIN_INPUT, 0) /* (M17) OSPI0_D7 */
 			AM64X_IOPAD(0x0008, PIN_INPUT, 0) /* (N19) OSPI0_DQS */
 		>;
+		bootph-all;
 	};
 
 	main_ecap0_pins_default: main-ecap0-default-pins {
@@ -450,7 +465,7 @@
 		>;
 	};
 
-	icssg1_rgmii1_pins_default: icssg1-rgmii1-default-pins{
+	icssg1_rgmii1_pins_default: icssg1-rgmii1-default-pins {
 		pinctrl-single,pins = <
 			AM64X_IOPAD(0x00b8, PIN_INPUT, 2) /* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
 			AM64X_IOPAD(0x00bc, PIN_INPUT, 2) /* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
@@ -474,6 +489,10 @@
 	};
 };
 
+&fss {
+	bootph-all;
+};
+
 &main_uart0 {
 	bootph-all;
 	status = "okay";
@@ -581,6 +600,7 @@
 
 /* eMMC */
 &sdhci0 {
+	bootph-all;
 	status = "okay";
 	non-removable;
 	ti,driver-strength-ohm = <50>;
@@ -617,6 +637,11 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&rgmii1_pins_default>, <&rgmii2_pins_default>;
 	status = "okay";
+
+	/* Map HW8_TS_PUSH to GENF1 */
+	cpts@3d000 {
+		ti,pps = <7 1>;
+	};
 };
 
 &cpsw_port1 {
@@ -659,6 +684,7 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&ospi0_pins_default>;
+	bootph-all;
 
 	flash@0 {
 		compatible = "jedec,spi-nor";
@@ -671,11 +697,14 @@
 		cdns,tchsh-ns = <60>;
 		cdns,tslch-ns = <60>;
 		cdns,read-delay = <4>;
+		cdns,phy-mode;
+		bootph-all;
 
 		partitions {
 			compatible = "fixed-partitions";
 			#address-cells = <1>;
 			#size-cells = <1>;
+			bootph-all;
 
 			partition@0 {
 				label = "ospi.tiboot3";
@@ -710,6 +739,7 @@
 			partition@3fc0000 {
 				label = "ospi.phypattern";
 				reg = <0x3fc0000 0x40000>;
+				bootph-all;
 			};
 		};
 	};
@@ -776,6 +806,30 @@
 			<&main_r5fss1_core1_memory_region>;
 };
 
+&mcu_m4fss {
+	mboxes = <&mailbox0_cluster6 &mbox_m4_0>;
+	memory-region = <&mcu_m4fss_dma_memory_region>,
+			<&mcu_m4fss_memory_region>;
+	status = "okay";
+};
+
+/* main domain timers 8 to 11 are used by TI MCU FW */
+&main_timer8 {
+	status = "reserved";
+};
+
+&main_timer9 {
+	status = "reserved";
+};
+
+&main_timer10 {
+	status = "reserved";
+};
+
+&main_timer11 {
+	status = "reserved";
+};
+
 &serdes_ln_ctrl {
 	idle-states = <AM64_SERDES0_LANE0_PCIE0>;
 };
@@ -839,3 +893,22 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&icssg1_iep0_pins_default>;
 };
+
+&timesync_router {
+	/* Use Time Sync Router to map GENF1 input to HW8_TS_PUSH output. */
+	mux-reg-masks-state = <
+		/* pps [cpts genf1] in22 -> out37 [cpts hw8_push] */
+		K3_TS_OFFSET(37, 0x0001ffff, 22)
+		/* iep-pps [iep sync_out0] in29 -> out23 [navss cpts hw8_push] */
+		K3_TS_OFFSET(23, 0x0001ffff, 29)
+		>;
+	status = "okay";
+};
+
+&main_cpts0 {
+	/*
+	 * Use HW8_TS_PUSH of NAVSS CPTS to generate events for IEP PPS
+	 * signal (PRGx_IEP0_EDC_SYNC_OUT0)
+	 */
+	ti,pps = <7 1>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am642-evm-pcie0-ep.dtso b/arch/arm64/boot/dts/ti/k3-am642-evm-pcie0-ep.dtso
--- a/arch/arm64/boot/dts/ti/k3-am642-evm-pcie0-ep.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm-pcie0-ep.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for enabling PCIE0 instance in Endpoint Configuration with the
+ * AM642 EVM.
+ *
+ * AM642 EVM Product Link: https://www.ti.com/tool/TMDS64EVM
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+#include "k3-pinctrl.h"
+
+/*
+ * Since Root Complex and Endpoint modes are mutually exclusive
+ * disable Root Complex mode.
+ */
+&pcie0_rc {
+	status = "disabled";
+};
+
+&cbass_main {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&gic500>;
+
+	pcie0_ep: pcie-ep@f102000 {
+		compatible = "ti,am64-pcie-ep", "ti,j721e-pcie-ep";
+		reg = <0x00 0x0f102000 0x00 0x1000>,
+		      <0x00 0x0f100000 0x00 0x400>,
+		      <0x00 0x0d000000 0x00 0x00800000>,
+		      <0x00 0x68000000 0x00 0x08000000>;
+		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+		interrupt-names = "link_state";
+		interrupts = <GIC_SPI 203 IRQ_TYPE_EDGE_RISING>;
+		max-link-speed = <2>;
+		num-lanes = <1>;
+		power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 114 0>;
+		clock-names = "fck";
+		max-functions = /bits/ 8 <1>;
+		phys = <&serdes0_pcie_link>;
+		phy-names = "pcie-phy";
+		bootph-all;
+		ti,syscon-pcie-ctrl = <&main_conf 0x4070>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am642-evm-sk-cpsw3g-pps.dtso b/arch/arm64/boot/dts/ti/k3-am642-evm-sk-cpsw3g-pps.dtso
--- a/arch/arm64/boot/dts/ti/k3-am642-evm-sk-cpsw3g-pps.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm-sk-cpsw3g-pps.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT overlay for enabling PPS in CPSW3G via SYNC0_OUT signal
+ * This overlay is applicable for both AM642-EVM and AM642-SK
+ * boards.
+ *
+ * AM642 EVM Product Link: https://www.ti.com/tool/TMDS64EVM
+ * AM642 SK Product Link: https://www.ti.com/tool/SK-AM64B
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "k3-pinctrl.h"
+#include "k3-timesync-router.h"
+
+&main_pmx0 {
+	cpsw3g_pps_pins_default: cpsw3g-pps-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0270, PIN_INPUT, 1) /* (D18) SYNC0_OUT */
+		>;
+	};
+};
+
+/*
+ * Since D18 is used by CPSW for SYNC0_OUT, disable ECAP which uses D18 for
+ * ECAP0_IN_APWM_OUT.
+ */
+
+&ecap0 {
+	status = "disabled";
+};
+
+&cpsw3g {
+	pinctrl-0 = <&rgmii1_pins_default>, <&rgmii2_pins_default>,
+		    <&cpsw3g_pps_pins_default>;
+};
+
+&timesync_router {
+	/* Use Time Sync Router to map GENF1 input to HW8_TS_PUSH output. */
+	mux-reg-masks-state = <
+		/* pps [cpts genf1] in22 -> out37 [cpts hw8_push] */
+		K3_TS_OFFSET(37, 0x0001ffff, 22)
+		/* pps [cpts genf1] in22 -> out24 [SYNC0_OUT pin] */
+		K3_TS_OFFSET(24, 0x0001ffff, 22)
+		>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
--- a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts	2025-10-23 09:30:40.282462115 -0400
@@ -344,6 +344,10 @@
 	};
 };
 
+&i2c_som_rtc {
+	trickle-resistor-ohms = <3000>;
+};
+
 &main_i2c1 {
 	status = "okay";
 	pinctrl-names = "default";
@@ -423,7 +427,6 @@
 	vmmc-supply = <&vcc_3v3_mmc>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	bus-width = <4>;
 	disable-wp;
 	no-1-8-v;
 };
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts	2025-10-23 09:30:40.282462115 -0400
@@ -12,6 +12,7 @@
 #include "k3-am642.dtsi"
 
 #include "k3-serdes.h"
+#include "k3-timesync-router.h"
 
 / {
 	compatible = "ti,am642-sk", "ti,am642";
@@ -25,6 +26,7 @@
 		serial0 = &mcu_uart0;
 		serial1 = &main_uart1;
 		serial2 = &main_uart0;
+		serial3 = &icssg0_uart;
 		i2c0 = &main_i2c0;
 		i2c1 = &main_i2c1;
 		mmc0 = &sdhci0;
@@ -99,6 +101,18 @@
 			no-map;
 		};
 
+		mcu_m4fss_dma_memory_region: m4f-dma-memory@a4000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa4000000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_m4fss_memory_region: m4f-memory@a4100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa4100000 0x00 0xf00000>;
+			no-map;
+		};
+
 		rtos_ipc_memory_region: ipc-memories@a5000000 {
 			reg = <0x00 0xa5000000 0x00 0x00800000>;
 			alignment = <0x1000>;
@@ -350,6 +364,7 @@
 			AM64X_IOPAD(0x0028, PIN_INPUT, 0) /* (M17) OSPI0_D7 */
 			AM64X_IOPAD(0x0008, PIN_INPUT, 0) /* (N19) OSPI0_DQS */
 		>;
+		bootph-all;
 	};
 
 	main_ecap0_pins_default: main-ecap0-default-pins {
@@ -357,6 +372,16 @@
 			AM64X_IOPAD(0x0270, PIN_INPUT, 0) /* (D18) ECAP0_IN_APWM_OUT */
 		>;
 	};
+
+	main_eqep0_pins_default: main-eqep0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x00a0, PIN_INPUT, 3) /* (N16) GPMC0_WPn.EQEP0_A */
+			AM64X_IOPAD(0x00a4, PIN_INPUT, 3) /* (N17) GPMC0_DIR.EQEP0_B */
+			AM64X_IOPAD(0x00ac, PIN_INPUT, 3) /* (R20) GPMC0_CSn1.EQEP0_I */
+			AM64X_IOPAD(0x00a8, PIN_INPUT, 3) /* (R19) GPMC0_CSn0.EQEP0_S */
+		>;
+	};
+
 	main_wlan_en_pins_default: main-wlan-en-default-pins {
 		pinctrl-single,pins = <
 			AM64X_IOPAD(0x00c4, PIN_OUTPUT_PULLUP, 7) /* (V8) GPIO0_48 */
@@ -374,6 +399,15 @@
 			AM64X_IOPAD(0x00bc, PIN_INPUT, 7) /* (U8) GPIO0_46 */
 		>;
 	};
+
+	icssg0_uart_pins_default: icssg0-uart-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0184, PIN_INPUT, 2) /* (W6) PRG0_PRU0_GPO9.PRG0_UART0_CTSn */
+			AM64X_IOPAD(0x0188, PIN_OUTPUT, 2) /* (AA5) PRG0_PRU0_GPO10.PRG0_UART0_RTSn */
+			AM64X_IOPAD(0x01d4, PIN_INPUT, 2) /* (Y5) PRG0_PRU1_GPO9.PRG0_UART0_RXD */
+			AM64X_IOPAD(0x01d8, PIN_OUTPUT, 2) /* (V6) PRG0_PRU1_GPO10.PRG0_UART0_TXD */
+		>;
+	};
 };
 
 &main_uart0 {
@@ -528,6 +562,11 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&rgmii1_pins_default>, <&rgmii2_pins_default>;
 	status = "okay";
+
+	/* Map HW8_TS_PUSH to GENF1 */
+	cpts@3d000 {
+		ti,pps = <7 1>;
+	};
 };
 
 &cpsw_port1 {
@@ -564,6 +603,7 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&ospi0_pins_default>;
+	bootph-all;
 
 	flash@0 {
 		compatible = "jedec,spi-nor";
@@ -576,11 +616,14 @@
 		cdns,tchsh-ns = <60>;
 		cdns,tslch-ns = <60>;
 		cdns,read-delay = <4>;
+		cdns,phy-mode;
+		bootph-all;
 
 		partitions {
 			compatible = "fixed-partitions";
 			#address-cells = <1>;
 			#size-cells = <1>;
+			bootph-all;
 
 			partition@0 {
 				label = "ospi.tiboot3";
@@ -615,6 +658,7 @@
 			partition@3fc0000 {
 				label = "ospi.phypattern";
 				reg = <0x3fc0000 0x40000>;
+				bootph-all;
 			};
 		};
 	};
@@ -681,9 +725,55 @@
 			<&main_r5fss1_core1_memory_region>;
 };
 
+&mcu_m4fss {
+	mboxes = <&mailbox0_cluster6 &mbox_m4_0>;
+	memory-region = <&mcu_m4fss_dma_memory_region>,
+			<&mcu_m4fss_memory_region>;
+	status = "okay";
+};
+
+/* main domain timers 8 to 11 are used by TI MCU FW */
+&main_timer8 {
+	status = "reserved";
+};
+
+&main_timer9 {
+	status = "reserved";
+};
+
+&main_timer10 {
+	status = "reserved";
+};
+
+&main_timer11 {
+	status = "reserved";
+};
+
 &ecap0 {
 	status = "okay";
 	/* PWM is available on Pin 1 of header J3 */
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_ecap0_pins_default>;
 };
+
+&eqep0 {
+	status = "okay";
+	/* EQEP0 A & B available on pins 18 & 22 of J4 header */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_eqep0_pins_default>;
+};
+
+&timesync_router {
+	/* Use Time Sync Router to map GENF1 input to HW8_TS_PUSH output. */
+	mux-reg-masks-state = <
+		/* pps [cpts genf1] in22 -> out37 [cpts hw8_push] */
+		K3_TS_OFFSET(37, 0x0001ffff, 22)
+		>;
+	status = "okay";
+};
+
+&icssg0_uart {
+	pinctrl-names = "default";
+	pinctrl-0 = <&icssg0_uart_pins_default>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am642-sk-pwm.dtso b/arch/arm64/boot/dts/ti/k3-am642-sk-pwm.dtso
--- a/arch/arm64/boot/dts/ti/k3-am642-sk-pwm.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk-pwm.dtso	2025-10-23 09:30:40.282462115 -0400
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT Overlay for enabling PWM output on user expansion connector for AM64 SK
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+	main_ecap0_pins_default: main_ecap0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0270, PIN_OUTPUT, 0) /* (D18) ECAP0_IN_APWM_OUT */
+		>;
+	};
+	main_ecap1_pins_default: main_ecap1-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0258, PIN_OUTPUT, 2) /* (C17) MCAN1_TX.ECAP1_IN_APWM_OUT */
+		>;
+	};
+	main_ecap2_pins_default: main_ecap2-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x025c, PIN_OUTPUT, 2) /* (D17) MCAN1_RX.ECAP2_IN_APWM_OUT */
+		>;
+	};
+	main_epwm4_pins_default: main_epwm4-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0088, PIN_OUTPUT, 3) /* (R18) GPMC0_OEn_REn.EHRPWM4_A */
+			AM64X_IOPAD(0x008c, PIN_OUTPUT, 3) /* (T21) GPMC0_WEn.EHRPWM4_B */
+		>;
+	};
+	main_epwm5_pins_default: main_epwm5-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0094, PIN_OUTPUT, 3) /* (T19) GPMC0_BE1n.EHRPWM5_A */
+			AM64X_IOPAD(0x0098, PIN_OUTPUT, 3) /* (W19) GPMC0_WAIT0.EHRPWM5_B */
+		>;
+	};
+	main_epwm6_pins_default: main_epwm6-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x021c, PIN_OUTPUT, 3) /* (B14) SPI1_CS0.EHRPWM6_A */
+			AM64X_IOPAD(0x022c, PIN_OUTPUT, 3) /* (A15) SPI1_D1.EHRPWM6_B */
+		>;
+	};
+	main_epwm7_pins_default: main_epwm7-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0090, PIN_OUTPUT, 5) /* (P17) GPMC0_BE0n_CLE.EHRPWM7_A */
+			AM64X_IOPAD(0x009c, PIN_OUTPUT, 5) /* (Y18) GPMC0_WAIT1.EHRPWM7_B */
+		>;
+	};
+	main_epwm8_pins_default: main_epwm8-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01a8, PIN_OUTPUT, 6) /* (V1) PRG0_PRU0_GPO18.EHRPWM8_A */
+			AM64X_IOPAD(0x01ac, PIN_OUTPUT, 6) /* (W1) PRG0_PRU0_GPO19.EHRPWM8_B */
+		>;
+	};
+};
+
+&main_mcan1 {
+	/* For AM64x EVM only */
+	status = "disabled";
+};
+
+&ecap0 {
+	/* ECAP0 in APWM mode */
+	/* Pin 1 of J3 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap0_pins_default>;
+	status = "okay";
+};
+
+&ecap1 {
+	/* ECAP1 in APWM mode */
+	/* Pin 10 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap1_pins_default>;
+	status = "okay";
+};
+
+&ecap2 {
+	/* ECAP2 in APWM mode */
+	/* Pin 8 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap2_pins_default>;
+	status = "okay";
+};
+
+&epwm4 {
+	/* Pin 32/33 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm4_pins_default>;
+	status = "okay";
+};
+
+&epwm5 {
+	/* Pin 29/31 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm5_pins_default>;
+	status = "okay";
+};
+
+&epwm6 {
+	/* Pin 12/35 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm6_pins_default>;
+	status = "okay";
+};
+
+&epwm7 {
+	/* Pin 7/16 of J4 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm7_pins_default>;
+	status = "okay";
+};
+
+&epwm8 {
+	/* Pin 38/43 of J10 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm8_pins_default>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
--- a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts	2025-10-23 09:30:40.282462115 -0400
@@ -201,8 +201,6 @@
 		reset-gpios = <&main_gpio0 44 GPIO_ACTIVE_LOW>;
 		reset-assert-us = <1000>;
 		reset-deassert-us = <1000>;
-		ti,rx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
-		ti,tx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
 		ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
 	};
@@ -230,8 +228,6 @@
 		reset-gpios = <&main_gpio1 47 GPIO_ACTIVE_LOW>;
 		reset-assert-us = <1000>;
 		reset-deassert-us = <1000>;
-		ti,rx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
-		ti,tx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
 		ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
 	};
@@ -242,8 +238,6 @@
 		reset-gpios = <&main_gpio1 51 GPIO_ACTIVE_LOW>;
 		reset-assert-us = <1000>;
 		reset-deassert-us = <1000>;
-		ti,rx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
-		ti,tx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
 		ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
 	};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am64.dtsi b/arch/arm64/boot/dts/ti/k3-am64.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am64.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am64.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -19,6 +19,10 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	aliases {
+		spi0 = &ospi0;
+	};
+
 	chosen { };
 
 	firmware {
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -51,6 +51,11 @@
 			reg = <0x00000014 0x4>;
 		};
 
+		pcie0_ctrl: pcie-ctrl@4070 {
+			compatible = "ti,j784s4-pcie-ctrl", "syscon";
+			reg = <0x4070 0x4>;
+		};
+
 		serdes_ln_ctrl: mux-controller@4080 {
 			compatible = "reg-mux";
 			reg = <0x4080 0x4>;
@@ -754,12 +759,11 @@
 		ti,cpts-ext-ts-inputs = <8>;
 	};
 
-	timesync_router: pinctrl@a40000 {
-		compatible = "pinctrl-single";
+	timesync_router: mux-controller@a40000 {
+		compatible = "reg-mux";
 		reg = <0x0 0xa40000 0x0 0x800>;
-		#pinctrl-cells = <1>;
-		pinctrl-single,register-width = <32>;
-		pinctrl-single,function-mask = <0x000107ff>;
+		#mux-control-cells = <1>;
+		status = "disabled";
 	};
 
 	usbss0: cdns-usb@f900000 {
@@ -825,6 +829,7 @@
 			cdns,fifo-depth = <256>;
 			cdns,fifo-width = <4>;
 			cdns,trigger-address = <0x0>;
+			cdns,phase-detect-selector = <2>;
 			#address-cells = <0x1>;
 			#size-cells = <0x0>;
 			clocks = <&k3_clks 75 6>;
@@ -1031,12 +1036,12 @@
 		reg = <0x00 0x0f102000 0x00 0x1000>,
 		      <0x00 0x0f100000 0x00 0x400>,
 		      <0x00 0x0d000000 0x00 0x00800000>,
-		      <0x00 0x68000000 0x00 0x00001000>;
+		      <0x06 0x00000000 0x00 0x00001000>; /* ECAM (4 KB) */
 		reg-names = "intd_cfg", "user_cfg", "reg", "cfg";
 		interrupt-names = "link_state";
 		interrupts = <GIC_SPI 203 IRQ_TYPE_EDGE_RISING>;
 		device_type = "pci";
-		ti,syscon-pcie-ctrl = <&main_conf 0x4070>;
+		ti,syscon-pcie-ctrl = <&pcie0_ctrl 0x0>;
 		max-link-speed = <2>;
 		num-lanes = <1>;
 		power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
@@ -1049,8 +1054,8 @@
 		vendor-id = <0x104c>;
 		device-id = <0xb010>;
 		msi-map = <0x0 &gic_its 0x0 0x10000>;
-		ranges = <0x01000000 0x00 0x68001000  0x00 0x68001000  0x00 0x0010000>,
-			 <0x02000000 0x00 0x68011000  0x00 0x68011000  0x00 0x7fef000>;
+		ranges = <0x01000000 0x00 0x00001000 0x06 0x00001000 0x00 0x00100000>, /* IO (1 MB) */
+			 <0x02000000 0x00 0x00101000 0x06 0x00101000 0x00 0xffeff000>; /* 32-bit Non-Prefetchable MEM (4 GB - 1 MB - 4 KB) */
 		dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x00000010 0x0>;
 		status = "disabled";
 	};
@@ -1175,6 +1180,33 @@
 		status = "disabled";
 	};
 
+	eqep0: counter@23200000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23200000 0x00 0x100>;
+		power-domains = <&k3_pds 59 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 59 0>;
+		interrupts = <GIC_SPI 116 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
+	eqep1: counter@23210000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23210000 0x00 0x100>;
+		power-domains = <&k3_pds 60 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 60 0>;
+		interrupts = <GIC_SPI 117 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
+	eqep2: counter@23220000 {
+		compatible = "ti,am62-eqep";
+		reg = <0x00 0x23220000 0x00 0x100>;
+		power-domains = <&k3_pds 62 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 62 0>;
+		interrupts = <GIC_SPI 118 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
+	};
+
 	main_rti0: watchdog@e000000 {
 		compatible = "ti,j7-rti-wdt";
 		reg = <0x00 0xe000000 0x00 0x100>;
@@ -1200,6 +1232,15 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges = <0x0 0x00 0x30000000 0x80000>;
+		clocks = <&k3_clks 81 0>,  /* icssg0_core_clk */
+			 <&k3_clks 81 3>,  /* icssg0_iep_clk */
+			 <&k3_clks 81 16>, /* icssg0_rgmii_mhz_250_clk */
+			 <&k3_clks 81 17>, /* icssg0_rgmii_mhz_50_clk */
+			 <&k3_clks 81 18>, /* icssg0_rgmii_mhz_5_clk */
+			 <&k3_clks 81 19>, /* icssg0_uart_clk */
+			 <&k3_clks 81 20>; /* icssg0_iclk */
+		assigned-clocks = <&k3_clks 81 0>;
+		assigned-clock-parents = <&k3_clks 81 2>;
 
 		icssg0_mem: memories@0 {
 			reg = <0x0 0x2000>,
@@ -1225,7 +1266,7 @@
 					clocks = <&k3_clks 81 0>,  /* icssg0_core_clk */
 						 <&k3_clks 81 20>; /* icssg0_iclk */
 					assigned-clocks = <&icssg0_coreclk_mux>;
-					assigned-clock-parents = <&k3_clks 81 20>;
+					assigned-clock-parents = <&k3_clks 81 0>;
 				};
 
 				icssg0_iepclk_mux: iepclk-mux@30 {
@@ -1239,6 +1280,15 @@
 			};
 		};
 
+		icssg0_uart: serial@28000 {
+			compatible = "ti,pruss-uart";
+			reg = <0x28000 0x40>;
+			clocks = <&k3_clks 81 19>;
+			interrupt-parent = <&icssg0_intc>;
+			interrupts = <6 6 6>;
+			status = "disabled";
+		};
+
 		icssg0_iep0: iep@2e000 {
 			compatible = "ti,am654-icss-iep";
 			reg = <0x2e000 0x1000>;
@@ -1261,6 +1311,11 @@
 			reg = <0x33000 0x1000>;
 		};
 
+		icssg0_pa_stats: pa-stats@2c000 {
+			compatible = "ti,pruss-pa-st", "syscon";
+			reg = <0x2c000 0x1000>;
+		};
+
 		icssg0_intc: interrupt-controller@20000 {
 			compatible = "ti,icssg-intc";
 			reg = <0x20000 0x2000>;
@@ -1365,6 +1420,15 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges = <0x0 0x00 0x30080000 0x80000>;
+		clocks = <&k3_clks 82 0>,  /* icssg1_core_clk */
+			 <&k3_clks 82 3>,  /* icssg1_iep_clk */
+			 <&k3_clks 82 16>, /* icssg1_rgmii_mhz_250_clk */
+			 <&k3_clks 82 17>, /* icssg1_rgmii_mhz_50_clk */
+			 <&k3_clks 82 18>, /* icssg1_rgmii_mhz_5_clk */
+			 <&k3_clks 82 19>, /* icssg1_uart_clk */
+			 <&k3_clks 82 20>; /* icssg1_iclk */
+		assigned-clocks = <&k3_clks 82 0>;
+		assigned-clock-parents = <&k3_clks 82 2>;
 
 		icssg1_mem: memories@0 {
 			reg = <0x0 0x2000>,
@@ -1390,7 +1454,7 @@
 					clocks = <&k3_clks 82 0>,   /* icssg1_core_clk */
 						 <&k3_clks 82 20>;  /* icssg1_iclk */
 					assigned-clocks = <&icssg1_coreclk_mux>;
-					assigned-clock-parents = <&k3_clks 82 20>;
+					assigned-clock-parents = <&k3_clks 82 0>;
 				};
 
 				icssg1_iepclk_mux: iepclk-mux@30 {
@@ -1404,6 +1468,15 @@
 			};
 		};
 
+		icssg1_uart: serial@28000 {
+			compatible = "ti,pruss-uart";
+			reg = <0x28000 0x40>;
+			clocks = <&k3_clks 82 19>;
+			interrupt-parent = <&icssg1_intc>;
+			interrupts = <6 6 6>;
+			status = "disabled";
+		};
+
 		icssg1_iep0: iep@2e000 {
 			compatible = "ti,am654-icss-iep";
 			reg = <0x2e000 0x1000>;
@@ -1426,6 +1499,11 @@
 			reg = <0x33000 0x1000>;
 		};
 
+		icssg1_pa_stats: pa-stats@2c000 {
+			compatible = "ti,pruss-pa-st", "syscon";
+			reg = <0x2c000 0x1000>;
+		};
+
 		icssg1_intc: interrupt-controller@20000 {
 			compatible = "ti,icssg-intc";
 			reg = <0x20000 0x2000>;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -161,4 +161,17 @@
 		/* Interrupt sources: esm0_cfg, esm0_hi, esm0_low, mrti0 */
 		ti,esm-pins = <0>, <1>, <2>, <85>;
 	};
+
+	mcu_m4fss: m4fss@5000000 {
+		compatible = "ti,am64-m4fss";
+		reg = <0x00 0x5000000 0x00 0x30000>,
+		      <0x00 0x5040000 0x00 0x10000>;
+		reg-names = "iram", "dram";
+		resets = <&k3_reset 9 1>;
+		firmware-name = "am64-mcu-m4f0_0-fw";
+		ti,sci = <&dmsc>;
+		ti,sci-dev-id = <9>;
+		ti,sci-proc-ids = <0x18 0xff>;
+		status = "disabled";
+	};
 };
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi	2025-10-23 09:30:40.282462115 -0400
@@ -87,6 +87,18 @@
 			reg = <0x00 0xa3100000 0x00 0xf00000>;
 			no-map;
 		};
+
+		mcu_m4fss_dma_memory_region: m4f-dma-memory@a4000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa4000000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_m4fss_memory_region: m4f-memory@a4100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa4100000 0x00 0xf00000>;
+			no-map;
+		};
 	};
 
 	leds {
@@ -240,6 +252,15 @@
 	};
 };
 
+&mailbox0_cluster6 {
+	status = "okay";
+
+	mbox_m4_0: mbox-m4-0 {
+		ti,mbox-rx = <0 0 2>;
+		ti,mbox-tx = <1 0 2>;
+	};
+};
+
 &main_i2c0 {
 	status = "okay";
 	pinctrl-names = "default";
@@ -333,6 +354,13 @@
 			<&main_r5fss1_core1_memory_region>;
 };
 
+&mcu_m4fss {
+	mboxes = <&mailbox0_cluster6 &mbox_m4_0>;
+	memory-region = <&mcu_m4fss_dma_memory_region>,
+			<&mcu_m4fss_memory_region>;
+	status = "okay";
+};
+
 &ospi0 {
 	status = "okay";
 	pinctrl-names = "default";
@@ -354,7 +382,6 @@
 
 &sdhci0 {
 	status = "okay";
-	bus-width = <8>;
 	non-removable;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am654-evm-oldi-lcd1evm.dtso b/arch/arm64/boot/dts/ti/k3-am654-evm-oldi-lcd1evm.dtso
--- a/arch/arm64/boot/dts/ti/k3-am654-evm-oldi-lcd1evm.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am654-evm-oldi-lcd1evm.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * OLDI-LCD1EVM Rocktech integrated panel and touch DT overlay for AM654-EVM.
+ *
+ * Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&{/} {
+	display0 {
+		compatible = "rocktech,rk101ii01d-ct";
+		backlight = <&lcd_bl>;
+		enable-gpios = <&pca9555 8 GPIO_ACTIVE_HIGH>;
+		port {
+			lcd_in0: endpoint {
+				remote-endpoint = <&oldi_out0>;
+			};
+		};
+	};
+	lcd_bl: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&ecap0 0 50000 PWM_POLARITY_INVERTED>;
+		brightness-levels =
+			<0 32 64 96 128 160 192 224 255>;
+		default-brightness-level = <8>;
+	};
+};
+
+&dss {
+	status = "okay";
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+
+		oldi_out0: endpoint {
+			remote-endpoint = <&lcd_in0>;
+		};
+	};
+};
+
+&main_i2c1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	gt928: touchscreen@14 {
+		status = "okay";
+		compatible = "goodix,gt928";
+		reg = <0x14>;
+
+		interrupt-parent = <&pca9554>;
+		interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+		touchscreen-size-x = <1280>;
+		touchscreen-size-y = <800>;
+
+		reset-gpios = <&pca9555 9 GPIO_ACTIVE_HIGH>;
+		irq-gpios = <&pca9554 3 GPIO_ACTIVE_HIGH>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso b/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso
--- a/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -41,6 +41,7 @@
 
 		ti,mii-g-rt = <&icssg2_mii_g_rt>;
 		ti,mii-rt = <&icssg2_mii_rt>;
+		ti,pa-stats = <&icssg2_pa_stats>;
 		ti,iep = <&icssg2_iep0>, <&icssg2_iep1>;
 
 		interrupt-parent = <&icssg2_intc>;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am654-idk.dtso b/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
--- a/arch/arm64/boot/dts/ti/k3-am654-idk.dtso	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am654-idk.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -43,6 +43,7 @@
 
 		ti,mii-g-rt = <&icssg0_mii_g_rt>;
 		ti,mii-rt = <&icssg0_mii_rt>;
+		ti,pa-stats = <&icssg0_pa_stats>;
 		ti,iep = <&icssg0_iep0>,  <&icssg0_iep1>;
 
 		interrupt-parent = <&icssg0_intc>;
@@ -109,6 +110,7 @@
 
 		ti,mii-g-rt = <&icssg1_mii_g_rt>;
 		ti,mii-rt = <&icssg1_mii_rt>;
+		ti,pa-stats = <&icssg1_pa_stats>;
 		ti,iep = <&icssg1_iep0>,  <&icssg1_iep1>;
 
 		interrupt-parent = <&icssg1_intc>;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -1169,6 +1169,11 @@
 			reg = <0x33000 0x1000>;
 		};
 
+		icssg0_pa_stats: pa-stats@2c000 {
+			compatible = "ti,pruss-pa-st", "syscon";
+			reg = <0x2c000 0x1000>;
+		};
+
 		icssg0_intc: interrupt-controller@20000 {
 			compatible = "ti,icssg-intc";
 			reg = <0x20000 0x2000>;
@@ -1335,6 +1340,11 @@
 			reg = <0x33000 0x1000>;
 		};
 
+		icssg1_pa_stats: pa-stats@2c000 {
+			compatible = "ti,pruss-pa-st", "syscon";
+			reg = <0x2c000 0x1000>;
+		};
+
 		icssg1_intc: interrupt-controller@20000 {
 			compatible = "ti,icssg-intc";
 			reg = <0x20000 0x2000>;
@@ -1501,6 +1511,11 @@
 			reg = <0x33000 0x1000>;
 		};
 
+		icssg2_pa_stats: pa-stats@2c000 {
+			compatible = "ti,pruss-pa-st", "syscon";
+			reg = <0x2c000 0x1000>;
+		};
+
 		icssg2_intc: interrupt-controller@20000 {
 			compatible = "ti,icssg-intc";
 			reg = <0x20000 0x2000>;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts	2025-10-23 09:30:40.283462146 -0400
@@ -10,7 +10,12 @@
 
 #include <dt-bindings/leds/common.h>
 #include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/phy/phy.h>
 #include "k3-j722s.dtsi"
+#include "k3-serdes.h"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "k3-am67a-beagley-ai-pinmux.dtsi"
 
 / {
 	compatible = "beagle,am67a-beagley-ai", "ti,j722s";
@@ -19,8 +24,12 @@
 	aliases {
 		serial0 = &wkup_uart0;
 		serial2 = &main_uart0;
+		serial3 = &main_uart1;
+		serial6 = &main_uart6;
 		mmc1 = &sdhci1;
+		mmc2 = &sdhci2;
 		rtc0 = &rtc;
+		i2c1 = &mcu_i2c0;
 	};
 
 	chosen {
@@ -40,6 +49,14 @@
 		#size-cells = <2>;
 		ranges;
 
+		/* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x38000000>;
+			linux,cma-default;
+		};
+
 		secure_tfa_ddr: tfa@9e780000 {
 			reg = <0x00 0x9e780000 0x00 0x80000>;
 			no-map;
@@ -50,11 +67,71 @@
 			no-map;
 		};
 
+		wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@a0000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0000000 0x00 0x100000>;
+			no-map;
+		};
+
 		wkup_r5fss0_core0_memory_region: r5f-memory@a0100000 {
 			compatible = "shared-dma-pool";
 			reg = <0x00 0xa0100000 0x00 0xf00000>;
 			no-map;
 		};
+
+		mcu_r5fss0_core0_dma_memory_region: mcu-r5fss-dma-memory-region@a1000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1000000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_r5fss0_core0_memory_region: mcu-r5fss-memory-region@a1100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss0_core0_dma_memory_region: main-r5fss-dma-memory-region@a2000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core0_memory_region: main-r5fss-memory-region@a2100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		c7x_0_dma_memory_region: c7x-dma-memory@a3000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3000000 0x00 0x100000>;
+			no-map;
+		};
+
+		c7x_0_memory_region: c7x-memory@a3100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		c7x_1_dma_memory_region: c7x-dma-memory@a4000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa4000000 0x00 0x100000>;
+			no-map;
+		};
+
+		c7x_1_memory_region: c7x-memory@a4100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa4100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		rtos_ipc_memory_region: ipc-memories@a5000000 {
+			reg = <0x00 0xa5000000 0x00 0x1c00000>;
+			alignment = <0x1000>;
+			no-map;
+		};
 	};
 
 	vsys_5v0: regulator-1 {
@@ -123,6 +200,20 @@
 		regulator-boot-on;
 	};
 
+	wlan_en: regulator-7 {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan_en";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+		/* regulator-always-on; */
+		regulator-off-in-suspend;
+		vin-supply = <&vdd_3v3>;
+		gpio = <&main_gpio0 4 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_en_pins_default>;
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -140,6 +231,22 @@
 			default-state = "on";
 		};
 	};
+
+	fan: cooling_fan {
+		compatible = "pwm-fan";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm_fan_pins>;
+		fan-supply = <&vsys_5v0>;
+		#cooling-cells = <2>;
+		cooling-min-state = <0>;
+		cooling-max-state = <3>;
+		cooling-levels = <0 75 125 175 250>;
+		pwms = <&epwm2 0 40000 0>;
+		pulses-per-revolution = <2>;
+		interrupt-parent = <&main_gpio1>;
+		interrupts = <22 IRQ_TYPE_EDGE_FALLING>;
+		status = "okay";
+	};
 };
 
 &main_pmx0 {
@@ -159,6 +266,14 @@
 		bootph-all;
 	};
 
+	main_uart1_pins_default: main-uart1-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x01ac, PIN_INPUT, 2) /* (C27) MCASP0_AFSR.UART1_RXD */
+			J722S_IOPAD(0x01b0, PIN_OUTPUT, 2) /* (F24) MCASP0_ACLKR.UART1_TXD */
+		>;
+		bootph-all;
+	};
+
 	vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
 		pinctrl-single,pins = <
 			J722S_IOPAD(0x0244, PIN_OUTPUT, 7) /* (A24) MMC1_SDWP.GPIO1_49 */
@@ -221,6 +336,46 @@
 			J722S_IOPAD(0x0254, PIN_OUTPUT, 7) /* (E25) USB0_DRVVBUS.GPIO1_50 */
 		>;
 	};
+
+	wifi_pins_default: wifi-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0120, PIN_INPUT, 0) /* (F27) MMC2_CMD */
+			J722S_IOPAD(0x0118, PIN_OUTPUT, 0) /* (H26) MMC2_CLK */
+			J722S_IOPAD(0x011C, PIN_INPUT, 0) /* () MMC2_CLKLB */
+			J722S_IOPAD(0x0114, PIN_INPUT, 0) /* (G26) MMC2_DAT0 */
+			J722S_IOPAD(0x0110, PIN_INPUT_PULLUP, 0) /* (G27) MMC2_DAT1 */
+			J722S_IOPAD(0x010c, PIN_INPUT_PULLUP, 0) /* (H27) MMC2_DAT2 */
+			J722S_IOPAD(0x0108, PIN_INPUT_PULLUP, 0) /* (J27) MMC2_DAT3 */
+		>;
+	};
+
+	wifi_en_pins_default: wifi-en-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0010, PIN_OUTPUT, 7) /* (L27) OSPI0_D1.GPIO0_4 */
+		>;
+	};
+
+	wifi_wlirq_pins_default: wifi-wlirq-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0014, PIN_INPUT, 7) /* (L26) OSPI0_D2.GPIO0_5 */
+		>;
+	};
+
+	pwm_fan_pins: pwm-fan-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0124, PIN_OUTPUT, 4) /* (F26) MMC2_SDCD.EHRPWM2_A FAN_PWM */
+			J722S_IOPAD(0x01d0, PIN_INPUT, 7) /* (E22) UART0_CTSn.GPIO1_22 FAN_TACH */
+		>;
+	};
+
+	main_uart6_pins_default: main-uart6-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0028, PIN_INPUT, 3)	/* (M27) OSPI0_D7.UART6_CTSn */
+			J722S_IOPAD(0x0024, PIN_OUTPUT, 3)	/* (N27) OSPI0_D6.UART6_RTSn */
+			J722S_IOPAD(0x001c, PIN_INPUT, 3)	/* (L21) OSPI0_D4.UART6_RXD */
+			J722S_IOPAD(0x0020, PIN_OUTPUT, 3)	/* (M26) OSPI0_D5.UART6_TXD */
+		>;
+	};
 };
 
 &cpsw3g {
@@ -248,7 +403,16 @@
 	status = "okay";
 };
 
+&main_gpio0 {
+	status = "okay";
+};
+
 &main_gpio1 {
+	bootph-all;
+	status = "okay";
+};
+
+&mcu_gpio0 {
 	status = "okay";
 };
 
@@ -259,7 +423,70 @@
 	status = "okay";
 };
 
+&main_uart1 {
+	symlink = "ttyAMA0";
+	//pinctrl-names = "default";
+	//pinctrl-0 = <&main_uart1_pins_default>;
+	bootph-all;
+	status = "okay";
+};
+
+&main_uart6 {
+	symlink = "board/bluetooth/uart";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart6_pins_default>;
+	bootph-all;
+	status = "okay";
+
+	bluetooth {
+		compatible = "ti,cc33xx-bt";
+		cc33xx-supply = <&wlan_en>;
+		max-speed = <115200>;
+	};
+};
+
+&main0_thermal {
+	trips {
+		main0_active0: trip-active0 {
+			temperature = <40000>;
+			hysteresis = <5000>;
+			type = "active";
+		};
+
+		main0_active1: trip-active1 {
+			temperature = <48000>;
+			hysteresis = <3000>;
+			type = "active";
+		};
+
+		main0_active2: trip-active2 {
+			temperature = <60000>;
+			hysteresis = <10000>;
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		map1 {
+			trip = <&main0_active0>;
+			cooling-device = <&fan 1 1>;
+		};
+
+		map2 {
+			trip = <&main0_active1>;
+			cooling-device = <&fan 2 2>;
+		};
+
+		map3 {
+			trip = <&main0_active2>;
+			cooling-device = <&fan 3 3>;
+		};
+	};
+};
+
 &mcu_pmx0 {
+	bootph-all;
+
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
 			J722S_MCU_IOPAD(0x02c, PIN_INPUT, 0)	/* (C7) WKUP_UART0_CTSn */
@@ -277,6 +504,29 @@
 		>;
 		bootph-all;
 	};
+
+	wifi_32k_clk: mcu-clk-out-default-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x0084, PIN_OUTPUT, 0) /* (F12) WKUP_CLKOUT0 */
+		>;
+	};
+
+	pcie_pins_default: pcie-default-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x0018, PIN_OUTPUT, 7)	/* (B4) MCU_UART0_TXD.MCU_GPIO0_6 */
+			J722S_MCU_IOPAD(0x0014, PIN_INPUT, 7)	/* (B8) MCU_UART0_RXD.MCU_GPIO0_5 */ /* PCIE_DET_WAKE */
+			J722S_MCU_IOPAD(0x0020, PIN_OUTPUT, 7)	/* (C5) MCU_UART0_RTSn.MCU_GPIO0_8 */ /* PCIE_PWR_EN */
+		>;
+		bootph-all;
+	};
+
+	mcu_i2c0_pins_default: mcu-i2c0-default-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x0044, PIN_INPUT_PULLUP, 0) /* (B13) MCU_I2C0_SCL */
+			J722S_MCU_IOPAD(0x0048, PIN_INPUT_PULLUP, 0) /* (E11) MCU_I2C0_SDA */
+		>;
+		bootph-all;
+	};
 };
 
 &wkup_uart0 {
@@ -287,6 +537,15 @@
 	status = "reserved";
 };
 
+&mcu_i2c0 {
+	symlink = "hat/mcu_i2c0";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_i2c0_pins_default>;
+	clock-frequency = <100000>;
+	bootph-all;
+	status = "okay";
+};
+
 &wkup_i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&wkup_i2c0_pins_default>;
@@ -391,3 +650,166 @@
 	ti,fails-without-test-cd;
 	status = "okay";
 };
+
+&sdhci2 {
+	vmmc-supply = <&wlan_en>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&wifi_pins_default>, <&wifi_32k_clk>;
+	bus-width = <4>;
+	non-removable;
+	ti,fails-without-test-cd;
+	cap-power-off-card;
+	keep-power-in-suspend;
+	ti,driver-strength-ohm = <50>;
+	assigned-clocks = <&k3_clks 157 174>;
+	assigned-clock-parents = <&k3_clks 157 175>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	cc33xx: cc33xx@0 {
+		//compatible = "ti,cc3301";
+		compatible = "ti,cc3300";
+		reg = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_wlirq_pins_default>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <5 IRQ_TYPE_EDGE_RISING>;
+	};
+};
+
+&mailbox0_cluster0 {
+	status = "okay";
+
+	mbox_wkup_r5_0: mbox-wkup-r5-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&mailbox0_cluster1 {
+	status = "okay";
+
+	mbox_mcu_r5_0: mbox-mcu-r5-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&mailbox0_cluster2 {
+	status = "okay";
+
+	mbox_c7x_0: mbox-c7x-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&mailbox0_cluster3 {
+	status = "okay";
+
+	mbox_main_r5_0: mbox-main-r5-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+
+	mbox_c7x_1: mbox-c7x-1 {
+		ti,mbox-rx = <2 0 0>;
+		ti,mbox-tx = <3 0 0>;
+	};
+};
+
+/* Timers are used by Remoteproc firmware */
+&main_timer0 {
+	status = "reserved";
+};
+
+&main_timer1 {
+	status = "reserved";
+};
+
+&main_timer2 {
+	status = "reserved";
+};
+
+&wkup_r5fss0 {
+	status = "okay";
+};
+
+&wkup_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster0 &mbox_wkup_r5_0>;
+	memory-region = <&wkup_r5fss0_core0_dma_memory_region>,
+			<&wkup_r5fss0_core0_memory_region>;
+};
+
+&mcu_r5fss0 {
+	status = "okay";
+};
+
+&mcu_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster1 &mbox_mcu_r5_0>;
+	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
+			<&mcu_r5fss0_core0_memory_region>;
+};
+
+&main_r5fss0 {
+	status = "okay";
+};
+
+&main_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster3 &mbox_main_r5_0>;
+	memory-region = <&main_r5fss0_core0_dma_memory_region>,
+			<&main_r5fss0_core0_memory_region>;
+};
+
+&c7x_0 {
+	mboxes = <&mailbox0_cluster2 &mbox_c7x_0>;
+	memory-region = <&c7x_0_dma_memory_region>,
+			<&c7x_0_memory_region>;
+	status = "okay";
+};
+
+&c7x_1 {
+	mboxes = <&mailbox0_cluster3 &mbox_c7x_1>;
+	memory-region = <&c7x_1_dma_memory_region>,
+			<&c7x_1_memory_region>;
+	status = "okay";
+};
+
+&serdes_ln_ctrl {
+	idle-states = <J722S_SERDES0_LANE0_USB>,
+		      <J722S_SERDES1_LANE0_PCIE0_LANE0>;
+};
+
+&serdes0 {
+	status = "okay";
+	serdes0_usb_link: phy@0 {
+		reg = <0>;
+		cdns,num-lanes = <1>;
+		#phy-cells = <0>;
+		cdns,phy-type = <PHY_TYPE_USB3>;
+		resets = <&serdes_wiz0 1>;
+	};
+};
+
+&serdes1 {
+	serdes1_pcie_link: phy@0 {
+		reg = <0>;
+		cdns,num-lanes = <1>;
+		#phy-cells = <0>;
+		cdns,phy-type = <PHY_TYPE_PCIE>;
+		resets = <&serdes_wiz1 1>;
+	};
+};
+
+&pcie0_rc {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie_pins_default>;
+	phys = <&serdes1_pcie_link>;
+	phy-names = "pcie-phy";
+	num-lanes = <1>;
+	max-link-speed = <3>;
+	reset-gpios = <&mcu_gpio0 6 GPIO_ACTIVE_HIGH>;
+	enable-gpios = <&mcu_gpio0 8 GPIO_ACTIVE_HIGH>; /* Extra GPIO for pwr_en for BeagleY AI */
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-400000.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-400000.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-400000.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-400000.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for I2C1 at 400000 within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-i2c1-400000.kernel = __TIMESTAMP__;
+	};
+};
+
+&mcu_i2c0 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-ads1115.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-ads1115.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-ads1115.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-ads1115.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for I2C1 with Gravity: I2C ADS1115 16-Bit ADC Module
+ * https://www.dfrobot.com/product-1730.html
+ * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml
+ *
+ * Copyright (C) 2024 Robert Nelson, BeagleBoard.org Foundation
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-i2c1-ads1115.kernel = __TIMESTAMP__;
+	};
+};
+
+&mcu_i2c0 {
+	status = "okay";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	adc@48 {
+		compatible = "ti,ads1115";
+		reg = <0x48>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		channel@4 {
+			reg = <4>;
+			ti,gain = <1>;
+			ti,datarate = <7>;
+		};
+
+		channel@5 {
+			reg = <5>;
+			ti,gain = <1>;
+			ti,datarate = <7>;
+		};
+
+		channel@6 {
+			reg = <6>;
+			ti,gain = <1>;
+			ti,datarate = <7>;
+		};
+
+		channel@7 {
+			reg = <7>;
+			ti,gain = <1>;
+			ti,datarate = <7>;
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-rtc-rv3028.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-rtc-rv3028.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-rtc-rv3028.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-rtc-rv3028.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ *
+ * Copyright (C) 2025 Robert Nelson, BeagleBoard.org Foundation
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-i2c1-rtc-rv3028.kernel = __TIMESTAMP__;
+	};
+};
+
+&{/aliases} {
+	rtc0 = &rv3028;
+	/* find /sys/firmware/devicetree/ | grep rtc@ */
+	/* rtc-ds1307 beagley-ai battery connector */
+	rtc1 = "/bus@f0000/bus@b00000/i2c@2b200000/rtc@68";
+	/* rtc-ti-k3 k3 internal */
+	rtc2 = "/bus@f0000/bus@b00000/rtc@2b1f0000";
+};
+
+&mcu_i2c0 {
+	status = "okay";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	rv3028: rv3028@52 {
+		compatible = "microcrystal,rv3028";
+		reg = <0x52>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-ssd1306.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-ssd1306.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-ssd1306.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-i2c1-ssd1306.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,30 @@
+/dts-v1/;
+/plugin/;
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+        overlays {
+                k3-am67a-beagley-ai-i2c1-ssd1306.kernel = __TIMESTAMP__;
+        };
+};
+
+&mcu_i2c0 {
+	status = "okay";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+        ssd1306@3c {
+                compatible = "solomon,ssd1306fb-i2c";
+                reg = <0x3c>;
+                solomon,height = <64>;
+                solomon,width = <128>;
+                solomon,com-invdir;
+                solomon,page-offset = <0>;
+        };
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-mikroe-eth.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-mikroe-eth.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-mikroe-eth.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-mikroe-eth.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for mikroe on BeagleY-AI board.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-mikroe-eth.kernel = __TIMESTAMP__;
+	};
+};
+
+&spi_gpio {
+	compatible = "spi-gpio";
+	#address-cells = <0x1>;
+	#size-cells = <0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_gpio_default_pins>;
+
+	sck-gpios = <&mcu_gpio0 2 GPIO_ACTIVE_HIGH>;
+	miso-gpios = <&mcu_gpio0 4 GPIO_ACTIVE_HIGH>;
+	mosi-gpios = <&mcu_gpio0 3 GPIO_ACTIVE_HIGH>;
+
+	num-chipselects = <1>;
+	cs-gpios = <
+		&mcu_gpio0 0 GPIO_ACTIVE_HIGH
+	>;
+
+	status = "okay";
+
+	enc28j60@0 {
+		compatible = "microchip,enc28j60";
+		reg = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&hat_31_gpio>;
+		interrupt-parent = <&main_gpio1>;
+		interrupts = <17 IRQ_TYPE_EDGE_FALLING>;
+		spi-max-frequency = <100000>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-mikroe-microsd.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-mikroe-microsd.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-mikroe-microsd.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-mikroe-microsd.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for mikroe on BeagleY-AI board.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-mikroe-eth.kernel = __TIMESTAMP__;
+	};
+};
+
+&spi_gpio {
+	compatible = "spi-gpio";
+	#address-cells = <0x1>;
+	#size-cells = <0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_gpio_default_pins>;
+
+	sck-gpios = <&mcu_gpio0 2 GPIO_ACTIVE_HIGH>;
+	miso-gpios = <&mcu_gpio0 4 GPIO_ACTIVE_HIGH>;
+	mosi-gpios = <&mcu_gpio0 3 GPIO_ACTIVE_HIGH>;
+
+	num-chipselects = <1>;
+	cs-gpios = <
+		&mcu_gpio0 0 GPIO_ACTIVE_LOW
+	>;
+
+	status = "okay";
+
+	mmc-slot@0 {
+		compatible = "mmc-spi-slot";
+		reg = <0>;
+		voltage-ranges = <3300 3300>;
+		spi-max-frequency = <100000>;
+		disable-wp;
+		broken-cd;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pinmux.dtsi b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pinmux.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pinmux.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pinmux.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,964 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * https://beagley-ai.org/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2024 Robert Nelson, BeagleBoard.org Foundation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	chosen {
+		base_dtb = "k3-am67a-beagley-ai.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
+
+	leds {
+		led-0 {
+			color = <LED_COLOR_ID_RED>;
+			label = "PWR";
+		};
+
+		led-1 {
+			color = <LED_COLOR_ID_GREEN>;
+			label = "ACT";
+		};
+	};
+};
+
+&main_pmx0 {
+	pinctrl-single,gpio-range =
+		<&main_pmx0_range 0 32 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 33 38 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 72 17 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 101 25 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 137 5 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 143 3 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 149 2 PIN_GPIO_RANGE_IOPAD>;
+
+	main_pmx0_range: gpio-range {
+		#pinctrl-single,gpio-range-cells = <3>;
+	};
+
+	hat_07_uart6_rxd: hat-07-uart6-rxd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x09C, PIN_INPUT, 3) /* (W26) GPMC0_WAIT1.UART6_RXD */
+		>;
+	};
+
+	hat_07_gpio: hat-07-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x09C, PIN_INPUT, 7) /* (W26) GPMC0_WAIT1.GPIO0_38 */
+		>;
+	};
+
+	hat_07_gpio_pu: hat-07-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x09C, PIN_INPUT_PULLUP, 7) /* (W26) GPMC0_WAIT1.GPIO0_38 */
+		>;
+	};
+
+	hat_07_gpio_pd: hat-07-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x09C, PIN_INPUT_PULLDOWN, 7) /* (W26) GPMC0_WAIT1.GPIO0_38 */
+		>;
+	};
+
+	hat_08_audio: hat-08-audio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B0, PIN_INPUT, 0) /* (F24) MCASP0_ACLKR */
+		>;
+	};
+
+	hat_08_spi: hat-08-spi-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B0, PIN_INPUT, 1) /* (F24) MCASP0_ACLKR.SPI2_CLK */
+		>;
+	};
+
+	hat_08_uart1_txd: hat-08-uart1-txd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B0, PIN_OUTPUT, 2) /* (F24) MCASP0_ACLKR.UART1_TXD */
+		>;
+	};
+
+	hat_08_pwm: hat-08-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B0, PIN_OUTPUT, 6) /* (F24) MCASP0_ACLKR.EHRPWM0_B */
+		>;
+	};
+
+	hat_08_gpio: hat-08-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B0, PIN_INPUT, 7) /* (F24) MCASP0_ACLKR.GPIO1_14 */
+		>;
+	};
+
+	hat_08_gpio_pu: hat-08-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B0, PIN_INPUT_PULLUP, 7) /* (F24) MCASP0_ACLKR.GPIO1_14 */
+		>;
+	};
+
+	hat_08_gpio_pd: hat-08-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B0, PIN_INPUT_PULLDOWN, 7) /* (F24) MCASP0_ACLKR.GPIO1_14 */
+		>;
+	};
+
+	hat_08_eqep: hat-08-eqep-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B0, PIN_INPUT, 8) /* (F24) MCASP0_ACLKR.EQEP1_I */
+		>;
+	};
+
+	hat_10_audio: hat-10-audio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1AC, PIN_INPUT, 0) /* (C27) MCASP0_AFSR */
+		>;
+	};
+
+	hat_10_spi: hat-10-spi-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1AC, PIN_INPUT, 1) /* (C27) MCASP0_AFSR.SPI2_CS0 */
+		>;
+	};
+
+	hat_10_uart1_rxd: hat-10-uart1-rxd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1AC, PIN_INPUT, 2) /* (C27) MCASP0_AFSR.UART1_RXD */
+		>;
+	};
+
+	hat_10_pwm: hat-10-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1AC, PIN_OUTPUT, 6) /* (C27) MCASP0_AFSR.EHRPWM0_A */
+		>;
+	};
+
+	hat_10_gpio: hat-10-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1AC, PIN_INPUT, 7) /* (C27) MCASP0_AFSR.GPIO1_13 */
+		>;
+	};
+
+	hat_10_gpio_pu: hat-10-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1AC, PIN_INPUT_PULLUP, 7) /* (C27) MCASP0_AFSR.GPIO1_13 */
+		>;
+	};
+
+	hat_10_gpio_pd: hat-10-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1AC, PIN_INPUT_PULLDOWN, 7) /* (C27) MCASP0_AFSR.GPIO1_13 */
+		>;
+	};
+
+	hat_10_eqep: hat-10-eqep-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1AC, PIN_INPUT, 8) /* (C27) MCASP0_AFSR.EQEP1_S */
+		>;
+	};
+
+	hat_11_audio: hat-11-audio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x198, PIN_INPUT, 0) /* (A26) MCASP0_AXR2 */
+		>;
+	};
+
+	hat_11_spi: hat-11-spi-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x198, PIN_INPUT, 1) /* (A26) MCASP0_AXR2.SPI2_D1 */
+		>;
+	};
+
+	/* USED by BLE */
+	hat_11_uart6_txd: hat-11-uart6-txd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x198, PIN_OUTPUT, 3) /* (A26) MCASP0_AXR2.UART6_TXD */
+		>;
+	};
+
+	hat_11_pwm_ecap: hat-11-pwm-ecap-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x198, PIN_OUTPUT, 5) /* (A26) MCASP0_AXR2.ECAP2_IN_APWM_OUT */
+		>;
+	};
+
+	hat_11_gpio: hat-11-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x198, PIN_INPUT, 7) /* (A26) MCASP0_AXR2.GPIO1_8 */
+		>;
+	};
+
+	hat_11_gpio_pu: hat-11-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x198, PIN_INPUT_PULLUP, 7) /* (A26) MCASP0_AXR2.GPIO1_8 */
+		>;
+	};
+
+	hat_11_gpio_pd: hat-11-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x198, PIN_INPUT_PULLDOWN, 7) /* (A26) MCASP0_AXR2.GPIO1_8 */
+		>;
+	};
+
+	hat_11_eqep: hat-11-eqep-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x198, PIN_INPUT, 8) /* (A26) MCASP0_AXR2.EQEP0_B */
+		>;
+	};
+
+	hat_12_audio: hat-12-audio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A4, PIN_INPUT, 0) /* (D25) MCASP0_ACLKX */
+		>;
+	};
+
+	hat_12_spi: hat-12-spi-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A4, PIN_INPUT, 1) /* (D25) MCASP0_ACLKX.SPI2_CS1 */
+		>;
+	};
+
+	hat_12_pwm_ecap: hat-12-pwm-ecap-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A4, PIN_OUTPUT, 2) /* (D25) MCASP0_ACLKX.ECAP2_IN_APWM_OUT */
+		>;
+	};
+
+	hat_12_gpio: hat-12-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A4, PIN_INPUT, 7) /* (D25) MCASP0_ACLKX.GPIO1_11 */
+		>;
+	};
+
+	hat_12_gpio_pu: hat-12-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A4, PIN_INPUT_PULLUP, 7) /* (D25) MCASP0_ACLKX.GPIO1_11 */
+		>;
+	};
+
+	hat_12_gpio_pd: hat-12-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A4, PIN_INPUT_PULLDOWN, 7) /* (D25) MCASP0_ACLKX.GPIO1_11 */
+		>;
+	};
+
+	hat_12_eqep: hat-12-eqep-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A4, PIN_INPUT, 8) /* (D25) MCASP0_ACLKX.EQEP1_A */
+		>;
+	};
+
+	hat_13_audio: hat-13-audio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x088, PIN_INPUT, 2) /* (N22) GPMC0_OEn_REn.MCASP1_AXR1 */
+		>;
+	};
+
+	hat_13_gpio: hat-13-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x088, PIN_INPUT, 7) /* (N22) GPMC0_OEn_REn.GPIO0_33 */
+		>;
+	};
+
+	hat_13_gpio_pu: hat-13-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x088, PIN_INPUT_PULLUP, 7) /* (N22) GPMC0_OEn_REn.GPIO0_33 */
+		>;
+	};
+
+	hat_13_gpio_pd: hat-13-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x088, PIN_INPUT_PULLDOWN, 7) /* (N22) GPMC0_OEn_REn.GPIO0_33 */
+		>;
+	};
+
+	hat_15_i2c: hat-15-i2c-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0A8, PIN_INPUT_PULLUP, 1) /* (R27) GPMC0_CSn0.I2C4_SCL */
+		>;
+	};
+
+	hat_15_audio: hat-15-audio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0A8, PIN_INPUT, 3) /* (R27) GPMC0_CSn0.MCASP2_AXR14 */
+		>;
+	};
+
+	hat_15_gpio: hat-15-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0A8, PIN_INPUT, 7) /* (R27) GPMC0_CSn0.GPIO0_41 */
+		>;
+	};
+
+	hat_15_gpio_pu: hat-15-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0A8, PIN_INPUT_PULLUP, 7) /* (R27) GPMC0_CSn0.GPIO0_41 */
+		>;
+	};
+
+	hat_15_gpio_pd: hat-15-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0A8, PIN_INPUT_PULLDOWN, 7) /* (R27) GPMC0_CSn0.GPIO0_41 */
+		>;
+	};
+
+	hat_22_i2c: hat-22-i2c-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0AC, PIN_INPUT_PULLUP, 1) /* (P21) GPMC0_CSn1.I2C4_SDA */
+		>;
+	};
+
+	hat_22_audio: hat-22-audio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0AC, PIN_INPUT, 3) /* (P21) GPMC0_CSn1.MCASP2_AXR15 */
+		>;
+	};
+
+	hat_22_gpio: hat-22-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0AC, PIN_INPUT, 7) /* (P21) GPMC0_CSn1.GPIO0_42 */
+		>;
+	};
+
+	hat_22_gpio_pu: hat-22-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0AC, PIN_INPUT_PULLUP, 7) /* (P21) GPMC0_CSn1.GPIO0_42 */
+		>;
+	};
+
+	hat_22_gpio_pd: hat-22-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0AC, PIN_INPUT_PULLDOWN, 7) /* (P21) GPMC0_CSn1.GPIO0_42 */
+		>;
+	};
+
+	hat_29_pwm: hat-29-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B4, PIN_OUTPUT, 2) /* (B20) SPI0_CS0.EHRPWM0_A */
+		>;
+	};
+
+	hat_29_gpio: hat-29-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B4, PIN_INPUT, 7) /* (B20) SPI0_CS0.GPIO1_15 */
+		>;
+	};
+
+	hat_29_gpio_pu: hat-29-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B4, PIN_INPUT_PULLUP, 7) /* (B20) SPI0_CS0.GPIO1_15 */
+		>;
+	};
+
+	hat_29_gpio_pd: hat-29-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B4, PIN_INPUT_PULLDOWN, 7) /* (B20) SPI0_CS0.GPIO1_15 */
+		>;
+	};
+
+	hat_31_pwm: hat-31-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1BC, PIN_OUTPUT, 2) /* (D20) SPI0_CLK.EHRPWM1_A */
+		>;
+	};
+
+	hat_31_gpio: hat-31-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1BC, PIN_INPUT, 7) /* (D20) SPI0_CLK.GPIO1_17 */
+		>;
+	};
+
+	hat_31_gpio_pu: hat-31-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1BC, PIN_INPUT_PULLUP, 7) /* (D20) SPI0_CLK.GPIO1_17 */
+		>;
+	};
+
+	hat_31_gpio_pd: hat-31-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1BC, PIN_INPUT_PULLDOWN, 7) /* (D20) SPI0_CLK.GPIO1_17 */
+		>;
+	};
+
+	hat_32_pwm: hat-32-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B8, PIN_OUTPUT, 2) /* (C20) SPI0_CS1.EHRPWM0_B */
+		>;
+	};
+
+	hat_32_pwm_ecap: hat-32-pwm-ecap-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B8, PIN_OUTPUT, 3) /* (C20) SPI0_CS1.ECAP0_IN_APWM_OUT */
+		>;
+	};
+
+	hat_32_gpio: hat-32-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B8, PIN_INPUT, 7) /* (C20) SPI0_CS1.GPIO1_16 */
+		>;
+	};
+
+	hat_32_gpio_pu: hat-32-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B8, PIN_INPUT_PULLUP, 7) /* (C20) SPI0_CS1.GPIO1_16 */
+		>;
+	};
+
+	hat_32_gpio_pd: hat-32-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B8, PIN_INPUT_PULLDOWN, 7) /* (C20) SPI0_CS1.GPIO1_16 */
+		>;
+	};
+
+	hat_33_pwm: hat-33-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1C0, PIN_OUTPUT, 2) /* (E19) SPI0_D0.EHRPWM1_B */
+		>;
+	};
+
+	hat_33_gpio: hat-33-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1C0, PIN_INPUT, 7) /* (E19) SPI0_D0.GPIO1_18 */
+		>;
+	};
+
+	hat_33_gpio_pu: hat-33-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1C0, PIN_INPUT_PULLUP, 7) /* (E19) SPI0_D0.GPIO1_18 */
+		>;
+	};
+
+	hat_33_gpio_pd: hat-33-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1C0, PIN_INPUT_PULLDOWN, 7) /* (E19) SPI0_D0.GPIO1_18 */
+		>;
+	};
+
+	hat_35_audio: hat-35-audio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A8, PIN_INPUT, 0) /* (C26) MCASP0_AFSX */
+		>;
+	};
+
+	hat_35_spi: hat-35-spi-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A8, PIN_INPUT, 1) /* (C26) MCASP0_AFSX.SPI2_CS3 */
+		>;
+	};
+
+	hat_35_gpio: hat-35-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A8, PIN_INPUT, 7) /* (C26) MCASP0_AFSX.GPIO1_12 */
+		>;
+	};
+
+	hat_35_gpio_pu: hat-35-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A8, PIN_INPUT_PULLUP, 7) /* (C26) MCASP0_AFSX.GPIO1_12 */
+		>;
+	};
+
+	hat_35_gpio_pd: hat-35-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A8, PIN_INPUT_PULLDOWN, 7) /* (C26) MCASP0_AFSX.GPIO1_12 */
+		>;
+	};
+
+	hat_35_eqep: hat-35-eqep-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A8, PIN_INPUT, 8) /* (C26) MCASP0_AFSX.EQEP1_B */
+		>;
+	};
+
+	hat_36_audio: hat-36-audio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x194, PIN_INPUT, 0) /* (A25) MCASP0_AXR3 */
+		>;
+	};
+
+	hat_36_spi: hat-36-spi-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x194, PIN_INPUT, 1) /* (A25) MCASP0_AXR3.SPI2_D0 */
+		>;
+	};
+
+	/* USED by BLE */
+	hat_36_uart6_rxd: hat-36-uart6-rxd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x194, PIN_INPUT, 3) /* (A25) MCASP0_AXR3.UART6_RXD */
+		>;
+	};
+
+	hat_36_pwm_ecap: hat-36-pwm-ecap-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x194, PIN_OUTPUT, 5) /* (A25) MCASP0_AXR3.ECAP1_IN_APWM_OUT */
+		>;
+	};
+
+	hat_36_gpio: hat-36-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x194, PIN_INPUT, 7) /* (A25) MCASP0_AXR3.GPIO1_7 */
+		>;
+	};
+
+	hat_36_gpio_pu: hat-36-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x194, PIN_INPUT_PULLUP, 7) /* (A25) MCASP0_AXR3.GPIO1_7 */
+		>;
+	};
+
+	hat_36_gpio_pd: hat-36-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x194, PIN_INPUT_PULLDOWN, 7) /* (A25) MCASP0_AXR3.GPIO1_7 */
+		>;
+	};
+
+	hat_36_eqep: hat-36-eqep-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x194, PIN_INPUT, 8) /* (A25) MCASP0_AXR3.EQEP0_A */
+		>;
+	};
+
+	hat_37_audio: hat-37-audio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x094, PIN_INPUT, 3) /* (P26) GPMC0_BE1n.MCASP2_AXR12 */
+		>;
+	};
+
+	hat_37_gpio: hat-37-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x094, PIN_INPUT, 7) /* (P26) GPMC0_BE1n.GPIO0_36 */
+		>;
+	};
+
+	hat_37_gpio_pu: hat-37-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x094, PIN_INPUT_PULLUP, 7) /* (P26) GPMC0_BE1n.GPIO0_36 */
+		>;
+	};
+
+	hat_37_gpio_pd: hat-37-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x094, PIN_INPUT_PULLDOWN, 7) /* (P26) GPMC0_BE1n.GPIO0_36 */
+		>;
+	};
+
+	hat_38_audio: hat-38-audio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A0, PIN_INPUT, 0) /* (F23) MCASP0_AXR0 */
+		>;
+	};
+
+	hat_38_pwm: hat-38-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A0, PIN_OUTPUT, 6) /* (F23) MCASP0_AXR0.EHRPWM1_B */
+		>;
+	};
+
+	hat_38_gpio: hat-38-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A0, PIN_INPUT, 7) /* (F23) MCASP0_AXR0.GPIO1_10 */
+		>;
+	};
+
+	hat_38_gpio_pu: hat-38-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A0, PIN_INPUT_PULLUP, 7) /* (F23) MCASP0_AXR0.GPIO1_10 */
+		>;
+	};
+
+	hat_38_gpio_pd: hat-38-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A0, PIN_INPUT_PULLDOWN, 7) /* (F23) MCASP0_AXR0.GPIO1_10 */
+		>;
+	};
+
+	hat_38_eqep: hat-38-eqep-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A0, PIN_INPUT, 8) /* (F23) MCASP0_AXR0.EQEP0_I */
+		>;
+	};
+
+	hat_40_audio: hat-40-audio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x19C, PIN_INPUT, 0) /* (B25) MCASP0_AXR1 */
+		>;
+	};
+
+	hat_40_spi: hat-40-spi-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x19C, PIN_INPUT, 1) /* (B25) MCASP0_AXR1.SPI2_CS2 */
+		>;
+	};
+
+	hat_40_pwm_ecap: hat-40-pwm-ecap-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x19C, PIN_OUTPUT, 2) /* (B25) MCASP0_AXR1.ECAP1_IN_APWM_OUT */
+		>;
+	};
+
+	hat_40_pwm: hat-40-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x19C, PIN_OUTPUT, 6) /* (B25) MCASP0_AXR1.EHRPWM1_A */
+		>;
+	};
+
+	hat_40_gpio: hat-40-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x19C, PIN_INPUT, 7) /* (B25) MCASP0_AXR1.GPIO1_9 */
+		>;
+	};
+
+	hat_40_gpio_pu: hat-40-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x19C, PIN_INPUT_PULLUP, 7) /* (B25) MCASP0_AXR1.GPIO1_9 */
+		>;
+	};
+
+	hat_40_gpio_pd: hat-40-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x19C, PIN_INPUT_PULLDOWN, 7) /* (B25) MCASP0_AXR1.GPIO1_9 */
+		>;
+	};
+
+	hat_40_eqep: hat-40-eqep-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x19C, PIN_INPUT, 8) /* (B25) MCASP0_AXR1.EQEP0_S */
+		>;
+	};
+
+};
+
+&mcu_pmx0 {
+	pinctrl-single,gpio-range =
+		<&mcu_pmx_range 0 21 PIN_GPIO_RANGE_IOPAD>,
+		<&mcu_pmx_range 23 1 PIN_GPIO_RANGE_IOPAD>,
+		<&mcu_pmx_range 32 2 PIN_GPIO_RANGE_IOPAD>;
+
+	mcu_pmx_range: gpio-range {
+		#pinctrl-single,gpio-range-cells = <3>;
+	};
+
+	hat_03_i2c: hat-03-i2c-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x048, PIN_INPUT_PULLUP, 0) /* (E11) MCU_I2C0_SDA */
+		>;
+	};
+
+	hat_03_gpio: hat-03-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x048, PIN_INPUT, 7) /* (E11) MCU_I2C0_SDA.MCU_GPIO0_18 */
+		>;
+	};
+
+	hat_03_gpio_pu: hat-03-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x048, PIN_INPUT_PULLUP, 7) /* (E11) MCU_I2C0_SDA.MCU_GPIO0_18 */
+		>;
+	};
+
+	hat_03_gpio_pd: hat-03-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x048, PIN_INPUT_PULLDOWN, 7) /* (E11) MCU_I2C0_SDA.MCU_GPIO0_18 */
+		>;
+	};
+
+	hat_05_i2c: hat-05-i2c-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x044, PIN_INPUT_PULLUP, 0) /* (B13) MCU_I2C0_SCL */
+		>;
+	};
+
+	hat_05_gpio: hat-05-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x044, PIN_INPUT, 7) /* (B13) MCU_I2C0_SCL.MCU_GPIO0_17 */
+		>;
+	};
+
+	hat_05_gpio_pu: hat-05-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x044, PIN_INPUT_PULLUP, 7) /* (B13) MCU_I2C0_SCL.MCU_GPIO0_17 */
+		>;
+	};
+
+	hat_05_gpio_pd: hat-05-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x044, PIN_INPUT_PULLDOWN, 7) /* (B13) MCU_I2C0_SCL.MCU_GPIO0_17 */
+		>;
+	};
+
+	hat_16_gpio: hat-16-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x01C, PIN_INPUT, 7) /* (B5) MCU_UART0_CTSn.MCU_GPIO0_7 */
+		>;
+	};
+
+	hat_16_gpio_pu: hat-16-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x01C, PIN_INPUT_PULLUP, 7) /* (B5) MCU_UART0_CTSn.MCU_GPIO0_7 */
+		>;
+	};
+
+	hat_16_gpio_pd: hat-16-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x01C, PIN_INPUT_PULLDOWN, 7) /* (B5) MCU_UART0_CTSn.MCU_GPIO0_7 */
+		>;
+	};
+
+	/* Device Manager firmware */
+	hat_18_wkup_uart0_txd: hat-18-wkup-uart0-txd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x028, PIN_OUTPUT, 0) /* (C8) WKUP_UART0_TXD */
+		>;
+	};
+
+	hat_18_gpio: hat-18-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x028, PIN_INPUT, 7) /* (C8) WKUP_UART0_TXD.MCU_GPIO0_10 */
+		>;
+	};
+
+	hat_18_gpio_pu: hat-18-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x028, PIN_INPUT_PULLUP, 7) /* (C8) WKUP_UART0_TXD.MCU_GPIO0_10 */
+		>;
+	};
+
+	hat_18_gpio_pd: hat-18-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x028, PIN_INPUT_PULLDOWN, 7) /* (C8) WKUP_UART0_TXD.MCU_GPIO0_10 */
+		>;
+	};
+
+	hat_19_gpio: hat-19-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x00C, PIN_INPUT, 7) /* (B12) MCU_SPI0_D0.MCU_GPIO0_3 */
+		>;
+	};
+
+	hat_19_gpio_pu: hat-19-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x00C, PIN_INPUT_PULLUP, 7) /* (B12) MCU_SPI0_D0.MCU_GPIO0_3 */
+		>;
+	};
+
+	hat_19_gpio_pd: hat-19-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x00C, PIN_INPUT_PULLDOWN, 7) /* (B12) MCU_SPI0_D0.MCU_GPIO0_3 */
+		>;
+	};
+
+	hat_21_gpio: hat-21-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x010, PIN_INPUT, 7) /* (C11) MCU_SPI0_D1.MCU_GPIO0_4 */
+		>;
+	};
+
+	hat_21_gpio_pu: hat-21-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x010, PIN_INPUT_PULLUP, 7) /* (C11) MCU_SPI0_D1.MCU_GPIO0_4 */
+		>;
+	};
+
+	hat_21_gpio_pd: hat-21-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x010, PIN_INPUT_PULLDOWN, 7) /* (C11) MCU_SPI0_D1.MCU_GPIO0_4 */
+		>;
+	};
+
+	hat_23_gpio: hat-23-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x008, PIN_INPUT, 7) /* (A9) MCU_SPI0_CLK.MCU_GPIO0_2 */
+		>;
+	};
+
+	hat_23_gpio_pu: hat-23-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x008, PIN_INPUT_PULLUP, 7) /* (A9) MCU_SPI0_CLK.MCU_GPIO0_2 */
+		>;
+	};
+
+	hat_23_gpio_pd: hat-23-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x008, PIN_INPUT_PULLDOWN, 7) /* (A9) MCU_SPI0_CLK.MCU_GPIO0_2 */
+		>;
+	};
+
+	hat_24_gpio: hat-24-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x000, PIN_INPUT, 7) /* (C12) MCU_SPI0_CS0.MCU_GPIO0_0 */
+		>;
+	};
+
+	hat_24_gpio_pu: hat-24-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x000, PIN_INPUT_PULLUP, 7) /* (C12) MCU_SPI0_CS0.MCU_GPIO0_0 */
+		>;
+	};
+
+	hat_24_gpio_pd: hat-24-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x000, PIN_INPUT_PULLDOWN, 7) /* (C12) MCU_SPI0_CS0.MCU_GPIO0_0 */
+		>;
+	};
+
+	/* Device Manager firmware */
+	hat_26_wkup_uart0_rxd: hat-26-wkup-uart0-rxd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x024, PIN_INPUT, 0) /* (B3) WKUP_UART0_RXD */
+		>;
+	};
+
+	hat_26_gpio: hat-26-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x024, PIN_INPUT, 7) /* (B3) WKUP_UART0_RXD.MCU_GPIO0_9 */
+		>;
+	};
+
+	hat_26_gpio_pu: hat-26-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x024, PIN_INPUT_PULLUP, 7) /* (B3) WKUP_UART0_RXD.MCU_GPIO0_9 */
+		>;
+	};
+
+	hat_26_gpio_pd: hat-26-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x024, PIN_INPUT_PULLDOWN, 7) /* (B3) WKUP_UART0_RXD.MCU_GPIO0_9 */
+		>;
+	};
+
+	/* I2C PMIC and eeprom */
+	hat_27_i2c: hat-27-i2c-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x050, PIN_INPUT_PULLUP, 0) /* (D11) WKUP_I2C0_SDA */
+		>;
+	};
+
+	hat_27_gpio: hat-27-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x050, PIN_INPUT, 7) /* (D11) WKUP_I2C0_SDA.MCU_GPIO0_20 */
+		>;
+	};
+
+	hat_27_gpio_pu: hat-27-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x050, PIN_INPUT_PULLUP, 7) /* (D11) WKUP_I2C0_SDA.MCU_GPIO0_20 */
+		>;
+	};
+
+	hat_27_gpio_pd: hat-27-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x050, PIN_INPUT_PULLDOWN, 7) /* (D11) WKUP_I2C0_SDA.MCU_GPIO0_20 */
+		>;
+	};
+
+	/* I2C PMIC and eeprom */
+	hat_28_i2c: hat-28-i2c-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x04C, PIN_INPUT_PULLUP, 0) /* (B9) WKUP_I2C0_SCL */
+		>;
+	};
+
+	hat_28_gpio: hat-28-gpio-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x04C, PIN_INPUT, 7) /* (B9) WKUP_I2C0_SCL.MCU_GPIO0_19 */
+		>;
+	};
+
+	hat_28_gpio_pu: hat-28-gpio-pu-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x04C, PIN_INPUT_PULLUP, 7) /* (B9) WKUP_I2C0_SCL.MCU_GPIO0_19 */
+		>;
+	};
+
+	hat_28_gpio_pd: hat-28-gpio-pd-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x04C, PIN_INPUT_PULLDOWN, 7) /* (B9) WKUP_I2C0_SCL.MCU_GPIO0_19 */
+		>;
+	};
+};
+
+&main_gpio0 {
+	pinctrl-names = "default";
+	gpio-line-names = "", "", "", "", "", /* 0-4 */
+			  "", "", "", "", "", /* 5-9 */
+			  "", "", "", "", "", /* 10-14 */
+			  "", "", "", "", "", /* 15-19 */
+			  "", "", "", "", "", /* 20-24 */
+			  "", "", "", "", "", /* 25-29 */
+			  "", "", "USB_RST", "GPIO27", "", /* 30-34 */
+			  "", "GPIO26", "", "GPIO4", "", /* 35-39 */
+			  "", "GPIO22", "GPIO25", "", ""; /* 40-44 */
+};
+
+&main_gpio1 {
+	pinctrl-names = "default";
+	gpio-line-names = "", "", "", "", "", /* 0-4 */
+			  "", "", "GPIO16", "GPIO17", "GPIO21", /* 5-9 */
+			  "GPIO20", "GPIO18", "GPIO19", "GPIO15", "GPIO14", /* 10-14 */
+			  "GPIO5", "GPIO12", "GPIO6", "GPIO13", ""; /* 15-19 */
+};
+
+&mcu_gpio0 {
+	pinctrl-names = "default";
+	gpio-line-names = "GPIO8", "", "GPIO11", "GPIO10", "GPIO9", /* 0-4 */
+			  "", "", "GPIO23", "", "GPIO7", /* 5-9 */
+			  "GPIO24", "", "", "HDMI_RSTn", "HDMI_INTn", /* 10-14 */
+			  "", "", "GPIO3", "GPIO2", ""; /* 15-19 */
+};
+
+&ecap0 {
+	status = "okay";
+};
+
+&ecap1 {
+	status = "okay";
+};
+
+&ecap2 {
+	status = "okay";
+};
+
+&epwm0 {
+	status = "okay";
+};
+
+&epwm1 {
+	status = "okay";
+};
+
+&epwm2 {
+	status = "okay";
+};
+
+&mcu_i2c0 {
+	symlink = "hat/mcu_i2c0";
+	status = "okay";
+	clock-frequency = <100000>;
+};
+
+dsi0_csi1_i2c: &main_i2c0 {
+	symlink = "hat/dsi0_csi1_i2c";
+};
+
+&main_i2c1 {
+	symlink = "play/main_i2c1";
+};
+
+csi0_i2c: &main_i2c2 {
+	symlink = "hat/csi0";
+};
+
+&wkup_i2c0 {
+	symlink = "hat/wkup_i2c0";
+};
+
+//&main_i2c4 {
+//	symlink = "hat/i2c4";
+//	status = "okay";
+//	clock-frequency = <100000>;
+//};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pps-gpio18.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pps-gpio18.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pps-gpio18.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pps-gpio18.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pps-gpio18.kernel = __TIMESTAMP__;
+	};
+};
+
+&{/} {
+	pps {
+		compatible = "pps-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&hat_12_gpio>;
+
+		gpios = <&main_gpio1 11 GPIO_ACTIVE_HIGH>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap0-gpio12.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap0-gpio12.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap0-gpio12.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap0-gpio12.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO12 ecap0 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-ecap0-gpio12.kernel = __TIMESTAMP__;
+		hat-32.23100000.pwm = "k3-am67a-beagley-ai-pwm-ecap0-gpio12.23100000.0.GPIO12";
+		gpio12.23100000.pwm = "k3-am67a-beagley-ai-pwm-ecap0-gpio12.23100000.0.GPIO12";
+	};
+};
+
+&main_pmx0 {
+	hat_32_pwm_ecap: hat-32-pwm-ecap-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B8, PIN_OUTPUT, 3) /* (C20) SPI0_CS1.ECAP0_IN_APWM_OUT */
+		>;
+	};
+};
+
+&ecap0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_32_pwm_ecap>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap1-gpio16.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap1-gpio16.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap1-gpio16.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap1-gpio16.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO16 ecap1 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-ecap1-gpio16.kernel = __TIMESTAMP__;
+		hat-36.23110000.pwm = "k3-am67a-beagley-ai-pwm-ecap1-gpio16.23110000.0.GPIO16";
+		gpio16.23110000.pwm = "k3-am67a-beagley-ai-pwm-ecap1-gpio16.23110000.0.GPIO16";
+	};
+};
+
+&main_pmx0 {
+	hat_36_pwm_ecap: hat-36-pwm-ecap-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x194, PIN_OUTPUT, 5) /* (A25) MCASP0_AXR3.ECAP1_IN_APWM_OUT */
+		>;
+	};
+};
+
+&ecap1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_36_pwm_ecap>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap1-gpio21.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap1-gpio21.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap1-gpio21.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap1-gpio21.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO21 ecap1 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-ecap1-gpio21.kernel = __TIMESTAMP__;
+		hat-40.23110000.pwm = "k3-am67a-beagley-ai-pwm-ecap1-gpio21.23110000.0.GPIO21";
+		gpio21.23110000.pwm = "k3-am67a-beagley-ai-pwm-ecap1-gpio21.23110000.0.GPIO21";
+	};
+};
+
+&main_pmx0 {
+	hat_40_pwm_ecap: hat-40-pwm-ecap-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x19C, PIN_OUTPUT, 2) /* (B25) MCASP0_AXR1.ECAP1_IN_APWM_OUT */
+		>;
+	};
+};
+
+&ecap1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_40_pwm_ecap>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap2-gpio17.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap2-gpio17.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap2-gpio17.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap2-gpio17.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO17 ecap2 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-ecap2-gpio17.kernel = __TIMESTAMP__;
+		hat-11.23120000.pwm = "k3-am67a-beagley-ai-pwm-ecap2-gpio17.23120000.0.GPIO17";
+		gpio17.23120000.pwm = "k3-am67a-beagley-ai-pwm-ecap2-gpio17.23120000.0.GPIO17";
+	};
+};
+
+&main_pmx0 {
+	hat_11_pwm_ecap: hat-11-pwm-ecap-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x198, PIN_OUTPUT, 5) /* (A26) MCASP0_AXR2.ECAP2_IN_APWM_OUT */
+		>;
+	};
+};
+
+&ecap2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_11_pwm_ecap>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap2-gpio18.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap2-gpio18.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap2-gpio18.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-ecap2-gpio18.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO18 ecap2 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-ecap2-gpio18.kernel = __TIMESTAMP__;
+		hat-12.23120000.pwm = "k3-am67a-beagley-ai-pwm-ecap2-gpio18.23120000.0.GPIO18";
+		gpio18.23120000.pwm = "k3-am67a-beagley-ai-pwm-ecap2-gpio18.23120000.0.GPIO18";
+	};
+};
+
+&main_pmx0 {
+	hat_12_pwm_ecap: hat-12-pwm-ecap-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A4, PIN_OUTPUT, 2) /* (D25) MCASP0_ACLKX.ECAP2_IN_APWM_OUT */
+		>;
+	};
+};
+
+&ecap2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_12_pwm_ecap>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio12.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio12.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio12.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio12.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO12 epwm0 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm0-gpio12.kernel = __TIMESTAMP__;
+		hat-32.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio12.23000000.1.GPIO12";
+		gpio12.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio12.23000000.1.GPIO12";
+	};
+};
+
+&main_pmx0 {
+	hat_32_pwm: hat-32-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B8, PIN_OUTPUT, 2) /* (C20) SPI0_CS1.EHRPWM0_B */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_32_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio14.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio14.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio14.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio14.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO14 epwm0 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm0-gpio14.kernel = __TIMESTAMP__;
+		hat-08.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio14.23000000.1.GPIO14";
+		gpio14.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio14.23000000.1.GPIO14";
+	};
+};
+
+&main_pmx0 {
+	hat_08_pwm: hat-08-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B0, PIN_OUTPUT, 6) /* (F24) MCASP0_ACLKR.EHRPWM0_B */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_08_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio15.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio15.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio15.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio15.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO15 epwm0 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm0-gpio15.kernel = __TIMESTAMP__;
+		hat-10.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio15.23000000.0.GPIO15";
+		gpio15.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio15.23000000.0.GPIO15";
+	};
+};
+
+&main_pmx0 {
+	hat_10_pwm: hat-10-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1AC, PIN_OUTPUT, 6) /* (C27) MCASP0_AFSR.EHRPWM0_A */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_10_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio15-gpio12.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio15-gpio12.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio15-gpio12.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio15-gpio12.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO15 and GPIO12 epwm0 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm0-gpio15-gpio12..kernel = __TIMESTAMP__;
+		hat-10.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio15.23000000.0.GPIO15";
+		gpio15.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio15.23000000.0.GPIO15";
+		hat-32.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio12.23000000.1.GPIO12";
+		gpio12.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio12.23000000.1.GPIO12";
+	};
+};
+
+&main_pmx0 {
+	gpio15_gpio12_pwm: gpio15-gpio12-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1AC, PIN_OUTPUT, 6) /* (C27) MCASP0_AFSR.EHRPWM0_A */
+			J722S_IOPAD(0x1B8, PIN_OUTPUT, 2) /* (C20) SPI0_CS1.EHRPWM0_B */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio15_gpio12_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio15-gpio14.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio15-gpio14.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio15-gpio14.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio15-gpio14.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO15 and GPIO14 epwm0 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm0-gpio15-gpio14.kernel = __TIMESTAMP__;
+		hat-10.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio15.23000000.0.GPIO15";
+		gpio15.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio15.23000000.0.GPIO15";
+		hat-08.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio14.23000000.1.GPIO14";
+		gpio14.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio14.23000000.1.GPIO14";
+	};
+};
+
+&main_pmx0 {
+	gpio15_gpio14_pwm: gpio15-gpio14-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1AC, PIN_OUTPUT, 6) /* (C27) MCASP0_AFSR.EHRPWM0_A */
+			J722S_IOPAD(0x1B0, PIN_OUTPUT, 6) /* (F24) MCASP0_ACLKR.EHRPWM0_B */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio15_gpio14_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio5.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio5.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio5.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio5.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO5 epwm0 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm0-gpio5.kernel = __TIMESTAMP__;
+		hat-29.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio5.23000000.0.GPIO5";
+		gpio5.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio5.23000000.0.GPIO5";
+	};
+};
+
+&main_pmx0 {
+	hat_29_pwm: hat-29-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B4, PIN_OUTPUT, 2) /* (B20) SPI0_CS0.EHRPWM0_A */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_29_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio5-gpio12.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio5-gpio12.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio5-gpio12.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio5-gpio12.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO5 and GPIO12 epwm0 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm0-gpio5-gpio12.kernel = __TIMESTAMP__;
+		hat-29.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio5.23000000.0.GPIO5";
+		gpio5.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio5.23000000.0.GPIO5";
+		hat-32.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio12.23000000.1.GPIO12";
+		gpio12.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio12.23000000.1.GPIO12";
+	};
+};
+
+&main_pmx0 {
+	gpio5_gpio12_pwm: gpio5-gpio12-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B4, PIN_OUTPUT, 2) /* (B20) SPI0_CS0.EHRPWM0_A */
+			J722S_IOPAD(0x1B8, PIN_OUTPUT, 2) /* (C20) SPI0_CS1.EHRPWM0_B */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio5_gpio12_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio5-gpio14.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio5-gpio14.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio5-gpio14.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm0-gpio5-gpio14.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO5 and GPIO14 epwm0 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm0-gpio5-gpio14.kernel = __TIMESTAMP__;
+		hat-29.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio5.23000000.0.GPIO5";
+		gpio5.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio5.23000000.0.GPIO5";
+		hat-08.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio14.23000000.1.GPIO14";
+		gpio14.23000000.pwm = "k3-am67a-beagley-ai-pwm-epwm0-gpio14.23000000.1.GPIO14";
+	};
+};
+
+&main_pmx0 {
+	gpio5_gpio14_pwm: gpio5-gpio14-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1B4, PIN_OUTPUT, 2) /* (B20) SPI0_CS0.EHRPWM0_A */
+			J722S_IOPAD(0x1B0, PIN_OUTPUT, 6) /* (F24) MCASP0_ACLKR.EHRPWM0_B */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio5_gpio14_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio13.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio13.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio13.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio13.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO13 epwm1 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm1-gpio13.kernel = __TIMESTAMP__;
+		hat-33.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio13.23010000.1.GPIO13";
+		gpio13.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio13.23010000.1.GPIO13";
+	};
+};
+
+&main_pmx0 {
+	hat_33_pwm: hat-33-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1C0, PIN_OUTPUT, 2) /* (E19) SPI0_D0.EHRPWM1_B */
+		>;
+	};
+};
+
+&epwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_33_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio20.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio20.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio20.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio20.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO20 epwm1 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm1-gpio20.kernel = __TIMESTAMP__;
+		hat-38.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio20.23010000.1.GPIO20";
+		gpio20.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio20.23010000.1.GPIO20";
+	};
+};
+
+&main_pmx0 {
+	hat_38_pwm: hat-38-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1A0, PIN_OUTPUT, 6) /* (F23) MCASP0_AXR0.EHRPWM1_B */
+		>;
+	};
+};
+
+&epwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_38_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio21.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio21.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio21.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio21.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO21 epwm1 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm1-gpio21.kernel = __TIMESTAMP__;
+		hat-40.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio21.23010000.0.GPIO21";
+		gpio21.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio21.23010000.0.GPIO21";
+	};
+};
+
+&main_pmx0 {
+	hat_40_pwm: hat-40-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x19C, PIN_OUTPUT, 6) /* (B25) MCASP0_AXR1.EHRPWM1_A */
+		>;
+	};
+};
+
+&epwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_40_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio21-gpio13.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio21-gpio13.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio21-gpio13.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio21-gpio13.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO21 and GPIO13 epwm1 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm1-gpio21.kernel = __TIMESTAMP__;
+		hat-40.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio21.23010000.0.GPIO21";
+		gpio21.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio21.23010000.0.GPIO21";
+		hat-33.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio13.23010000.1.GPIO13";
+		gpio13.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio13.23010000.1.GPIO13";
+	};
+};
+
+&main_pmx0 {
+	gpio21_gpio13_pwm: gpio21-gpio13-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x19C, PIN_OUTPUT, 6) /* (B25) MCASP0_AXR1.EHRPWM1_A */
+			J722S_IOPAD(0x1C0, PIN_OUTPUT, 2) /* (E19) SPI0_D0.EHRPWM1_B */
+		>;
+	};
+};
+
+&epwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio21_gpio13_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio21-gpio20.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio21-gpio20.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio21-gpio20.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio21-gpio20.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO21 and GPIO20 epwm1 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm1-gpio21.kernel = __TIMESTAMP__;
+		hat-40.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio21.23010000.0.GPIO21";
+		gpio21.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio21.23010000.0.GPIO21";
+		hat-38.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio20.23010000.1.GPIO20";
+		gpio20.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio20.23010000.1.GPIO20";
+	};
+};
+
+&main_pmx0 {
+	gpio21_gpio20_pwm: gpio21-gpio20-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x19C, PIN_OUTPUT, 6) /* (B25) MCASP0_AXR1.EHRPWM1_A */
+			J722S_IOPAD(0x1A0, PIN_OUTPUT, 6) /* (F23) MCASP0_AXR0.EHRPWM1_B */
+		>;
+	};
+};
+
+&epwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio21_gpio20_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio6.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio6.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio6.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio6.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO6 epwm1 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm1-gpio6.kernel = __TIMESTAMP__;
+		hat-31.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio6.23010000.0.GPIO6";
+		gpio6.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio6.23010000.0.GPIO6";
+	};
+};
+
+&main_pmx0 {
+	hat_31_pwm: hat-31-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1BC, PIN_OUTPUT, 2) /* (D20) SPI0_CLK.EHRPWM1_A */
+		>;
+	};
+};
+
+&epwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&hat_31_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio6-gpio13.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio6-gpio13.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio6-gpio13.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio6-gpio13.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO6 and GPIO13 epwm1 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm1-gpio6.kernel = __TIMESTAMP__;
+		hat-31.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio6.23010000.0.GPIO6";
+		gpio6.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio6.23010000.0.GPIO6";
+		hat-33.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio13.23010000.1.GPIO13";
+		gpio13.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio13.23010000.1.GPIO13";
+	};
+};
+
+&main_pmx0 {
+	gpio6_gpio13_pwm: gpio6-gpio13-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1BC, PIN_OUTPUT, 2) /* (D20) SPI0_CLK.EHRPWM1_A */
+			J722S_IOPAD(0x1C0, PIN_OUTPUT, 2) /* (E19) SPI0_D0.EHRPWM1_B */
+		>;
+	};
+};
+
+&epwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio6_gpio13_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio6-gpio20.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio6-gpio20.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio6-gpio20.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-pwm-epwm1-gpio6-gpio20.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for GPIO6 and GPIO20 epwm1 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-pwm-epwm1-gpio6-gpio20.kernel = __TIMESTAMP__;
+		hat-31.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio6.23010000.0.GPIO6";
+		gpio6.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio6.23010000.0.GPIO6";
+		hat-38.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio20.23010000.1.GPIO20";
+		gpio20.23010000.pwm = "k3-am67a-beagley-ai-pwm-epwm1-gpio20.23010000.1.GPIO20";
+	};
+};
+
+&main_pmx0 {
+	gpio6_gpio20_pwm: gpio6-gpio20-pwm-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x1BC, PIN_OUTPUT, 2) /* (D20) SPI0_CLK.EHRPWM1_A */
+			J722S_IOPAD(0x1A0, PIN_OUTPUT, 6) /* (F23) MCASP0_AXR0.EHRPWM1_B */
+		>;
+	};
+};
+
+&epwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio6_gpio20_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-spi0-1cs.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-spi0-1cs.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-spi0-1cs.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-spi0-1cs.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for spi0-1cs on BeagleY-AI board.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-spi0-1cs.kernel = __TIMESTAMP__;
+	};
+};
+
+&spi_gpio {
+	compatible = "spi-gpio";
+	#address-cells = <0x1>;
+	#size-cells = <0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_gpio_default_pins>;
+
+	sck-gpios = <&mcu_gpio0 2 GPIO_ACTIVE_HIGH>;
+	miso-gpios = <&mcu_gpio0 4 GPIO_ACTIVE_HIGH>;
+	mosi-gpios = <&mcu_gpio0 3 GPIO_ACTIVE_HIGH>;
+
+	num-chipselects = <1>;
+	cs-gpios = <
+		&mcu_gpio0 0 GPIO_ACTIVE_HIGH
+	>;
+
+	status = "okay";
+
+//	mcp795@0 {
+//		compatible = "maxim,mcp795";
+//		reg = <0x0>;
+//		spi-max-frequency = <100000>;
+//	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-spi0-2cs.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-spi0-2cs.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-spi0-2cs.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-spi0-2cs.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for spi0-2cs on BeagleY-AI board.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-spi0-2cs.kernel = __TIMESTAMP__;
+	};
+};
+
+&spi_gpio {
+	compatible = "spi-gpio";
+	#address-cells = <0x1>;
+	#size-cells = <0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_gpio_default_pins>;
+
+	sck-gpios = <&mcu_gpio0 2 GPIO_ACTIVE_HIGH>;
+	miso-gpios = <&mcu_gpio0 4 GPIO_ACTIVE_HIGH>;
+	mosi-gpios = <&mcu_gpio0 3 GPIO_ACTIVE_HIGH>;
+
+	num-chipselects = <2>;
+	cs-gpios = <
+		&mcu_gpio0 0 GPIO_ACTIVE_HIGH
+		&mcu_gpio0 9 GPIO_ACTIVE_HIGH
+	>;
+
+	status = "okay";
+
+//	mcp795@0 {
+//		compatible = "maxim,mcp795";
+//		reg = <0x0>;
+//		spi-max-frequency = <100000>;
+//	};
+
+//	mcp795@1 {
+//		compatible = "maxim,mcp795";
+//		reg = <0x1>;
+//		spi-max-frequency = <100000>;
+//	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-spidev0.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-spidev0.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-spidev0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-spidev0.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for spidev0.0 & spidev0.1 on BeagleY-AI board.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+ */
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-spidev0.kernel = __TIMESTAMP__;
+	};
+};
+
+&spi_gpio {
+	compatible = "spi-gpio";
+	#address-cells = <0x1>;
+	#size-cells = <0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_gpio_default_pins>;
+
+	sck-gpios = <&mcu_gpio0 2 GPIO_ACTIVE_HIGH>;
+	miso-gpios = <&mcu_gpio0 4 GPIO_ACTIVE_HIGH>;
+	mosi-gpios = <&mcu_gpio0 3 GPIO_ACTIVE_HIGH>;
+
+	num-chipselects = <2>;
+	cs-gpios = <
+		&mcu_gpio0 0 GPIO_ACTIVE_HIGH
+		&mcu_gpio0 9 GPIO_ACTIVE_HIGH
+	>;
+
+	status = "okay";
+
+	channel@0 {
+		compatible = "rohm,dh2228fv";
+
+		reg = <0>;
+		spi-max-frequency = <100000>;
+	};
+
+	channel@1 {
+		compatible = "rohm,dh2228fv";
+
+		reg = <1>;
+		spi-max-frequency = <100000>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-uart-ttyama0.dtso b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-uart-ttyama0.dtso
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-uart-ttyama0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai-uart-ttyama0.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for /dev/ttyAMA0 uart pins within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-am67a-beagley-ai-uart-ttyama0.kernel = __TIMESTAMP__;
+	};
+};
+
+&main_uart1 {
+	symlink = "ttyAMA0";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart1_pins_default>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts	2025-10-23 09:30:40.283462146 -0400
@@ -135,6 +135,23 @@
 		max-bitrate = <5000000>;
 	};
 
+	edp0_refclk: clock-edp0-refclk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <19200000>;
+	};
+
+	dp0_pwr_3v3: fixedregulator-dp0-pwr {
+		compatible = "regulator-fixed";
+		regulator-name = "dp0-pwr";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		pinctrl-names = "default";
+		gpio = <&exp2 2 GPIO_ACTIVE_HIGH>;     /*P0 - DP0_3V3 _EN */
+		enable-active-high;
+		regulator-always-on;
+	};
+
 	connector-hdmi {
 		compatible = "hdmi-connector";
 		label = "hdmi";
@@ -195,6 +212,7 @@
 			J721S2_IOPAD(0x0d0, PIN_INPUT, 11) /* (AF26) SPI0_CS1.UART8_RXD */
 			J721S2_IOPAD(0x0d4, PIN_OUTPUT, 11) /* (AH27) SPI0_CLK.UART8_TXD */
 		>;
+		bootph-all;
 	};
 
 	main_i2c0_pins_default: main-i2c0-default-pins {
@@ -222,6 +240,7 @@
 			J721S2_IOPAD(0x0f0, PIN_INPUT, 0) /* (R22) MMC1_DAT3 */
 			J721S2_IOPAD(0x0e8, PIN_INPUT, 8) /* (AE25) TIMER_IO0.MMC1_SDCD */
 		>;
+		bootph-all;
 	};
 
 	vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
@@ -324,6 +343,7 @@
 			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (D28) WKUP_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (D27) WKUP_UART0_TXD */
 		>;
+		bootph-all;
 	};
 
 	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
@@ -341,6 +361,7 @@
 			J721S2_WKUP_IOPAD(0x018, PIN_OUTPUT, 0) /* (F21) MCU_RGMII1_TXC */
 			J721S2_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (F22) MCU_RGMII1_TX_CTL */
 		>;
+		bootph-all;
 	};
 
 	mcu_mdio_pins_default: mcu-mdio-default-pins {
@@ -348,6 +369,7 @@
 			J721S2_WKUP_IOPAD(0x034, PIN_OUTPUT, 0) /* (A21) MCU_MDIO0_MDC */
 			J721S2_WKUP_IOPAD(0x030, PIN_INPUT, 0) /* (A22) MCU_MDIO0_MDIO */
 		>;
+		bootph-all;
 	};
 
 	mcu_mcan0_pins_default: mcu-mcan0-default-pins {
@@ -383,6 +405,7 @@
 			J721S2_WKUP_IOPAD(0x08c, PIN_INPUT, 0) /* (C24) WKUP_GPIO0_13.MCU_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x088, PIN_OUTPUT, 0) /* (C25) WKUP_GPIO0_12.MCU_UART0_TXD */
 		>;
+		bootph-all;
 	};
 
 	mcu_rpi_header_gpio0_pins0_default: mcu-rpi-header-gpio0-default-pins-0 {
@@ -424,6 +447,7 @@
 	status = "reserved";
 	pinctrl-names = "default";
 	pinctrl-0 = <&wkup_uart0_pins_default>;
+	bootph-all;
 };
 
 &wkup_i2c0 {
@@ -506,6 +530,7 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_uart0_pins_default>;
+	bootph-all;
 };
 
 &main_uart8 {
@@ -514,6 +539,7 @@
 	pinctrl-0 = <&main_uart8_pins_default>;
 	/* Shared with TFA on this platform */
 	power-domains = <&k3_pds 357 TI_SCI_PD_SHARED>;
+	bootph-all;
 };
 
 &main_i2c0 {
@@ -598,6 +624,52 @@
 		gpio-line-names = "HDMI_PDn","HDMI_LS_OE",
 				  "DP0_3V3_EN","eDP_ENABLE";
 	};
+
+	dsi_edp_bridge: dsi-edp-bridge@2c {
+		compatible = "ti,sn65dsi86";
+		reg = <0x2c>;
+		clock-names = "refclk";
+		clocks = <&edp0_refclk>;
+		enable-gpios = <&exp2 3 GPIO_ACTIVE_HIGH>;
+		vpll-supply = <&vsys_io_1v8>;
+		vccio-supply = <&vsys_io_1v8>;
+		vcca-supply = <&vsys_io_1v2>;
+		vcc-supply = <&vsys_io_1v2>;
+
+		aux-bus {
+			panel {
+				compatible = "ti,panel-edp";
+				power-supply = <&dp0_pwr_3v3>;
+
+				port {
+					dp0_panel_in: endpoint {
+						remote-endpoint = <&dp0_out>;
+					};
+				};
+			};
+		};
+
+		dsi_edp_bridge_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				dp0_in: endpoint {
+					remote-endpoint = <&dsi0_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				dp0_out: endpoint {
+					remote-endpoint = <&dp0_panel_in>;
+				};
+			};
+		};
+	};
 };
 
 &main_sdhci1 {
@@ -608,6 +680,7 @@
 	disable-wp;
 	vmmc-supply = <&vdd_mmc1>;
 	vqmmc-supply = <&vdd_sd_dv>;
+	bootph-all;
 };
 
 &mcu_cpsw {
@@ -618,6 +691,7 @@
 &davinci_mdio {
 	phy0: ethernet-phy@0 {
 		reg = <0>;
+		bootph-all;
 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
 		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
 		ti,min-output-impedance;
@@ -682,7 +756,6 @@
 &dss_ports {
 	#address-cells = <1>;
 	#size-cells = <0>;
-
 	/* HDMI */
 	port@1 {
 		reg = <1>;
@@ -691,6 +764,15 @@
 			remote-endpoint = <&tfp410_in>;
 		};
 	};
+
+	/* DSI */
+	port@2 {
+		reg = <2>;
+
+		dpi0_out: endpoint {
+			remote-endpoint = <&dsi0_in>;
+		};
+	};
 };
 
 &serdes_ln_ctrl {
@@ -748,3 +830,28 @@
 	phys = <&serdes0_usb_link>;
 	phy-names = "cdns3,usb3-phy";
 };
+
+&dphy_tx0 {
+	status = "okay";
+};
+
+&dsi0 {
+	status = "okay";
+};
+
+&dsi0_ports {
+
+	port@0 {
+		reg = <0>;
+		dsi0_out: endpoint {
+			remote-endpoint = <&dp0_in>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		dsi0_in: endpoint {
+			remote-endpoint = <&dpi0_out>;
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board-pcie1-ep.dtso b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board-pcie1-ep.dtso
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board-pcie1-ep.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board-pcie1-ep.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for enabling PCIE1 instance in Endpoint Configuration with the
+ * AM68-SK board.
+ *
+ * AM68-SK Board Product Link: https://www.ti.com/tool/SK-AM68
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+#include "k3-pinctrl.h"
+
+/*
+ * Since Root Complex and Endpoint modes are mutually exclusive
+ * disable Root Complex mode.
+ */
+&pcie1_rc {
+	status = "disabled";
+};
+
+&cbass_main {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&gic500>;
+
+	pcie1_ep: pcie-ep@2910000 {
+		compatible = "ti,j7200-pcie-ep", "ti,j721e-pcie-ep";
+		reg = <0x00 0x02910000 0x00 0x1000>,
+		      <0x00 0x02917000 0x00 0x400>,
+		      <0x00 0x0d800000 0x00 0x00800000>,
+		      <0x00 0x18000000 0x00 0x08000000>;
+		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+		interrupt-names = "link_state";
+		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
+		max-link-speed = <3>;
+		num-lanes = <2>;
+		power-domains = <&k3_pds 276 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 276 41>;
+		clock-names = "fck";
+		max-functions = /bits/ 8 <6>;
+		max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+		dma-coherent;
+		phys = <&serdes0_pcie_link>;
+		phy-names = "pcie-phy";
+		ti,syscon-pcie-ctrl = <&pcie1_ctrl 0x0>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am68-sk-bb-csi2-ov5640.dtso b/arch/arm64/boot/dts/ti/k3-am68-sk-bb-csi2-ov5640.dtso
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-bb-csi2-ov5640.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-bb-csi2-ov5640.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * LI OV5640 MIPI Camera module.
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_ov5640_fixed: ov5640-xclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&cam0_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ov5640: camera@3c {
+		compatible = "ovti,ov5640";
+		reg = <0x3c>;
+		powerdown-gpios = <&exp3 2 GPIO_ACTIVE_LOW>;
+		clocks = <&clk_ov5640_fixed>;
+		clock-names = "xclk";
+
+		port {
+			csi2_cam0: endpoint {
+				remote-endpoint = <&csi2rx0_in_sensor>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx0_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam0>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -22,6 +22,14 @@
 		#size-cells = <2>;
 		ranges;
 
+		 /* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x38000000>;
+			linux,cma-default;
+		};
+
 		secure_ddr: optee@9e800000 {
 			reg = <0x00 0x9e800000 0x00 0x01800000>;
 			no-map;
@@ -156,6 +164,7 @@
 			J721S2_WKUP_IOPAD(0x098, PIN_INPUT, 0) /* (H24) WKUP_I2C0_SCL */
 			J721S2_WKUP_IOPAD(0x09c, PIN_INPUT, 0) /* (H27) WKUP_I2C0_SDA */
 		>;
+		bootph-all;
 	};
 };
 
@@ -169,6 +178,7 @@
 		/* AT24C512C-MAHM-T */
 		compatible = "atmel,24c512";
 		reg = <0x51>;
+		bootph-all;
 	};
 };
 
@@ -190,7 +200,6 @@
 		cdns,read-delay = <4>;
 
 		partitions {
-			bootph-all;
 			compatible = "fixed-partitions";
 			#address-cells = <1>;
 			#size-cells = <1>;
@@ -226,9 +235,9 @@
 			};
 
 			partition@3fc0000 {
-				bootph-pre-ram;
 				label = "ospi.phypattern";
 				reg = <0x3fc0000 0x40000>;
+				bootph-all;
 			};
 		};
 	};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion.dtso b/arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion.dtso
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Arducam V3Link UC-A09 board
+ * https://www.arducam.com/fpd-link-3-cameras/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&csi_mux {
+	idle-state = <1>;
+};
+
+&cam0_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	deser@30 {
+		compatible = "ti,ds90ub960-q1";
+		reg = <0x30>;
+
+		clock-names = "refclk";
+		clocks = <&clk_fusion_25M_fixed>;
+
+		i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+		deserializer_0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@4 {
+				reg = <4>;
+				ds90ub960_0_csi_out: endpoint {
+					data-lanes = <1 2 3 4>;
+					clock-lanes = <0>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy0>;
+				};
+			};
+		};
+
+		deserializer_0_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&cam1_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	deser@30 {
+		compatible = "ti,ds90ub960-q1";
+		reg = <0x30>;
+
+		clock-names = "refclk";
+		clocks = <&clk_fusion_25M_fixed>;
+
+		i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+		deserializer_1_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@4 {
+				reg = <4>;
+				ds90ub960_1_csi_out: endpoint {
+					data-lanes = <1 2 3 4>;
+					clock-lanes = <0>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy1>;
+				};
+			};
+		};
+
+		deserializer_1_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub960_0_csi_out>;
+				bus-type = <4>; /* CSI2 DPHY. */
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy1: endpoint {
+				remote-endpoint = <&ds90ub960_1_csi_out>;
+				bus-type = <4>; /* CSI2 DPHY. */
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
+
+&dphy1 {
+	status = "okay";
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion-dual-csitx.dtso b/arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion-dual-csitx.dtso
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion-dual-csitx.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion-dual-csitx.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Arducam V3Link UC-A09 board
+ * https://www.arducam.com/fpd-link-3-cameras/
+ *
+ * Copyright (c) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&csi_mux {
+	idle-state = <1>;
+};
+
+&cam0_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	deser@30 {
+		compatible = "ti,ds90ub960-q1";
+		reg = <0x30>;
+
+		clock-names = "refclk";
+		clocks = <&clk_fusion_25M_fixed>;
+
+		i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+		deserializer_0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@4 {
+				reg = <4>;
+				ds90ub960_0_csi_out: endpoint {
+					data-lanes = <1 2 3 4>;
+					clock-lanes = <0>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy0>;
+				};
+			};
+		};
+
+		deserializer_0_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&cam1_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	deser@30 {
+		compatible = "ti,ds90ub960-q1";
+		reg = <0x30>;
+
+		clock-names = "refclk";
+		clocks = <&clk_fusion_25M_fixed>;
+
+		i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+		deserializer_1_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@5 {
+				reg = <5>;
+				ds90ub960_1_csi_out: endpoint {
+					data-lanes = <1 2 3 4>;
+					clock-lanes = <0>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy1>;
+				};
+			};
+		};
+
+		deserializer_1_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub960_0_csi_out>;
+				bus-type = <4>; /* CSI2 DPHY. */
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy1: endpoint {
+				remote-endpoint = <&ds90ub960_1_csi_out>;
+				bus-type = <4>; /* CSI2 DPHY. */
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
+
+&dphy1 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am69-sk-csi2-ov5640.dtso b/arch/arm64/boot/dts/ti/k3-am69-sk-csi2-ov5640.dtso
--- a/arch/arm64/boot/dts/ti/k3-am69-sk-csi2-ov5640.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk-csi2-ov5640.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT Overlay for OV5640 Camera module on MIPI CSI connector for AM69 SK board.
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_ov5640_fixed: ov5640-xclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&cam0_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ov5640: camera@3c {
+		compatible = "ovti,ov5640";
+		reg = <0x3c>;
+		powerdown-gpios = <&exp2 2 GPIO_ACTIVE_LOW>;
+		clocks = <&clk_ov5640_fixed>;
+		clock-names = "xclk";
+
+		port {
+			csi2_cam0: endpoint {
+				remote-endpoint = <&csi2rx0_in_sensor>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx0_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam0>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts	2025-10-23 09:30:40.283462146 -0400
@@ -44,6 +44,14 @@
 		#size-cells = <2>;
 		ranges;
 
+		/* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x70000000>;
+			linux,cma-default;
+		};
+
 		secure_ddr: optee@9e800000 {
 			reg = <0x00 0x9e800000 0x00 0x01800000>;
 			no-map;
@@ -484,6 +492,12 @@
 		>;
 	};
 
+	main_usbss0_pins_default: main-usbss0-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x0ec, PIN_OUTPUT, 6) /* (AN37) TIMER_IO1.USB0_DRVVBUS */
+		>;
+	};
+
 };
 
 &wkup_pmx0 {
@@ -755,6 +769,7 @@
 				regulator-max-microvolt = <1100000>;
 				regulator-boot-on;
 				regulator-always-on;
+				bootph-all;
 			};
 
 			bucka3: buck3 {
@@ -763,6 +778,7 @@
 				regulator-max-microvolt = <850000>;
 				regulator-boot-on;
 				regulator-always-on;
+				bootph-all;
 			};
 
 			bucka4: buck4 {
@@ -771,6 +787,7 @@
 				regulator-max-microvolt = <1800000>;
 				regulator-boot-on;
 				regulator-always-on;
+				bootph-all;
 			};
 
 			bucka5: buck5 {
@@ -779,6 +796,7 @@
 				regulator-max-microvolt = <850000>;
 				regulator-boot-on;
 				regulator-always-on;
+				bootph-all;
 			};
 
 			ldoa1: ldo1 {
@@ -787,6 +805,7 @@
 				regulator-max-microvolt = <1800000>;
 				regulator-boot-on;
 				regulator-always-on;
+				bootph-all;
 			};
 
 			ldoa2: ldo2 {
@@ -795,6 +814,7 @@
 				regulator-max-microvolt = <3300000>;
 				regulator-boot-on;
 				regulator-always-on;
+				bootph-all;
 			};
 
 			ldoa3: ldo3 {
@@ -803,6 +823,7 @@
 				regulator-max-microvolt = <800000>;
 				regulator-boot-on;
 				regulator-always-on;
+				bootph-all;
 			};
 
 			ldoa4: ldo4 {
@@ -811,6 +832,7 @@
 				regulator-max-microvolt = <1800000>;
 				regulator-boot-on;
 				regulator-always-on;
+				bootph-all;
 			};
 		};
 	};
@@ -1132,6 +1154,7 @@
 		reg = <0>;
 		cdns,num-lanes = <4>;
 		#phy-cells = <0>;
+		cdns,max-bit-rate = <2700>;
 		cdns,phy-type = <PHY_TYPE_DP>;
 		resets = <&serdes_wiz4 1>, <&serdes_wiz4 2>,
 			 <&serdes_wiz4 3>, <&serdes_wiz4 4>;
@@ -1216,6 +1239,11 @@
 	phys = <&transceiver4>;
 };
 
+&fss {
+	bootph-all;
+	status = "okay";
+};
+
 &ospi0 {
 	status = "okay";
 	pinctrl-names = "default";
@@ -1232,6 +1260,7 @@
 		cdns,tchsh-ns = <60>;
 		cdns,tslch-ns = <60>;
 		cdns,read-delay = <4>;
+		cdns,phy-mode;
 
 		partitions {
 			bootph-all;
@@ -1270,7 +1299,7 @@
 			};
 
 			partition@3fc0000 {
-				bootph-pre-ram;
+				bootph-all;
 				label = "ospi.phypattern";
 				reg = <0x3fc0000 0x40000>;
 			};
@@ -1281,8 +1310,12 @@
 &serdes_ln_ctrl {
 	idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>, <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
 		      <J784S4_SERDES0_LANE2_PCIE3_LANE0>, <J784S4_SERDES0_LANE3_USB>,
-			<J784S4_SERDES1_LANE0_PCIE0_LANE0>, <J784S4_SERDES1_LANE1_PCIE0_LANE1>,
-			<J784S4_SERDES1_LANE2_PCIE0_LANE2>, <J784S4_SERDES1_LANE3_PCIE0_LANE3>;
+		      <J784S4_SERDES1_LANE0_PCIE0_LANE0>, <J784S4_SERDES1_LANE1_PCIE0_LANE1>,
+		      <J784S4_SERDES1_LANE2_PCIE0_LANE2>, <J784S4_SERDES1_LANE3_PCIE0_LANE3>,
+		      <J784S4_SERDES2_LANE0_IP2_UNUSED>, <J784S4_SERDES2_LANE1_IP2_UNUSED>,
+		      <J784S4_SERDES2_LANE2_QSGMII_LANE1>, <J784S4_SERDES2_LANE3_QSGMII_LANE2>,
+		      <J784S4_SERDES4_LANE0_EDP_LANE0>, <J784S4_SERDES4_LANE1_EDP_LANE1>,
+		      <J784S4_SERDES4_LANE2_EDP_LANE2>, <J784S4_SERDES4_LANE3_EDP_LANE3>;
 };
 
 &serdes_wiz0 {
@@ -1292,12 +1325,28 @@
 &serdes0 {
 	status = "okay";
 
-	serdes0_pcie_link: phy@0 {
+	serdes0_pcie_link1: phy@0 {
 		reg = <0>;
-		cdns,num-lanes = <3>;
+		cdns,num-lanes = <2>;
 		#phy-cells = <0>;
 		cdns,phy-type = <PHY_TYPE_PCIE>;
-		resets = <&serdes_wiz0 1>, <&serdes_wiz0 2>, <&serdes_wiz0 3>;
+		resets = <&serdes_wiz0 1>, <&serdes_wiz0 2>;
+	};
+
+	serdes0_pcie_link2: phy@2 {
+		reg = <2>;
+		cdns,num-lanes = <1>;
+		#phy-cells = <0>;
+		cdns,phy-type = <PHY_TYPE_PCIE>;
+		resets = <&serdes_wiz0 3>;
+	};
+
+	serdes0_usb_link: phy@3 {
+		reg = <3>;
+		cdns,num-lanes = <1>;
+		#phy-cells = <0>;
+		cdns,phy-type = <PHY_TYPE_USB3>;
+		resets = <&serdes_wiz0 4>;
 	};
 };
 
@@ -1327,7 +1376,7 @@
 &pcie1_rc {
 	status = "okay";
 	reset-gpios = <&exp1 5 GPIO_ACTIVE_HIGH>;
-	phys = <&serdes0_pcie_link>;
+	phys = <&serdes0_pcie_link1>;
 	phy-names = "pcie-phy";
 	num-lanes = <2>;
 };
@@ -1335,7 +1384,26 @@
 &pcie3_rc {
 	status = "okay";
 	reset-gpios = <&exp1 6 GPIO_ACTIVE_HIGH>;
-	phys = <&serdes0_pcie_link>;
+	phys = <&serdes0_pcie_link2>;
 	phy-names = "pcie-phy";
 	num-lanes = <1>;
 };
+
+&usb_serdes_mux {
+	idle-states = <0>; /* USB0 to SERDES0 */
+};
+
+&usbss0 {
+	status = "okay";
+	pinctrl-0 = <&main_usbss0_pins_default>;
+	pinctrl-names = "default";
+	ti,vbus-divider;
+};
+
+&usb0 {
+	status = "okay";
+	dr_mode = "otg";
+	maximum-speed = "super-speed";
+	phys = <&serdes0_usb_link>;
+	phy-names = "cdns3,usb3-phy";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am69-sk-fpdlink-fusion-auxport.dtso b/arch/arm64/boot/dts/ti/k3-am69-sk-fpdlink-fusion-auxport.dtso
--- a/arch/arm64/boot/dts/ti/k3-am69-sk-fpdlink-fusion-auxport.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk-fpdlink-fusion-auxport.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Fusion (FPD-Link III) board on AM69 SK CSI2 Aux Port
+ * https://svtronics.com/portfolio/evm577pfusion-v1-0-fusion/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	clk_fusion1_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&cam1_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	deser@3d {
+		compatible = "ti,ds90ub960-q1";
+		reg = <0x3d>;
+		clocks = <&clk_fusion1_25M_fixed>;
+		clock-names = "refclk";
+		i2c-alias-pool = <0x6a 0x6b 0x6c 0x6d 0x6e 0x6f>;
+
+		ds90ub960_2_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX*/
+			port@4 {
+				reg = <4>;
+				ds90ub960_2_csi_out: endpoint {
+					clock-lanes = <0>;
+					data-lanes = <1 2 3 4>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy2>;
+				};
+			};
+		};
+
+		ds90ub960_2_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&cdns_csi2rx2 {
+	ports {
+		port@0 {
+			status = "okay";
+
+			csi2_phy2: endpoint {
+				remote-endpoint = <&ds90ub960_2_csi_out>;
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx2 {
+	status = "okay";
+};
+
+&dphy_rx2 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-am69-sk-pcie0-ep.dtso b/arch/arm64/boot/dts/ti/k3-am69-sk-pcie0-ep.dtso
--- a/arch/arm64/boot/dts/ti/k3-am69-sk-pcie0-ep.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk-pcie0-ep.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for enabling PCIE0 instances of PCIe in Endpoint Configuration
+ * on AM69-SK.
+ *
+ * AM69-SK Product Link: https://www.ti.com/tool/SK-AM69
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+#include "k3-pinctrl.h"
+
+/*
+ * Since Root Complex and Endpoint modes are mutually exclusive
+ * disable Root Complex mode.
+ */
+&pcie0_rc {
+	status = "disabled";
+};
+
+&cbass_main {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&gic500>;
+
+	pcie0_ep: pcie-ep@2900000 {
+		compatible = "ti,j784s4-pcie-ep";
+		reg = <0x00 0x02900000 0x00 0x1000>,
+		      <0x00 0x02907000 0x00 0x400>,
+		      <0x00 0x0d000000 0x00 0x00800000>,
+		      <0x00 0x10000000 0x00 0x08000000>;
+		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+		interrupt-names = "link_state";
+		interrupts = <GIC_SPI 318 IRQ_TYPE_EDGE_RISING>;
+		max-link-speed = <3>;
+		num-lanes = <4>;
+		power-domains = <&k3_pds 332 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 332 0>;
+		clock-names = "fck";
+		max-functions = /bits/ 8 <6>;
+		max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+		dma-coherent;
+		phys = <&serdes1_pcie_link>;
+		phy-names = "pcie-phy";
+		ti,syscon-pcie-ctrl = <&pcie0_ctrl 0x0>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-cm-0-0.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-cm-0-0.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-cm-0-0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-cm-0-0.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * Copyright (c) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 0 */
+	port@0 {
+		reg = <0>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@0 {
+		reg = <0>;
+		i2c-alias = <0x44>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@21 {
+					compatible = "sony,imx390";
+					reg = <0x21>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 0 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 1 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-cm-0-1.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-cm-0-1.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-cm-0-1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-cm-0-1.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * Copyright (c) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 1 */
+	port@1 {
+		reg = <1>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@1 {
+		reg = <1>;
+		i2c-alias = <0x45>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@21 {
+					compatible = "sony,imx390";
+					reg = <0x21>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 0 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 1 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
+
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-0.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-0.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-0.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * Copyright (c) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 0 */
+	port@0 {
+		reg = <0>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@0 {
+		reg = <0>;
+		i2c-alias = <0x44>;
+
+		ti,rx-mode = <3>;
+		ti,cdr-mode = <0>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@1a {
+					compatible = "sony,imx390";
+					reg = <0x1a>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 1 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 0 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-1.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-1.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-1.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * Copyright (c) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 1 */
+	port@1 {
+		reg = <1>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@1 {
+		reg = <1>;
+		i2c-alias = <0x45>;
+
+		ti,rx-mode = <3>;
+		ti,cdr-mode = <0>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@1a {
+					compatible = "sony,imx390";
+					reg = <0x1a>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 1 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 0 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-2.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-2.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-2.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * Copyright (c) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 2 */
+	port@2 {
+		reg = <2>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@2 {
+		reg = <2>;
+		i2c-alias = <0x46>;
+
+		ti,rx-mode = <3>;
+		ti,cdr-mode = <0>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@1a {
+					compatible = "sony,imx390";
+					reg = <0x1a>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 1 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 0 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-3.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-3.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-3.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-0-3.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * Copyright (c) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 3 */
+	port@3 {
+		reg = <3>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@3 {
+		reg = <3>;
+		i2c-alias = <0x47>;
+
+		ti,rx-mode = <3>;
+		ti,cdr-mode = <0>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@1a {
+					compatible = "sony,imx390";
+					reg = <0x1a>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 1 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 0 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-0.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-0.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-0.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * https://www.d3engineering.co/product/designcore-d3rcm-imx390-953-rugged-camera-module/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 0 */
+	port@0 {
+		reg = <0>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_1_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@0 {
+		reg = <0>;
+		i2c-alias = <0x54>;
+
+		ti,cdr-mode = <0>;
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@1a {
+					compatible = "sony,imx390";
+					reg = <0x1a>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 1 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 0 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-1.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-1.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-1.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * https://www.d3engineering.co/product/designcore-d3rcm-imx390-953-rugged-camera-module/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 1 */
+	port@1 {
+		reg = <1>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_1_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@1 {
+		reg = <1>;
+		i2c-alias = <0x55>;
+
+		ti,rx-mode = <3>;
+		ti,cdr-mode = <0>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@1a {
+					compatible = "sony,imx390";
+					reg = <0x1a>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 1 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 0 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-2.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-2.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-2.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * https://www.d3engineering.co/product/designcore-d3rcm-imx390-953-rugged-camera-module/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 2 */
+	port@2 {
+		reg = <2>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_1_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@2 {
+		reg = <2>;
+		i2c-alias = <0x56>;
+
+		ti,rx-mode = <3>;
+		ti,cdr-mode = <0>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@1a {
+					compatible = "sony,imx390";
+					reg = <0x1a>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 1 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 0 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-3.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-3.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-3.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-1-3.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * https://www.d3engineering.co/product/designcore-d3rcm-imx390-953-rugged-camera-module/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 3 */
+	port@3 {
+		reg = <3>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_1_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@3 {
+		reg = <3>;
+		i2c-alias = <0x57>;
+
+		ti,rx-mode = <3>;
+		ti,cdr-mode = <0>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@1a {
+					compatible = "sony,imx390";
+					reg = <0x1a>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 1 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 0 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-0.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-0.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-0.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * https://www.d3engineering.co/product/designcore-d3rcm-imx390-953-rugged-camera-module/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_2_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 0 */
+	port@0 {
+		reg = <0>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_2_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@0 {
+		reg = <0>;
+		i2c-alias = <0x64>;
+
+		ti,rx-mode = <3>;
+		ti,cdr-mode = <0>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@1a {
+					compatible = "sony,imx390";
+					reg = <0x1a>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 1 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 0 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-1.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-1.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-1.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * https://www.d3engineering.co/product/designcore-d3rcm-imx390-953-rugged-camera-module/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_2_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 1 */
+	port@1 {
+		reg = <1>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_2_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@1 {
+		reg = <1>;
+		i2c-alias = <0x65>;
+
+		ti,rx-mode = <3>;
+		ti,cdr-mode = <0>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@1a {
+					compatible = "sony,imx390";
+					reg = <0x1a>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 1 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 0 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-2.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-2.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-2.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * https://www.d3engineering.co/product/designcore-d3rcm-imx390-953-rugged-camera-module/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_2_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 2 */
+	port@2 {
+		reg = <2>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_2_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@2 {
+		reg = <2>;
+		i2c-alias = <0x66>;
+
+		ti,rx-mode = <3>;
+		ti,cdr-mode = <0>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@1a {
+					compatible = "sony,imx390";
+					reg = <0x1a>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 1 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 0 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-3.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-3.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-3.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx390-rcm-2-3.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * https://www.d3engineering.co/product/designcore-d3rcm-imx390-953-rugged-camera-module/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_2_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 3 */
+	port@3 {
+		reg = <3>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_2_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@3 {
+		reg = <3>;
+		i2c-alias = <0x67>;
+
+		ti,rx-mode = <3>;
+		ti,cdr-mode = <0>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@1a {
+					compatible = "sony,imx390";
+					reg = <0x1a>;
+
+					clocks = <&serializer>;
+					clock-names = "inck";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <27000000>;
+
+					xclr-gpios = <&serializer 1 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&serializer 3 GPIO_ACTIVE_HIGH>;
+					comready-gpios = <&serializer 0 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-imx728-rcm-0-0.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-imx728-rcm-0-0.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-imx728-rcm-0-0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-imx728-rcm-0-0.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * D3 IMX728 FPD-Link 4 Camera Module
+ *
+ * Copyright (c) 2024 Define Design Deploy Corp - https://www.d3embedded.com
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx728_fixed_00: imx728-inck-00 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 0 */
+	port@0 {
+		reg = <0>;
+		ub9702_fpd4_1_in: endpoint {
+			remote-endpoint = <&ub971_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@0 {
+		reg = <0>;
+		i2c-alias = <0x44>;
+
+		ti,cdr-mode = <1>;
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub971-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub971_1_in: endpoint {
+						data-lanes = <1 2 3 4>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub971_1_out: endpoint {
+						remote-endpoint = <&ub9702_fpd4_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sens_exp: gpio@70 {
+					compatible = "nxp,pca9538";
+					reg = <0x70>;
+					gpio-controller;
+					#gpio-cells = <2>;
+					gpio-line-names = "IMG_RESET", "IMG_ERR0",
+							  "IMG_ERR1", "IMG_GPI0",
+							  "IMG_GPI1", "NC",
+							  "NC", "NC";
+				};
+
+				sensor@1a {
+					compatible = "sony,imx728";
+					reg = <0x1a>;
+
+					clocks = <&clk_imx728_fixed_00>;
+					clock-names = "inck";
+
+					reset-gpios = <&sens_exp 0 GPIO_ACTIVE_LOW>;
+					error0-gpios = <&sens_exp 1 GPIO_ACTIVE_HIGH>;
+					error1-gpios = <&sens_exp 2 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub971_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-0.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-0.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-0.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * Copyright (c) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 0 */
+	port@0 {
+		reg = <0>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@0 {
+		reg = <0>;
+		i2c-alias = <0x44>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2>;
+						/*clock-noncontinuous;*/
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@60 {
+					compatible = "ovti,ov2312";
+					reg = <0x60>;
+
+					clocks = <&serializer>;
+					clock-names = "xvclk";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <24000000>;
+
+					reset-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-1.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-1.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-1.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * Copyright (c) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 1 */
+	port@1 {
+		reg = <1>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@1 {
+		reg = <1>;
+		i2c-alias = <0x45>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2>;
+						/*clock-noncontinuous;*/
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@60 {
+					compatible = "ovti,ov2312";
+					reg = <0x60>;
+
+					clocks = <&serializer>;
+					clock-names = "xvclk";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <24000000>;
+
+					reset-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-2.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-2.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-2.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * Copyright (c) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 2 */
+	port@2 {
+		reg = <2>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@2 {
+		reg = <2>;
+		i2c-alias = <0x46>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2>;
+						/*clock-noncontinuous;*/
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@60 {
+					compatible = "ovti,ov2312";
+					reg = <0x60>;
+
+					clocks = <&serializer>;
+					clock-names = "xvclk";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <24000000>;
+
+					reset-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-3.dtso b/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-3.dtso
--- a/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-3.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-fpdlink-ov2312-0-3.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX390 FPD-Link 3 Camera Module
+ * Copyright (c) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 3 */
+	port@3 {
+		reg = <3>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@3 {
+		reg = <3>;
+		i2c-alias = <0x47>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						data-lanes = <1 2>;
+						/*clock-noncontinuous;*/
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@60 {
+					compatible = "ovti,ov2312";
+					reg = <0x60>;
+
+					clocks = <&serializer>;
+					clock-names = "xvclk";
+					assigned-clocks = <&serializer>;
+					assigned-clock-rates = <24000000>;
+
+					reset-gpios = <&serializer 2 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts	2025-10-23 09:30:40.283462146 -0400
@@ -11,6 +11,7 @@
 #include <dt-bindings/phy/phy.h>
 
 #include "k3-serdes.h"
+#include "k3-timesync-router.h"
 
 / {
 	compatible = "ti,j7200-evm", "ti,j7200";
@@ -129,6 +130,7 @@
 			J721E_WKUP_IOPAD(0x8c, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
 			J721E_WKUP_IOPAD(0x88, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
 		>;
+		bootph-all;
 	};
 
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
@@ -136,6 +138,7 @@
 			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
 			J721E_WKUP_IOPAD(0x4c, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
 		>;
+		bootph-all;
 	};
 
 	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
@@ -204,6 +207,7 @@
 			J721E_IOPAD(0xc0, PIN_INPUT, 2) /* (W3) SPI0_CS0.UART0_CTSn */
 			J721E_IOPAD(0xc4, PIN_OUTPUT, 2) /* (U5) SPI0_CS1.UART0_RTSn */
 		>;
+		bootph-all;
 	};
 
 	main_uart1_pins_default: main-uart1-default-pins {
@@ -238,6 +242,7 @@
 			J721E_IOPAD(0xec, PIN_INPUT, 0) /* (N19) MMC1_DAT3 */
 			J721E_IOPAD(0xe4, PIN_INPUT, 8) /* (V1) TIMER_IO0.MMC1_SDCD */
 		>;
+		bootph-all;
 	};
 
 	vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
@@ -259,6 +264,7 @@
 		pinctrl-single,pins = <
 			J721E_IOPAD(0x04, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */
 		>;
+		bootph-all;
 	};
 };
 
@@ -267,12 +273,14 @@
 	status = "reserved";
 	pinctrl-names = "default";
 	pinctrl-0 = <&wkup_uart0_pins_default>;
+	bootph-all;
 };
 
 &mcu_uart0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_uart0_pins_default>;
+	bootph-all;
 };
 
 &main_uart0 {
@@ -281,6 +289,7 @@
 	power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_uart0_pins_default>;
+	bootph-all;
 };
 
 &main_uart1 {
@@ -315,6 +324,11 @@
 &mcu_cpsw {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_cpsw_pins_default>, <&mcu_mdio_pins_default>;
+
+	cpts@3d000 {
+		/* Map HW4_TS_PUSH to GENF1 */
+		ti,pps = <3 1>;
+	};
 };
 
 &davinci_mdio {
@@ -379,6 +393,7 @@
 	/* eMMC */
 	status = "okay";
 	non-removable;
+	bootph-all;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
@@ -390,6 +405,7 @@
 	pinctrl-names = "default";
 	vmmc-supply = <&vdd_mmc1>;
 	vqmmc-supply = <&vdd_sd_dv>;
+	bootph-all;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
@@ -399,13 +415,19 @@
 		      <J7200_SERDES0_LANE2_QSGMII_LANE1>, <J7200_SERDES0_LANE3_IP4_UNUSED>;
 };
 
+&mcu_spi1 {
+	mux-controls = <&spi1_linkdis 0>;
+};
+
 &usb_serdes_mux {
 	idle-states = <1>; /* USB0 to SERDES lane 3 */
+	bootph-all;
 };
 
 &usbss0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_usbss0_pins_default>;
+	bootph-all;
 	ti,vbus-divider;
 	ti,usb2-only;
 };
@@ -413,6 +435,7 @@
 &usb0 {
 	dr_mode = "otg";
 	maximum-speed = "high-speed";
+	bootph-all;
 };
 
 &tscadc0 {
@@ -471,3 +494,12 @@
 	pinctrl-0 = <&main_mcan3_pins_default>;
 	phys = <&transceiver3>;
 };
+
+&timesync_router {
+	/* Use Time Sync Router to map GENF1 input to HW4_TS_PUSH output */
+	mux-reg-masks-state = <
+		/* pps [mcu cpsw cpts genf1] in17 -> out25 [mcu cpsw cpts hw4_push] */
+		K3_TS_OFFSET(25, 0x0001ffff, 17)
+		>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j7200-evm-ethfw.dtso b/arch/arm64/boot/dts/ti/k3-j7200-evm-ethfw.dtso
--- a/arch/arm64/boot/dts/ti/k3-j7200-evm-ethfw.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j7200-evm-ethfw.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for CPSW5G functionality with Ethernet Switch Firmware (EthFw)
+ * and CPSW Proxy Client driver.
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+/* uart2 is assigned to EthFw running on remote CPU core */
+&main_uart2 {
+	status = "reserved";
+};
+
+/* Reserve shared memory for inter-core network communication */
+&reserved_memory {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	main_r5fss0_core0_shared_memory_queue_region:r5f-virtual-eth-queues@a5000000 {
+		compatible = "shared-dma-pool";
+		reg = <0x00 0xa5000000 0x00 0x200000>;
+		no-map;
+	};
+
+	main_r5fss0_core0_shared_memory_bufpool_region:r5f-virtual-eth-buffers@a5200000 {
+		compatible = "shared-dma-pool";
+		reg = <0x00 0xa5200000 0x00 0x1e00000>;
+		no-map;
+	};
+};
+
+&main_r5fss0_core0 {
+	memory-region = <&main_r5fss0_core0_dma_memory_region>,
+			<&main_r5fss0_core0_memory_region>,
+			<&main_r5fss0_core0_shared_memory_queue_region>,
+			<&main_r5fss0_core0_shared_memory_bufpool_region>;
+};
+
+/* EthFw uses timers so mark them reserved */
+&main_timer0 {
+	status = "reserved";
+};
+
+&main_timer1 {
+	status = "reserved";
+};
+
+&main_timer2 {
+	status = "reserved";
+};
+
+&main_timer3 {
+	status = "reserved";
+};
+
+&main_timer4 {
+	status = "reserved";
+};
+
+&main_timer5 {
+	status = "reserved";
+};
+
+&main_timer6 {
+	status = "reserved";
+};
+
+&main_timer7 {
+	status = "reserved";
+};
+
+&main_timer8 {
+	status = "reserved";
+};
+
+&main_timer9 {
+	status = "reserved";
+};
+
+&main_timer10 {
+	status = "reserved";
+};
+
+&main_timer11 {
+	status = "reserved";
+};
+
+&main_timer12 {
+	status = "reserved";
+};
+
+&main_timer13 {
+	status = "reserved";
+};
+
+&main_timer14 {
+	status = "reserved";
+};
+
+&main_timer15 {
+	status = "reserved";
+};
+
+&main_timer16 {
+	status = "reserved";
+};
+
+&main_timer17 {
+	status = "reserved";
+};
+
+&main_timer18 {
+	status = "reserved";
+};
+
+&main_timer19 {
+	status = "reserved";
+};
+
+/* EthFw configures pin W16 (MCAN3_RX) for PPS demo */
+&main_mcan3 {
+	status = "disabled";
+};
+
+&transceiver3 {
+	status = "disabled";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j7200-evm-mcspi-loopback.dtso b/arch/arm64/boot/dts/ti/k3-j7200-evm-mcspi-loopback.dtso
--- a/arch/arm64/boot/dts/ti/k3-j7200-evm-mcspi-loopback.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j7200-evm-mcspi-loopback.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MCSPI internal master-slave loopback example overlay for J7200.
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * J7200 has MCSPI4 connected as master to MCU_MCSPI2 by default and not
+ * pinned out to external pads, This overlay enables spidev on these
+ * interfaces for userspace testing.
+ */
+
+/dts-v1/;
+/plugin/;
+
+&main_spi4 {
+	status = "okay";
+	#address-cells = <0>;
+	#size-cells = <0>;
+	spi-slave;
+	dmas = <&main_udmap 0xc610>, <&main_udmap 0x4610>;
+	dma-names = "tx0", "rx0";
+
+	slave {
+		/*
+		 * Using spidev compatible is warned loudly,
+		 * thus use another equivalent compatible id
+		 * from spidev.
+		 */
+		compatible = "rohm,dh2228fv";
+		spi-max-frequency = <24000000>;
+	};
+};
+
+&mcu_spi2 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	spidev@0 {
+		/*
+		 * Using spidev compatible is warned loudly,
+		 * thus use another equivalent compatible id
+		 * from spidev.
+		 */
+		compatible = "rohm,dh2228fv";
+		spi-max-frequency = <24000000>;
+		reg = <0>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j7200-evm-pcie1-ep.dtso b/arch/arm64/boot/dts/ti/k3-j7200-evm-pcie1-ep.dtso
--- a/arch/arm64/boot/dts/ti/k3-j7200-evm-pcie1-ep.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j7200-evm-pcie1-ep.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for enabling PCIE1 instance in Endpoint Configuration with the
+ * J7 common processor board.
+ *
+ * J7 Common Processor Board Product Link: https://www.ti.com/tool/J721EXCPXEVM
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+#include "k3-pinctrl.h"
+
+/*
+ * Since Root Complex and Endpoint modes are mutually exclusive
+ * disable Root Complex mode.
+ */
+&pcie1_rc {
+	status = "disabled";
+};
+
+&cbass_main {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&gic500>;
+
+	pcie1_ep: pcie-ep@2910000 {
+		compatible = "ti,j7200-pcie-ep", "ti,j721e-pcie-ep";
+		reg = <0x00 0x02910000 0x00 0x1000>,
+		      <0x00 0x02917000 0x00 0x400>,
+		      <0x00 0x0d800000 0x00 0x00800000>,
+		      <0x00 0x18000000 0x00 0x08000000>;
+		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+		interrupt-names = "link_state";
+		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
+		max-link-speed = <3>;
+		num-lanes = <2>;
+		power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 240 6>;
+		clock-names = "fck";
+		max-functions = /bits/ 8 <6>;
+		max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+		dma-coherent;
+		phys = <&serdes0_pcie_link>;
+		phy-names = "pcie-phy";
+		ti,syscon-pcie-ctrl = <&pcie1_ctrl 0x0>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -25,13 +25,17 @@
 		};
 	};
 
-	scm_conf: scm-conf@100000 {
-		compatible = "ti,j721e-system-controller", "syscon", "simple-mfd";
-		reg = <0x00 0x00100000 0x00 0x1c000>;
+	scm_conf: bus@100000 {
+		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges = <0x00 0x00 0x00100000 0x1c000>;
 
+		pcie1_ctrl: pcie-ctrl@4074 {
+			compatible = "ti,j784s4-pcie-ctrl", "syscon";
+			reg = <0x4074 0x4>;
+		};
+
 		serdes_ln_ctrl: mux-controller@4080 {
 			compatible = "reg-mux";
 			reg = <0x4080 0x20>;
@@ -136,6 +140,7 @@
 			      <0x00 0x32800000 0x00 0x100000>;
 			interrupt-names = "rx_011";
 			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+			bootph-all;
 		};
 
 		hwspinlock: spinlock@30e00000 {
@@ -758,12 +763,12 @@
 		reg = <0x00 0x02910000 0x00 0x1000>,
 		      <0x00 0x02917000 0x00 0x400>,
 		      <0x00 0x0d800000 0x00 0x00800000>,
-		      <0x00 0x18000000 0x00 0x00001000>;
+		      <0x41 0x00000000 0x00 0x00001000>; /* ECAM (4 KB) */
 		reg-names = "intd_cfg", "user_cfg", "reg", "cfg";
 		interrupt-names = "link_state";
 		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
 		device_type = "pci";
-		ti,syscon-pcie-ctrl = <&scm_conf 0x4074>;
+		ti,syscon-pcie-ctrl = <&pcie1_ctrl 0x0>;
 		max-link-speed = <3>;
 		num-lanes = <4>;
 		power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>;
@@ -777,8 +782,8 @@
 		device-id = <0xb00f>;
 		msi-map = <0x0 &gic_its 0x0 0x10000>;
 		dma-coherent;
-		ranges = <0x01000000 0x0 0x18001000  0x00 0x18001000  0x0 0x0010000>,
-			 <0x02000000 0x0 0x18011000  0x00 0x18011000  0x0 0x7fef000>;
+		ranges = <0x01000000 0x00 0x00001000 0x41 0x00001000 0x00 0x00100000>, /* IO (1 MB) */
+			 <0x02000000 0x00 0x00101000 0x41 0x00101000 0x00 0xffeff000>; /* 32-bit Non-Prefetchable MEM (4 GB - 1 MB - 4 KB) */
 		dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
 		status = "disabled";
 	};
@@ -1545,6 +1550,14 @@
 	main_esm: esm@700000 {
 		compatible = "ti,j721e-esm";
 		reg = <0x0 0x700000 0x0 0x1000>;
+		bootph-pre-ram;
 		ti,esm-pins = <656>, <657>;
 	};
+
+	timesync_router: mux-controller@a40000 {
+		compatible = "reg-mux";
+		reg = <0x0 0xa40000 0x0 0x800>;
+		#mux-control-cells = <1>;
+		status = "disabled";
+	};
 };
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -21,16 +21,19 @@
 		k3_pds: power-controller {
 			compatible = "ti,sci-pm-domain";
 			#power-domain-cells = <2>;
+			bootph-all;
 		};
 
 		k3_clks: clock-controller {
 			compatible = "ti,k2g-sci-clk";
 			#clock-cells = <2>;
+			bootph-all;
 		};
 
 		k3_reset: reset-controller {
 			compatible = "ti,sci-reset";
 			#reset-cells = <2>;
+			bootph-all;
 		};
 	};
 
@@ -44,6 +47,7 @@
 		assigned-clocks = <&k3_clks 35 1>;
 		assigned-clock-parents = <&k3_clks 35 2>;
 		power-domains = <&k3_pds 35 TI_SCI_PD_EXCLUSIVE>;
+		bootph-pre-ram;
 		ti,timer-pwm;
 	};
 
@@ -180,6 +184,13 @@
 			reg = <0x4040 0x4>;
 			#phy-cells = <1>;
 		};
+
+		spi1_linkdis: mux-controller@4060 {
+			compatible = "reg-mux";
+			reg = <0x4060 0x4>;
+			#mux-control-cells = <1>;
+			mux-reg-masks = <0x0 0x1>;
+		};
 	};
 
 	wkup_conf: bus@43000000 {
@@ -191,6 +202,7 @@
 		chipid: chipid@14 {
 			compatible = "ti,am654-chipid";
 			reg = <0x14 0x4>;
+			bootph-all;
 		};
 	};
 
@@ -344,6 +356,7 @@
 			      <0x00 0x28440000 0x00 0x40000>;
 			reg-names = "rt", "fifos", "proxy_gcfg",
 				    "proxy_target", "cfg";
+			bootph-all;
 			ti,num-rings = <286>;
 			ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */
 			ti,sci = <&dmsc>;
@@ -363,6 +376,7 @@
 				    "tchan", "rchan", "rflow";
 			msi-parent = <&main_udmass_inta>;
 			#dma-cells = <1>;
+			bootph-all;
 
 			ti,sci = <&dmsc>;
 			ti,sci-dev-id = <236>;
@@ -383,6 +397,8 @@
 		reg = <0x0 0x2a480000 0x0 0x80000>,
 		      <0x0 0x2a380000 0x0 0x80000>,
 		      <0x0 0x2a400000 0x0 0x80000>;
+		bootph-pre-ram;
+
 		/*
 		 * Marked Disabled:
 		 * Node is incomplete as it is meant for bootloaders and
@@ -534,6 +550,7 @@
 			reg = <0x00 0x47000004 0x00 0x4>;
 			#mux-control-cells = <1>;
 			mux-reg-masks = <0x0 0x2>; /* HBMC select */
+			bootph-all;
 		};
 
 		hbmc: hyperbus@47034000 {
@@ -557,6 +574,7 @@
 			cdns,fifo-depth = <256>;
 			cdns,fifo-width = <4>;
 			cdns,trigger-address = <0x0>;
+			cdns,phase-detect-selector = <2>;
 			clocks = <&k3_clks 103 0>;
 			assigned-clocks = <&k3_clks 103 0>;
 			assigned-clock-parents = <&k3_clks 103 2>;
@@ -589,7 +607,7 @@
 
 	mcu_r5fss0: r5fss@41000000 {
 		compatible = "ti,j7200-r5fss";
-		ti,cluster-mode = <1>;
+		ti,cluster-mode = <0>;
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges = <0x41000000 0x00 0x41000000 0x20000>,
@@ -652,6 +670,7 @@
 		      <0x00 0x42050000 0x00 0x350>;
 		power-domains = <&k3_pds 154 TI_SCI_PD_EXCLUSIVE>;
 		#thermal-sensor-cells = <1>;
+		bootph-pre-ram;
 	};
 
 	mcu_esm: esm@40800000 {
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -121,6 +121,7 @@
 			J721E_WKUP_IOPAD(0x24, PIN_INPUT, 1) /* (A8) MCU_OSPI0_D6.MCU_HYPERBUS0_DQ6 */
 			J721E_WKUP_IOPAD(0x28, PIN_INPUT, 1) /* (A7) MCU_OSPI0_D7.MCU_HYPERBUS0_DQ7 */
 		>;
+		bootph-all;
 	};
 
 	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-default-pins {
@@ -137,6 +138,7 @@
 			J721E_WKUP_IOPAD(0x0028, PIN_INPUT, 0)  /* MCU_OSPI0_D7 */
 			J721E_WKUP_IOPAD(0x0008, PIN_INPUT, 0)  /* MCU_OSPI0_DQS */
 		>;
+		bootph-all;
 	};
 };
 
@@ -146,6 +148,7 @@
 			J721E_WKUP_IOPAD(0x98, PIN_INPUT_PULLUP, 0) /* (F20) WKUP_I2C0_SCL */
 			J721E_WKUP_IOPAD(0x9c, PIN_INPUT_PULLUP, 0) /* (H21) WKUP_I2C0_SDA */
 		>;
+		bootph-all;
 	};
 };
 
@@ -186,6 +189,7 @@
 	flash@0,0 {
 		compatible = "cypress,hyperflash", "cfi-flash";
 		reg = <0x00 0x00 0x4000000>;
+		bootph-all;
 
 		partitions {
 			compatible = "fixed-partitions";
@@ -347,6 +351,7 @@
 				regulator-max-microvolt = <1800000>;
 				regulator-boot-on;
 				regulator-always-on;
+				bootph-all;
 			};
 
 			bucka2: buck2 {
@@ -481,6 +486,7 @@
 		cdns,tchsh-ns = <60>;
 		cdns,tslch-ns = <60>;
 		cdns,read-delay = <4>;
+		cdns,phy-mode;
 
 		partitions {
 			compatible = "fixed-partitions";
@@ -520,6 +526,7 @@
 			partition@3fc0000 {
 				label = "ospi.phypattern";
 				reg = <0x3fc0000 0x40000>;
+				bootph-all;
 			};
 		};
 	};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-BBORG_MOTOR.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-BBORG_MOTOR.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-BBORG_MOTOR.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-BBORG_MOTOR.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for BBORG_MOTOR connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-j721e-beagleboneai64-BBORG_MOTOR.kernel = __TIMESTAMP__;
+		p8_13.3000000.pwm = "k3-j721e-beagleboneai64-pwm-epwm0-p8_13.3000000.1.P8_13";
+		p8_19.3000000.pwm = "k3-j721e-beagleboneai64-pwm-epwm0-p8_19.3000000.0.P8_19";
+		p9_14.3020000.pwm = "k3-j721e-beagleboneai64-pwm-epwm2-p9_14.3020000.0.P9_14";
+		p9_16.3020000.pwm = "k3-j721e-beagleboneai64-pwm-epwm2-p9_16.3020000.1.P9_16";
+	};
+};
+
+&main_pmx0 {
+	P8_13_P8_19_pwm: P8-13-P8-19pwm-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x168, PIN_OUTPUT, 6) /* (V27) RGMII5_TD1.EHRPWM0_B */
+			J721E_IOPAD(0x164, PIN_OUTPUT, 6) /* (V29) RGMII5_TD2.EHRPWM0_A */
+		>;
+	};
+
+	P9_14_P9_16_pwm: P9-14-P9-16-pwm-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x178, PIN_OUTPUT, 6) /* (U27) RGMII5_RD3.EHRPWM2_A */
+			J721E_IOPAD(0x17C, PIN_OUTPUT, 6) /* (U24) RGMII5_RD2.EHRPWM2_B */
+		>;
+	};
+
+	bborg_motor: bborg-motor-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x10, PIN_OUTPUT, 7) /* (AJ23) PRG1_PRU0_GPO3.GPIO0_4 P8_18 m1 */
+			J721E_IOPAD(0xFC, PIN_OUTPUT, 7) /* (AB28) PRG0_PRU0_GPO19.GPIO0_62 P8_16 m2 */
+			J721E_IOPAD(0x130, PIN_OUTPUT, 7) /* (AF27) PRG0_PRU1_GPO12.GPIO0_75 P8_14 m3 */
+			J721E_IOPAD(0xD0, PIN_OUTPUT, 7) /* (AC27) PRG0_PRU0_GPO8.GPIO0_51 P8_26 m4 */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&P8_13_P8_19_pwm>;
+	status = "okay";
+};
+
+&epwm2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&P9_14_P9_16_pwm>;
+	status = "okay";
+};
+
+&{/} {
+	leds {
+		pinctrl-names = "default";
+		pinctrl-0 = <&bborg_motor>;
+		compatible = "gpio-leds";
+
+		motor-1 {
+			label = "m1_high";
+			gpios = <&main_gpio0 4 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		motor-2 {
+			label = "m2_high";
+			gpios = <&main_gpio0 62 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		motor-3 {
+			label = "m3_high";
+			gpios = <&main_gpio0 75 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		motor-4 {
+			label = "m4_high";
+			gpios = <&main_gpio0 51 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-dsi-rpi-7inch-panel.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-dsi-rpi-7inch-panel.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-dsi-rpi-7inch-panel.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-dsi-rpi-7inch-panel.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * DT Overlay for RPi 7inch touchscreen panel interfaced with DSI on
+ * J721E based BeagleBone AI-64 (BBAI-64) platform.
+ *
+ * BBAI-64: https://www.beagleboard.org/boards/beaglebone-ai-64
+ * RPi DSI Panel: https://www.raspberrypi.com/products/raspberry-pi-touch-display/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "k3-pinctrl.h"
+
+&{/} {
+	bridge_reg: bridge-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "bridge-reg";
+		gpio = <&display_reg 0 0>;
+		vin-supply = <&display_reg>;
+		enable-active-high;
+	};
+
+	panel0 {
+		compatible = "raspberrypi,7inch-dsi", "simple-panel";
+		backlight = <&display_reg>;
+		power-supply = <&display_reg>;
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&panel_bridge_out>;
+			};
+		};
+	};
+};
+
+&main_pmx0 {
+	dsi_main_i2c4_pins: dsi-main-i2c4-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0xa8, PIN_INPUT_PULLUP, 2) /* (AD19) PRG1_MDIO0_MDIO.I2C4_SCL */
+			J721E_IOPAD(0xac, PIN_INPUT_PULLUP, 2) /* (AD18) PRG1_MDIO0_MDC.I2C4_SDA */
+		>;
+	};
+};
+
+&main_i2c4 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&dsi_main_i2c4_pins>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	display_reg: regulator@45 {
+		compatible = "raspberrypi,7inch-touchscreen-panel-regulator";
+		reg = <0x45>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	touch-controller@38 {
+		compatible = "edt,edt-ft5406";
+		reg = <0x38>;
+
+		touchscreen-size-x = < 800 >;
+		touchscreen-size-y = < 480 >;
+
+		vcc-supply = <&display_reg>;
+		reset-gpio = <&display_reg 1 1>;
+
+		touchscreen-inverted-x;
+		touchscreen-inverted-y;
+	};
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@2 {
+		reg = <2>;
+
+		dpi2_out: endpoint {
+			remote-endpoint = <&dsi0_in>;
+		};
+	};
+};
+
+&dphy2 {
+	status = "okay";
+};
+
+&dsi0 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			dsi0_out: endpoint {
+				remote-endpoint = <&panel_bridge_in>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			dsi0_in: endpoint {
+				remote-endpoint = <&dpi2_out>;
+			};
+		};
+	};
+
+	bridge@0 {
+		compatible = "toshiba,tc358762";
+		reg = <0>;
+		vddc-supply = <&bridge_reg>;
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				panel_bridge_in: endpoint {
+					remote-endpoint = <&dsi0_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				panel_bridge_out: endpoint {
+					remote-endpoint = <&panel_in>;
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts	2025-10-23 09:30:40.283462146 -0400
@@ -14,6 +14,7 @@
 #include <dt-bindings/leds/common.h>
 #include <dt-bindings/net/ti-dp83867.h>
 #include <dt-bindings/phy/phy-cadence.h>
+#include "k3-j721e-beagleboneai64-pinmux.dtsi"
 
 / {
 	compatible = "beagle,j721e-beagleboneai64", "ti,j721e";
@@ -698,7 +699,7 @@
 		resets = <&serdes_wiz4 1>;
 		cdns,phy-type = <PHY_TYPE_DP>;
 		cdns,num-lanes = <4>;
-		cdns,max-bit-rate = <5400>;
+		cdns,max-bit-rate = <2700>;
 		#phy-cells = <0>;
 	};
 };
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-microtips-mf070zima-lcd3.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-microtips-mf070zima-lcd3.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-microtips-mf070zima-lcd3.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-microtips-mf070zima-lcd3.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/**
+ * DT Overlay for Microtips SK-LCD3 interfaced with DSI on
+ * J721E based BeagleBone AI-64 (BBAI-64) platform.
+ *
+ * BBAI-64: https://www.beagleboard.org/boards/beaglebone-ai-64
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+	dsi_main_i2c4_pins: dsi-main-i2c4-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0xa8, PIN_INPUT_PULLUP, 2) /* (AD19) PRG1_MDIO0_MDIO.I2C4_SCL */
+			J721E_IOPAD(0xac, PIN_INPUT_PULLUP, 2) /* (AD18) PRG1_MDIO0_MDC.I2C4_SDA */
+		>;
+	};
+
+	dsi0_gpio_pins_default: dsi0-gpio-default-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x18c, PIN_OUTPUT, 7) /* (V23) RGMII6_RX_CTL.GPIO0_98 */
+			J721E_IOPAD(0x1b4, PIN_INPUT, 7) /* (W25) RGMII6_RD0.GPIO0_108 */
+		>;
+	};
+};
+
+&main_i2c4 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&dsi_main_i2c4_pins>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	touchscreen@41 {
+		compatible = "ilitek,ili251x";
+		reg = <0x41>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&dsi0_gpio_pins_default>;
+		reset-gpios = <&main_gpio0 98 GPIO_ACTIVE_LOW>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <108 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@2 {
+		reg = <2>;
+
+		dpi2_out: endpoint {
+			remote-endpoint = <&dsi0_in>;
+		};
+	};
+};
+
+&dphy2 {
+	status = "okay";
+};
+
+&dsi0 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			dsi0_out: endpoint {
+				remote-endpoint = <&panel_in>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			dsi0_in: endpoint {
+				remote-endpoint = <&dpi2_out>;
+			};
+		};
+	};
+
+	dsi_panel0: panel-dsi@0 {
+		compatible = "microtips,mf-070zimacaa0", "ilitek,ili9881c";
+		reg = <0>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&dsi0_out>;
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pinmux.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pinmux.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pinmux.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pinmux.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * https://beagleboard.org/ai-64
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Jason Kridner, BeagleBoard.org Foundation
+ * Copyright (C) 2022-2024 Robert Nelson, BeagleBoard.org Foundation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	chosen {
+		base_dtb = "k3-j721e-beagleboneai64.dts";
+		base_dtb_timestamp = __TIMESTAMP__;
+	};
+
+	leds {
+		led-0 {
+			label = "beaglebone:green:usr0";
+		};
+
+		led-1 {
+			label = "beaglebone:green:usr1";
+		};
+
+		led-2 {
+			label = "beaglebone:green:usr2";
+		};
+
+		led-3 {
+			label = "beaglebone:green:usr3";
+		};
+
+		led-4 {
+			label = "beaglebone:green:usr4";
+			linux,default-trigger = "phy0tx";
+		};
+	};
+};
+
+&main_pmx0 {
+	pinctrl-single,gpio-range =
+		<&main_pmx0_range 0 18 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 19 110 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 129 29 PIN_GPIO_RANGE_IOPAD>,
+		<&main_pmx0_range 164 7 PIN_GPIO_RANGE_IOPAD>;
+
+	main_pmx0_range: gpio-range {
+		#pinctrl-single,gpio-range-cells = <3>;
+	};
+};
+
+&wkup_pmx0 {
+	pinctrl-single,gpio-range =
+		<&wkup_pmx_range 44 16 PIN_GPIO_RANGE_IOPAD>,
+		<&wkup_pmx_range 0 44 PIN_GPIO_RANGE_IOPAD>,
+		<&wkup_pmx_range 60 24 PIN_GPIO_RANGE_IOPAD>;
+
+	wkup_pmx_range: gpio-range {
+		#pinctrl-single,gpio-range-cells = <3>;
+	};
+};
+
+&main_gpio0 {
+	gpio-line-names = "", "", "", "", "P8_18", /* 0-4 */
+			  "", "", "", "", "", /* 5-9 */
+			  "", "", "", "", "", /* 10-14 */
+			  "", "", "", "", "", /* 15-19 */
+			  "", "", "", "", "", /* 20-24 */
+			  "", "", "", "", "", /* 25-29 */
+			  "", "", "", "", "", /* 30-34 */
+			  "", "", "", "", "", /* 35-39 */
+			  "", "", "", "", "", /* 40-44 */
+			  "", "", "", "", "", /* 45-49 */
+			  "", "P8_26", "", "", "", /* 50-54 */
+			  "", "", "", "", "", /* 55-59 */
+			  "", "", "P8_16", "", "", /* 60-64 */
+			  "", "", "", "", "", /* 65-69 */
+			  "", "", "", "", "", /* 70-74 */
+			  "P8_14", "", "", "", "", /* 75-79 */
+			  "", "", "", "", "", /* 80-84 */
+			  "", "", "", "", "", /* 85-89 */
+			  "", "", "", "P9_14", "P9_16", /* 90-94 */
+			  "", "", "", "", ""; /* 95-99 */
+};
+
+&main_gpio1 {
+	gpio-line-names = "", "", "", "", "", /* 0-4 */
+			  "", "", "", "", "", /* 5-9 */
+			  "", "", "", "", "", /* 10-14 */
+			  "", "", "", "", "", /* 15-19 */
+			  "", "", "", "", "", /* 20-24 */
+			  "", "", "", "", "", /* 25-29 */
+			  "", "", "", "", "", /* 30-34 */
+			  "", "", "", "", "", /* 35-39 */
+			  "", "", "", "", ""; /* 40-44 */
+};
+
+&wkup_gpio0 {
+	gpio-ranges = <&wkup_pmx0 0 44 16>, <&wkup_pmx0 16 0 44>,
+		      <&wkup_pmx0 60 60 24>;
+};
+
+bone_i2c_2: &main_i2c2 {
+	/* BBB Header: P9.19 and P9.20 */
+	clock-frequency = <100000>;
+};
+
+bone_i2c_3: &main_i2c4 {
+	/* BBB Header: P9.24 and P9.26 */
+	clock-frequency = <100000>;
+};
+
+bone_i2c_1: &main_i2c6 {
+	/* BBB Header: P9.17 and P9.18 */
+	clock-frequency = <100000>;
+};
+
+epwm0: &main_ehrpwm0 {
+	status = "okay";
+};
+
+epwm2: &main_ehrpwm2 {
+	status = "okay";
+};
+
+&pcie1_rc {
+	/*
+	 * There is no on-board or external reference clock generators,
+	 * use refclk from the ACSPCIE module's PAD IO Buffers.
+	 */
+	ti,syscon-acspcie-proxy-ctrl = <&acspcie0_proxy_ctrl 0x3>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm0-p8_13.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm0-p8_13.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm0-p8_13.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm0-p8_13.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for P8_13 epwm0 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-j721e-beagleboneai64-pwm-epwm0-p8_13.kernel = __TIMESTAMP__;
+		p8_13.3000000.pwm = "k3-j721e-beagleboneai64-pwm-epwm0-p8_13.3000000.1.P8_13";
+	};
+};
+
+&main_pmx0 {
+	P8_13_pwm: P8-13-pwm-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x168, PIN_OUTPUT, 6) /* (V27) RGMII5_TD1.EHRPWM0_B */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&P8_13_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm0-p8_13-p8_19.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm0-p8_13-p8_19.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm0-p8_13-p8_19.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm0-p8_13-p8_19.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for P8_13 and P8_19 epwm0 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-j721e-beagleboneai64-pwm-epwm0-p8_13-p8_19.kernel = __TIMESTAMP__;
+		p8_13.3000000.pwm = "k3-j721e-beagleboneai64-pwm-epwm0-p8_13.3000000.1.P8_13";
+		p8_19.3000000.pwm = "k3-j721e-beagleboneai64-pwm-epwm0-p8_19.3000000.0.P8_19";
+	};
+};
+
+&main_pmx0 {
+	P8_13_P8_19_pwm: P8-13-P8-19pwm-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x168, PIN_OUTPUT, 6) /* (V27) RGMII5_TD1.EHRPWM0_B */
+			J721E_IOPAD(0x164, PIN_OUTPUT, 6) /* (V29) RGMII5_TD2.EHRPWM0_A */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&P8_13_P8_19_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm0-p8_19.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm0-p8_19.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm0-p8_19.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm0-p8_19.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for P8_19 epwm0 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-j721e-beagleboneai64-pwm-epwm0-p8_19.kernel = __TIMESTAMP__;
+		p8_19.3000000.pwm = "k3-j721e-beagleboneai64-pwm-epwm0-p8_19.3000000.0.P8_19";
+	};
+};
+
+&main_pmx0 {
+	P8_19_pwm: P8-19-pwm-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x164, PIN_OUTPUT, 6) /* (V29) RGMII5_TD2.EHRPWM0_A */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&P8_19_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm2-p9_14.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm2-p9_14.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm2-p9_14.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm2-p9_14.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for P9_14 epwm2 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-j721e-beagleboneai64-pwm-epwm2-p9_14.kernel = __TIMESTAMP__;
+		p9_14.3020000.pwm = "k3-j721e-beagleboneai64-pwm-epwm2-p9_14.3020000.0.P9_14";
+	};
+};
+
+&main_pmx0 {
+	P9_14_pwm: P9-14-pwm-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x178, PIN_OUTPUT, 6) /* (U27) RGMII5_RD3.EHRPWM2_A */
+		>;
+	};
+};
+
+&epwm2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&P9_14_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm2-p9_14-p9_16.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm2-p9_14-p9_16.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm2-p9_14-p9_16.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm2-p9_14-p9_16.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for P9_14 and P9_16 epwm2 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-j721e-beagleboneai64-pwm-epwm2-p9_14-p9_16.kernel = __TIMESTAMP__;
+		p9_14.3020000.pwm = "k3-j721e-beagleboneai64-pwm-epwm2-p9_14.3020000.0.P9_14";
+		p9_16.3020000.pwm = "k3-j721e-beagleboneai64-pwm-epwm2-p9_16.3020000.1.P9_16";
+	};
+};
+
+&main_pmx0 {
+	P9_14_P9_16_pwm: P9-14-P9-16-pwm-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x178, PIN_OUTPUT, 6) /* (U27) RGMII5_RD3.EHRPWM2_A */
+			J721E_IOPAD(0x17C, PIN_OUTPUT, 6) /* (U24) RGMII5_RD2.EHRPWM2_B */
+		>;
+	};
+};
+
+&epwm2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&P9_14_P9_16_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm2-p9_16.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm2-p9_16.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm2-p9_16.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm2-p9_16.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for P9_16 epwm2 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-j721e-beagleboneai64-pwm-epwm2-p9_16.kernel = __TIMESTAMP__;
+		p9_16.3020000.pwm = "k3-j721e-beagleboneai64-pwm-epwm2-p9_16.3020000.1.P9_16";
+	};
+};
+
+&main_pmx0 {
+	P9_16_pwm: P9-16-pwm-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x17C, PIN_OUTPUT, 6) /* (U24) RGMII5_RD2.EHRPWM2_B */
+		>;
+	};
+};
+
+&epwm2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&P9_16_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm4-p9_25.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm4-p9_25.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm4-p9_25.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-pwm-epwm4-p9_25.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for P9_25 epwm4 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+	overlays {
+		k3-j721e-beagleboneai64-pwm-epwm4-p9_25.kernel = __TIMESTAMP__;
+		p9_25.3040000.pwm = "k3-j721e-beagleboneai64-pwm-epwm4-p9_25.3040000.1.P9_25";
+	};
+};
+
+&main_pmx0 {
+	P9_25_pwm: P9-25-pwm-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x1A4, PIN_OUTPUT, 6) /* (W26) RGMII6_RXC.EHRPWM4_B */
+			J721E_IOPAD(0x200, PIN_DISABLE, 7) /* (AC4) UART1_CTSn.GPIO0_127 */
+		>;
+	};
+};
+
+&main_ehrpwm4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&P9_25_pwm>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi1-cs0.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi1-cs0.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi1-cs0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi1-cs0.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for SPI1 pins P8_35b(cs0), P9_26a(clk), P9_24a(MOSI).
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/*
+ * WARNING!!!
+ * This overlay will not mux if there are pin conflicts. For example, by default i2c4 is enabled taking
+ * pins P9_24 and P9_26. To stop pin conflicts, this overlay disables i2c4 and i2c6. This overlay
+ * also conflicts with SPI6_D1, the miso for spi6
+ *
+ * Look for errors in `sudo beagle-version \| grep UBOOT`
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+        overlays {
+                k3-j721e-beagleboneai64-spi-mcspi1-cs0.kernel = __TIMESTAMP__;
+                mcspi1.2110000.spi = "k3-j721e-beagleboneai64-spi-mcspi1-cs0.2110000";
+        };
+};
+
+/* Disable i2c4 to free up pins p9_24 and p9_26 */
+&main_i2c4 {
+        status = "disable";
+};
+
+/* Disable i2c6 to free up pin p9_18 */
+&main_i2c6 {
+        status = "disable";
+};
+
+/* To figure out which SoC pad numbers go with which BB header pins, look at columns A and B
+ * in the following spreadsheet. To figure out mux modes, look at row 10.
+ * https://drive.google.com/file/d/15NLaUeMBy-iT8s6rFrP4Esf0Qh57T4xu/view?pli=1
+ *
+ * To figure out the addresses of SoC pads, look at table "Table 5-125. Pin Multiplexing" in the TDA4VM Processor datasheet
+ * https://www.ti.com/lit/ds/symlink/tda4vm.pdf?ts=1741890214437&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FTDA4VM
+ *
+*/
+&main_pmx0 {
+    mcspi1_cs_zero: mcspi1-cs0-pins {
+        pinctrl-single,pins = <
+            /* Used TI SysConfig app to generate these, had manually adjust output modes */
+			J721E_IOPAD(0x1dc, PIN_OUTPUT, 0) /* (Y1) SPI1_CLK P9_26a*/
+			J721E_IOPAD(0x1d4, PIN_OUTPUT, 0) /* (Y3) SPI1_CS0 P8_35b*/
+			J721E_IOPAD(0x1e0, PIN_OUTPUT, 0) /* (Y5) SPI1_D0 P9_24a*/
+            J721E_IOPAD(0x1e4, PIN_INPUT, 0)  /* (Y2) SPI1_D1 P9_18b......Conflicts with SPI6_D1*/
+
+            /* Disable SoC pins that share same BB header pins */
+            J721E_IOPAD(0x30, PIN_DISABLE, 7) /* (AF24) disable P9_26b */
+            J721E_IOPAD(0x64, PIN_DISABLE, 7) /* (AD23) disable P835a  */
+            J721E_IOPAD(0x34, PIN_DISABLE, 7) /* (AJ24) disable P9_24b */
+            J721E_IOPAD(0xA4, PIN_DISABLE, 7) /* (AH22) disable P9_18a */
+        >;
+    };
+};
+
+/*
+ * Most of the stuff in this section is here for the spidev linux driver. For control from
+ * from a DSP or R5 core, only the status and pinctrl parts matter.
+ *
+ * Make sure to load the spidev driver to control SPI from linux.
+ */
+&main_spi1 {
+    #address-cells = <1>;
+    #size-cells = <0>;
+    pinctrl-names = "default";
+    pinctrl-0 = <&mcspi1_cs_zero>;
+    ti,spi-num-cs = <1>; /* With this number wrong, no spi device would get created, error seen with `sudo journalctl -k` */
+    ti,pindir-d0-out-d1-in; /* d1 is not really an input, the pin is not muxed */
+    status = "okay";
+
+    /* When controlling SPI from outside linux, you may want to delete this spidev stuff */
+    channel@0 {
+        symlink = "bone/spi/1.0"; /* /dev/bone/spi/1.0 */
+        compatible = "rohm,dh2228fv";
+        reg = <0>; /* CE0 */
+        spi-max-frequency = <125000000>;
+    };
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi1-cs0-no-miso.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi1-cs0-no-miso.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi1-cs0-no-miso.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi1-cs0-no-miso.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for SPI1 pins P8_35b(cs0), P9_26a(clk), P9_24a(MOSI).
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/*
+ * WARNING!!!
+ * This overlay will not mux if there are pin conflicts. For example, by default i2c4 is enabled taking
+ * pins P9_24 and P9_26. To stop pin conflicts, this overlay disables i2c4.
+ *
+ * Look for errors in `sudo beagle-version \| grep UBOOT`
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+        overlays {
+                k3-j721e-beagleboneai64-spi-mcspi1-cs0.kernel = __TIMESTAMP__;
+                mcspi1.2110000.spi = "k3-j721e-beagleboneai64-spi-mcspi1-cs0.2110000";
+        };
+};
+
+/* Disable i2c4 to free up pins p9_24 and p9_26 */
+&main_i2c4 {
+        status = "disable";
+};
+
+/* To figure out which SoC pad numbers go with which BB header pins, look at columns A and B
+ * in the following spreadsheet. To figure out mux modes, look at row 10.
+ * https://drive.google.com/file/d/15NLaUeMBy-iT8s6rFrP4Esf0Qh57T4xu/view?pli=1
+ *
+ * To figure out the addresses of SoC pads, look at table "Table 5-125. Pin Multiplexing" in the TDA4VM Processor datasheet
+ * https://www.ti.com/lit/ds/symlink/tda4vm.pdf?ts=1741890214437&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FTDA4VM
+ *
+*/
+&main_pmx0 {
+    mcspi1_cs_zero: mcspi1-cs0-pins {
+        pinctrl-single,pins = <
+            /* Used TI SysConfig app to generate these, had manually adjust output modes */
+			J721E_IOPAD(0x1dc, PIN_OUTPUT, 0) /* (Y1) SPI1_CLK P9_26a*/
+			J721E_IOPAD(0x1d4, PIN_OUTPUT, 0) /* (Y3) SPI1_CS0 P8_35b*/
+			J721E_IOPAD(0x1e0, PIN_OUTPUT, 0) /* (Y5) SPI1_D0 P9_24a*/
+            /* J721E_IOPAD(0x1e4, PIN_INPUT, 0) (Y2) SPI1_D1 P9_18b......Conflicts with SPI6_D1*/
+
+            /* Disable SoC pins that share same BB header pins */
+            J721E_IOPAD(0x30, PIN_DISABLE, 7) /* (AF24) disable P9_26b */
+            J721E_IOPAD(0x64, PIN_DISABLE, 7) /* (AD23) disable P8_35a  */
+            J721E_IOPAD(0x34, PIN_DISABLE, 7) /* (AJ24) disable P9_24b */
+            /* J721E_IOPAD(0xA4, PIN_DISABLE, 7) (0xA4) disable P9_18a .... for if we are using P9_18b */
+        >;
+    };
+};
+
+/*
+ * Most of the stuff in this section is here for the spidev linux driver. For control from
+ * from a DSP or R5 core, only the status and pinctrl parts matter.
+ *
+ * Make sure to load the spidev driver to control SPI from linux.
+ */
+&main_spi1 {
+    #address-cells = <1>;
+    #size-cells = <0>;
+    pinctrl-names = "default";
+    pinctrl-0 = <&mcspi1_cs_zero>;
+    ti,spi-num-cs = <1>; /* With this number wrong, no spi device would get created, error seen with `sudo journalctl -k` */
+    ti,pindir-d0-out-d1-in; /* d1 is not really an input, the pin is not muxed */
+    status = "okay";
+
+    /* When controlling SPI from outside linux, you may want to delete this spidev stuff */
+    channel@0 {
+        symlink = "bone/spi/1.0_no_miso"; /* /dev/bone/spi/1.0_no_miso */
+        compatible = "rohm,dh2228fv";
+        reg = <0>; /* CE0 */
+        spi-max-frequency = <125000000>;
+    };
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi2-cs0.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi2-cs0.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi2-cs0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi2-cs0.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for SPI6 pins P9_17(cs0), P9_22(clk), P9_21(MOSI), P9_18(MISO).
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/*
+ * WARNING!!!
+ * This overlay will not mux if there are pin conflicts. For example, by default i2c6 is enabled taking
+ * pins P9_17 and P9_18. To stop pin conflicts, this overlay disables i2c6.
+ *
+ * Look for errors in `sudo beagle-version \| grep UBOOT`
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+        overlays {
+                k3-j721e-beagleboneai64-spi-mcspi2-cs0.kernel = __TIMESTAMP__;
+                mcspi2.2120000.spi = "k3-j721e-beagleboneai64-spi-mcspi2-cs0.2120000";
+        };
+};
+
+/* To figure out which SoC pad numbers go with which BB header pins, look at columns A and B
+ * in the following spreadsheet. To figure out mux modes, look at row 10.
+ * https://drive.google.com/file/d/15NLaUeMBy-iT8s6rFrP4Esf0Qh57T4xu/view?pli=1
+ *
+ * To figure out the addresses of SoC pads, look at table "Table 5-125. Pin Multiplexing" in the TDA4VM Processor datasheet
+ * https://www.ti.com/lit/ds/symlink/tda4vm.pdf?ts=1741890214437&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FTDA4VM
+ *
+*/
+&main_pmx0 {
+    mcspi2_cs_zero: mcspi2-cs0-pins {
+        pinctrl-single,pins = <
+            /* Used TI SysConfig app to generate these, had manually adjust output modes */
+            J721E_IOPAD(0x1f4, PIN_OUTPUT, 4) /* (AB1) UART0_RTSn.SPI2_CLK */
+            J721E_IOPAD(0x1f0, PIN_OUTPUT, 4) /* (AC2) UART0_CTSn.SPI2_CS0 */
+            J721E_IOPAD(0x200, PIN_OUTPUT, 4) /* (AC4) UART1_CTSn.SPI2_D0 */
+            J721E_IOPAD(0x204, PIN_INPUT, 4) /* (AD5) UART1_RTSn.SPI2_D1 */
+
+            /* Disable SoC pins that share same BB header pins */
+            /* This pin conflics*/
+            J721E_IOPAD(0xbc, PIN_DISABLE, 7) /* (AD26) disable P9_27a */
+            J721E_IOPAD(0x4c, PIN_DISABLE, 7) /* (AJ21) disable P9_42b */
+            J721E_IOPAD(0x1A4, PIN_DISABLE, 7) /* (W26) disable P9_25b */
+        >;
+    };
+};
+
+/*
+ * Most of the stuff in this section is here for the spidev linux driver. For control from
+ * from a DSP or R5 core, only the status and pinctrl parts matter.
+ *
+ * Make sure to load the spidev driver to control SPI from linux.
+ */
+&main_spi2 {
+    #address-cells = <1>;
+    #size-cells = <0>;
+    pinctrl-names = "default";
+    pinctrl-0 = <&mcspi2_cs_zero>;
+    ti,spi-num-cs = <1>;
+    ti,pindir-d0-out-d1-in;
+    status = "okay";
+
+    /* When controlling SPI from outside linux, you may want to delete this spidev stuff */
+    channel@0 {
+        symlink = "bone/spi/2.0"; /* /dev/bone/spi/2.0 */
+        compatible = "rohm,dh2228fv";
+        reg = <0>; /* CE0 */
+        spi-max-frequency = <125000000>;
+    };
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi3-cs0-no-miso.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi3-cs0-no-miso.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi3-cs0-no-miso.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi3-cs0-no-miso.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for SPI6 pins P8_40(cs0), P8_46(clk), P9_40b(MOSI).
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+        overlays {
+                k3-j721e-beagleboneai64-spi-mcspi3-cs0.kernel = __TIMESTAMP__;
+                mcspi3.2130000.spi = "k3-j721e-beagleboneai64-spi-mcspi3-cs0.2130000";
+        };
+};
+
+/* To figure out which SoC pad numbers go with which BB header pins, look at columns A and B
+ * in the following spreadsheet. To figure out mux modes, look at row 10.
+ * https://drive.google.com/file/d/15NLaUeMBy-iT8s6rFrP4Esf0Qh57T4xu/view?pli=1
+ *
+ * To figure out the addresses of SoC pads, look at table "Table 5-125. Pin Multiplexing" in the TDA4VM Processor datasheet
+ * https://www.ti.com/lit/ds/symlink/tda4vm.pdf?ts=1741890214437&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FTDA4VM
+ *
+*/
+&main_pmx0 {
+    mcspi3_cs_zero: mcspi3-cs0-pins {
+        pinctrl-single,pins = <
+            /* Used TI SysConfig app to generate these, had manually adjust output modes */
+            J721E_IOPAD(0x144, PIN_OUTPUT, 4) /* (Y25) PRG0_PRU1_GPO17.SPI3_CLK P8_46 */
+            J721E_IOPAD(0x11c, PIN_OUTPUT, 4) /* (AA24) PRG0_PRU1_GPO7.SPI3_CS0 P8_40*/
+            J721E_IOPAD(0x148, PIN_OUTPUT, 4) /* (AA26) PRG0_PRU1_GPO18.SPI3_D0 P9_40b*/
+
+            /* Disable SoC pins that share same BB header pins
+             *
+             * Turns out there is no P9_40a pin connected to the main domain. You may be tempted to disable the pad K26
+             * using the J721E_WKUP_IOPAD() macro. It turns out in actuality this disables P8_20. MCU pad K26 and main domain
+             * pad AF2,as seen from the processor datasheet, happen to have the same address 11c134. It turns out the
+             * J721E_IOPAD() and J721E_WKUP_IOPAD() marcos are the same. They do not do anything different.
+             *
+            */
+        >;
+    };
+};
+
+/*
+ * Most of the stuff in this section is here for the spidev linux driver. For control from
+ * from a DSP or R5 core, only the status and pinctrl parts matter.
+ *
+ * Make sure to load the spidev driver to control SPI from linux.
+ */
+&main_spi3 {
+    #address-cells = <1>;
+    #size-cells = <0>;
+    pinctrl-names = "default";
+    pinctrl-0 = <&mcspi3_cs_zero>;
+    ti,spi-num-cs = <1>; /* With this number wrong, no spi device would get created, error seen with `sudo journalctl -k` */
+    ti,pindir-d0-out-d1-in; /* d1 is not really an input, the pin is not muxed */
+    status = "okay";
+
+    /* When controlling SPI from outside linux, you may want to delete this spidev stuff */
+    channel@0 {
+        symlink = "bone/spi/3.0_no_miso"; /* /dev/bone/spi/3.0_no_miso */
+        compatible = "rohm,dh2228fv";
+        reg = <0>; /* CE0 */
+        spi-max-frequency = <125000000>;
+    };
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi6-cs0-cs1.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi6-cs0-cs1.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi6-cs0-cs1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi6-cs0-cs1.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for SPI6 CS0 and CS1 on the BeagleBoneAI64.
+ * Pins:
+ * - CS0: P9_17a (SPI6_CS0)
+ * - CS1: P9_23 (SPI6_CS1)
+ * - CLK: P9_22a (SPI6_CLK)
+ * - MOSI: P9_21a (SPI6_D0)
+ * - MISO: P9_18a (SPI6_D1)
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/*
+ *WARNING!!!
+ * This overlay will not mux if there are pin conflicts. For example, by default i2c6 is enabled taking
+ * pins P9_17 and P9_18. To stop pin conflicts, this overlay disables i2c6.
+ *
+ * Look for errors in `sudo beagle-version \| grep UBOOT`
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+    overlays {
+        k3-j721e-beagleboneai64-spi-mcspi6-cs0-cs1.kernel = __TIMESTAMP__;
+        mcspi6.2160000.spi = "k3-j721e-beagleboneai64-spi-mcspi6-cs0-cs1.2160000";
+    };
+};
+
+/* Disable i2c6 to free up pins p9_17 and p9_18 */
+&main_i2c6 {
+        status = "disable";
+};
+
+/* To figure out which SoC pad numbers go with which BB header pins, look at columns A and B
+ * in the following spreadsheet. To figure out mux modes, look at row 10.
+ * https://drive.google.com/file/d/15NLaUeMBy-iT8s6rFrP4Esf0Qh57T4xu/view?pli=1
+ *
+ * To figure out the addresses of SoC pads, look at table "Table 5-125. Pin Multiplexing" in the TDA4VM Processor datasheet
+ * https://www.ti.com/lit/ds/symlink/tda4vm.pdf?ts=1741890214437&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FTDA4VM
+ *
+*/
+&main_pmx0 {
+	mcspi6_pins: mcspi6-pins {
+		pinctrl-single,pins = <
+            /* Used TI SysConfig app to generate these, had manually adjust output modes */
+            J721E_IOPAD(0x9c, PIN_OUTPUT, 4) /* (AC22) PRG1_PRU1_GPO17.SPI6_CLK P9_22a */
+			J721E_IOPAD(0x74, PIN_OUTPUT, 4) /* (AC21) PRG1_PRU1_GPO7.SPI6_CS0 P9_17a */
+			J721E_IOPAD(0xa0, PIN_OUTPUT, 4) /* (AJ22) PRG1_PRU1_GPO18.SPI6_D0 MOSI P9_21a */
+			J721E_IOPAD(0xa4, PIN_INPUT, 4) /* (AH22) PRG1_PRU1_GPO19.SPI6_D1 MISO P9_18a */
+            J721E_IOPAD(0x28, PIN_OUTPUT, 4) /* (AG20) PRG1_PRU1_GPO8.SPI6_CS1 P9_23 */
+
+            /* Disable SoC pins that share same BB header pins */
+            /* These pins conflict */
+            J721E_IOPAD(0x170, PIN_DISABLE, 7) /* (U29) disable P9_22b */
+            J721E_IOPAD(0x1D0, PIN_DISABLE, 7) /* (AA3) disable P9_17b */
+            J721E_IOPAD(0x16C, PIN_DISABLE, 7) /* (U28) disable P9_21b */
+            J721E_IOPAD(0x1E4, PIN_DISABLE, 7) /* (Y2) disable P9_18b */
+            /* No conflicting pad for P9_23 (AG20), so no disable needed */
+		>;
+	};
+};
+
+/*
+ * SPI6 controller configuration with support for two chip selects (CS0 and CS1).
+ *
+ *
+ * Most of the stuff in this section is here for the spidev linux driver. For control from
+ * from a DSP or R5 core, only the status and pinctrl parts matter.
+ *
+ * Make sure to load the spidev driver to control SPI from linux.
+ */
+&main_spi6 {
+    #address-cells = <1>;
+    #size-cells = <0>;
+    pinctrl-names = "default";
+    pinctrl-0 = <&mcspi6_pins>;
+    ti,spi-num-cs = <2>; /* Support two chip selects */
+    ti,pindir-d0-out-d1-in;
+    status = "okay";
+
+	/* THIS IS FOR SPIDEV, to see device at /dev/bone/spi, first run `sudo modprobe spidev` */
+	/* When controlling SPI from outside linux, you may want to delete this spidev stuff */
+
+    /* Channel for SPI6_CS0 */
+    channel@0 {
+        symlink = "bone/spi/6.0"; /* /dev/bone/spi/6.0 */
+        compatible = "rohm,dh2228fv";
+        reg = <0>; /* CE0 */
+        spi-max-frequency = <125000000>;
+    };
+
+    /* Channel for SPI6_CS1 */
+    channel@1 {
+        symlink = "bone/spi/6.1"; /* /dev/bone/spi/6.1 */
+        compatible = "rohm,dh2228fv";
+        reg = <1>;  /* CE1 */
+        spi-max-frequency = <125000000>;
+    };
+
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi6-cs0.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi6-cs0.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi6-cs0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi6-cs0.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for SPI6 pins P9_17(cs0), P9_22(clk), P9_21(MOSI), P9_18(MISO).
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/*
+ * WARNING!!!
+ * This overlay will not mux if there are pin conflicts. For example, by default i2c6 is enabled taking
+ * pins P9_17 and P9_18. To stop pin conflicts, this overlay disables i2c6.
+ *
+ * Look for errors in `sudo beagle-version \| grep UBOOT`
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+        overlays {
+                k3-j721e-beagleboneai64-spi-mcspi6-cs0.kernel = __TIMESTAMP__;
+                mcspi6.2160000.spi = "k3-j721e-beagleboneai64-spi-mcspi6-cs0.2160000";
+        };
+};
+
+/* Disable i2c6 to free up pins p9_17 and p9_18 */
+&main_i2c6 {
+        status = "disable";
+};
+
+/* To figure out which SoC pad numbers go with which BB header pins, look at columns A and B
+ * in the following spreadsheet. To figure out mux modes, look at row 10.
+ * https://drive.google.com/file/d/15NLaUeMBy-iT8s6rFrP4Esf0Qh57T4xu/view?pli=1
+ *
+ * To figure out the addresses of SoC pads, look at table "Table 5-125. Pin Multiplexing" in the TDA4VM Processor datasheet
+ * https://www.ti.com/lit/ds/symlink/tda4vm.pdf?ts=1741890214437&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FTDA4VM
+ *
+*/
+&main_pmx0 {
+    mcspi6_cs_zero: mcspi6-cs0-pins {
+        pinctrl-single,pins = <
+            /* Used TI SysConfig app to generate these, had manually adjust output modes */
+            J721E_IOPAD(0x9c, PIN_OUTPUT, 4) /* (AC22) PRG1_PRU1_GPO17.SPI6_CLK P9_22a */
+            J721E_IOPAD(0x74, PIN_OUTPUT, 4) /* (AC21) PRG1_PRU1_GPO7.SPI6_CS0 P9_17a */
+            J721E_IOPAD(0xa0, PIN_OUTPUT, 4) /* (AJ22) PRG1_PRU1_GPO18.SPI6_D0 MOSI P9_21a */
+            J721E_IOPAD(0xa4, PIN_INPUT, 4) /* (AH22) PRG1_PRU1_GPO19.SPI6_D1 MISO P9_18a */
+
+            /* Disable SoC pins that share same BB header pins */
+            /* This pin conflics*/
+            J721E_IOPAD(0x170, PIN_DISABLE, 7) /* (U29) disable P9_22b */
+            J721E_IOPAD(0x1D0, PIN_DISABLE, 7) /* (AA3) disable P9_17b */
+            J721E_IOPAD(0x16C, PIN_DISABLE, 7) /* (U28) disable P9_21b */
+            J721E_IOPAD(0x1E4, PIN_DISABLE, 7) /* (Y2) disable P9_18b */
+        >;
+    };
+};
+
+/*
+ * Most of the stuff in this section is here for the spidev linux driver. For control from
+ * from a DSP or R5 core, only the status and pinctrl parts matter.
+ *
+ * Make sure to load the spidev driver to control SPI from linux.
+ */
+&main_spi6 {
+    #address-cells = <1>;
+    #size-cells = <0>;
+    pinctrl-names = "default";
+    pinctrl-0 = <&mcspi6_cs_zero>;
+    ti,spi-num-cs = <1>;
+    ti,pindir-d0-out-d1-in;
+    status = "okay";
+
+    /* When controlling SPI from outside linux, you may want to delete this spidev stuff */
+    channel@0 {
+        symlink = "bone/spi/6.0"; /* /dev/bone/spi/6.0 */
+        compatible = "rohm,dh2228fv";
+        reg = <0>; /* CE0 */
+        spi-max-frequency = <125000000>;
+    };
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi6-cs1-no-miso.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi6-cs1-no-miso.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi6-cs1-no-miso.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi6-cs1-no-miso.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for SPI6 pins P9_23(cs1), P9_22(clk), P9_21(MOSI).
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+        overlays {
+                k3-j721e-beagleboneai64-spi-mcspi6-cs1.kernel = __TIMESTAMP__;
+                mcspi6.2160000.spi = "k3-j721e-beagleboneai64-spi-mcspi6-cs1.2160000";
+        };
+};
+
+/* To figure out which SoC pad numbers go with which BB header pins, look at columns A and B
+ * in the following spreadsheet. To figure out mux modes, look at row 10.
+ * https://drive.google.com/file/d/15NLaUeMBy-iT8s6rFrP4Esf0Qh57T4xu/view?pli=1
+ *
+ * To figure out the addresses of SoC pads, look at table "Table 5-125. Pin Multiplexing" in the TDA4VM Processor datasheet
+ * https://www.ti.com/lit/ds/symlink/tda4vm.pdf?ts=1741890214437&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FTDA4VM
+ *
+*/
+&main_pmx0 {
+	mcspi6_cs_one: mcspi6-cs1-pins {
+		pinctrl-single,pins = <
+            /* Used TI SysConfig app to generate these, had manually adjust output modes */
+            J721E_IOPAD(0x9c, PIN_OUTPUT, 4) /* (AC22) PRG1_PRU1_GPO17.SPI6_CLK P9_22a */
+			J721E_IOPAD(0xa0, PIN_OUTPUT, 4) /* (AJ22) PRG1_PRU1_GPO18.SPI6_D0 MOSI P9_21a */
+            J721E_IOPAD(0x28, PIN_OUTPUT, 4) /* (AG20) PRG1_PRU1_GPO8.SPI6_CS1 P9_23 */
+
+            /* Disable SoC pins that share same BB header pins */
+            /* This pin conflics*/
+            J721E_IOPAD(0x170, PIN_DISABLE, 7) /* (U29) disable P9_22b */
+            J721E_IOPAD(0x16C, PIN_DISABLE, 7) /* (U28) disable P9_21b */
+            /* No conflicting pad for P9_23 (AG20), so no disable needed */
+		>;
+	};
+};
+
+/*
+ * Most of the stuff in this section is here for the spidev linux driver. For control from
+ * from a DSP or R5 core, only the status and pinctrl parts matter.
+ *
+ * Make sure to load the spidev driver to control SPI from linux.
+ */
+&main_spi6 {
+    #address-cells = <1>;
+    #size-cells = <0>;
+    pinctrl-names = "default";
+    pinctrl-0 = <&mcspi6_cs_one>;
+    ti,spi-num-cs = <2>; /* With this number wrong, no spi device would get created, error seen with `sudo journalctl -k` */
+    ti,pindir-d0-out-d1-in; /* d1 is not really an input, the pin is not muxed */
+    status = "okay";
+
+	/* When controlling SPI from outside linux, you may want to delete this spidev stuff */
+    channel@1 {
+        symlink = "bone/spi/6.1_no_miso"; /* /dev/bone/spi/6.1_no_miso */
+        compatible = "rohm,dh2228fv";
+        reg = <1>; /* CE1 */
+        spi-max-frequency = <125000000>;
+    };
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi7-cs0.dtso b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi7-cs0.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi7-cs0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64-spi-mcspi7-cs0.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for pins P9_28(cs0), P9_31(clk), P9_30(MOSI), P9_29B(MISO) SPI7 connections within the expansion header.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+/*
+ * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
+*/
+&{/chosen} {
+        overlays {
+                k3-j721e-beagleboneai64-spi-mcspi7-cs0.kernel = __TIMESTAMP__;
+                mcspi7.2170000.spi = "k3-j721e-beagleboneai64-spi-mcspi7-cs0.2170000";
+        };
+};
+
+&main_pmx0 {
+	mcspi7_cs_zero: mcspi7-cs0-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x234, PIN_OUTPUT, 6) /* (U3) EXT_REFCLK1.SPI7_CLK P9_31a*/
+			J721E_IOPAD(0xD4, PIN_DISABLE, 7) /* (AB26) disable p9_31b */
+			J721E_IOPAD(0x230, PIN_OUTPUT, 6) /* (U2) ECAP0_IN_APWM_OUT.SPI7_CS0 P9_28a */
+			J721E_IOPAD(0xB0, PIN_DISABLE, 7) /* (AF28) disable p9_28b */
+			J721E_IOPAD(0x238, PIN_OUTPUT, 6) /* (V6) TIMER_IO0.SPI7_D0 MOSI P9_30a */
+			J721E_IOPAD(0xB4, PIN_DISABLE, 7) /* (AE28) disable P9_30b */
+			J721E_IOPAD(0x23c, PIN_INPUT, 6) /* (V5) TIMER_IO1.SPI7_D1 MISO P9_29a */
+			J721E_IOPAD(0xD8, PIN_DISABLE, 7) /* (AB25) disable p9_29b */
+		>;
+	};
+};
+
+/*
+ * Most of the stuff in this section is here for the spidev linux driver. For control from
+ * from a DSP or R5 core, only the status and pinctrl parts matter.
+ *
+ * Make sure to load the spidev driver to control SPI from linux.
+ */
+&main_spi7 {
+    #address-cells = <1>;
+    #size-cells = <0>;
+    pinctrl-names = "default";
+    pinctrl-0 = <&mcspi7_cs_zero>;
+    ti,spi-num-cs = <1>;
+    ti,pindir-d0-out-d1-in;
+    status = "okay";
+
+    /* When controlling SPI from outside linux, you may want to delete this spidev stuff */
+    channel@0 {
+        symlink = "bone/spi/7.0";
+        compatible = "rohm,dh2228fv";
+        reg = <0>; /* CE0 */
+        spi-max-frequency = <125000000>;
+    };
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
--- a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts	2025-10-23 09:30:40.283462146 -0400
@@ -13,6 +13,8 @@
 #include <dt-bindings/net/ti-dp83867.h>
 #include <dt-bindings/phy/phy-cadence.h>
 
+#include "k3-timesync-router.h"
+
 / {
 	compatible = "ti,j721e-evm", "ti,j721e";
 	model = "Texas Instruments J721e EVM";
@@ -193,6 +195,7 @@
 			J721E_IOPAD(0x1e8, PIN_INPUT, 0) /* (AB2) UART0_RXD */
 			J721E_IOPAD(0x1ec, PIN_OUTPUT, 0) /* (AB3) UART0_TXD */
 		>;
+		bootph-all;
 	};
 
 	main_uart1_pins_default: main-uart1-default-pins {
@@ -234,6 +237,7 @@
 			J721E_IOPAD(0x258, PIN_INPUT, 0) /* (P23) MMC1_SDCD */
 			J721E_IOPAD(0x25c, PIN_INPUT, 0) /* (R28) MMC1_SDWP */
 		>;
+		bootph-all;
 	};
 
 	vdd_sd_dv_alt_pins_default: vdd-sd-dv-alt-default-pins {
@@ -247,6 +251,7 @@
 			J721E_IOPAD(0x290, PIN_OUTPUT, 0) /* (U6) USB0_DRVVBUS */
 			J721E_IOPAD(0x210, PIN_INPUT, 7) /* (W3) MCAN1_RX.GPIO1_3 */
 		>;
+		bootph-all;
 	};
 
 	main_usbss1_pins_default: main-usbss1-default-pins {
@@ -342,6 +347,7 @@
 			J721E_WKUP_IOPAD(0xa0, PIN_INPUT, 0) /* (J29) WKUP_UART0_RXD */
 			J721E_WKUP_IOPAD(0xa4, PIN_OUTPUT, 0) /* (J28) WKUP_UART0_TXD */
 		>;
+		bootph-all;
 	};
 
 	mcu_uart0_pins_default: mcu-uart0-default-pins {
@@ -351,6 +357,7 @@
 			J721E_WKUP_IOPAD(0xe4, PIN_INPUT, 0) /* (H28) WKUP_GPIO0_13.MCU_UART0_RXD */
 			J721E_WKUP_IOPAD(0xe0, PIN_OUTPUT, 0) /* (G29) WKUP_GPIO0_12.MCU_UART0_TXD */
 		>;
+		bootph-all;
 	};
 
 	sw11_button_pins_default: sw11-button-default-pins {
@@ -370,6 +377,7 @@
 			J721E_WKUP_IOPAD(0x3c, PIN_INPUT, 0) /* (B23) MCU_OSPI1_DQS */
 			J721E_WKUP_IOPAD(0x38, PIN_INPUT, 0) /* (A23) MCU_OSPI1_LBCLKO */
 		>;
+		bootph-all;
 	};
 
 	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
@@ -435,12 +443,14 @@
 	status = "reserved";
 	pinctrl-names = "default";
 	pinctrl-0 = <&wkup_uart0_pins_default>;
+	bootph-all;
 };
 
 &mcu_uart0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_uart0_pins_default>;
+	bootph-all;
 };
 
 &main_uart0 {
@@ -449,6 +459,7 @@
 	pinctrl-0 = <&main_uart0_pins_default>;
 	/* Shared with ATF on this platform */
 	power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>;
+	bootph-all;
 };
 
 &main_uart1 {
@@ -487,6 +498,7 @@
 	/* eMMC */
 	status = "okay";
 	non-removable;
+	bootph-all;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
@@ -498,12 +510,14 @@
 	vqmmc-supply = <&vdd_sd_dv_alt>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
+	bootph-all;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
 &usb_serdes_mux {
 	idle-states = <1>, <0>; /* USB0 to SERDES3, USB1 to SERDES1 */
+	bootph-all;
 };
 
 &serdes_ln_ctrl {
@@ -513,6 +527,7 @@
 		      <J721E_SERDES3_LANE0_USB3_0_SWAP>, <J721E_SERDES3_LANE1_USB3_0>,
 		      <J721E_SERDES4_LANE0_EDP_LANE0>, <J721E_SERDES4_LANE1_EDP_LANE1>,
 		      <J721E_SERDES4_LANE2_EDP_LANE2>, <J721E_SERDES4_LANE3_EDP_LANE3>;
+	bootph-all;
 };
 
 &serdes_wiz3 {
@@ -533,6 +548,7 @@
 &usbss0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_usbss0_pins_default>;
+	bootph-all;
 	ti,vbus-divider;
 };
 
@@ -541,6 +557,7 @@
 	maximum-speed = "super-speed";
 	phys = <&serdes3_usb_link>;
 	phy-names = "cdns3,usb3-phy";
+	bootph-all;
 };
 
 &usbss1 {
@@ -555,6 +572,7 @@
 };
 
 &ospi1 {
+	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_fss0_ospi1_pins_default>;
 	status = "okay";
@@ -614,6 +632,7 @@
 			partition@3fe0000 {
 				label = "qspi.phypattern";
 				reg = <0x3fe0000 0x20000>;
+				bootph-all;
 			};
 		};
 	};
@@ -752,6 +771,11 @@
 &mcu_cpsw {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_cpsw_pins_default>, <&mcu_mdio_pins_default>;
+
+	cpts@3d000 {
+		/* Map HW4_TS_PUSH to GENF1 */
+		ti,pps = <3 1>;
+	};
 };
 
 &davinci_mdio {
@@ -912,7 +936,7 @@
 		resets = <&serdes_wiz4 1>;
 		cdns,phy-type = <PHY_TYPE_DP>;
 		cdns,num-lanes = <4>;
-		cdns,max-bit-rate = <5400>;
+		cdns,max-bit-rate = <2700>;
 		#phy-cells = <0>;
 	};
 };
@@ -975,3 +999,11 @@
 	pinctrl-0 = <&main_mcan2_pins_default>;
 	phys = <&transceiver4>;
 };
+
+&timesync_router {
+	/* Use Time Sync Router to map GENF1 input to HW4_TS_PUSH output */
+	mux-reg-masks-state = <
+		K3_TS_OFFSET(25, 0x0001ffff, 17)
+		>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e.dtsi b/arch/arm64/boot/dts/ti/k3-j721e.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j721e.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721e.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -126,6 +126,8 @@
 			 <0x00 0x10000000 0x00 0x10000000 0x00 0x10000000>, /* PCIe DAT */
 			 <0x00 0x64800000 0x00 0x64800000 0x00 0x00800000>, /* C71 */
 			 <0x00 0x6f000000 0x00 0x6f000000 0x00 0x00310000>, /* A72 PERIPHBASE */
+			 <0x40 0x00000000 0x40 0x00000000 0x01 0x00000000>, /* PCIe0 DAT1 */
+			 <0x41 0x00000000 0x41 0x00000000 0x01 0x00000000>, /* PCIe1 DAT1 */
 			 <0x44 0x00000000 0x44 0x00000000 0x00 0x08000000>, /* PCIe2 DAT */
 			 <0x44 0x10000000 0x44 0x10000000 0x00 0x08000000>, /* PCIe3 DAT */
 			 <0x4d 0x80800000 0x4d 0x80800000 0x00 0x00800000>, /* C66_0 */
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-evm-csi2-ov5640.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-csi2-ov5640.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-evm-csi2-ov5640.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-csi2-ov5640.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * LI OV5640 MIPI Camera module on MIPI CSI connector.
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_ov5640_fixed: ov5640-xclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&main_i2c6 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ov5640: camera@3c {
+		compatible = "ovti,ov5640";
+		reg = <0x3c>;
+		clocks = <&clk_ov5640_fixed>;
+		clock-names = "xclk";
+		powerdown-gpios = <&exp5 0 GPIO_ACTIVE_LOW>;
+
+		port {
+			csi2_cam0: endpoint {
+				remote-endpoint = <&csi2rx0_in_sensor>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx0_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam0>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-evm-ethfw.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-ethfw.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-evm-ethfw.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-ethfw.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for CPSW9G functionality with Ethernet Switch Firmware (EthFw)
+ * and CPSW Proxy Client driver.
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "k3-serdes.h"
+
+&serdes_ln_ctrl {
+	idle-states = <J721E_SERDES0_LANE0_PCIE0_LANE0>, <J721E_SERDES0_LANE1_QSGMII_LANE2>,
+		      <J721E_SERDES1_LANE0_PCIE1_LANE0>, <J721E_SERDES1_LANE1_PCIE1_LANE1>,
+		      <J721E_SERDES2_LANE0_PCIE2_LANE0>, <J721E_SERDES2_LANE1_PCIE2_LANE1>,
+		      <J721E_SERDES3_LANE0_USB3_0_SWAP>, <J721E_SERDES3_LANE1_USB3_0>,
+		      <J721E_SERDES4_LANE0_EDP_LANE0>, <J721E_SERDES4_LANE1_EDP_LANE1>,
+		      <J721E_SERDES4_LANE2_EDP_LANE2>, <J721E_SERDES4_LANE3_EDP_LANE3>;
+};
+
+/* uart2 is assigned to EthFw running on remote CPU core */
+&main_uart2 {
+	status = "reserved";
+};
+
+/* Reserve shared memory for inter-core network communication */
+&reserved_memory {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	main_r5fss0_core0_shared_memory_queue_region:r5f-virtual-eth-queues@ac000000 {
+		compatible = "shared-dma-pool";
+		reg = <0x00 0xac000000 0x00 0x200000>;
+		no-map;
+	};
+
+	main_r5fss0_core0_shared_memory_bufpool_region:r5f-virtual-eth-buffers@ac200000 {
+		compatible = "shared-dma-pool";
+		reg = <0x00 0xac200000 0x00 0x1e00000>;
+		no-map;
+	};
+};
+
+&main_r5fss0_core0 {
+	memory-region = <&main_r5fss0_core0_dma_memory_region>,
+			<&main_r5fss0_core0_memory_region>,
+			<&main_r5fss0_core0_shared_memory_queue_region>,
+			<&main_r5fss0_core0_shared_memory_bufpool_region>;
+};
+
+/* EthFw uses timers so mark them reserved */
+&main_timer12 {
+	status = "reserved";
+};
+
+&main_timer13 {
+	status = "reserved";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-evm-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-fusion.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-evm-fusion.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-fusion.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Fusion (FPD-Link III) board on J721E EVM
+ * https://svtronics.com/portfolio/evm577pfusion-v1-0-fusion/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+
+&main_i2c6 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	deser@3d {
+		compatible = "ti,ds90ub960-q1";
+		reg = <0x3d>;
+		clocks = <&clk_fusion_25M_fixed>;
+		clock-names = "refclk";
+		i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+		deserializer_0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@4 {
+				reg = <4>;
+				ds90ub960_0_csi_out: endpoint {
+					data-lanes = <1 2 3 4>;
+					clock-lanes = <0>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy0>;
+				};
+			};
+		};
+
+		deserializer_0_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	deser@36 {
+		compatible = "ti,ds90ub960-q1";
+		reg = <0x36>;
+		clocks = <&clk_fusion_25M_fixed>;
+		clock-names = "refclk";
+		i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+		deserializer_1_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@4 {
+				reg = <4>;
+				ds90ub960_1_csi_out: endpoint {
+					data-lanes = <1 2 3 4>;
+					clock-lanes = <0>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy1>;
+				};
+			};
+		};
+
+		deserializer_1_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub960_0_csi_out>;
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+
+			};
+		};
+	};
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy1: endpoint {
+				remote-endpoint = <&ds90ub960_1_csi_out>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
+
+&dphy1 {
+	status = "okay";
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -38,7 +38,7 @@
 		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
 		interrupt-names = "link_state";
 		interrupts = <GIC_SPI 318 IRQ_TYPE_EDGE_RISING>;
-		ti,syscon-pcie-ctrl = <&scm_conf 0x4070>;
+		ti,syscon-pcie-ctrl = <&pcie0_ctrl 0x0>;
 		max-link-speed = <3>;
 		num-lanes = <1>;
 		power-domains = <&k3_pds 239 TI_SCI_PD_EXCLUSIVE>;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie1-ep.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie1-ep.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie1-ep.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie1-ep.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for enabling PCIE1 instance in Endpoint Configuration with the
+ * J7 common processor board.
+ *
+ * J7 Common Processor Board Product Link: https://www.ti.com/tool/J721EXCPXEVM
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+#include "k3-pinctrl.h"
+
+/*
+ * Since Root Complex and Endpoint modes are mutually exclusive
+ * disable Root Complex mode.
+ */
+&pcie1_rc {
+	status = "disabled";
+};
+
+&cbass_main {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&gic500>;
+
+	pcie1_ep: pcie-ep@2910000 {
+		compatible = "ti,j721e-pcie-ep";
+		reg = <0x00 0x02910000 0x00 0x1000>,
+		      <0x00 0x02917000 0x00 0x400>,
+		      <0x00 0x0d800000 0x00 0x00800000>,
+		      <0x00 0x18000000 0x00 0x08000000>;
+		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+		interrupt-names = "link_state";
+		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
+		max-link-speed = <3>;
+		num-lanes = <2>;
+		power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 240 1>;
+		clock-names = "fck";
+		max-functions = /bits/ 8 <6>;
+		max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+		dma-coherent;
+		phys = <&serdes1_pcie_link>;
+		phy-names = "pcie-phy";
+		ti,syscon-pcie-ctrl = <&pcie1_ctrl 0x0>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie-ntb.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie-ntb.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie-ntb.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie-ntb.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for enabling NTB functionality using PCIE0 and PCIE1 instances of
+ * PCIe on the J7 common processor board.
+ *
+ * J7 Common Processor Board Product Link: https://www.ti.com/tool/J721EXCPXEVM
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+#include "k3-pinctrl.h"
+
+&{/} {
+	epf_bus {
+		compatible = "pci-epf-bus";
+
+		ntb {
+			compatible = "pci-epf-ntb";
+			epcs = <&pcie0_ep>, <&pcie1_ep>;
+			epc-names = "primary", "secondary";
+			vendor-id = /bits/ 16 <0x104c>;
+			device-id = /bits/ 16 <0xb00d>;
+			num-mws = <4>;
+			mws-size = <0x100000>, <0x100000>, <0x100000>, <0x100000>;
+		};
+	};
+};
+
+&pcie0_rc {
+	status = "disabled";
+};
+
+&pcie1_rc {
+	status = "disabled";
+};
+
+&cbass_main {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&gic500>;
+
+	pcie0_ep: pcie-ep@2900000 {
+		compatible = "ti,j721e-pcie-ep";
+		reg = <0x00 0x02900000 0x00 0x1000>,
+		      <0x00 0x02907000 0x00 0x400>,
+		      <0x00 0x0d000000 0x00 0x00800000>,
+		      <0x00 0x10000000 0x00 0x08000000>;
+		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+		interrupt-names = "link_state";
+		interrupts = <GIC_SPI 318 IRQ_TYPE_EDGE_RISING>;
+		max-link-speed = <3>;
+		num-lanes = <1>;
+		power-domains = <&k3_pds 239 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 239 1>;
+		clock-names = "fck";
+		max-functions = /bits/ 8 <6>;
+		max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+		dma-coherent;
+		phys = <&serdes0_pcie_link>;
+		phy-names = "pcie-phy";
+		ti,syscon-pcie-ctrl = <&pcie0_ctrl 0x0>;
+	};
+
+	pcie1_ep: pcie-ep@2910000 {
+		compatible = "ti,j721e-pcie-ep";
+		reg = <0x00 0x02910000 0x00 0x1000>,
+		      <0x00 0x02917000 0x00 0x400>,
+		      <0x00 0x0d800000 0x00 0x00800000>,
+		      <0x00 0x18000000 0x00 0x08000000>;
+		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+		interrupt-names = "link_state";
+		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
+		max-link-speed = <3>;
+		num-lanes = <2>;
+		power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 240 1>;
+		clock-names = "fck";
+		max-functions = /bits/ 8 <6>;
+		max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+		dma-coherent;
+		phys = <&serdes1_pcie_link>;
+		phy-names = "pcie-phy";
+		ti,syscon-pcie-ctrl = <&pcie1_ctrl 0x0>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-evm-ub954.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-ub954.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-evm-ub954.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-ub954.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for DS90UB954-Q1EVM FPDLink-III deserializer board on J721E EVM
+ * https://www.ti.com/tool/DS90UB954-Q1EVM
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+
+&main_i2c6 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	deser@3d {
+		compatible = "ti,ds90ub954-q1";
+		reg = <0x3d>;
+		clock-names = "refclk";
+		clocks = <&clk_fusion_25M_fixed>;
+		i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+		deserializer_0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@2 {
+				reg = <2>;
+				ds90ub960_0_csi_out: endpoint {
+					data-lanes = <1 2 3 4>;
+					clock-lanes = <0>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy0>;
+				};
+			};
+		};
+
+		deserializer_0_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub960_0_csi_out>;
+				data-lanes = <1 2 3 4>;
+				clock-lanes = <0>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -5,6 +5,7 @@
  * Copyright (C) 2016-2024 Texas Instruments Incorporated - https://www.ti.com/
  */
 #include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-cadence.h>
 #include <dt-bindings/phy/phy-ti.h>
 #include <dt-bindings/mux/mux.h>
 
@@ -37,13 +38,32 @@
 		};
 	};
 
-	scm_conf: scm-conf@100000 {
-		compatible = "ti,j721e-system-controller", "syscon", "simple-mfd";
-		reg = <0 0x00100000 0 0x1c000>; /* excludes pinctrl region */
+	scm_conf: bus@100000 {
+		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges = <0x0 0x0 0x00100000 0x1c000>;
 
+		pcie0_ctrl: pcie-ctrl@4070 {
+			compatible = "ti,j784s4-pcie-ctrl", "syscon";
+			reg = <0x4070 0x4>;
+		};
+
+		pcie1_ctrl: pcie-ctrl@4074 {
+			compatible = "ti,j784s4-pcie-ctrl", "syscon";
+			reg = <0x4074 0x4>;
+		};
+
+		pcie2_ctrl: pcie-ctrl@4078 {
+			compatible = "ti,j784s4-pcie-ctrl", "syscon";
+			reg = <0x4078 0x4>;
+		};
+
+		pcie3_ctrl: pcie-ctrl@407c {
+			compatible = "ti,j784s4-pcie-ctrl", "syscon";
+			reg = <0x407c 0x4>;
+		};
+
 		serdes_ln_ctrl: mux-controller@4080 {
 			compatible = "reg-mux";
 			reg = <0x4080 0x50>;
@@ -82,6 +102,11 @@
 			reg = <0x4140 0x18>;
 			#clock-cells = <1>;
 		};
+
+		acspcie0_proxy_ctrl: syscon@18090 {
+			compatible = "ti,j721e-acspcie-proxy-ctrl", "syscon";
+			reg = <0x18090 0x4>;
+		};
 	};
 
 	main_ehrpwm0: pwm@3000000 {
@@ -226,6 +251,7 @@
 			      <0x00 0x32800000 0x00 0x100000>;
 			interrupt-names = "rx_011";
 			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+			bootph-all;
 		};
 
 		smmu0: iommu@36600000 {
@@ -579,18 +605,27 @@
 		ranges;
 		#address-cells = <2>;
 		#size-cells = <2>;
-		dmas = <&main_udmap 0x4940>;
-		dma-names = "rx0";
+		dmas = <&main_udmap 0x4940>, <&main_udmap 0x4941>, <&main_udmap 0x4942>,
+		       <&main_udmap 0x4943>, <&main_udmap 0x4944>, <&main_udmap 0x4945>,
+		       <&main_udmap 0x4946>, <&main_udmap 0x4947>, <&main_udmap 0x4948>,
+		       <&main_udmap 0x4949>, <&main_udmap 0x494a>, <&main_udmap 0x494b>,
+		       <&main_udmap 0x494c>, <&main_udmap 0x494d>, <&main_udmap 0x494e>,
+		       <&main_udmap 0x494f>;
+		dma-names = "rx0", "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7",
+			    "rx8", "rx9", "rx10", "rx11", "rx12", "rx13", "rx14", "rx15";
 		power-domains = <&k3_pds 26 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 
 		cdns_csi2rx0: csi-bridge@4504000 {
 			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
 			reg = <0x0 0x4504000 0x0 0x1000>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
 			clocks = <&k3_clks 26 2>, <&k3_clks 26 0>, <&k3_clks 26 2>,
-				<&k3_clks 26 2>, <&k3_clks 26 3>, <&k3_clks 26 3>;
+				 <&k3_clks 26 2>, <&k3_clks 26 3>, <&k3_clks 26 3>;
 			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
-				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+				      "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
 			phys = <&dphy0>;
 			phy-names = "dphy";
 
@@ -632,14 +667,23 @@
 		ranges;
 		#address-cells = <2>;
 		#size-cells = <2>;
-		dmas = <&main_udmap 0x4960>;
-		dma-names = "rx0";
+		dmas = <&main_udmap 0x4960>, <&main_udmap 0x4961>, <&main_udmap 0x4962>,
+		       <&main_udmap 0x4963>, <&main_udmap 0x4964>, <&main_udmap 0x4965>,
+		       <&main_udmap 0x4966>, <&main_udmap 0x4967>, <&main_udmap 0x4968>,
+		       <&main_udmap 0x4969>, <&main_udmap 0x496a>, <&main_udmap 0x496b>,
+		       <&main_udmap 0x496c>, <&main_udmap 0x496d>, <&main_udmap 0x496e>,
+		       <&main_udmap 0x496f>;
+		dma-names = "rx0", "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7",
+			    "rx8", "rx9", "rx10", "rx11", "rx12", "rx13", "rx14", "rx15";
 		power-domains = <&k3_pds 27 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 
 		cdns_csi2rx1: csi-bridge@4514000 {
 			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
 			reg = <0x0 0x4514000 0x0 0x1000>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
 			clocks = <&k3_clks 27 2>, <&k3_clks 27 0>, <&k3_clks 27 2>,
 				 <&k3_clks 27 2>, <&k3_clks 27 3>, <&k3_clks 27 3>;
 			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
@@ -940,12 +984,12 @@
 		reg = <0x00 0x02900000 0x00 0x1000>,
 		      <0x00 0x02907000 0x00 0x400>,
 		      <0x00 0x0d000000 0x00 0x00800000>,
-		      <0x00 0x10000000 0x00 0x00001000>;
+		      <0x40 0x00000000 0x00 0x00001000>; /* ECAM (4 KB) */
 		reg-names = "intd_cfg", "user_cfg", "reg", "cfg";
 		interrupt-names = "link_state";
 		interrupts = <GIC_SPI 318 IRQ_TYPE_EDGE_RISING>;
 		device_type = "pci";
-		ti,syscon-pcie-ctrl = <&scm_conf 0x4070>;
+		ti,syscon-pcie-ctrl = <&pcie0_ctrl 0x0>;
 		max-link-speed = <3>;
 		num-lanes = <2>;
 		power-domains = <&k3_pds 239 TI_SCI_PD_EXCLUSIVE>;
@@ -958,8 +1002,8 @@
 		device-id = <0xb00d>;
 		msi-map = <0x0 &gic_its 0x0 0x10000>;
 		dma-coherent;
-		ranges = <0x01000000 0x0 0x10001000 0x0 0x10001000 0x0 0x0010000>,
-			 <0x02000000 0x0 0x10011000 0x0 0x10011000 0x0 0x7fef000>;
+		ranges = <0x01000000 0x00 0x00001000 0x40 0x00001000 0x00 0x00100000>, /* IO (1 MB) */
+			 <0x02000000 0x00 0x00101000 0x40 0x00101000 0x00 0xffeff000>; /* 32-bit Non-Prefetchable MEM (4 GB - 1 MB - 4 KB) */
 		dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
 		status = "disabled";
 	};
@@ -969,17 +1013,17 @@
 		reg = <0x00 0x02910000 0x00 0x1000>,
 		      <0x00 0x02917000 0x00 0x400>,
 		      <0x00 0x0d800000 0x00 0x00800000>,
-		      <0x00 0x18000000 0x00 0x00001000>;
+		      <0x41 0x00000000 0x00 0x00001000>; /* ECAM (4 KB) */
 		reg-names = "intd_cfg", "user_cfg", "reg", "cfg";
 		interrupt-names = "link_state";
 		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
 		device_type = "pci";
-		ti,syscon-pcie-ctrl = <&scm_conf 0x4074>;
+		ti,syscon-pcie-ctrl = <&pcie1_ctrl 0x0>;
 		max-link-speed = <3>;
 		num-lanes = <2>;
 		power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 240 1>;
-		clock-names = "fck";
+		clocks = <&k3_clks 240 1>, <&serdes1 CDNS_SIERRA_DERIVED_REFCLK>;
+		clock-names = "fck", "pcie_refclk";
 		#address-cells = <3>;
 		#size-cells = <2>;
 		bus-range = <0x0 0xff>;
@@ -987,8 +1031,8 @@
 		device-id = <0xb00d>;
 		msi-map = <0x0 &gic_its 0x10000 0x10000>;
 		dma-coherent;
-		ranges = <0x01000000 0x0 0x18001000 0x0 0x18001000 0x0 0x0010000>,
-			 <0x02000000 0x0 0x18011000 0x0 0x18011000 0x0 0x7fef000>;
+		ranges = <0x01000000 0x00 0x00001000 0x41 0x00001000 0x00 0x00100000>, /* IO (1 MB) */
+			 <0x02000000 0x00 0x00101000 0x41 0x00101000 0x00 0xffeff000>; /* 32-bit Non-Prefetchable MEM (4 GB - 1 MB - 4 KB) */
 		dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
 		status = "disabled";
 	};
@@ -1003,7 +1047,7 @@
 		interrupt-names = "link_state";
 		interrupts = <GIC_SPI 342 IRQ_TYPE_EDGE_RISING>;
 		device_type = "pci";
-		ti,syscon-pcie-ctrl = <&scm_conf 0x4078>;
+		ti,syscon-pcie-ctrl = <&pcie2_ctrl 0x0>;
 		max-link-speed = <3>;
 		num-lanes = <2>;
 		power-domains = <&k3_pds 241 TI_SCI_PD_EXCLUSIVE>;
@@ -1032,7 +1076,7 @@
 		interrupt-names = "link_state";
 		interrupts = <GIC_SPI 354 IRQ_TYPE_EDGE_RISING>;
 		device_type = "pci";
-		ti,syscon-pcie-ctrl = <&scm_conf 0x407c>;
+		ti,syscon-pcie-ctrl = <&pcie3_ctrl 0x0>;
 		max-link-speed = <3>;
 		num-lanes = <2>;
 		power-domains = <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>;
@@ -1807,6 +1851,22 @@
 		status = "disabled";
 	};
 
+	vxe384: video-encoder@4200000 {
+		compatible = "img,vxe384";
+		reg = <0x00 0x04200000>,
+			<0x00 0x100000>;
+		power-domains = <&k3_pds 153 TI_SCI_PD_EXCLUSIVE>;
+		interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	d5520: video-decoder@4300000 {
+		compatible = "img,d5500-vxd";
+		reg = <0x00 0x04300000>,
+			<0x00 0x100000>;
+		power-domains = <&k3_pds 144 TI_SCI_PD_EXCLUSIVE>;
+		interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
 	ufs_wrapper: ufs-wrapper@4e80000 {
 		compatible = "ti,j721e-ufs";
 		reg = <0x0 0x4e80000 0x0 0x100>;
@@ -1860,6 +1920,37 @@
 		};
 	};
 
+	dphy2: phy@4480000 {
+		compatible = "ti,j721e-dphy";
+		reg = <0x0 0x04480000 0x0 0x1000>;
+		clocks = <&k3_clks 296 1>, <&k3_clks 296 3>;
+		clock-names = "psm", "pll_ref";
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 296 TI_SCI_PD_EXCLUSIVE>;
+		assigned-clocks = <&k3_clks 296 3>;
+		assigned-clock-parents = <&k3_clks 296 4>;
+		assigned-clock-rates = <19200000>;
+		status = "disabled";
+	};
+
+	dsi0: dsi@48000000 {
+		compatible = "ti,j721e-dsi";
+		reg = <0x0 0x04800000 0x0 0x100000>, <0x0 0x04710000 0x0 0x100>;
+		clocks = <&k3_clks 150 1>, <&k3_clks 150 5>;
+		clock-names = "dsi_p_clk", "dsi_sys_clk";
+		power-domains = <&k3_pds 150 TI_SCI_PD_EXCLUSIVE>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 600 IRQ_TYPE_LEVEL_HIGH>;
+		phys = <&dphy2>;
+		phy-names = "dphy";
+		status = "disabled";
+
+		dsi0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
 	dss: dss@4a00000 {
 		compatible = "ti,j721e-dss";
 		reg =
@@ -2268,6 +2359,13 @@
 		status = "disabled";
 	};
 
+	timesync_router: mux-controller@a40000 {
+		compatible = "reg-mux";
+		reg = <0x0 0xa40000 0x0 0x800>;
+		#mux-control-cells = <1>;
+		status = "disabled";
+	};
+
 	icssg0: icssg@b000000 {
 		compatible = "ti,j721e-icssg";
 		reg = <0x00 0xb000000 0x00 0x80000>;
@@ -2552,6 +2650,19 @@
 		};
 	};
 
+	gpu: gpu@4e20000000 {
+		 compatible = "ti,j721e-pvr", "img,pvr-ge8430";
+		 reg = <0x4e 0x20000000 0x00 0x80000>;
+		 interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+		 power-domains = <&k3_pds 125 TI_SCI_PD_EXCLUSIVE>,
+				 <&k3_pds 126 TI_SCI_PD_EXCLUSIVE>;
+		 power-domain-names = "firmware", "dust";
+		 clocks = <&k3_clks 125 0>;
+		 assigned-clocks = <&k3_clks 125 0>;
+		 assigned-clock-rates = <750000000>;
+		 clock-names = "core";
+	};
+
 	main_mcan0: can@2701000 {
 		compatible = "bosch,m_can";
 		reg = <0x00 0x02701000 0x00 0x200>,
@@ -2853,6 +2964,7 @@
 	main_esm: esm@700000 {
 		compatible = "ti,j721e-esm";
 		reg = <0x0 0x700000 0x0 0x1000>;
+		bootph-pre-ram;
 		ti,esm-pins = <344>, <345>;
 	};
 };
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -21,16 +21,19 @@
 		k3_pds: power-controller {
 			compatible = "ti,sci-pm-domain";
 			#power-domain-cells = <2>;
+			bootph-all;
 		};
 
 		k3_clks: clock-controller {
 			compatible = "ti,k2g-sci-clk";
 			#clock-cells = <2>;
+			bootph-all;
 		};
 
 		k3_reset: reset-controller {
 			compatible = "ti,sci-reset";
 			#reset-cells = <2>;
+			bootph-all;
 		};
 	};
 
@@ -61,6 +64,7 @@
 		chipid: chipid@14 {
 			compatible = "ti,am654-chipid";
 			reg = <0x14 0x4>;
+			bootph-all;
 		};
 	};
 
@@ -112,6 +116,7 @@
 		assigned-clocks = <&k3_clks 35 1>;
 		assigned-clock-parents = <&k3_clks 35 2>;
 		power-domains = <&k3_pds 35 TI_SCI_PD_EXCLUSIVE>;
+		bootph-pre-ram;
 		ti,timer-pwm;
 		/* Non-MPU Firmware usage */
 		status = "reserved";
@@ -362,6 +367,7 @@
 			reg = <0x00 0x47000004 0x00 0x4>;
 			#mux-control-cells = <1>;
 			mux-reg-masks = <0x0 0x2>; /* HBMC select */
+			bootph-all;
 		};
 
 		hbmc: hyperbus@47034000 {
@@ -386,6 +392,7 @@
 			cdns,fifo-depth = <256>;
 			cdns,fifo-width = <4>;
 			cdns,trigger-address = <0x0>;
+			cdns,phase-detect-selector = <2>;
 			clocks = <&k3_clks 103 0>;
 			assigned-clocks = <&k3_clks 103 0>;
 			assigned-clock-parents = <&k3_clks 103 2>;
@@ -404,6 +411,7 @@
 			cdns,fifo-depth = <256>;
 			cdns,fifo-width = <4>;
 			cdns,trigger-address = <0x0>;
+			cdns,phase-detect-selector = <2>;
 			clocks = <&k3_clks 104 0>;
 			power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
 			#address-cells = <1>;
@@ -470,6 +478,7 @@
 			      <0x0 0x2a500000 0x0 0x40000>,
 			      <0x0 0x28440000 0x0 0x40000>;
 			reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target", "cfg";
+			bootph-all;
 			ti,num-rings = <286>;
 			ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */
 			ti,sci = <&dmsc>;
@@ -489,6 +498,7 @@
 				    "tchan", "rchan", "rflow";
 			msi-parent = <&main_udmass_inta>;
 			#dma-cells = <1>;
+			bootph-all;
 
 			ti,sci = <&dmsc>;
 			ti,sci-dev-id = <236>;
@@ -509,6 +519,7 @@
 		reg = <0x0 0x2a480000 0x0 0x80000>,
 		      <0x0 0x2a380000 0x0 0x80000>,
 		      <0x0 0x2a400000 0x0 0x80000>;
+		bootph-pre-ram;
 		/*
 		 * Marked Disabled:
 		 * Node is incomplete as it is meant for bootloaders and
@@ -579,7 +590,7 @@
 
 	mcu_r5fss0: r5fss@41000000 {
 		compatible = "ti,j721e-r5fss";
-		ti,cluster-mode = <1>;
+		ti,cluster-mode = <0>;
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges = <0x41000000 0x00 0x41000000 0x20000>,
@@ -687,6 +698,7 @@
 		      <0x00 0x43000300 0x00 0x10>;
 		power-domains = <&k3_pds 154 TI_SCI_PD_EXCLUSIVE>;
 		#thermal-sensor-cells = <1>;
+		bootph-pre-ram;
 	};
 
 	mcu_esm: esm@40800000 {
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-ov5640.dtso b/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-ov5640.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-ov5640.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-ov5640.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * LI OV5640 MIPI Camera module on MIPI CSI connector.
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	clk_ov5640_fixed: ov5640-xclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&main_pmx0 {
+	csi2_exp_pins_default: csi2-exp-pins-default {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x140, PIN_OUTPUT, 7) /* (AG29) PRG0_PRU1_GPO16.GPIO0_79 */
+		>;
+	};
+};
+
+&cam0_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ov5640: camera@3c {
+		compatible = "ovti,ov5640";
+		reg = <0x3c>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&csi2_exp_pins_default>;
+		powerdown-gpios = <&main_gpio0 79 GPIO_ACTIVE_LOW>;
+		clocks = <&clk_ov5640_fixed>;
+		clock-names = "xclk";
+
+		port {
+			csi2_cam0: endpoint {
+				remote-endpoint = <&csi2rx0_in_sensor>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx0_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam0>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
--- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts	2025-10-23 09:30:40.283462146 -0400
@@ -42,6 +42,14 @@
 		#size-cells = <2>;
 		ranges;
 
+		 /* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x20000000>;
+			linux,cma-default;
+		};
+
 		secure_ddr: optee@9e800000 {
 			reg = <0x00 0x9e800000 0x00 0x01800000>;
 			alignment = <0x1000>;
@@ -371,6 +379,7 @@
 			J721E_IOPAD(0x240, PIN_INPUT, 0) /* (R26) MMC1_DAT3 */
 			J721E_IOPAD(0x258, PIN_INPUT, 0) /* (P23) MMC1_SDCD */
 		>;
+		bootph-all;
 	};
 
 	main_uart0_pins_default: main-uart0-default-pins {
@@ -380,6 +389,7 @@
 			J721E_IOPAD(0x1e8, PIN_INPUT, 0) /* (AB2) UART0_RXD */
 			J721E_IOPAD(0x1ec, PIN_OUTPUT, 0) /* (AB3) UART0_TXD */
 		>;
+		bootph-all;
 	};
 
 	main_uart1_pins_default: main-uart1-default-pins {
@@ -415,12 +425,14 @@
 			J721E_IOPAD(0x290, PIN_OUTPUT, 0) /* (U6) USB0_DRVVBUS */
 			J721E_IOPAD(0x210, PIN_INPUT, 7) /* (W3) MCAN1_RX.GPIO1_3 */
 		>;
+		bootph-all;
 	};
 
 	main_usbss1_pins_default: main-usbss1-default-pins {
 		pinctrl-single,pins = <
 			J721E_IOPAD(0x214, PIN_OUTPUT, 4) /* (V4) MCAN1_TX.USB1_DRVVBUS */
 		>;
+		bootph-all;
 	};
 
 	main_csi_mux_sel_pins_default: main-csi-mux-sel-default-pins {
@@ -619,6 +631,7 @@
 			J721E_WKUP_IOPAD(0x28, PIN_INPUT, 0) /* (G21) MCU_OSPI0_D7 */
 			J721E_WKUP_IOPAD(0x8, PIN_INPUT, 0) /* (D21) MCU_OSPI0_DQS */
 		>;
+		bootph-all;
 	};
 
 	vdd_mmc1_en_pins_default: vdd-mmc1-en-default-pins {
@@ -653,6 +666,7 @@
 			J721E_WKUP_IOPAD(0xe4, PIN_INPUT, 0) /* (H28) WKUP_GPIO0_13.MCU_UART0_RXD */
 			J721E_WKUP_IOPAD(0xe0, PIN_OUTPUT, 0)/* (G29) WKUP_GPIO0_12.MCU_UART0_TXD */
 		>;
+		bootph-all;
 	};
 
 	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
@@ -660,6 +674,7 @@
 			J721E_WKUP_IOPAD(0xf8, PIN_INPUT_PULLUP, 0) /* (J25) WKUP_I2C0_SCL */
 			J721E_WKUP_IOPAD(0xfc, PIN_INPUT_PULLUP, 0) /* (H24) WKUP_I2C0_SDA */
 		>;
+		bootph-all;
 	};
 
 	mcu_mcan0_pins_default: mcu-mcan0-default-pins {
@@ -688,6 +703,7 @@
 	status = "reserved";
 	pinctrl-names = "default";
 	pinctrl-0 = <&wkup_uart0_pins_default>;
+	bootph-all;
 };
 
 &wkup_i2c0 {
@@ -852,6 +868,7 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_uart0_pins_default>;
+	bootph-all;
 };
 
 &main_uart0 {
@@ -860,6 +877,7 @@
 	pinctrl-0 = <&main_uart0_pins_default>;
 	/* Shared with ATF on this platform */
 	power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>;
+	bootph-all;
 };
 
 &main_uart1 {
@@ -875,6 +893,7 @@
 	vqmmc-supply = <&vdd_sd_dv_alt>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
+	bootph-all;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
@@ -939,6 +958,7 @@
 			partition@3fc0000 {
 				label = "ospi.phypattern";
 				reg = <0x3fc0000 0x40000>;
+				bootph-all;
 			};
 		};
 	};
@@ -1034,6 +1054,7 @@
 
 &usb_serdes_mux {
 	idle-states = <1>, <1>; /* USB0 to SERDES3, USB1 to SERDES2 */
+	bootph-all;
 };
 
 &serdes_ln_ctrl {
@@ -1043,6 +1064,7 @@
 		      <J721E_SERDES3_LANE0_USB3_0_SWAP>, <J721E_SERDES3_LANE1_USB3_0>,
 		      <J721E_SERDES4_LANE0_EDP_LANE0>, <J721E_SERDES4_LANE1_EDP_LANE1>,
 		      <J721E_SERDES4_LANE2_EDP_LANE2>, <J721E_SERDES4_LANE3_EDP_LANE3>;
+	bootph-all;
 };
 
 &serdes_wiz3 {
@@ -1066,7 +1088,7 @@
 		resets = <&serdes_wiz4 1>;
 		cdns,phy-type = <PHY_TYPE_DP>;
 		cdns,num-lanes = <4>;
-		cdns,max-bit-rate = <5400>;
+		cdns,max-bit-rate = <2700>;
 		#phy-cells = <0>;
 	};
 };
@@ -1081,6 +1103,7 @@
 &usbss0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_usbss0_pins_default>;
+	bootph-all;
 	ti,vbus-divider;
 };
 
@@ -1089,6 +1112,7 @@
 	maximum-speed = "super-speed";
 	phys = <&serdes3_usb_link>;
 	phy-names = "cdns3,usb3-phy";
+	bootph-all;
 };
 
 &serdes2 {
@@ -1104,6 +1128,7 @@
 &usbss1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_usbss1_pins_default>;
+	bootph-all;
 	ti,vbus-divider;
 };
 
@@ -1112,6 +1137,7 @@
 	maximum-speed = "super-speed";
 	phys = <&serdes2_usb_link>;
 	phy-names = "cdns3,usb3-phy";
+	bootph-all;
 };
 
 &mcu_cpsw {
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-sk-fpdlink-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j721e-sk-fpdlink-fusion.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721e-sk-fpdlink-fusion.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk-fpdlink-fusion.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Fusion (FPD-Link III) board on J721E SK,
+ * AM68 SK or AM69 SK.
+ * https://svtronics.com/portfolio/evm577pfusion-v1-0-fusion/
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+
+&cam0_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	deser@3d {
+		compatible = "ti,ds90ub960-q1";
+		reg = <0x3d>;
+		clocks = <&clk_fusion_25M_fixed>;
+		clock-names = "refclk";
+		i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+		deserializer_0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX*/
+			port@4 {
+				reg = <4>;
+				ds90ub960_0_csi_out: endpoint {
+					clock-lanes = <0>;
+					data-lanes = <1 2 3 4>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy0>;
+				};
+			};
+		};
+
+		deserializer_0_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	deser@36 {
+		compatible = "ti,ds90ub960-q1";
+		reg       = <0x36>;
+		clocks = <&clk_fusion_25M_fixed>;
+		clock-names = "refclk";
+		i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+		deserializer_1_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX*/
+			port@4 {
+				reg = <4>;
+				ds90ub960_1_csi_out: endpoint {
+					clock-lanes = <0>;
+					data-lanes = <1 2 3 4>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy1>;
+				};
+			};
+		};
+
+		deserializer_1_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub960_0_csi_out>;
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+
+			};
+		};
+	};
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy1: endpoint {
+				remote-endpoint = <&ds90ub960_1_csi_out>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
+
+&dphy1 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -23,6 +23,14 @@
 		#size-cells = <2>;
 		ranges;
 
+		 /* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x20000000>;
+			linux,cma-default;
+		};
+
 		secure_ddr: optee@9e800000 {
 			reg = <0x00 0x9e800000 0x00 0x01800000>;
 			alignment = <0x1000>;
@@ -151,6 +159,7 @@
 			J721E_WKUP_IOPAD(0xf8, PIN_INPUT_PULLUP, 0) /* (J25) WKUP_I2C0_SCL */
 			J721E_WKUP_IOPAD(0xfc, PIN_INPUT_PULLUP, 0) /* (H24) WKUP_I2C0_SDA */
 		>;
+		bootph-all;
 	};
 
 	pmic_irq_pins_default: pmic-irq-default-pins {
@@ -173,6 +182,7 @@
 			J721E_WKUP_IOPAD(0x0028, PIN_INPUT, 0)  /* MCU_OSPI0_D7 */
 			J721E_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* MCU_OSPI0_CSn0 */
 		>;
+		bootph-all;
 	};
 
 	mcu_fss0_hpb0_pins_default: mcu-fss0-hpb0-default-pins {
@@ -192,6 +202,7 @@
 			J721E_WKUP_IOPAD(0x24, PIN_INPUT, 1)  /* MCU_HYPERBUS0_DQ6 */
 			J721E_WKUP_IOPAD(0x28, PIN_INPUT, 1)  /* MCU_HYPERBUS0_DQ7 */
 		>;
+		bootph-all;
 	};
 };
 
@@ -378,6 +389,7 @@
 		cdns,tchsh-ns = <60>;
 		cdns,tslch-ns = <60>;
 		cdns,read-delay = <0>;
+		cdns,phy-mode;
 
 		partitions {
 			compatible = "fixed-partitions";
@@ -422,6 +434,7 @@
 			partition@3fe0000 {
 				label = "ospi.phypattern";
 				reg = <0x3fe0000 0x20000>;
+				bootph-all;
 			};
 		};
 	};
@@ -440,6 +453,7 @@
 	flash@0,0 {
 		compatible = "cypress,hyperflash", "cfi-flash";
 		reg = <0x00 0x00 0x4000000>;
+		bootph-all;
 
 		partitions {
 			compatible = "fixed-partitions";
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
--- a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts	2025-10-23 09:30:40.283462146 -0400
@@ -13,6 +13,7 @@
 #include <dt-bindings/phy/phy.h>
 
 #include "k3-serdes.h"
+#include "k3-timesync-router.h"
 
 / {
 	compatible = "ti,j721s2-evm", "ti,j721s2";
@@ -128,6 +129,74 @@
 		standby-gpios = <&exp_som 7 GPIO_ACTIVE_HIGH>;
 		mux-states = <&mux1 1>;
 	};
+
+	dp0_pwr_3v3: fixedregulator-dp0-prw {
+		compatible = "regulator-fixed";
+		regulator-name = "dp0-pwr";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&exp4 0 0>;	/* P0 - DP0_PWR_SW_EN */
+		enable-active-high;
+	};
+
+	dp1_pwr_3v3: regulator-dp1-prw {
+		compatible = "regulator-fixed";
+		regulator-name = "dp1-pwr";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&exp4 1 GPIO_ACTIVE_HIGH>; /* P1 - DP1_PWR_SW_EN */
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	dp0: dp0-connector {
+		compatible = "dp-connector";
+		label = "DP0";
+		type = "full-size";
+		dp-pwr-supply = <&dp0_pwr_3v3>;
+
+		port {
+			dp0_connector_in: endpoint {
+				remote-endpoint = <&dp0_out>;
+			};
+		};
+	};
+
+	codec_audio: sound {
+		compatible = "ti,j7200-cpb-audio";
+		model = "j721e-cpb";
+
+		ti,cpb-mcasp = <&mcasp4>;
+		ti,cpb-codec = <&pcm3168a_1>;
+
+		clocks = <&k3_clks 213 0>, <&k3_clks 213 1>,
+			 <&k3_clks 157 299>, <&k3_clks 157 328>;
+		clock-names = "cpb-mcasp-auxclk", "cpb-mcasp-auxclk-48000",
+			      "cpb-codec-scki", "cpb-codec-scki-48000";
+	};
+
+	i2c_mux: mux-controller-2 {
+		compatible = "gpio-mux";
+		#mux-state-cells = <1>;
+		mux-gpios = <&wkup_gpio0 54 GPIO_ACTIVE_HIGH>;
+		idle-state = <1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_i2c3_mux_pins_default>;
+	};
+};
+
+&main_i2c4 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c4_pins_default>;
+	clock-frequency = <400000>;
+
+	exp4: gpio@20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
 };
 
 &main_pmx0 {
@@ -138,6 +207,7 @@
 			J721S2_IOPAD(0x0d0, PIN_INPUT, 11) /* (AF26) SPI0_CS1.UART8_RXD */
 			J721S2_IOPAD(0x0d4, PIN_OUTPUT, 11) /* (AH27) SPI0_CLK.UART8_TXD */
 		>;
+		bootph-all;
 	};
 
 	main_i2c3_pins_default: main-i2c3-default-pins {
@@ -165,6 +235,7 @@
 			J721S2_IOPAD(0x0f0, PIN_INPUT, 0) /* (R22) MMC1_DAT3 */
 			J721S2_IOPAD(0x0e8, PIN_INPUT, 8) /* (AE25) TIMER_IO0.MMC1_SDCD */
 		>;
+		bootph-all;
 	};
 
 	vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
@@ -177,6 +248,7 @@
 		pinctrl-single,pins = <
 			J721S2_IOPAD(0x0ec, PIN_OUTPUT, 6) /* (AG25) TIMER_IO1.USB0_DRVVBUS */
 		>;
+		bootph-all;
 	};
 
 	main_mcan3_pins_default: main-mcan3-default-pins {
@@ -192,6 +264,35 @@
 			J721S2_IOPAD(0x038, PIN_OUTPUT, 0) /* (AB28) MCASP0_ACLKX.MCAN5_TX */
 		>;
 	};
+
+	main_i2c4_pins_default: main-i2c4-pins-default {
+		pinctrl-single,pins = <
+			J721S2_IOPAD(0x014, PIN_INPUT_PULLUP, 8) /* (AD25) I2C4_SCL */
+			J721S2_IOPAD(0x010, PIN_INPUT_PULLUP, 8) /* (AF28) I2C4_SDA */
+		>;
+	};
+
+	dp0_pins_default: dp0-pins-default {
+		pinctrl-single,pins = <
+			J721S2_IOPAD(0x0b8, PIN_INPUT, 3) /* (AA24) MCASP1_ACLKX.DP0_HPD */
+		>;
+	};
+
+	mcasp4_pins_default: mcasp4-default-pins {
+		pinctrl-single,pins = <
+			J721S2_IOPAD(0x0c8, PIN_OUTPUT_PULLDOWN, 1) /* (AD28) MCASP4_ACLKX */
+			J721S2_IOPAD(0x06c, PIN_OUTPUT_PULLDOWN, 1) /* (V26) MCASP4_AFSX */
+			J721S2_IOPAD(0x068, PIN_INPUT_PULLDOWN, 1) /* (U28) MCASP4_AXR1 */
+			J721S2_IOPAD(0x0c4, PIN_OUTPUT_PULLDOWN, 1) /* (AB26) MCASP4_AXR2 */
+			J721S2_IOPAD(0x070, PIN_OUTPUT_PULLDOWN, 1) /* (R27) MCASP4_AXR3 */
+		>;
+	};
+
+	audio_ext_refclk1_pins_default: audio-ext-refclk1-default-pins {
+		pinctrl-single,pins = <
+			J721S2_IOPAD(0x078, PIN_OUTPUT, 1) /* (Y25) MCAN2_RX.AUDIO_EXT_REFCLK1 */
+		>;
+	};
 };
 
 &wkup_pmx2 {
@@ -200,6 +301,7 @@
 			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (D28) WKUP_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (D27) WKUP_UART0_TXD */
 		>;
+		bootph-all;
 	};
 
 	mcu_uart0_pins_default: mcu-uart0-default-pins {
@@ -209,6 +311,7 @@
 			J721S2_WKUP_IOPAD(0x08c, PIN_INPUT, 0) /* (C24) WKUP_GPIO0_13.MCU_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x088, PIN_OUTPUT, 0) /* (C25) WKUP_GPIO0_12.MCU_UART0_TXD */
 		>;
+		bootph-all;
 	};
 
 	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
@@ -287,6 +390,18 @@
 			J721S2_WKUP_IOPAD(0x108, PIN_INPUT, 0) /* (N27) MCU_ADC1_AIN7 */
 		>;
 	};
+
+	main_i2c3_mux_pins_default: main-i2c3-mux-default-pins {
+		pinctrl-single,pins = <
+			J721S2_WKUP_IOPAD(0x038, PIN_OUTPUT, 7) /* (B27) WKUP_GPIO0_54 */
+		>;
+	};
+
+	wkup_gpio_pins_default: wkup_gpio_pins_default {
+		pinctrl-single,pins = <
+				J784S4_WKUP_IOPAD(0x0d8, PIN_INPUT, 7) /* (L37) WKUP_GPIO0_6 */
+		>;
+	};
 };
 
 &wkup_pmx1 {
@@ -301,6 +416,7 @@
 			J721S2_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (B19) MCU_OSPI1_DQS */
 			J721S2_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (B20) MCU_OSPI1_LBCLKO */
 		>;
+		bootph-all;
 	};
 };
 
@@ -316,12 +432,14 @@
 	status = "reserved";
 	pinctrl-names = "default";
 	pinctrl-0 = <&wkup_uart0_pins_default>;
+	bootph-all;
 };
 
 &mcu_uart0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_uart0_pins_default>;
+	bootph-all;
 };
 
 &main_uart8 {
@@ -330,6 +448,7 @@
 	pinctrl-0 = <&main_uart8_pins_default>;
 	/* Shared with TFA on this platform */
 	power-domains = <&k3_pds 357 TI_SCI_PD_SHARED>;
+	bootph-all;
 };
 
 &main_i2c0 {
@@ -358,6 +477,22 @@
 				  "MLB_MUX_SEL", "MCAN_MUX_SEL", "MCASP2/SPI3_MUX_SEL", "PCIe_CLKREQn_MUX_SEL",
 				  "CDCI2_RSTZ", "ENET_EXP_PWRDN", "ENET_EXP_RESETZ", "ENET_I2CMUX_SEL",
 				  "ENET_EXP_SPARE2", "M2PCIE_RTSZ", "USER_INPUT1", "USER_LED1", "USER_LED2";
+
+		p09-hog {
+			/* P09 - MCASP/TRACE_MUX_S0 */
+			gpio-hog;
+			gpios = <9 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "MCASP/TRACE_MUX_S0";
+		};
+
+		p10-hog {
+			/* P10 - MCASP/TRACE_MUX_S1 */
+			gpio-hog;
+			gpios = <10 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "MCASP/TRACE_MUX_S1";
+		};
 	};
 };
 
@@ -383,6 +518,7 @@
 	/* eMMC */
 	status = "okay";
 	non-removable;
+	bootph-all;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
@@ -395,11 +531,17 @@
 	disable-wp;
 	vmmc-supply = <&vdd_mmc1>;
 	vqmmc-supply = <&vdd_sd_dv>;
+	bootph-all;
 };
 
 &mcu_cpsw {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_cpsw_pins_default>, <&mcu_mdio_pins_default>;
+
+	cpts@3d000 {
+		/* Map HW4_TS_PUSH to GENF1 */
+		ti,pps = <3 1>;
+	};
 };
 
 &davinci_mdio {
@@ -440,10 +582,15 @@
 	idle-states = <1>; /* USB0 to SERDES lane 1 */
 };
 
+&edp_serdes_mux {
+	idle-states = <1>; /* EDP0 to SERDES lane 2/3 */
+};
+
 &usbss0 {
 	status = "okay";
 	pinctrl-0 = <&main_usbss0_pins_default>;
 	pinctrl-names = "default";
+	bootph-all;
 	ti,vbus-divider;
 	ti,usb2-only;
 };
@@ -451,6 +598,12 @@
 &usb0 {
 	dr_mode = "otg";
 	maximum-speed = "high-speed";
+	bootph-all;
+};
+
+&wkup_gpio0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_gpio_pins_default>;
 };
 
 &ospi1 {
@@ -458,17 +611,59 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_fss0_ospi1_pins_default>;
 
-	flash@0 {
+	ospi1_nor: flash@0 {
 		compatible = "jedec,spi-nor";
 		reg = <0x0>;
 		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <4>;
 		spi-max-frequency = <40000000>;
+		bootph-all;
 		cdns,tshsl-ns = <60>;
 		cdns,tsd2d-ns = <60>;
 		cdns,tchsh-ns = <60>;
 		cdns,tslch-ns = <60>;
 		cdns,read-delay = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "qspi.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition@80000 {
+				label = "qspi.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition@280000 {
+				label = "qspi.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition@680000 {
+				label = "qspi.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition@6c0000 {
+				label = "qspi.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition@800000 {
+				label = "qspi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition@3fc0000 {
+				label = "qspi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
 	};
 };
 
@@ -525,3 +720,203 @@
 	pinctrl-0 = <&main_mcan5_pins_default>;
 	phys = <&transceiver4>;
 };
+
+&dss {
+	/*
+	 * These clock assignments are chosen to enable the following outputs:
+	 *
+	 * VP0 - DisplayPort SST
+	 * VP1 - DPI0
+	 * VP2 - DSI
+	 * VP3 - DPI1
+	 */
+	status = "okay";
+	assigned-clocks = <&k3_clks 158 2>,
+			  <&k3_clks 158 5>,
+			  <&k3_clks 158 14>,
+			  <&k3_clks 158 18>;
+	assigned-clock-parents = <&k3_clks 158 3>,
+				 <&k3_clks 158 7>,
+				 <&k3_clks 158 16>,
+				 <&k3_clks 158 22>;
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		dpi0_out: endpoint {
+			remote-endpoint = <&dp0_in>;
+		};
+	};
+
+	port@2 {
+		reg = <2>;
+		dpi2_out: endpoint {
+			remote-endpoint = <&dsi0_in>;
+		};
+	};
+};
+
+&mhdp {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&dp0_pins_default>;
+	cdns,no-hpd;
+};
+
+&dp0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+		dp0_in: endpoint {
+			remote-endpoint = <&dpi0_out>;
+		};
+	};
+
+	port@4 {
+		reg = <4>;
+		dp0_out: endpoint {
+			remote-endpoint = <&dp0_connector_in>;
+		};
+	};
+};
+
+&dsi0_ports {
+	port@0 {
+		reg = <0>;
+		dsi0_out: endpoint {
+			remote-endpoint = <&dp1_in>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		dsi0_in: endpoint {
+			remote-endpoint = <&dpi2_out>;
+		};
+	};
+};
+
+&dsi_edp_bridge_ports {
+	port@0 {
+		reg = <0>;
+		dp1_in: endpoint {
+			remote-endpoint = <&dsi0_out>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		dp1_out: endpoint {
+			remote-endpoint = <&dp1_panel_in>;
+		};
+	};
+};
+
+&dsi_edp_bridge {
+	aux-bus {
+		panel {
+			compatible = "ti,panel-edp";
+			power-supply = <&dp1_pwr_3v3>;
+
+			port {
+				dp1_panel_in: endpoint {
+					remote-endpoint = <&dp1_out>;
+				};
+			};
+		};
+	};
+};
+
+&dphy_tx0 {
+	status = "okay";
+};
+
+&dsi0 {
+	status = "okay";
+};
+
+&mux0 {
+	idle-state = <0>;
+};
+
+&mux1 {
+	idle-state = <0>;
+};
+
+&exp_som {
+	p03-hog {
+		/* P03 - CANUART_MUX_SEL1 */
+		gpio-hog;
+		gpios = <3 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CANUART_MUX_SEL1";
+	};
+};
+
+&k3_clks {
+	/* Confiure AUDIO_EXT_REFCLK1 pin as output */
+	pinctrl-names = "default";
+	pinctrl-0 = <&audio_ext_refclk1_pins_default>;
+};
+
+&main_i2c3 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c3_pins_default>;
+	clock-frequency = <400000>;
+	mux-states = <&i2c_mux 1>;
+
+	exp3: gpio@20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	pcm3168a_1: audio-codec@44 {
+		compatible = "ti,pcm3168a";
+		reg = <0x44>;
+		#sound-dai-cells = <1>;
+		reset-gpios = <&exp3 0 GPIO_ACTIVE_LOW>;
+		/* C_AUDIO_REFCLK1 -> MCAN2_RX (Y25) */
+		clocks = <&audio_refclk1>;
+		clock-names = "scki";
+		VDD1-supply = <&vsys_3v3>;
+		VDD2-supply = <&vsys_3v3>;
+		VCCAD1-supply = <&vsys_5v0>;
+		VCCAD2-supply = <&vsys_5v0>;
+		VCCDA1-supply = <&vsys_5v0>;
+		VCCDA2-supply = <&vsys_5v0>;
+	};
+};
+
+&mcasp4 {
+	status = "okay";
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcasp4_pins_default>;
+	op-mode = <0>;          /* MCASP_IIS_MODE */
+	tdm-slots = <2>;
+	auxclk-fs-ratio = <256>;
+	serial-dir = <	/* 0: INACTIVE, 1: TX, 2: RX */
+		0 2 1 1
+		0 0 0 0
+		0 0 0 0
+		0 0 0 0
+	>;
+};
+
+&timesync_router {
+       /* Use Time Sync Router to map GENF1 input to HW4_TS_PUSH output */
+	mux-reg-masks-state = <
+		/* pps [mcu cpsw cpts genf1] in17 -> out25 [mcu cpsw cpts hw4_push] */
+		K3_TS_OFFSET(25, 0x0001ffff, 17)
+		>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721s2.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j721s2.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721s2.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -118,6 +118,7 @@
 		ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
 			 <0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
 			 <0x00 0x00700000 0x00 0x00700000 0x00 0x00001000>, /* ESM */
+			 <0x00 0x00a40000 0x00 0x00a40000 0x00 0x00000800>, /* Time Sync Router */
 			 <0x00 0x01000000 0x00 0x01000000 0x00 0x0d000000>, /* Most peripherals */
 			 <0x00 0x0d800000 0x00 0x0d800000 0x00 0x00800000>, /* PCIe Core*/
 			 <0x00 0x18000000 0x00 0x18000000 0x00 0x08000000>, /* PCIe1 DAT0 */
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721s2-evm-csi2-ov5640.dtso b/arch/arm64/boot/dts/ti/k3-j721s2-evm-csi2-ov5640.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721s2-evm-csi2-ov5640.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-evm-csi2-ov5640.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * LI OV5640 MIPI Camera module on MIPI CSI connector.
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_ov5640_fixed: ov5640-xclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&main_i2c5 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ov5640: camera@3c {
+		compatible = "ovti,ov5640";
+		reg = <0x3c>;
+		clocks = <&clk_ov5640_fixed>;
+		clock-names = "xclk";
+		powerdown-gpios = <&exp5 0 GPIO_ACTIVE_LOW>;
+
+		port {
+			csi2_cam0: endpoint {
+				remote-endpoint = <&csi2rx0_in_sensor>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx0_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam0>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721s2-evm-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j721s2-evm-fusion.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721s2-evm-fusion.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-evm-fusion.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Fusion (FPD-Link III) board on J721S2 and J784S4 EVM
+ * https://svtronics.com/portfolio/evm577pfusion-v1-0-fusion/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+
+&main_i2c5 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	deser@3d {
+		compatible = "ti,ds90ub960-q1";
+		reg = <0x3d>;
+		clocks = <&clk_fusion_25M_fixed>;
+		clock-names = "refclk";
+		i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+		deserializer_0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@4 {
+				reg = <4>;
+				ds90ub960_0_csi_out: endpoint {
+					clock-lanes = <0>;
+					data-lanes = <1 2 3 4>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy0>;
+				};
+			};
+		};
+
+		deserializer_0_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	deser@36 {
+		compatible = "ti,ds90ub960-q1";
+		reg = <0x36>;
+		clocks = <&clk_fusion_25M_fixed>;
+		clock-names = "refclk";
+		i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+		deserializer_1_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@4 {
+				reg = <4>;
+				ds90ub960_1_csi_out: endpoint {
+					clock-lanes = <0>;
+					data-lanes = <1 2 3 4>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy1>;
+				};
+			};
+		};
+
+		deserializer_1_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub960_0_csi_out>;
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+
+			};
+		};
+	};
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy1: endpoint {
+				remote-endpoint = <&ds90ub960_1_csi_out>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
+
+&dphy1 {
+	status = "okay";
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721s2-evm-pcie1-ep.dtso b/arch/arm64/boot/dts/ti/k3-j721s2-evm-pcie1-ep.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721s2-evm-pcie1-ep.dtso	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-evm-pcie1-ep.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -38,7 +38,7 @@
 		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
 		interrupt-names = "link_state";
 		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
-		ti,syscon-pcie-ctrl = <&scm_conf 0x074>;
+		ti,syscon-pcie-ctrl = <&pcie1_ctrl 0x0>;
 		max-link-speed = <3>;
 		num-lanes = <1>;
 		power-domains = <&k3_pds 276 TI_SCI_PD_EXCLUSIVE>;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721s2-evm-ub954.dtso b/arch/arm64/boot/dts/ti/k3-j721s2-evm-ub954.dtso
--- a/arch/arm64/boot/dts/ti/k3-j721s2-evm-ub954.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-evm-ub954.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for DS90UB954-Q1EVM FPDLink-III deserializer board on J721S2 and J784S4 EVM
+ * https://www.ti.com/tool/DS90UB954-Q1EVM
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+
+&main_i2c5 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	deser@3d {
+		compatible = "ti,ds90ub954-q1";
+		reg = <0x3d>;
+		clock-names = "refclk";
+		clocks = <&clk_fusion_25M_fixed>;
+		i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+		deserializer_0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@2 {
+				reg = <2>;
+				ds90ub960_0_csi_out: endpoint {
+					data-lanes = <1 2 3 4>;
+					clock-lanes = <0>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy0>;
+				};
+			};
+		};
+
+		deserializer_0_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub960_0_csi_out>;
+				data-lanes = <1 2 3 4>;
+				clock-lanes = <0>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
  */
+#include <dt-bindings/phy/phy.h>
 
 #include <dt-bindings/phy/phy-cadence.h>
 #include <dt-bindings/phy/phy-ti.h>
@@ -37,9 +38,8 @@
 		};
 	};
 
-	scm_conf: syscon@104000 {
-		compatible = "ti,j721e-system-controller", "syscon", "simple-mfd";
-		reg = <0x00 0x00104000 0x00 0x18000>;
+	scm_conf: bus@104000 {
+		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges = <0x00 0x00 0x00104000 0x18000>;
@@ -57,6 +57,11 @@
 			#phy-cells = <1>;
 		};
 
+		pcie1_ctrl: pcie-ctrl@74 {
+			compatible = "ti,j784s4-pcie-ctrl", "syscon";
+			reg = <0x74 0x4>;
+		};
+
 		serdes_ln_ctrl: mux-controller@80 {
 			compatible = "reg-mux";
 			reg = <0x80 0x10>;
@@ -70,6 +75,23 @@
 			reg = <0x140 0x18>;
 			#clock-cells = <1>;
 		};
+
+		edp_serdes_mux: mux-controller@310 {
+			compatible = "reg-mux";
+			reg = <0x310 0x4>;
+			#mux-control-cells = <1>;
+			/* EDP0 to SERDES0 lane 0/1 or 2/3 mux */
+			mux-reg-masks = <0x0 0x10000000>;
+		};
+
+		audio_refclk1: clock-controller@42e4 {
+			compatible = "ti,am62-audio-refclk";
+			reg = <0x42e4 0x4>;
+			clocks = <&k3_clks 157 299>;
+			assigned-clocks = <&k3_clks 157 299>;
+			assigned-clock-parents = <&k3_clks 157 328>;
+			#clock-cells = <0>;
+		};
 	};
 
 	main_ehrpwm0: pwm@3000000 {
@@ -555,6 +577,19 @@
 		status = "disabled";
 	};
 
+	gpu: gpu@4e20000000 {
+		 compatible = "ti,j721s2-pvr", "img,pvr-bxs64";
+		 reg = <0x4e 0x20000000 0x00 0x80000>;
+		 interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+		 power-domains = <&k3_pds 130 TI_SCI_PD_EXCLUSIVE>,
+				 <&k3_pds 373 TI_SCI_PD_EXCLUSIVE>;
+		 power-domain-names = "firmware", "dust";
+		 clocks = <&k3_clks 130 1>;
+		 assigned-clocks = <&k3_clks 130 1>;
+		 assigned-clock-rates = <800000000>;
+		 clock-names = "core";
+	};
+
 	main_gpio0: gpio@600000 {
 		compatible = "ti,j721e-gpio", "ti,keystone-gpio";
 		reg = <0x00 0x00600000 0x00 0x100>;
@@ -712,6 +747,7 @@
 		interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&k3_clks 179 2>;
 		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
+		sram = <&main_navss_sram>;
 	};
 
 	main_sdhci0: mmc@4f80000 {
@@ -780,6 +816,14 @@
 		dma-coherent;
 		dma-ranges;
 
+		main_navss_sram: navss-sram@30000000{
+			compatible = "mmio-sram";
+			reg = <0x00 0x30000000 0x00 0x10000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x00 0x30000000 0x10000>;
+		};
+
 		main_navss_intr: interrupt-controller@310e0000 {
 			compatible = "ti,sci-intr";
 			reg = <0x00 0x310e0000 0x00 0x4000>;
@@ -816,6 +860,7 @@
 			      <0x00 0x32800000 0x00 0x100000>;
 			interrupt-names = "rx_011";
 			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+			bootph-all;
 		};
 
 		hwspinlock: spinlock@30e00000 {
@@ -1234,18 +1279,24 @@
 		ranges;
 		#address-cells = <2>;
 		#size-cells = <2>;
-		dmas = <&main_bcdma_csi 0 0x4940 0>;
-		dma-names = "rx0";
+		dmas = <&main_bcdma_csi 0 0x4940 0>, <&main_bcdma_csi 0 0x4941 0>,
+		       <&main_bcdma_csi 0 0x4942 0>, <&main_bcdma_csi 0 0x4943 0>,
+		       <&main_bcdma_csi 0 0x4944 0>, <&main_bcdma_csi 0 0x4945 0>,
+		       <&main_bcdma_csi 0 0x4946 0>, <&main_bcdma_csi 0 0x4947 0>;
+		dma-names = "rx0", "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7";
 		power-domains = <&k3_pds 38 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 
 		cdns_csi2rx0: csi-bridge@4504000 {
 			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
 			reg = <0x00 0x04504000 0x00 0x1000>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
 			clocks = <&k3_clks 38 3>, <&k3_clks 38 1>, <&k3_clks 38 3>,
-				<&k3_clks 38 3>, <&k3_clks 38 4>, <&k3_clks 38 4>;
+				 <&k3_clks 38 3>, <&k3_clks 38 4>, <&k3_clks 38 4>;
 			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
-				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+				      "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
 			phys = <&dphy0>;
 			phy-names = "dphy";
 
@@ -1287,18 +1338,24 @@
 		ranges;
 		#address-cells = <2>;
 		#size-cells = <2>;
-		dmas = <&main_bcdma_csi 0 0x4960 0>;
-		dma-names = "rx0";
+		dmas = <&main_bcdma_csi 0 0x4960 0>, <&main_bcdma_csi 0 0x4961 0>,
+		       <&main_bcdma_csi 0 0x4962 0>, <&main_bcdma_csi 0 0x4963 0>,
+		       <&main_bcdma_csi 0 0x4964 0>, <&main_bcdma_csi 0 0x4965 0>,
+		       <&main_bcdma_csi 0 0x4966 0>, <&main_bcdma_csi 0 0x4967 0>;
+		dma-names = "rx0", "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7";
 		power-domains = <&k3_pds 39 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 
 		cdns_csi2rx1: csi-bridge@4514000 {
 			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
 			reg = <0x00 0x04514000 0x00 0x1000>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
 			clocks = <&k3_clks 39 3>, <&k3_clks 39 1>, <&k3_clks 39 3>,
-				<&k3_clks 39 3>, <&k3_clks 39 4>, <&k3_clks 39 4>;
+				 <&k3_clks 39 3>, <&k3_clks 39 4>, <&k3_clks 39 4>;
 			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
-				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+				      "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
 			phys = <&dphy1>;
 			phy-names = "dphy";
 
@@ -1360,15 +1417,21 @@
 		num-lanes = <4>;
 		#reset-cells = <1>;
 		#clock-cells = <1>;
-		ranges = <0x5060000 0x0 0x5060000 0x10000>;
+		ranges = <0x5060000 0x0 0x5060000 0x10000>,
+			 <0xa030a00 0x0 0xa030a00 0x40>; /* DPTX PHY */
 
 		assigned-clocks = <&k3_clks 365 3>;
 		assigned-clock-parents = <&k3_clks 365 7>;
 
 		serdes0: serdes@5060000 {
+			/*
+			 * Note: we also map DPTX PHY registers as the Torrent
+			 * needs to manage those.
+			 */
 			compatible = "ti,j721e-serdes-10g";
-			reg = <0x05060000 0x00010000>;
-			reg-names = "torrent_phy";
+			reg = <0x05060000 0x00010000>,
+			      <0xa030a00 0x40>; /* DPTX PHY */
+			reg-names = "torrent_phy", "dptx_phy";
 			resets = <&serdes_wiz0 0>;
 			reset-names = "torrent_reset";
 			clocks = <&serdes_wiz0 TI_WIZ_PLL0_REFCLK>,
@@ -1385,6 +1448,15 @@
 			#clock-cells = <1>;
 
 			status = "disabled"; /* Needs lane config */
+
+			torrent_phy_dp: phy@2 {
+				reg = <2>;
+				resets = <&serdes_wiz0 3>;
+				cdns,phy-type = <PHY_TYPE_DP>;
+				cdns,num-lanes = <2>;
+				cdns,max-bit-rate = <5400>;
+				#phy-cells = <0>;
+			};
 		};
 	};
 
@@ -1393,12 +1465,12 @@
 		reg = <0x00 0x02910000 0x00 0x1000>,
 		      <0x00 0x02917000 0x00 0x400>,
 		      <0x00 0x0d800000 0x00 0x800000>,
-		      <0x00 0x18000000 0x00 0x1000>;
+		      <0x41 0x00000000 0x00 0x1000>; /* ECAM (4 KB) */
 		reg-names = "intd_cfg", "user_cfg", "reg", "cfg";
 		interrupt-names = "link_state";
 		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
 		device_type = "pci";
-		ti,syscon-pcie-ctrl = <&scm_conf 0x074>;
+		ti,syscon-pcie-ctrl = <&pcie1_ctrl 0x0>;
 		max-link-speed = <3>;
 		num-lanes = <4>;
 		power-domains = <&k3_pds 276 TI_SCI_PD_EXCLUSIVE>;
@@ -1411,8 +1483,8 @@
 		device-id = <0xb013>;
 		msi-map = <0x0 &gic_its 0x0 0x10000>;
 		dma-coherent;
-		ranges = <0x01000000 0x0 0x18001000  0x00 0x18001000  0x0 0x0010000>,
-			 <0x02000000 0x0 0x18011000  0x00 0x18011000  0x0 0x7fef000>;
+		ranges = <0x01000000 0x00 0x00001000 0x41 0x00001000 0x00 0x00100000>, /* IO (1 MB) */
+			 <0x02000000 0x00 0x00101000 0x41 0x00101000 0x00 0xffeff000>; /* 32-bit Non-Prefetchable MEM (4 GB - 1 MB - 4 KB) */
 		dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 0 7>;
@@ -1789,6 +1861,78 @@
 		status = "disabled";
 	};
 
+	mhdp: dp-bridge@a000000 {
+		compatible = "ti,j721e-mhdp8546";
+		/*
+		 * Note: we do not map DPTX PHY area, as that is handled by
+		 * the PHY driver.
+		 */
+		reg = <0x0 0xa000000 0x0 0x30a00>, /* DSS_EDP0_V2A_CORE_VP_REGS_APB */
+		      <0x0 0x4f40000 0x0 0x20>;    /* DSS_EDP0_INTG_CFG_VP */
+		reg-names = "mhdptx", "j721e-intg";
+
+		clocks = <&k3_clks 156 19>;
+
+		phys = <&torrent_phy_dp>;
+		phy-names = "dpphy";
+
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 614 IRQ_TYPE_LEVEL_HIGH>;
+
+		power-domains = <&k3_pds 156 TI_SCI_PD_EXCLUSIVE>;
+
+		status = "disabled";
+
+		dp0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	dphy_tx0: phy@4480000 {
+		compatible = "ti,j721e-dphy";
+		reg = <0x0 0x04480000 0x0 0x1000>;
+		clocks = <&k3_clks 363 8>, <&k3_clks 363 14>;
+		clock-names = "psm", "pll_ref";
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 363 TI_SCI_PD_EXCLUSIVE>;
+		assigned-clocks = <&k3_clks 363 14>;
+		assigned-clock-parents = <&k3_clks 363 15>;
+		assigned-clock-rates = <19200000>;
+		status = "disabled";
+	};
+
+	dsi0: dsi@4800000 {
+		compatible = "ti,j721e-dsi";
+		reg = <0x0 0x04800000 0x0 0x100000>, <0x0 0x04710000 0x0 0x100>;
+		clocks = <&k3_clks 154 4>, <&k3_clks 154 1>;
+		clock-names = "dsi_p_clk", "dsi_sys_clk";
+		power-domains = <&k3_pds 154 TI_SCI_PD_EXCLUSIVE>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 600 IRQ_TYPE_LEVEL_HIGH>;
+		phys = <&dphy_tx0>;
+		phy-names = "dphy";
+		status = "disabled";
+
+		dsi0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+			};
+			port@1 {
+				reg = <1>;
+			};
+		};
+	};
+
+	timesync_router: mux-controller@a40000 {
+		compatible = "reg-mux";
+		reg = <0x0 0xa40000 0x0 0x800>;
+		#mux-control-cells = <1>;
+		status = "disabled";
+	};
+
 	dss: dss@4a00000 {
 		compatible = "ti,j721e-dss";
 		reg = <0x00 0x04a00000 0x00 0x10000>, /* common_m */
@@ -2047,4 +2191,94 @@
 		/* reserved for MAIN_R5F1_1 */
 		status = "reserved";
 	};
+
+	mcasp0: mcasp@2b00000 {
+		compatible = "ti,am33xx-mcasp-audio";
+		reg = <0x0 0x02b00000 0x0 0x2000>,
+		      <0x0 0x02b08000 0x0 0x1000>;
+		reg-names = "mpu","dat";
+		interrupts = <GIC_SPI 512 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 513 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "tx", "rx";
+		dmas = <&main_udmap 0xc400>, <&main_udmap 0x4400>;
+		dma-names = "tx", "rx";
+		clocks = <&k3_clks 209 0>;
+		clock-names = "fck";
+		assigned-clocks = <&k3_clks 209 0>;
+		assigned-clock-parents = <&k3_clks 209 1>;
+		power-domains = <&k3_pds 209 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	mcasp1: mcasp@2b10000 {
+		compatible = "ti,am33xx-mcasp-audio";
+		reg = <0x0 0x02b10000 0x0 0x2000>,
+		      <0x0 0x02b18000 0x0 0x1000>;
+		reg-names = "mpu","dat";
+		interrupts = <GIC_SPI 514 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 515 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "tx", "rx";
+		dmas = <&main_udmap 0xc401>, <&main_udmap 0x4401>;
+		dma-names = "tx", "rx";
+		clocks = <&k3_clks 210 0>;
+		clock-names = "fck";
+		assigned-clocks = <&k3_clks 210 0>;
+		assigned-clock-parents = <&k3_clks 210 1>;
+		power-domains = <&k3_pds 210 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	mcasp2: mcasp@2b20000 {
+		compatible = "ti,am33xx-mcasp-audio";
+		reg = <0x0 0x02b20000 0x0 0x2000>,
+		      <0x0 0x02b28000 0x0 0x1000>;
+		reg-names = "mpu","dat";
+		interrupts = <GIC_SPI 516 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "tx", "rx";
+		dmas = <&main_udmap 0xc402>, <&main_udmap 0x4402>;
+		dma-names = "tx", "rx";
+		clocks = <&k3_clks 211 0>;
+		clock-names = "fck";
+		assigned-clocks = <&k3_clks 211 0>;
+		assigned-clock-parents = <&k3_clks 211 1>;
+		power-domains = <&k3_pds 211 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	mcasp3: mcasp@2b30000 {
+		compatible = "ti,am33xx-mcasp-audio";
+		reg = <0x0 0x02b30000 0x0 0x2000>,
+		      <0x0 0x02b38000 0x0 0x1000>;
+		reg-names = "mpu","dat";
+		interrupts = <GIC_SPI 518 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 519 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "tx", "rx";
+		dmas = <&main_udmap 0xc403>, <&main_udmap 0x4403>;
+		dma-names = "tx", "rx";
+		clocks = <&k3_clks 212 0>;
+		clock-names = "fck";
+		assigned-clocks = <&k3_clks 212 0>;
+		assigned-clock-parents = <&k3_clks 212 1>;
+		power-domains = <&k3_pds 212 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	mcasp4: mcasp@2b40000 {
+		compatible = "ti,am33xx-mcasp-audio";
+		reg = <0x0 0x02b40000 0x0 0x2000>,
+		      <0x0 0x02b48000 0x0 0x1000>;
+		reg-names = "mpu","dat";
+		interrupts = <GIC_SPI 520 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 521 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "tx", "rx";
+		dmas = <&main_udmap 0xc404>, <&main_udmap 0x4404>;
+		dma-names = "tx", "rx";
+		clocks = <&k3_clks 213 0>;
+		clock-names = "fck";
+		assigned-clocks = <&k3_clks 213 0>;
+		assigned-clock-parents = <&k3_clks 213 1>;
+		power-domains = <&k3_pds 213 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
 };
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -21,16 +21,19 @@
 		k3_pds: power-controller {
 			compatible = "ti,sci-pm-domain";
 			#power-domain-cells = <2>;
+			bootph-all;
 		};
 
 		k3_clks: clock-controller {
 			compatible = "ti,k2g-sci-clk";
 			#clock-cells = <2>;
+			bootph-all;
 		};
 
 		k3_reset: reset-controller {
 			compatible = "ti,sci-reset";
 			#reset-cells = <2>;
+			bootph-all;
 		};
 	};
 
@@ -43,6 +46,7 @@
 		chipid: chipid@14 {
 			compatible = "ti,am654-chipid";
 			reg = <0x14 0x4>;
+			bootph-all;
 		};
 	};
 
@@ -53,6 +57,8 @@
 		reg = <0x00 0x43600000 0x00 0x10000>,
 		      <0x00 0x44880000 0x00 0x20000>,
 		      <0x00 0x44860000 0x00 0x20000>;
+		bootph-pre-ram;
+
 		/*
 		 * Marked Disabled:
 		 * Node is incomplete as it is meant for bootloaders and
@@ -148,12 +154,14 @@
 		cpsw_mac_syscon: ethernet-mac-syscon@200 {
 			compatible = "ti,am62p-cpsw-mac-efuse", "syscon";
 			reg = <0x200 0x8>;
+			bootph-all;
 		};
 
 		phy_gmii_sel: phy@4040 {
 			compatible = "ti,am654-phy-gmii-sel";
 			reg = <0x4040 0x4>;
 			#phy-cells = <1>;
+			bootph-all;
 		};
 
 	};
@@ -167,6 +175,7 @@
 		assigned-clocks = <&k3_clks 35 1>;
 		assigned-clock-parents = <&k3_clks 35 2>;
 		power-domains = <&k3_pds 35 TI_SCI_PD_EXCLUSIVE>;
+		bootph-pre-ram;
 		ti,timer-pwm;
 		/* Non-MPU Firmware usage */
 		status = "reserved";
@@ -361,6 +370,7 @@
 		clocks = <&k3_clks 223 1>;
 		clock-names = "fck";
 		power-domains = <&k3_pds 223 TI_SCI_PD_EXCLUSIVE>;
+		bootph-all;
 		status = "disabled";
 	};
 
@@ -469,6 +479,7 @@
 			      <0x0 0x2a500000 0x0 0x40000>,
 			      <0x0 0x28440000 0x0 0x40000>;
 			reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target", "cfg";
+			bootph-all;
 			ti,num-rings = <286>;
 			ti,sci-rm-range-gp-rings = <0x1>;
 			ti,sci = <&sms>;
@@ -488,6 +499,7 @@
 				    "tchan", "rchan", "rflow";
 			msi-parent = <&main_udmass_inta>;
 			#dma-cells = <1>;
+			bootph-all;
 
 			ti,sci = <&sms>;
 			ti,sci-dev-id = <273>;
@@ -507,6 +519,8 @@
 		reg = <0x00 0x2a480000 0x00 0x80000>,
 		      <0x00 0x2a380000 0x00 0x80000>,
 		      <0x00 0x2a400000 0x00 0x80000>;
+		bootph-pre-ram;
+
 		/*
 		 * Marked Disabled:
 		 * Node is incomplete as it is meant for bootloaders and
@@ -526,6 +540,7 @@
 		clocks = <&k3_clks 29 28>;
 		clock-names = "fck";
 		power-domains = <&k3_pds 29 TI_SCI_PD_EXCLUSIVE>;
+		bootph-all;
 
 		dmas = <&mcu_udmap 0xf000>,
 		       <&mcu_udmap 0xf001>,
@@ -550,6 +565,7 @@
 				label = "port1";
 				ti,syscon-efuse = <&cpsw_mac_syscon 0x0>;
 				phys = <&phy_gmii_sel 1>;
+				bootph-all;
 			};
 		};
 
@@ -633,6 +649,7 @@
 			cdns,fifo-depth = <256>;
 			cdns,fifo-width = <4>;
 			cdns,trigger-address = <0x0>;
+			cdns,phase-detect-selector = <2>;
 			clocks = <&k3_clks 109 5>;
 			assigned-clocks = <&k3_clks 109 5>;
 			assigned-clock-parents = <&k3_clks 109 7>;
@@ -652,6 +669,7 @@
 			cdns,fifo-depth = <256>;
 			cdns,fifo-width = <4>;
 			cdns,trigger-address = <0x0>;
+			cdns,phase-detect-selector = <2>;
 			clocks = <&k3_clks 110 5>;
 			power-domains = <&k3_pds 110 TI_SCI_PD_EXCLUSIVE>;
 			#address-cells = <1>;
@@ -667,11 +685,12 @@
 		      <0x00 0x42050000 0x0 0x350>;
 		power-domains = <&k3_pds 180 TI_SCI_PD_SHARED>;
 		#thermal-sensor-cells = <1>;
+		bootph-pre-ram;
 	};
 
 	mcu_r5fss0: r5fss@41000000 {
 		compatible = "ti,j721s2-r5fss";
-		ti,cluster-mode = <1>;
+		ti,cluster-mode = <0>;
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges = <0x41000000 0x00 0x41000000 0x20000>,
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -25,6 +25,14 @@
 		#size-cells = <2>;
 		ranges;
 
+		 /* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x38000000>;
+			linux,cma-default;
+		};
+
 		secure_ddr: optee@9e800000 {
 			reg = <0x00 0x9e800000 0x00 0x01800000>;
 			alignment = <0x1000>;
@@ -152,6 +160,30 @@
 		#phy-cells = <0>;
 		max-bitrate = <5000000>;
 	};
+
+	vsys_io_1v8: regulator-vsys-io-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vsys_io_1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vsys_io_1v2: regulator-vsys-io-1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "vsys_io_1v2";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	edp1_refclk: clock-edp1-refclk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <19200000>;
+	};
 };
 
 &wkup_pmx0 {
@@ -168,8 +200,8 @@
 			J721S2_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (F19) MCU_OSPI0_D6 */
 			J721S2_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (F20) MCU_OSPI0_D7 */
 			J721S2_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (E18) MCU_OSPI0_DQS */
-			J721S2_WKUP_IOPAD(0x004, PIN_INPUT, 0) /* (E20) MCU_OSPI0_LBCLKO */
 		>;
+		bootph-all;
 	};
 };
 
@@ -180,6 +212,13 @@
 			J721S2_WKUP_IOPAD(0x028, PIN_INPUT, 7)
 		>;
 	};
+
+	mcu_fss0_ospi0_1_pins_default: mcu-fss0-ospi0_1_default-pins {
+		pinctrl-single,pins = <
+			J721S2_WKUP_IOPAD(0x004, PIN_OUTPUT, 6) /* (B19) MCU_OSPI0_ECC_FAIL */
+			J721S2_WKUP_IOPAD(0x000, PIN_OUTPUT, 6) /* (B20) MCU_OSPI0_RESET_OUT0 */
+		>;
+	};
 };
 
 &wkup_pmx2 {
@@ -188,6 +227,7 @@
 			J721S2_WKUP_IOPAD(0x98, PIN_INPUT, 0) /* (H24) WKUP_I2C0_SCL */
 			J721S2_WKUP_IOPAD(0x9c, PIN_INPUT, 0) /* (H27) WKUP_I2C0_SDA */
 		>;
+		bootph-pre-ram;
 	};
 };
 
@@ -432,19 +472,120 @@
 &ospi0 {
 	status = "okay";
 	pinctrl-names = "default";
-	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>, <&mcu_fss0_ospi0_1_pins_default>;
 
-	flash@0 {
+	ospi0_nor: flash@0 {
 		compatible = "jedec,spi-nor";
 		reg = <0x0>;
 		spi-tx-bus-width = <8>;
 		spi-rx-bus-width = <8>;
 		spi-max-frequency = <25000000>;
+		bootph-all;
 		cdns,tshsl-ns = <60>;
 		cdns,tsd2d-ns = <60>;
 		cdns,tchsh-ns = <60>;
 		cdns,tslch-ns = <60>;
 		cdns,read-delay = <4>;
+		cdns,phy-mode;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "ospi.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition@80000 {
+				label = "ospi.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition@280000 {
+				label = "ospi.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition@680000 {
+				label = "ospi.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition@6c0000 {
+				label = "ospi.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition@800000 {
+				label = "ospi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition@3fc0000 {
+				label = "ospi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
+	};
+
+	ospi0_nand: nand@0 {
+		compatible = "spi-nand";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <2>;
+		cdns,phy-mode;
+		status = "disabled";
+		bootph-all;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "ospi_nand.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition@80000 {
+				label = "ospi_nand.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition@280000 {
+				label = "ospi_nand.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition@680000 {
+				label = "ospi_nand.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition@6c0000 {
+				label = "ospi_nand.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition@2000000 {
+				label = "ospi_nand.rootfs";
+				reg = <0x2000000 0x5fc0000>;
+			};
+
+			partition@7fc0000 {
+				bootph-all;
+				label = "ospi_nand.phypattern";
+				reg = <0x7fc0000 0x40000>;
+			};
+		};
 	};
 };
 
@@ -586,3 +727,31 @@
 	memory-region = <&c71_1_dma_memory_region>,
 			<&c71_1_memory_region>;
 };
+
+&main_i2c4 {
+	dsi_edp_bridge: dsi-edp-bridge@2c {
+		compatible = "ti,sn65dsi86";
+		reg = <0x2c>;
+
+		clock-names = "refclk";
+		clocks = <&edp1_refclk>;
+
+		enable-gpios = <&exp_som 5 0>;
+
+		vpll-supply = <&vsys_io_1v8>;
+		vccio-supply = <&vsys_io_1v8>;
+		vcca-supply = <&vsys_io_1v2>;
+		vcc-supply = <&vsys_io_1v2>;
+
+		dsi_edp_bridge_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+			};
+			port@1 {
+				reg = <1>;
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j722s.dtsi b/arch/arm64/boot/dts/ti/k3-j722s.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j722s.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j722s.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -164,6 +164,7 @@
 			 <0x00 0x30210000 0x00 0x30210000 0x00 0x00010000>, /* VPU */
 			 <0x00 0x30220000 0x00 0x30220000 0x00 0x00010000>, /* DSS1 */
 			 <0x00 0x30270000 0x00 0x30270000 0x00 0x00010000>, /* DSI-base1 */
+			 <0x00 0x30300000 0x00 0x30300000 0x00 0x00001000>, /* MCRC64 */
 			 <0x00 0x30500000 0x00 0x30500000 0x00 0x00100000>, /* DSI-base2 */
 			 <0x00 0x31000000 0x00 0x31000000 0x00 0x00050000>, /* USB0 DWC3 Core window */
 			 <0x00 0x31200000 0x00 0x31200000 0x00 0x00040000>, /* USB1 DWC3 Core window */
@@ -222,6 +223,22 @@
 		};
 	};
 
+	dss0_vp1_clk: clock-divider-oldi-dss0 {
+		compatible = "fixed-factor-clock";
+		clocks = <&k3_clks 186 0>;
+		#clock-cells = <0>;
+		clock-div = <7>;
+		clock-mult = <1>;
+	};
+
+	dss1_vp1_clk: clock-divider-oldi-dss1 {
+		compatible = "fixed-factor-clock";
+		clocks = <&k3_clks 232 0>;
+		#clock-cells = <0>;
+		clock-div = <7>;
+		clock-mult = <1>;
+	};
+
 	#include "k3-am62p-j722s-common-thermal.dtsi"
 };
 
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtso b/arch/arm64/boot/dts/ti/k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtso
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,304 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for RPi Camera V2.1 on J722S-EVM board.
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Schematics: https://datasheets.raspberrypi.com/camera/camera-v2-schematics.pdf
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+	cam0_reset_pins_default: cam0-reset-pins-default {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x03c, PIN_OUTPUT, 7)
+		>;
+	};
+
+	cam1_reset_pins_default: cam1-reset-pins-default {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x044, PIN_OUTPUT, 7)
+		>;
+	};
+
+	cam2_reset_pins_default: cam2-reset-pins-default {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x04c, PIN_OUTPUT, 7)
+		>;
+	};
+
+	cam3_reset_pins_default: cam3-reset-pins-default {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x054, PIN_OUTPUT, 7)
+		>;
+	};
+};
+
+&{/} {
+	clk_imx219_fixed: imx219-xclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&exp1 {
+	p06-hog{
+		/* P06 - CSI01_MUX_SEL_2 */
+		gpio-hog;
+		gpios = <6 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI01_MUX_SEL_2";
+	};
+
+	p07-hog{
+		/* P01 - CSI23_MUX_SEL_2 */
+		gpio-hog;
+		gpios = <7 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI23_MUX_SEL_2";
+	};
+};
+
+&pca9543_0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	i2c-alias-pool = /bits/ 16 <0x10 0x11>;
+
+	/* CAM0 I2C */
+	i2c@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0>;
+
+		imx219_0: sensor@10 {
+			compatible = "sony,imx219";
+			reg = <0x10>;
+
+			clocks = <&clk_imx219_fixed>;
+			clock-names = "xclk";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&cam0_reset_pins_default>;
+
+			reset-gpios = <&main_gpio0 15 GPIO_ACTIVE_HIGH>;
+
+			port {
+				csi2_cam0: endpoint {
+					remote-endpoint = <&csi2rx0_in_sensor>;
+					link-frequencies = /bits/ 64 <456000000>;
+					clock-lanes = <0>;
+					data-lanes = <1 2>;
+				};
+			};
+		};
+	};
+
+	/* CAM1 I2C */
+	i2c@1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <1>;
+
+		imx219_1: sensor@10 {
+			compatible = "sony,imx219";
+			reg = <0x10>;
+
+			clocks = <&clk_imx219_fixed>;
+			clock-names = "xclk";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&cam1_reset_pins_default>;
+
+			reset-gpios = <&main_gpio0 17 GPIO_ACTIVE_HIGH>;
+
+			port {
+				csi2_cam1: endpoint {
+					remote-endpoint = <&csi2rx1_in_sensor>;
+					link-frequencies = /bits/ 64 <456000000>;
+					clock-lanes = <0>;
+					data-lanes = <1 2>;
+				};
+			};
+		};
+	};
+};
+
+&pca9543_1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	i2c-alias-pool = /bits/ 16 <0x10 0x11>;
+
+	/* CAM0 I2C */
+	i2c@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0>;
+
+		imx219_2: sensor@10 {
+			compatible = "sony,imx219";
+			reg = <0x10>;
+
+			clocks = <&clk_imx219_fixed>;
+			clock-names = "xclk";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&cam2_reset_pins_default>;
+
+			reset-gpios = <&main_gpio0 19 GPIO_ACTIVE_HIGH>;
+
+			port {
+				csi2_cam2: endpoint {
+					remote-endpoint = <&csi2rx2_in_sensor>;
+					link-frequencies = /bits/ 64 <456000000>;
+					clock-lanes = <0>;
+					data-lanes = <1 2>;
+				};
+			};
+		};
+	};
+
+	/* CAM1 I2C */
+	i2c@1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <1>;
+
+		imx219_3: sensor@10 {
+			compatible = "sony,imx219";
+			reg = <0x10>;
+
+			clocks = <&clk_imx219_fixed>;
+			clock-names = "xclk";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&cam3_reset_pins_default>;
+
+			reset-gpios = <&main_gpio0 21 GPIO_ACTIVE_HIGH>;
+
+			port {
+				csi2_cam3: endpoint {
+					remote-endpoint = <&csi2rx3_in_sensor>;
+					link-frequencies = /bits/ 64 <456000000>;
+					clock-lanes = <0>;
+					data-lanes = <1 2>;
+				};
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx0_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam0>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx1_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam1>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx2 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi2_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx2_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam2>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx3 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi3_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx3_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam3>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
+
+&dphy1 {
+	status = "okay";
+};
+
+&ti_csi2rx2 {
+	status = "okay";
+};
+
+&dphy2 {
+	status = "okay";
+};
+
+&ti_csi2rx3 {
+	status = "okay";
+};
+
+&dphy3 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j722s-evm-csi2-quad-tevi-ov5640.dtso b/arch/arm64/boot/dts/ti/k3-j722s-evm-csi2-quad-tevi-ov5640.dtso
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm-csi2-quad-tevi-ov5640.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm-csi2-quad-tevi-ov5640.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * 4 x TEVI OV5640 MIPI Camera module on RPI camera connector.
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	clk_ov5640_fixed: ov5640-xclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+
+&main_pmx0 {
+	cam0_reset_pins_default: cam0-reset-pins-default {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x03c, PIN_OUTPUT, 7)
+		>;
+	};
+
+	cam1_reset_pins_default: cam1-reset-pins-default {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x044, PIN_OUTPUT, 7)
+		>;
+	};
+
+	cam2_reset_pins_default: cam2-reset-pins-default {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x04c, PIN_OUTPUT, 7)
+		>;
+	};
+
+	cam3_reset_pins_default: cam3-reset-pins-default {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x054, PIN_OUTPUT, 7)
+		>;
+	};
+};
+
+&exp1 {
+	p06-hog{
+		/* P06 - CSI01_MUX_SEL_2 */
+		gpio-hog;
+		gpios = <6 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI01_MUX_SEL_2";
+	};
+
+	p07-hog{
+		/* P01 - CSI23_MUX_SEL_2 */
+		gpio-hog;
+		gpios = <7 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI23_MUX_SEL_2";
+	};
+};
+
+&main_gpio0 {
+	p15-hog {
+		/* P15 - CSI2_CAMERA_GPIO1 */
+		gpio-hog;
+		gpios = <15 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI2_CAMERA_GPIO1";
+	};
+
+	p17-hog {
+		/* P17 - CSI2_CAMERA_GPIO2 */
+		gpio-hog;
+		gpios = <17 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI2_CAMERA_GPIO2";
+	};
+
+	p19-hog {
+		/* P19 - CSI2_CAMERA_GPIO3 */
+		gpio-hog;
+		gpios = <19 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI2_CAMERA_GPIO3";
+	};
+
+	p21-hog {
+		/* P21 - CSI2_CAMERA_GPIO4 */
+		gpio-hog;
+		gpios = <21 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI2_CAMERA_GPIO4";
+	};
+};
+
+&pca9543_0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	i2c-alias-pool = /bits/ 16 <0x3c 0x3d>;
+
+	i2c@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0>;
+
+		ov5640_0: camera@3c {
+			compatible = "ovti,ov5640";
+			reg = <0x3c>;
+			clocks = <&clk_ov5640_fixed>;
+			clock-names = "xclk";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&cam0_reset_pins_default>;
+
+			port {
+				csi2_cam0: endpoint {
+					remote-endpoint = <&csi2rx0_in_sensor>;
+					clock-lanes = <0>;
+					data-lanes = <1 2>;
+				};
+			};
+		};
+	};
+
+	i2c@1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <1>;
+
+		ov5640_1: camera@3c {
+			compatible = "ovti,ov5640";
+			reg = <0x3c>;
+			clocks = <&clk_ov5640_fixed>;
+			clock-names = "xclk";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&cam1_reset_pins_default>;
+
+			port {
+				csi2_cam1: endpoint {
+					remote-endpoint = <&csi2rx1_in_sensor>;
+					clock-lanes = <0>;
+					data-lanes = <1 2>;
+				};
+			};
+		};
+	};
+};
+
+&pca9543_1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	i2c-alias-pool = /bits/ 16 <0x3c 0x3d>;
+
+	i2c@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0>;
+
+		ov5640_2: camera@3c {
+			compatible = "ovti,ov5640";
+			reg = <0x3c>;
+			clocks = <&clk_ov5640_fixed>;
+			clock-names = "xclk";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&cam2_reset_pins_default>;
+
+			port {
+				csi2_cam2: endpoint {
+					remote-endpoint = <&csi2rx2_in_sensor>;
+					clock-lanes = <0>;
+					data-lanes = <1 2>;
+				};
+			};
+		};
+	};
+
+	i2c@1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <1>;
+
+		ov5640_3: camera@3c {
+			compatible = "ovti,ov5640";
+			reg = <0x3c>;
+			clocks = <&clk_ov5640_fixed>;
+			clock-names = "xclk";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&cam3_reset_pins_default>;
+
+			port {
+				csi2_cam3: endpoint {
+					remote-endpoint = <&csi2rx3_in_sensor>;
+					clock-lanes = <0>;
+					data-lanes = <1 2>;
+				};
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx0_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam0>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx1_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam1>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx2 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi2_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx2_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam2>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx3 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi3_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx3_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam3>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
+
+&dphy1 {
+	status = "okay";
+};
+
+
+&ti_csi2rx2 {
+	status = "okay";
+};
+
+&dphy2 {
+	status = "okay";
+};
+
+
+&ti_csi2rx3 {
+	status = "okay";
+};
+
+&dphy3 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j722s-evm-dsi-rpi-7inch-panel.dtso b/arch/arm64/boot/dts/ti/k3-j722s-evm-dsi-rpi-7inch-panel.dtso
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm-dsi-rpi-7inch-panel.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm-dsi-rpi-7inch-panel.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT Overlay for RPi 7inch touchscreen panel interfaced with DSI on
+ * J722S EVM.
+ *
+ * RPi DSI Panel: https://www.raspberrypi.com/products/raspberry-pi-touch-display/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "k3-pinctrl.h"
+
+&{/} {
+	panel0 {
+		compatible = "raspberrypi,7inch-dsi", "simple-panel";
+		backlight = <&display_reg>;
+		power-supply = <&display_reg>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&panel_bridge_out>;
+			};
+		};
+	};
+
+	bridge_reg: bridge-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "bridge-reg";
+		gpio = <&display_reg 0 0>;
+		vin-supply = <&display_reg>;
+		enable-active-high;
+	};
+};
+
+&exp2 {
+	p00-hog {
+		/* P00 - DSI_Mux_SEL_2 */
+		gpio-hog;
+		gpios = <0 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "DSI_Mux_SEL_2";
+	};
+};
+
+&dphy_tx0 {
+	status = "okay";
+};
+
+&main_i2c1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	display_reg: regulator@45 {
+		compatible = "raspberrypi,7inch-touchscreen-panel-regulator";
+		reg = <0x45>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&dsi0 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+
+			dsi0_out: endpoint {
+				remote-endpoint = <&panel_bridge_in>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+
+			dsi0_in: endpoint {
+				remote-endpoint = <&dss1_dpi1_out>;
+			};
+		};
+	};
+
+	bridge@0 {
+		status = "okay";
+		compatible = "toshiba,tc358762";
+		reg = <0>;
+		vddc-supply = <&bridge_reg>;
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				panel_bridge_in: endpoint {
+					remote-endpoint = <&dsi0_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				panel_bridge_out: endpoint {
+					remote-endpoint = <&panel_in>;
+				};
+			};
+		};
+	};
+};
+
+&dss1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* DSS1-VP1: DSI Output */
+	port@1 {
+		reg = <1>;
+
+		dss1_dpi1_out: endpoint {
+			remote-endpoint = <&dsi0_in>;
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts	2025-10-23 09:30:40.283462146 -0400
@@ -42,6 +42,14 @@
 		#size-cells = <2>;
 		ranges;
 
+		/* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x38000000>;
+			linux,cma-default;
+		};
+
 		secure_tfa_ddr: tfa@9e780000 {
 			reg = <0x00 0x9e780000 0x00 0x80000>;
 			no-map;
@@ -244,6 +252,17 @@
 		max-bitrate = <5000000>;
 		standby-gpios = <&exp1 17 GPIO_ACTIVE_HIGH>;
 	};
+
+	hdmi0: connector-hdmi {
+		compatible = "hdmi-connector";
+		label = "hdmi";
+		type = "a";
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&sii9022_out>;
+			};
+		};
+	};
 };
 
 &main_pmx0 {
@@ -263,6 +282,21 @@
 		bootph-all;
 	};
 
+	main_i2c1_pins_default: main-i2c1-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x01e8, PIN_INPUT_PULLUP, 0) /* (C24) I2C1_SCL */
+			J722S_IOPAD(0x01ec, PIN_INPUT_PULLUP, 0) /* (A22) I2C1_SDA */
+		>;
+		bootph-all;
+	};
+
+	main_i2c2_pins_default: main-i2c2-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x00b0, PIN_INPUT_PULLUP, 1) /* (P22) GPMC0_CSn2.I2C2_SCL */
+			J722S_IOPAD(0x00b4, PIN_INPUT_PULLUP, 1) /* (P23) GPMC0_CSn3.I2C2_SDA */
+		>;
+	};
+
 	main_uart0_pins_default: main-uart0-default-pins {
 		pinctrl-single,pins = <
 			J722S_IOPAD(0x01c8, PIN_INPUT, 0)	/* (A22) UART0_RXD */
@@ -303,6 +337,7 @@
 			J722S_IOPAD(0x0160, PIN_OUTPUT, 0) /* (AC24) MDIO0_MDC */
 			J722S_IOPAD(0x015c, PIN_INPUT, 0) /* (AD25) MDIO0_MDIO */
 		>;
+		bootph-all;
 	};
 
 	ospi0_pins_default: ospi0-default-pins {
@@ -337,6 +372,7 @@
 			J722S_IOPAD(0x0130, PIN_OUTPUT, 0) /* (AG26) RGMII1_TXC */
 			J722S_IOPAD(0x012c, PIN_OUTPUT, 0) /* (AF25) RGMII1_TX_CTL */
 		>;
+		bootph-all;
 	};
 
 	main_usb1_pins_default: main-usb1-default-pins {
@@ -359,6 +395,52 @@
 			J722S_IOPAD(0x00a0, PIN_OUTPUT, 1) /* (N24) GPMC0_WPn.AUDIO_EXT_REFCLK1 */
 		>;
 	};
+
+	pmic_irq_pins_default: pmic-irq-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x030, PIN_INPUT, 7) /* (K23) GPIO0_12 */
+		>;
+	};
+
+	main_gpio0_ioexp_intr_pins_default: main-gpio0-ioexp-intr-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0110, PIN_INPUT, 7) /* (G27) MMC2_DAT1.GPIO0_67 */
+		>;
+	};
+
+	main_dpi_pins_default: main-dpi-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0100, PIN_OUTPUT, 0) /* (AB23) VOUT0_VSYNC */
+			J722S_IOPAD(0x00f8, PIN_OUTPUT, 0) /* (AB24) VOUT0_HSYNC */
+			J722S_IOPAD(0x0104, PIN_OUTPUT, 0) /* (AC26) VOUT0_PCLK */
+			J722S_IOPAD(0x00fc, PIN_OUTPUT, 0) /* (AC27) VOUT0_DE */
+			J722S_IOPAD(0x00b8, PIN_OUTPUT, 0) /* (W27) VOUT0_DATA0 */
+			J722S_IOPAD(0x00bc, PIN_OUTPUT, 0) /* (W25) VOUT0_DATA1 */
+			J722S_IOPAD(0x00c0, PIN_OUTPUT, 0) /* (W24) VOUT0_DATA2 */
+			J722S_IOPAD(0x00c4, PIN_OUTPUT, 0) /* (W23) VOUT0_DATA3 */
+			J722S_IOPAD(0x00c8, PIN_OUTPUT, 0) /* (W22) VOUT0_DATA4 */
+			J722S_IOPAD(0x00cc, PIN_OUTPUT, 0) /* (W21) VOUT0_DATA5 */
+			J722S_IOPAD(0x00d0, PIN_OUTPUT, 0) /* (Y26) VOUT0_DATA6 */
+			J722S_IOPAD(0x00d4, PIN_OUTPUT, 0) /* (Y27) VOUT0_DATA7 */
+			J722S_IOPAD(0x00d8, PIN_OUTPUT, 0) /* (AA24) VOUT0_DATA8 */
+			J722S_IOPAD(0x00dc, PIN_OUTPUT, 0) /* (AA27) VOUT0_DATA9 */
+			J722S_IOPAD(0x00e0, PIN_OUTPUT, 0) /* (AA25) VOUT0_DATA10 */
+			J722S_IOPAD(0x00e4, PIN_OUTPUT, 0) /* (AB25) VOUT0_DATA11 */
+			J722S_IOPAD(0x00e8, PIN_OUTPUT, 0) /* (AA23) VOUT0_DATA12 */
+			J722S_IOPAD(0x00ec, PIN_OUTPUT, 0) /* (AA22) VOUT0_DATA13 */
+			J722S_IOPAD(0x00f0, PIN_OUTPUT, 0) /* (AB26) VOUT0_DATA14 */
+			J722S_IOPAD(0x00f4, PIN_OUTPUT, 0) /* (AB27) VOUT0_DATA15 */
+			J722S_IOPAD(0x005c, PIN_OUTPUT, 1) /* (U27) GPMC0_AD8.VOUT0_DATA16 */
+			J722S_IOPAD(0x0060, PIN_OUTPUT, 1) /* (U26) GPMC0_AD9.VOUT0_DATA17 */
+			J722S_IOPAD(0x0064, PIN_OUTPUT, 1) /* (V27) GPMC0_AD10.VOUT0_DATA18 */
+			J722S_IOPAD(0x0068, PIN_OUTPUT, 1) /* (V25) GPMC0_AD11.VOUT0_DATA19 */
+			J722S_IOPAD(0x006c, PIN_OUTPUT, 1) /* (V26) GPMC0_AD12.VOUT0_DATA20 */
+			J722S_IOPAD(0x0070, PIN_OUTPUT, 1) /* (V24) GPMC0_AD13.VOUT0_DATA21 */
+			J722S_IOPAD(0x0074, PIN_OUTPUT, 1) /* (V22) GPMC0_AD14.VOUT0_DATA22 */
+			J722S_IOPAD(0x0078, PIN_OUTPUT, 1) /* (V23) GPMC0_AD15.VOUT0_DATA23 */
+			J722S_IOPAD(0x009c, PIN_OUTPUT, 1) /* (W26) GPMC0_WAIT1.VOUT0_EXTPCLKIN */
+		>;
+	};
 };
 
 &cpsw3g {
@@ -374,6 +456,7 @@
 
 	cpsw3g_phy0: ethernet-phy@0 {
 		reg = <0>;
+		bootph-all;
 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
 		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
 		ti,min-output-impedance;
@@ -406,6 +489,13 @@
 
 &mcu_pmx0 {
 
+	mcu_i2c0_pins_default: mcu-i2c0-default-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x048, PIN_INPUT, 0) /* (E11) MCU_I2C0_SDA */
+			J722S_MCU_IOPAD(0x044, PIN_INPUT, 0) /* (B13) MCU_I2C0_SCL */
+		>;
+	};
+
 	mcu_mcan0_pins_default: mcu-mcan0-default-pins {
 		pinctrl-single,pins = <
 			J722S_MCU_IOPAD(0x038, PIN_INPUT, 0) /* (D8) MCU_MCAN0_RX */
@@ -459,6 +549,87 @@
 	clock-frequency = <400000>;
 	status = "okay";
 	bootph-all;
+
+	tps65224: pmic@48 {
+		compatible = "ti,tps65224-q1";
+		reg = <0x48>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_irq_pins_default>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+		ti,primary-pmic;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		buck12-supply = <&vsys_io_3v3>;
+		buck3-supply = <&vsys_io_3v3>;
+		buck4-supply = <&vsys_io_3v3>;
+
+		ldo1-supply = <&vsys_io_3v3>;
+		ldo2-supply = <&vsys_io_3v3>;
+		ldo3-supply = <&vsys_io_3v3>;
+
+		regulators {
+
+			buck1: buck1 {
+				regulator-name = "vcc1v8_io_buck1";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+				bootph-all;
+			};
+
+			buck2: buck2 {
+				regulator-name = "vcc1v1_ddr_buck2";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck3: buck3 {
+				regulator-name = "vcc0v85_ram_buck3";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck4: buck4 {
+				regulator-name = "vcc0v75_ioret_buck4";
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo1: ldo1 {
+				regulator-name = "vdda1v8_pll_ldo1";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo2: ldo2 {
+				regulator-name = "dvdd3v3_ldo2";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo3: ldo3 {
+				regulator-name = "vdd1v85_phy_ldo3";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+	       };
+	};
 };
 
 &k3_clks {
@@ -491,11 +662,12 @@
 				  "PCIe0_1L_RC_RSTz", "PCIe0_1L_PRSNT#",
 				  "ENET1_EXP_SPARE2", "ENET1_EXP_PWRDN",
 				  "PD_I2ENET1_I2CMUX_SELC_IRQ", "ENET1_EXP_RESETZ";
+		bootph-all;
 
 		p05-hog {
 			/* P05 - USB2.0_MUX_SEL */
 			gpio-hog;
-			gpios = <5 GPIO_ACTIVE_HIGH>;
+			gpios = <5 GPIO_ACTIVE_LOW>;
 			output-high;
 		};
 
@@ -536,6 +708,117 @@
 	};
 };
 
+&main_i2c1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	clock-frequency = <100000>;
+
+	exp2: gpio@20 {
+		compatible = "ti,tca6416";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "DSI_Mux_SEL_2", "GPIO_eDP_ENABLE",
+				  "DP0_PWR_SW_EN", "GPIO_OLDI_RSTn",
+				  "GPIO_HDMI_RSTn", "HDMI_LS_OE",
+				  "", "",
+				  "DSI_GPIO0", "DSI_GPIO1",
+				  "DSI_EDID", "IO_eDP_IRQ",
+				  "OLDI_INT#", "HDMI_INTn",
+				  "", "";
+
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <67 IRQ_TYPE_EDGE_FALLING>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_gpio0_ioexp_intr_pins_default>;
+		bootph-all;
+
+		p04-hog {
+			/* P04 - GPIO_HDMI_RSTn */
+			gpio-hog;
+			gpios = <4 GPIO_ACTIVE_LOW>;
+			output-low;
+			line-name = "GPIO_HDMI_RSTn";
+		};
+
+		p03-hog {
+			/* P03 - GPIO_OLDI_RSTn */
+			gpio-hog;
+			gpios = <3 GPIO_ACTIVE_LOW>;
+			output-low;
+			line-name = "GPIO_OLDI_RSTn";
+		};
+
+		p05-hog {
+			/* P05 - HDMI_LS_OE */
+			gpio-hog;
+			gpios = <5 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "HDMI_LS_OE";
+		};
+	};
+
+	sii9022: bridge-hdmi@3b {
+		compatible = "sil,sii9022";
+		reg = <0x3b>;
+		interrupt-parent = <&exp2>;
+		interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+		#sound-dai-cells = <0>;
+		sil,i2s-data-lanes = < 0 >;
+
+		hdmi_tx_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/*
+			 * HDMI can be serviced with 3 potential VPs -
+			 * (DSS0 VP1 / DSS1 VP0 / DSS1 VP1).
+			 * For now, we will service it with DSS1 VP0.
+			 */
+			port@0 {
+				reg = <0>;
+
+				sii9022_in: endpoint {
+					remote-endpoint = <&dss1_dpi0_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				sii9022_out: endpoint {
+					remote-endpoint = <&hdmi_connector_in>;
+				};
+			};
+		};
+	};
+};
+
+&main_i2c2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c2_pins_default>;
+	clock-frequency = <400000>;
+
+	pca9543_0: i2c-mux@70 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+	};
+
+	pca9543_1: i2c-mux@71 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x71>;
+	};
+};
+
 &ospi0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ospi0_pins_default>;
@@ -552,6 +835,7 @@
 		cdns,tchsh-ns = <60>;
 		cdns,tslch-ns = <60>;
 		cdns,read-delay = <4>;
+		cdns,phy-mode;
 		bootph-all;
 
 		partitions {
@@ -590,12 +874,71 @@
 			};
 
 			partition@3fc0000 {
+				bootph-all;
 				label = "ospi.phypattern";
 				reg = <0x3fc0000 0x40000>;
 			};
 		};
 	};
 
+	ospi0_nand: nand@0 {
+		compatible = "spi-nand";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		bootph-all;
+		cdns,phy-mode;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "ospi_nand.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition@80000 {
+				label = "ospi_nand.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition@280000 {
+				label = "ospi_nand.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition@680000 {
+				label = "ospi_nand.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition@6c0000 {
+				label = "ospi_nand.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition@2000000 {
+				label = "ospi_nand.rootfs";
+				reg = <0x2000000 0x5fc0000>;
+			};
+
+			partition@7fc0000 {
+				bootph-all;
+				label = "ospi_nand.phypattern";
+				reg = <0x7fc0000 0x40000>;
+			};
+		};
+	};
 };
 
 &sdhci0 {
@@ -820,3 +1163,59 @@
 &mcu_gpio0 {
 	status = "okay";
 };
+
+&mcu_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_i2c0_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&dss1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_dpi_pins_default>;
+
+	clocks = <&k3_clks 232 8>,
+		 <&k3_clks 232 0>,
+		 <&k3_clks 232 4>;
+
+	assigned-clocks = <&k3_clks 241 0>,	/* DSS1-VP0 */
+			  <&k3_clks 240 0>,	/* DSS1-VP1 */
+			  <&k3_clks 245 0>;	/* DPI Output */
+
+	assigned-clock-parents = <&k3_clks 241 2>,	/* PLL 17 HDMI */
+				 <&k3_clks 240 1>,	/* PLL 18 DSI */
+				 <&k3_clks 245 2>;	/* DSS1-DPI0 */
+};
+
+&dss1_ports {
+	/* DSS1-VP0: DPI/HDMI Output */
+	port@0 {
+		reg = <0>;
+
+		dss1_dpi0_out: endpoint {
+			remote-endpoint = <&sii9022_in>;
+		};
+	};
+};
+
+&mcu_rti0 {
+	assigned-clock-parents = <&k3_clks 131 4>;
+};
+
+&main_rti0 {
+	assigned-clock-parents = <&k3_clks 125 4>;
+};
+
+&main_rti1 {
+	assigned-clock-parents = <&k3_clks 126 4>;
+};
+
+&main_rti2 {
+	assigned-clock-parents = <&k3_clks 127 4>;
+};
+
+&main_rti3 {
+	assigned-clock-parents = <&k3_clks 128 4>;
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-fusion.dtso
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-fusion.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-fusion.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Fusion (FPD-Link III) board on J721E EVM
+ * https://svtronics.com/portfolio/evm577pfusion-v1-0-fusion/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+
+&pca9543_0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	i2c@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0>;
+
+		deser@3d {
+			compatible = "ti,ds90ub960-q1";
+			reg = <0x3d>;
+			clocks = <&clk_fusion_25M_fixed>;
+			clock-names = "refclk";
+			i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+			deserializer_0_ports: ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				/* CSI-2 TX */
+				port@4 {
+					reg = <4>;
+					ds90ub960_0_csi_out: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2 3 4>;
+						link-frequencies = /bits/ 64 <800000000>;
+						remote-endpoint = <&csi2_phy0>;
+					};
+				};
+			};
+
+			deserializer_0_links: links {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
+		deser@36 {
+			compatible = "ti,ds90ub960-q1";
+			reg = <0x36>;
+			clocks = <&clk_fusion_25M_fixed>;
+			clock-names = "refclk";
+			i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+			deserializer_1_ports: ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				/* CSI-2 TX */
+				port@4 {
+					reg = <4>;
+					ds90ub960_1_csi_out: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2 3 4>;
+						link-frequencies = /bits/ 64 <800000000>;
+						remote-endpoint = <&csi2_phy1>;
+					};
+				};
+			};
+
+			deserializer_1_links: links {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub960_0_csi_out>;
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy1: endpoint {
+				remote-endpoint = <&ds90ub960_1_csi_out>;
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
+
+&dphy1 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-iv-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-iv-fusion.dtso
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-iv-fusion.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-iv-fusion.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,293 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for FPDLink IV UB9702 Deserializer on J722S
+ * https://www.ti.com/tool/J7EXPA01EVM
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&main_pmx0 {
+	csi_expansion_interface_reset: csi-expansion-interface-reset-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x114, PIN_OUTPUT, 7) /* (G26) GPIO0_68 */
+		>;
+	};
+};
+
+&main_gpio0 {
+	line68-hog{
+		gpio-hog;
+		gpios = <68 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI2_EXP_RSTZ";
+	};
+};
+
+&pca9543_0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	i2c@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0>;
+
+		deser@3d {
+			compatible = "ti,ds90ub9702-q1";
+			reg = <0x3d>;
+			clocks = <&clk_fusion_25M_fixed>;
+			clock-names = "refclk";
+			i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+			deserializer_0_ports: ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0{
+					reg= <0>;
+					status = "disabled";
+				};
+
+				port@1{
+					reg= <1>;
+					status = "disabled";
+				};
+
+				port@2{
+					reg= <2>;
+					status = "disabled";
+				};
+
+				port@3{
+					reg= <3>;
+					status = "disabled";
+				};
+
+				/* CSI-2 TX */
+				port@4 {
+					reg = <4>;
+					ds90ub970_0_csi_out: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2 3 4>;
+						link-frequencies = /bits/ 64 <800000000>;
+						remote-endpoint = <&csi2_phy0>;
+					};
+				};
+
+				port@5{
+					reg= <5>;
+					status = "disabled";
+				};
+			};
+
+			deserializer_0_links: links {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
+		deser@30 {
+			compatible = "ti,ds90ub9702-q1";
+			reg = <0x30>;
+			clocks = <&clk_fusion_25M_fixed>;
+			clock-names = "refclk";
+			i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+			deserializer_1_ports: ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0{
+					reg= <0>;
+					status = "disabled";
+				};
+
+				port@1{
+					reg= <1>;
+					status = "disabled";
+				};
+
+				port@2{
+					reg= <2>;
+					status = "disabled";
+				};
+
+				port@3{
+					reg= <3>;
+					status = "disabled";
+				};
+
+				/* CSI-2 TX */
+				port@4 {
+					reg = <4>;
+					ds90ub970_1_csi_out: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2 3 4>;
+						link-frequencies = /bits/ 64 <800000000>;
+						remote-endpoint = <&csi2_phy1>;
+					};
+				};
+
+				port@5{
+					reg= <5>;
+					status = "disabled";
+				};
+			};
+
+			deserializer_1_links: links {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
+		deser@32 {
+			compatible = "ti,ds90ub9702-q1";
+			reg = <0x32>;
+			clocks = <&clk_fusion_25M_fixed>;
+			clock-names = "refclk";
+			i2c-alias-pool = <0x6a 0x6b 0x6c 0x6d 0x6e 0x6f>;
+
+			deserializer_2_ports: ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0{
+					reg= <0>;
+					status = "disabled";
+				};
+
+				port@1{
+					reg= <1>;
+					status = "disabled";
+				};
+
+				port@2{
+					reg= <2>;
+					status = "disabled";
+				};
+
+				port@3{
+					reg= <3>;
+					status = "disabled";
+				};
+
+				/* CSI-2 TX */
+				port@4 {
+					reg = <4>;
+					ds90ub970_2_csi_out: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2 3 4>;
+						link-frequencies = /bits/ 64 <800000000>;
+						remote-endpoint = <&csi2_phy2>;
+					};
+				};
+
+				port@5{
+					reg= <5>;
+					status = "disabled";
+				};
+			};
+
+			deserializer_2_links: links {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub970_0_csi_out>;
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy1: endpoint {
+				remote-endpoint = <&ds90ub970_1_csi_out>;
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx2 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi2_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy2: endpoint {
+				remote-endpoint = <&ds90ub970_2_csi_out>;
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
+
+&dphy1 {
+	status = "okay";
+};
+
+&ti_csi2rx2 {
+	status = "okay";
+};
+
+&dphy2 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j722s-evm-microtips-mf101hie-panel.dtso b/arch/arm64/boot/dts/ti/k3-j722s-evm-microtips-mf101hie-panel.dtso
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm-microtips-mf101hie-panel.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm-microtips-mf101hie-panel.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * Microtips integrated OLDI panel (MF-101HIEBCAF0) and touch DT overlay for J722S-EVM
+ *
+ * Panel datasheet: https://simplespec.microtipsusa.com/uploads/spec/datasheetFile/2588/13-101HIEBCAF0-S_V1.1_20221104.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&{/} {
+	display {
+		compatible = "microtips,mf-101hiebcaf0", "panel-simple";
+		/*
+		* Note that the OLDI TX 0 transmits the odd set of pixels
+		* while the OLDI TX 1 transmits the even set. This is a
+		* fixed configuration in the IP integration and is not
+		* changeable. The properties, "dual-lvds-odd-pixels" and
+		* "dual-lvds-even-pixels" have been used to merely
+		* identify if a Dual Link configuration is required.
+		* Swapping them will cause an error in the dss oldi driver.
+		*/
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				dual-lvds-odd-pixels;
+
+				lcd_in0: endpoint {
+					remote-endpoint = <&oldi0_dss0_out>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				dual-lvds-even-pixels;
+
+				lcd_in1: endpoint {
+					remote-endpoint = <&oldi1_dss0_out>;
+				};
+			};
+		};
+	};
+};
+
+&dss0 {
+	status = "okay";
+};
+
+&oldi0_dss0 {
+	status = "okay";
+};
+
+&oldi1_dss0 {
+	status = "okay";
+};
+
+&oldi0_dss0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+
+		oldi0_dss0_in: endpoint {
+			remote-endpoint = <&dss0_dpi0_out0>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+
+		oldi0_dss0_out: endpoint {
+			remote-endpoint = <&lcd_in0>;
+		};
+	};
+};
+
+&oldi1_dss0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port@0 {
+		reg = <0>;
+
+		oldi1_dss0_in: endpoint {
+			remote-endpoint = <&dss0_dpi0_out1>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+
+		oldi1_dss0_out: endpoint {
+			remote-endpoint = <&lcd_in1>;
+		};
+	};
+};
+
+&dss0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* VP1: Output to OLDI */
+	port@0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dss0_dpi0_out0: endpoint@0 {
+			reg = <0>;
+			remote-endpoint = <&oldi0_dss0_in>;
+		};
+
+		dss0_dpi0_out1: endpoint@1 {
+			reg = <1>;
+			remote-endpoint = <&oldi1_dss0_in>;
+		};
+	};
+};
+
+&main_i2c1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	touchscreen@41 {
+		compatible = "ilitek,ili251x";
+		reg = <0x41>;
+		interrupt-parent = <&exp2>;
+		interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&exp2 3 GPIO_ACTIVE_LOW>;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j722s-evm-pwm.dtso b/arch/arm64/boot/dts/ti/k3-j722s-evm-pwm.dtso
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm-pwm.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm-pwm.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT Overlay for enabling PWM output on User Expansion header on J722S-EVM
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&main_pmx0 {
+
+	main_epwm0_pins_default: main-epwm0-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x01b4, PIN_OUTPUT, 2) /* (B20) EHRPWM0_A */
+		>;
+	};
+
+	main_epwm1_pins_default: main-epwm1-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x01bc, PIN_OUTPUT, 2) /* (D20) EHRPWM1_A */
+			J722S_IOPAD(0x01c0, PIN_OUTPUT, 2) /* (E19) EHRPWM1_B */
+		>;
+	};
+
+	main_ecap0_pins_default: main-ecap0-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x01b8, PIN_OUTPUT, 3) /* (C20) ECAP0_IN_APWM_OUT */
+		>;
+	};
+};
+
+&epwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm0_pins_default>;
+	status = "okay";
+};
+
+&epwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_epwm1_pins_default>;
+	status = "okay";
+};
+
+&ecap0 {
+	/* ECAP in APWM mode */
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_ecap0_pins_default>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j722s-evm-v3link-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j722s-evm-v3link-fusion.dtso
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm-v3link-fusion.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm-v3link-fusion.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Arducam V3Link UC-A09 board
+ * https://www.arducam.com/fpd-link-3-cameras/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&exp1 {
+	p06-hog {
+		/* P06 - CSI01_MUX_SEL_2 */
+		gpio-hog;
+		gpios = <6 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI01_MUX_SEL_2";
+	};
+
+	p07-hog {
+		/* P01 - CSI23_MUX_SEL_2 */
+		gpio-hog;
+		gpios = <7 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI23_MUX_SEL_2";
+	};
+};
+
+&pca9543_0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* CAM0 I2C */
+	i2c@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0>;
+
+		deser@30 {
+			compatible = "ti,ds90ub960-q1";
+			reg = <0x30>;
+
+			clock-names = "refclk";
+			clocks = <&clk_fusion_25M_fixed>;
+
+			i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+			deserializer_0_ports: ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				/* CSI-2 TX */
+				port@4 {
+					reg = <4>;
+					ds90ub960_0_csi_out: endpoint {
+						data-lanes = <1 2 3 4>;
+						clock-lanes = <0>;
+						link-frequencies = /bits/ 64 <800000000>;
+						remote-endpoint = <&csi2_phy0>;
+					};
+				};
+			};
+
+			deserializer_0_links: links {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+	};
+
+	/* CAM1 I2C */
+	i2c@1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <1>;
+
+		deser@30 {
+			compatible = "ti,ds90ub960-q1";
+			reg = <0x30>;
+
+			clock-names = "refclk";
+			clocks = <&clk_fusion_25M_fixed>;
+
+			i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+			deserializer_1_ports: ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				/* CSI-2 TX */
+				port@4 {
+					reg = <4>;
+					ds90ub960_1_csi_out: endpoint {
+						data-lanes = <1 2 3 4>;
+						clock-lanes = <0>;
+						link-frequencies = /bits/ 64 <800000000>;
+						remote-endpoint = <&csi2_phy1>;
+					};
+				};
+			};
+
+			deserializer_1_links: links {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub960_0_csi_out>;
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy1: endpoint {
+				remote-endpoint = <&ds90ub960_1_csi_out>;
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
+
+&dphy1 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi b/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -102,10 +102,10 @@
 		reg = <0x00 0x0f102000 0x00 0x1000>,
 		      <0x00 0x0f100000 0x00 0x400>,
 		      <0x00 0x0d000000 0x00 0x00800000>,
-		      <0x00 0x68000000 0x00 0x00001000>;
+		      <0x06 0x00000000 0x00 0x00001000>; /* ECAM (4 KB) */
 		reg-names = "intd_cfg", "user_cfg", "reg", "cfg";
-		ranges = <0x01000000 0x00 0x68001000  0x00 0x68001000  0x00 0x0010000>,
-			 <0x02000000 0x00 0x68011000  0x00 0x68011000  0x00 0x7fef000>;
+		ranges = <0x01000000 0x00 0x00001000 0x06 0x00001000 0x00 0x00100000>, /* IO (1 MB) */
+			 <0x02000000 0x00 0x00101000 0x06 0x00101000 0x00 0xffeff000>; /* 32-bit Non-Prefetchable MEM (4 GB - 1 MB - 4 KB) */
 		dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
 		interrupt-names = "link_state";
 		interrupts = <GIC_SPI 99 IRQ_TYPE_EDGE_RISING>;
@@ -139,7 +139,7 @@
 		ranges;
 		status = "disabled";
 
-		usb1: usb@31200000{
+		usb1: usb@31200000 {
 			compatible = "cdns,usb3";
 			reg = <0x00 0x31200000 0x00 0x10000>,
 			      <0x00 0x31210000 0x00 0x10000>,
@@ -158,6 +158,201 @@
 		};
 	};
 
+	ti_csi2rx1: ticsi2rx@30122000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x30122000 0x00 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x5100 0>, <&main_bcdma_csi 0 0x5101 0>,
+		       <&main_bcdma_csi 0 0x5102 0>, <&main_bcdma_csi 0 0x5103 0>;
+		dma-names = "rx0", "rx1", "rx2", "rx3";
+		power-domains = <&k3_pds 247 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx1: csi-bridge@30121000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x30121000 0x00 0x1000>;
+			interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
+			clocks = <&k3_clks 247 0>, <&k3_clks 247 3>, <&k3_clks 247 0>,
+				 <&k3_clks 247 0>, <&k3_clks 247 4>, <&k3_clks 247 4>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				      "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy1>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi1_port0: port@0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi1_port1: port@1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi1_port2: port@2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi1_port3: port@3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi1_port4: port@4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx2: ticsi2rx@30142000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x30142000 0x00 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		power-domains = <&k3_pds 248 TI_SCI_PD_EXCLUSIVE>;
+		dmas = <&main_bcdma_csi 0 0x5200 0>, <&main_bcdma_csi 0 0x5201 0>,
+		       <&main_bcdma_csi 0 0x5202 0>, <&main_bcdma_csi 0 0x5203 0>;
+		dma-names = "rx0", "rx1", "rx2", "rx3";
+		status = "disabled";
+
+		cdns_csi2rx2: csi-bridge@30141000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x30141000 0x00 0x1000>;
+			interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
+			clocks = <&k3_clks 248 0>, <&k3_clks 248 3>, <&k3_clks 248 0>,
+				 <&k3_clks 248 0>, <&k3_clks 248 4>, <&k3_clks 248 4>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				      "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy2>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi2_port0: port@0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi2_port1: port@1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi2_port2: port@2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi2_port3: port@3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi2_port4: port@4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx3: ticsi2rx@30162000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x30162000 0x00 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x5300 0>, <&main_bcdma_csi 0 0x5301 0>,
+		       <&main_bcdma_csi 0 0x5302 0>, <&main_bcdma_csi 0 0x5303 0>;
+		dma-names = "rx0", "rx1", "rx2", "rx3";
+		power-domains = <&k3_pds 249 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx3: csi-bridge@30161000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x30161000 0x00 0x1000>;
+			interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
+			clocks = <&k3_clks 249 0>, <&k3_clks 249 3>, <&k3_clks 249 0>,
+				 <&k3_clks 249 0>, <&k3_clks 249 4>, <&k3_clks 249 4>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				      "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy3>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi3_port0: port@0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi3_port1: port@1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi3_port2: port@2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi3_port3: port@3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi3_port4: port@4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	dphy1: phy@30130000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x30130000 0x00 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 251 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy2: phy@30150000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x30150000 0x00 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 252 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy3: phy@30170000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x30170000 0x00 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 253 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
 	main_r5fss0: r5fss@78400000 {
 		compatible = "ti,am62-r5fss";
 		#address-cells = <1>;
@@ -184,7 +379,7 @@
 	};
 
 	c7x_0: dsp@7e000000 {
-		compatible = "ti,am62a-c7xv-dsp";
+		compatible = "ti,j722s-c7xv-dsp";
 		reg = <0x00 0x7e000000 0x00 0x00200000>;
 		reg-names = "l2sram";
 		resets = <&k3_reset 208 1>;
@@ -196,7 +391,7 @@
 	};
 
 	c7x_1: dsp@7e200000 {
-		compatible = "ti,am62a-c7xv-dsp";
+		compatible = "ti,j722s-c7xv-dsp";
 		reg = <0x00 0x7e200000 0x00 0x00200000>;
 		reg-names = "l2sram";
 		resets = <&k3_reset 268 1>;
@@ -208,6 +403,16 @@
 	};
 };
 
+&main_bcdma_csi {
+	compatible = "ti,j722s-dmss-bcdma-csi";
+	reg = <0x00 0x4e230000 0x00 0x100>,
+	      <0x00 0x4e180000 0x00 0x20000>,
+	      <0x00 0x4e300000 0x00 0x10000>,
+	      <0x00 0x4e100000 0x00 0x80000>;
+	reg-names = "gcfg", "rchanrt", "tchanrt", "ringrt";
+	ti,sci-rm-range-tchan = <0x22>;
+};
+
 /* MCU domain overrides */
 
 &mcu_r5fss0_core0 {
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j742s2.dtsi b/arch/arm64/boot/dts/ti/k3-j742s2.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j742s2.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j742s2.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Device Tree Source for J742S2 SoC Family
+ *
+ * TRM: https://www.ti.com/lit/pdf/spruje3
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+#include "k3-j784s4-j742s2-common.dtsi"
+
+/ {
+	model = "Texas Instruments K3 J742S2 SoC";
+	compatible = "ti,j742s2";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0: cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+
+				core2 {
+					cpu = <&cpu2>;
+				};
+
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+		};
+
+		cpu0: cpu@0 {
+			compatible = "arm,cortex-a72";
+			reg = <0x000>;
+			device_type = "cpu";
+			enable-method = "psci";
+			i-cache-size = <0xc000>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <256>;
+			next-level-cache = <&L2_0>;
+		};
+
+		cpu1: cpu@1 {
+			compatible = "arm,cortex-a72";
+			reg = <0x001>;
+			device_type = "cpu";
+			enable-method = "psci";
+			i-cache-size = <0xc000>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <256>;
+			next-level-cache = <&L2_0>;
+		};
+
+		cpu2: cpu@2 {
+			compatible = "arm,cortex-a72";
+			reg = <0x002>;
+			device_type = "cpu";
+			enable-method = "psci";
+			i-cache-size = <0xc000>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <256>;
+			next-level-cache = <&L2_0>;
+		};
+
+		cpu3: cpu@3 {
+			compatible = "arm,cortex-a72";
+			reg = <0x003>;
+			device_type = "cpu";
+			enable-method = "psci";
+			i-cache-size = <0xc000>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			d-cache-size = <0x8000>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <256>;
+			next-level-cache = <&L2_0>;
+		};
+	};
+};
+
+#include "k3-j742s2-main.dtsi"
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j742s2-evm.dts b/arch/arm64/boot/dts/ti/k3-j742s2-evm.dts
--- a/arch/arm64/boot/dts/ti/k3-j742s2-evm.dts	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j742s2-evm.dts	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * EVM Board Schematics: https://www.ti.com/lit/zip/SPAC001
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-j742s2.dtsi"
+#include "k3-j784s4-j742s2-evm-common.dtsi"
+
+/ {
+	model = "Texas Instruments J742S2 EVM";
+	compatible = "ti,j742s2-evm", "ti,j742s2";
+
+	memory@80000000 {
+		/* 16G RAM */
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+		      <0x00000008 0x80000000 0x00000003 0x80000000>;
+		device_type = "memory";
+		bootph-all;
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j742s2-evm-ethfw.dtso b/arch/arm64/boot/dts/ti/k3-j742s2-evm-ethfw.dtso
--- a/arch/arm64/boot/dts/ti/k3-j742s2-evm-ethfw.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j742s2-evm-ethfw.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for CPSW5G functionality with Ethernet Switch Firmware (EthFw)
+ * and CPSW Proxy Client driver.
+ *
+ * Since the ENET Expansion connector on J742S2-EVM is connected to SERDES4,
+ * CPSW5G which uses SERDES1 is non-functional on the EVM. This overlay is
+ * provided as a reference for enabling EthFw with CPSW5G on custom boards
+ * built with the J742S2 SoC.
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "k3-serdes.h"
+
+&serdes_ln_ctrl {
+	idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>, <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
+		      <J784S4_SERDES0_LANE2_IP3_UNUSED>, <J784S4_SERDES0_LANE3_USB>,
+		      <J784S4_SERDES1_LANE0_QSGMII_LANE3>, <J784S4_SERDES1_LANE1_QSGMII_LANE4>,
+		      <J784S4_SERDES1_LANE2_QSGMII_LANE1>, <J784S4_SERDES1_LANE3_QSGMII_LANE2>,
+		      <J784S4_SERDES4_LANE0_EDP_LANE0>, <J784S4_SERDES4_LANE1_EDP_LANE1>,
+		      <J784S4_SERDES4_LANE2_EDP_LANE2>, <J784S4_SERDES4_LANE3_EDP_LANE3>;
+};
+
+/* SERDES1 is used by EthFw */
+&serdes_wiz1 {
+	status = "reserved";
+};
+
+/* Since SERDES1 is used by EthFw, PCIE0 is non-functional */
+&pcie0_rc {
+	status = "disabled";
+};
+
+/* uart2 is assigned to EthFw running on remote CPU core */
+&main_uart2 {
+	status = "reserved";
+};
+
+/* Reserve shared memory for inter-core network communication */
+&reserved_memory {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	main_r5fss0_core0_shared_memory_queue_region:r5f-virtual-eth-queues@af000000 {
+		compatible = "shared-dma-pool";
+		reg = <0x00 0xaf000000 0x00 0x200000>;
+		no-map;
+	};
+
+	main_r5fss0_core0_shared_memory_bufpool_region:r5f-virtual-eth-buffers@af200000 {
+		compatible = "shared-dma-pool";
+		reg = <0x00 0xaf200000 0x00 0x1e00000>;
+		no-map;
+	};
+};
+
+&main_r5fss0_core0 {
+	memory-region = <&main_r5fss0_core0_dma_memory_region>,
+			<&main_r5fss0_core0_memory_region>,
+			<&main_r5fss0_core0_shared_memory_queue_region>,
+			<&main_r5fss0_core0_shared_memory_bufpool_region>;
+};
+
+/* EthFw uses timers so mark them reserved */
+&main_timer12 {
+	status = "reserved";
+};
+
+&main_timer13 {
+	status = "reserved";
+};
+
+/*
+ * Disable the following to avoid overloading exp2.
+ * Otherwise it will result in PHY read/write errors.
+ */
+&main_mcan4 {
+	status = "disabled";
+};
+
+&transceiver3 {
+	status = "disabled";
+};
+
+&mux1 {
+	status = "disabled";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j742s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j742s2-main.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j742s2-main.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j742s2-main.dtsi	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Device Tree Source for J742S2 SoC Family
+ *
+ * TRM: https://www.ti.com/lit/pdf/spruje3
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+&c71_0 {
+	firmware-name = "j742s2-c71_0-fw";
+};
+
+&c71_1 {
+	firmware-name = "j742s2-c71_1-fw";
+};
+
+&c71_2 {
+	firmware-name = "j742s2-c71_2-fw";
+};
+
+&main_r5fss0_core0 {
+	firmware-name = "j742s2-main-r5f0_0-fw";
+};
+
+&main_r5fss0_core1 {
+	firmware-name = "j742s2-main-r5f0_1-fw";
+};
+
+&main_r5fss1_core0 {
+	firmware-name = "j742s2-main-r5f1_0-fw";
+};
+
+&main_r5fss1_core1 {
+	firmware-name = "j742s2-main-r5f1_1-fw";
+};
+
+&main_r5fss2_core0 {
+	firmware-name = "j742s2-main-r5f2_0-fw";
+};
+
+&main_r5fss2_core1 {
+	firmware-name = "j742s2-main-r5f2_1-fw";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j784s4-evm-csi2-ov5640.dtso b/arch/arm64/boot/dts/ti/k3-j784s4-evm-csi2-ov5640.dtso
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm-csi2-ov5640.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm-csi2-ov5640.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * LI OV5640 MIPI Camera module on MIPI CSI (CSI2-EXP-AUX) connector.
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_ov5640_fixed: ov5640-xclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&main_i2c5 {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ov5640: camera@3c {
+		compatible = "ovti,ov5640";
+		reg = <0x3c>;
+		clocks = <&clk_ov5640_fixed>;
+		clock-names = "xclk";
+		powerdown-gpios = <&exp5 0 GPIO_ACTIVE_LOW>;
+
+		port {
+			csi2_cam0: endpoint {
+				remote-endpoint = <&csi2rx2_in_sensor>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx2 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi2_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx2_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam0>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx2 {
+	status = "okay";
+};
+
+&dphy2 {
+	status = "okay";
+};
\ No newline at end of file
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts	2025-10-23 09:30:40.283462146 -0400
@@ -10,176 +10,23 @@
 #include <dt-bindings/net/ti-dp83867.h>
 #include <dt-bindings/gpio/gpio.h>
 #include "k3-j784s4.dtsi"
+#include "k3-j784s4-j742s2-evm-common.dtsi"
 
 / {
 	compatible = "ti,j784s4-evm", "ti,j784s4";
 	model = "Texas Instruments J784S4 EVM";
 
-	chosen {
-		stdout-path = "serial2:115200n8";
-	};
-
-	aliases {
-		serial0 = &wkup_uart0;
-		serial1 = &mcu_uart0;
-		serial2 = &main_uart8;
-		mmc0 = &main_sdhci0;
-		mmc1 = &main_sdhci1;
-		i2c0 = &wkup_i2c0;
-		i2c3 = &main_i2c0;
-		ethernet0 = &mcu_cpsw_port1;
-		ethernet1 = &main_cpsw1_port1;
-	};
-
 	memory@80000000 {
-		device_type = "memory";
-		bootph-all;
 		/* 32G RAM */
 		reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
 		      <0x00000008 0x80000000 0x00000007 0x80000000>;
+		device_type = "memory";
+		bootph-all;
 	};
 
 	reserved_memory: reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
-		ranges;
-
-		secure_ddr: optee@9e800000 {
-			reg = <0x00 0x9e800000 0x00 0x01800000>;
-			no-map;
-		};
-
-		mcu_r5fss0_core0_dma_memory_region: r5f-dma-memory@a0000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa0000000 0x00 0x100000>;
-			no-map;
-		};
-
-		mcu_r5fss0_core0_memory_region: r5f-memory@a0100000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa0100000 0x00 0xf00000>;
-			no-map;
-		};
-
-		mcu_r5fss0_core1_dma_memory_region: r5f-dma-memory@a1000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa1000000 0x00 0x100000>;
-			no-map;
-		};
-
-		mcu_r5fss0_core1_memory_region: r5f-memory@a1100000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa1100000 0x00 0xf00000>;
-			no-map;
-		};
-
-		main_r5fss0_core0_dma_memory_region: r5f-dma-memory@a2000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa2000000 0x00 0x100000>;
-			no-map;
-		};
-
-		main_r5fss0_core0_memory_region: r5f-memory@a2100000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa2100000 0x00 0xf00000>;
-			no-map;
-		};
-
-		main_r5fss0_core1_dma_memory_region: r5f-dma-memory@a3000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa3000000 0x00 0x100000>;
-			no-map;
-		};
-
-		main_r5fss0_core1_memory_region: r5f-memory@a3100000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa3100000 0x00 0xf00000>;
-			no-map;
-		};
-
-		main_r5fss1_core0_dma_memory_region: r5f-dma-memory@a4000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa4000000 0x00 0x100000>;
-			no-map;
-		};
-
-		main_r5fss1_core0_memory_region: r5f-memory@a4100000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa4100000 0x00 0xf00000>;
-			no-map;
-		};
-
-		main_r5fss1_core1_dma_memory_region: r5f-dma-memory@a5000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa5000000 0x00 0x100000>;
-			no-map;
-		};
-
-		main_r5fss1_core1_memory_region: r5f-memory@a5100000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa5100000 0x00 0xf00000>;
-			no-map;
-		};
-
-		main_r5fss2_core0_dma_memory_region: r5f-dma-memory@a6000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa6000000 0x00 0x100000>;
-			no-map;
-		};
-
-		main_r5fss2_core0_memory_region: r5f-memory@a6100000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa6100000 0x00 0xf00000>;
-			no-map;
-		};
-
-		main_r5fss2_core1_dma_memory_region: r5f-dma-memory@a7000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa7000000 0x00 0x100000>;
-			no-map;
-		};
-
-		main_r5fss2_core1_memory_region: r5f-memory@a7100000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa7100000 0x00 0xf00000>;
-			no-map;
-		};
-
-		c71_0_dma_memory_region: c71-dma-memory@a8000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa8000000 0x00 0x100000>;
-			no-map;
-		};
-
-		c71_0_memory_region: c71-memory@a8100000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa8100000 0x00 0xf00000>;
-			no-map;
-		};
-
-		c71_1_dma_memory_region: c71-dma-memory@a9000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa9000000 0x00 0x100000>;
-			no-map;
-		};
-
-		c71_1_memory_region: c71-memory@a9100000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xa9100000 0x00 0xf00000>;
-			no-map;
-		};
-
-		c71_2_dma_memory_region: c71-dma-memory@aa000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xaa000000 0x00 0x100000>;
-			no-map;
-		};
-
-		c71_2_memory_region: c71-memory@aa100000 {
-			compatible = "shared-dma-pool";
-			reg = <0x00 0xaa100000 0x00 0xf00000>;
-			no-map;
-		};
 
 		c71_3_dma_memory_region: c71-dma-memory@ab000000 {
 			compatible = "shared-dma-pool";
@@ -193,1339 +40,18 @@
 			no-map;
 		};
 	};
-
-	evm_12v0: regulator-evm12v0 {
-		/* main supply */
-		compatible = "regulator-fixed";
-		regulator-name = "evm_12v0";
-		regulator-min-microvolt = <12000000>;
-		regulator-max-microvolt = <12000000>;
-		regulator-always-on;
-		regulator-boot-on;
-	};
-
-	vsys_3v3: regulator-vsys3v3 {
-		/* Output of LM5140 */
-		compatible = "regulator-fixed";
-		regulator-name = "vsys_3v3";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		vin-supply = <&evm_12v0>;
-		regulator-always-on;
-		regulator-boot-on;
-	};
-
-	vsys_5v0: regulator-vsys5v0 {
-		/* Output of LM5140 */
-		compatible = "regulator-fixed";
-		regulator-name = "vsys_5v0";
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		vin-supply = <&evm_12v0>;
-		regulator-always-on;
-		regulator-boot-on;
-	};
-
-	vdd_mmc1: regulator-sd {
-		/* Output of TPS22918 */
-		compatible = "regulator-fixed";
-		regulator-name = "vdd_mmc1";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		regulator-boot-on;
-		enable-active-high;
-		vin-supply = <&vsys_3v3>;
-		gpio = <&exp2 2 GPIO_ACTIVE_HIGH>;
-	};
-
-	vdd_sd_dv: regulator-TLV71033 {
-		/* Output of TLV71033 */
-		compatible = "regulator-gpio";
-		regulator-name = "tlv71033";
-		pinctrl-names = "default";
-		pinctrl-0 = <&vdd_sd_dv_pins_default>;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <3300000>;
-		regulator-boot-on;
-		vin-supply = <&vsys_5v0>;
-		gpios = <&main_gpio0 8 GPIO_ACTIVE_HIGH>;
-		states = <1800000 0x0>,
-			 <3300000 0x1>;
-	};
-
-	dp0_pwr_3v3: regulator-dp0-prw {
-		compatible = "regulator-fixed";
-		regulator-name = "dp0-pwr";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&exp4 0 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
-	dp0: connector-dp0 {
-		compatible = "dp-connector";
-		label = "DP0";
-		type = "full-size";
-		dp-pwr-supply = <&dp0_pwr_3v3>;
-
-		port {
-			dp0_connector_in: endpoint {
-				remote-endpoint = <&dp0_out>;
-			};
-		};
-	};
-
-	transceiver0: can-phy0 {
-		compatible = "ti,tcan1042";
-		#phy-cells = <0>;
-		max-bitrate = <5000000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&mcu_mcan0_gpio_pins_default>;
-		standby-gpios = <&wkup_gpio0 69 GPIO_ACTIVE_HIGH>;
-	};
-
-	transceiver1: can-phy1 {
-		compatible = "ti,tcan1042";
-		#phy-cells = <0>;
-		max-bitrate = <5000000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&mcu_mcan1_gpio_pins_default>;
-		standby-gpios = <&wkup_gpio0 2 GPIO_ACTIVE_HIGH>;
-	};
-
-	transceiver2: can-phy2 {
-		/* standby pin has been grounded by default */
-		compatible = "ti,tcan1042";
-		#phy-cells = <0>;
-		max-bitrate = <5000000>;
-	};
-
-	transceiver3: can-phy3 {
-		compatible = "ti,tcan1042";
-		#phy-cells = <0>;
-		max-bitrate = <5000000>;
-		standby-gpios = <&exp2 7 GPIO_ACTIVE_HIGH>;
-		mux-states = <&mux1 1>;
-	};
-
-	mux1: mux-controller {
-		compatible = "gpio-mux";
-		#mux-state-cells = <1>;
-		mux-gpios = <&exp2 14 GPIO_ACTIVE_HIGH>;
-		idle-state = <1>;
-	};
-
-	codec_audio: sound {
-		compatible = "ti,j7200-cpb-audio";
-		model = "j784s4-cpb";
-
-		ti,cpb-mcasp = <&mcasp0>;
-		ti,cpb-codec = <&pcm3168a_1>;
-
-		clocks = <&k3_clks 265 0>, <&k3_clks 265 1>,
-			 <&k3_clks 157 34>, <&k3_clks 157 63>;
-		clock-names = "cpb-mcasp-auxclk", "cpb-mcasp-auxclk-48000",
-			      "cpb-codec-scki", "cpb-codec-scki-48000";
-	};
-};
-
-&wkup_gpio0 {
-	status = "okay";
-};
-
-&main_pmx0 {
-	bootph-all;
-	main_cpsw2g_default_pins: main-cpsw2g-default-pins {
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x0b8, PIN_INPUT, 6) /* (AC34) MCASP1_ACLKX.RGMII1_RD0 */
-			J784S4_IOPAD(0x0a0, PIN_INPUT, 6) /* (AD34) MCASP0_AXR12.RGMII1_RD1 */
-			J784S4_IOPAD(0x0a4, PIN_INPUT, 6) /* (AJ36) MCASP0_AXR13.RGMII1_RD2 */
-			J784S4_IOPAD(0x0a8, PIN_INPUT, 6) /* (AF34) MCASP0_AXR14.RGMII1_RD3 */
-			J784S4_IOPAD(0x0b0, PIN_INPUT, 6) /* (AL33) MCASP1_AXR3.RGMII1_RXC */
-			J784S4_IOPAD(0x0ac, PIN_INPUT, 6) /* (AE34) MCASP0_AXR15.RGMII1_RX_CTL */
-			J784S4_IOPAD(0x08c, PIN_INPUT, 6) /* (AE35) MCASP0_AXR7.RGMII1_TD0 */
-			J784S4_IOPAD(0x090, PIN_INPUT, 6) /* (AC35) MCASP0_AXR8.RGMII1_TD1 */
-			J784S4_IOPAD(0x094, PIN_INPUT, 6) /* (AG35) MCASP0_AXR9.RGMII1_TD2 */
-			J784S4_IOPAD(0x098, PIN_INPUT, 6) /* (AH36) MCASP0_AXR10.RGMII1_TD3 */
-			J784S4_IOPAD(0x0b4, PIN_INPUT, 6) /* (AL34) MCASP1_AXR4.RGMII1_TXC */
-			J784S4_IOPAD(0x09c, PIN_INPUT, 6) /* (AF35) MCASP0_AXR11.RGMII1_TX_CTL */
-		>;
-	};
-
-	main_cpsw2g_mdio_default_pins: main-cpsw2g-mdio-default-pins {
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x0c0, PIN_INPUT, 6) /* (AD38) MCASP1_AXR0.MDIO0_MDC */
-			J784S4_IOPAD(0x0bc, PIN_INPUT, 6) /* (AD33) MCASP1_AFSX.MDIO0_MDIO */
-		>;
-	};
-
-	main_uart8_pins_default: main-uart8-default-pins {
-		bootph-all;
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x040, PIN_INPUT, 14) /* (AF37) MCASP0_AXR0.UART8_CTSn */
-			J784S4_IOPAD(0x044, PIN_OUTPUT, 14) /* (AG37) MCASP0_AXR1.UART8_RTSn */
-			J784S4_IOPAD(0x0d0, PIN_INPUT, 11) /* (AP38) SPI0_CS1.UART8_RXD */
-			J784S4_IOPAD(0x0d4, PIN_OUTPUT, 11) /* (AN38) SPI0_CLK.UART8_TXD */
-		>;
-	};
-
-	main_i2c0_pins_default: main-i2c0-default-pins {
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x0e0, PIN_INPUT_PULLUP, 0) /* (AN36) I2C0_SCL */
-			J784S4_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AP37) I2C0_SDA */
-		>;
-	};
-
-	main_i2c5_pins_default: main-i2c5-default-pins {
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x01c, PIN_INPUT, 8) /* (AG34) MCAN15_TX.I2C5_SCL */
-			J784S4_IOPAD(0x018, PIN_INPUT, 8) /* (AK36) MCAN14_RX.I2C5_SDA */
-		>;
-	};
-
-	main_mmc1_pins_default: main-mmc1-default-pins {
-		bootph-all;
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x104, PIN_INPUT, 0) /* (AB38) MMC1_CLK */
-			J784S4_IOPAD(0x108, PIN_INPUT, 0) /* (AB36) MMC1_CMD */
-			J784S4_IOPAD(0x100, PIN_INPUT, 0) /* (No Pin) MMC1_CLKLB */
-			J784S4_IOPAD(0x0fc, PIN_INPUT, 0) /* (AA33) MMC1_DAT0 */
-			J784S4_IOPAD(0x0f8, PIN_INPUT, 0) /* (AB34) MMC1_DAT1 */
-			J784S4_IOPAD(0x0f4, PIN_INPUT, 0) /* (AA32) MMC1_DAT2 */
-			J784S4_IOPAD(0x0f0, PIN_INPUT, 0) /* (AC38) MMC1_DAT3 */
-			J784S4_IOPAD(0x0e8, PIN_INPUT, 8) /* (AR38) TIMER_IO0.MMC1_SDCD */
-		>;
-	};
-
-	vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x020, PIN_INPUT, 7) /* (AJ35) MCAN15_RX.GPIO0_8 */
-		>;
-	};
-
-	dp0_pins_default: dp0-default-pins {
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x0cc, PIN_INPUT, 12) /* (AM37) SPI0_CS0.DP0_HPD */
-		>;
-	};
-
-	main_i2c4_pins_default: main-i2c4-default-pins {
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x014, PIN_INPUT_PULLUP, 8) /* (AG33) MCAN14_TX.I2C4_SCL */
-			J784S4_IOPAD(0x010, PIN_INPUT_PULLUP, 8) /* (AH33) MCAN13_RX.I2C4_SDA */
-		>;
-	};
-
-	main_mcan4_pins_default: main-mcan4-default-pins {
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x088, PIN_INPUT, 0) /* (AF36) MCAN4_RX */
-			J784S4_IOPAD(0x084, PIN_OUTPUT, 0) /* (AG38) MCAN4_TX */
-		>;
-	};
-
-	main_mcan16_pins_default: main-mcan16-default-pins {
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x028, PIN_INPUT, 0) /* (AE33) MCAN16_RX */
-			J784S4_IOPAD(0x024, PIN_OUTPUT, 0) /* (AH34) MCAN16_TX */
-		>;
-	};
-
-	main_usbss0_pins_default: main-usbss0-default-pins {
-		bootph-all;
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x0ec, PIN_OUTPUT, 6) /* (AN37) TIMER_IO1.USB0_DRVVBUS */
-		>;
-	};
-
-	main_i2c3_pins_default: main-i2c3-default-pins {
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x064, PIN_INPUT, 13) /* (AF38) MCAN0_TX.I2C3_SCL */
-			J784S4_IOPAD(0x060, PIN_INPUT, 13) /* (AE36) MCASP2_AXR1.I2C3_SDA */
-		>;
-	};
-
-	main_mcasp0_pins_default: main-mcasp0-default-pins {
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x038, PIN_OUTPUT_PULLDOWN, 1) /* (AK35) MCASP0_ACLKX */
-			J784S4_IOPAD(0x03c, PIN_OUTPUT_PULLDOWN, 1) /* (AK38) MCASP0_AFSX */
-			J784S4_IOPAD(0x07c, PIN_OUTPUT_PULLDOWN, 1) /* (AJ38) MCASP0_AXR3 */
-			J784S4_IOPAD(0x080, PIN_INPUT_PULLDOWN, 1) /* (AK34) MCASP0_AXR4 */
-		>;
-	};
-
-	audio_ext_refclk1_pins_default: audio-ext-refclk1-default-pins {
-		pinctrl-single,pins = <
-			J784S4_IOPAD(0x078, PIN_OUTPUT, 1) /* (AH37) MCAN2_RX.AUDIO_EXT_REFCLK1 */
-		>;
-	};
-};
-
-&wkup_pmx2 {
-	bootph-all;
-	wkup_uart0_pins_default: wkup-uart0-default-pins {
-		bootph-all;
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
-			J784S4_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (K34) WKUP_UART0_TXD */
-		>;
-	};
-
-	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
-		bootph-all;
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x98, PIN_INPUT, 0) /* (N33) WKUP_I2C0_SCL */
-			J784S4_WKUP_IOPAD(0x9c, PIN_INPUT, 0) /* (N35) WKUP_I2C0_SDA */
-		>;
-	};
-
-	mcu_uart0_pins_default: mcu-uart0-default-pins {
-		bootph-all;
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x090, PIN_INPUT, 0) /* (H37) WKUP_GPIO0_14.MCU_UART0_CTSn */
-			J784S4_WKUP_IOPAD(0x094, PIN_OUTPUT, 0) /* (K37) WKUP_GPIO0_15.MCU_UART0_RTSn */
-			J784S4_WKUP_IOPAD(0x08c, PIN_INPUT, 0) /* (K38) WKUP_GPIO0_13.MCU_UART0_RXD */
-			J784S4_WKUP_IOPAD(0x088, PIN_OUTPUT, 0) /* (J37) WKUP_GPIO0_12.MCU_UART0_TXD */
-		>;
-	};
-
-	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x02c, PIN_INPUT, 0) /* (A35) MCU_RGMII1_RD0 */
-			J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (B36) MCU_RGMII1_RD1 */
-			J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (C36) MCU_RGMII1_RD2 */
-			J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (D36) MCU_RGMII1_RD3 */
-			J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (B37) MCU_RGMII1_RXC */
-			J784S4_WKUP_IOPAD(0x004, PIN_INPUT, 0) /* (C37) MCU_RGMII1_RX_CTL */
-			J784S4_WKUP_IOPAD(0x014, PIN_OUTPUT, 0) /* (D37) MCU_RGMII1_TD0 */
-			J784S4_WKUP_IOPAD(0x010, PIN_OUTPUT, 0) /* (D38) MCU_RGMII1_TD1 */
-			J784S4_WKUP_IOPAD(0x00c, PIN_OUTPUT, 0) /* (E37) MCU_RGMII1_TD2 */
-			J784S4_WKUP_IOPAD(0x008, PIN_OUTPUT, 0) /* (E38) MCU_RGMII1_TD3 */
-			J784S4_WKUP_IOPAD(0x018, PIN_OUTPUT, 0) /* (E36) MCU_RGMII1_TXC */
-			J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (C38) MCU_RGMII1_TX_CTL */
-		>;
-	};
-
-	mcu_mdio_pins_default: mcu-mdio-default-pins {
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x034, PIN_OUTPUT, 0) /* (A36) MCU_MDIO0_MDC */
-			J784S4_WKUP_IOPAD(0x030, PIN_INPUT, 0) /* (B35) MCU_MDIO0_MDIO */
-		>;
-	};
-
-	mcu_adc0_pins_default: mcu-adc0-default-pins {
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x0cc, PIN_INPUT, 0) /* (P36) MCU_ADC0_AIN0 */
-			J784S4_WKUP_IOPAD(0x0d0, PIN_INPUT, 0) /* (V36) MCU_ADC0_AIN1 */
-			J784S4_WKUP_IOPAD(0x0d4, PIN_INPUT, 0) /* (T34) MCU_ADC0_AIN2 */
-			J784S4_WKUP_IOPAD(0x0d8, PIN_INPUT, 0) /* (T36) MCU_ADC0_AIN3 */
-			J784S4_WKUP_IOPAD(0x0dc, PIN_INPUT, 0) /* (P34) MCU_ADC0_AIN4 */
-			J784S4_WKUP_IOPAD(0x0e0, PIN_INPUT, 0) /* (R37) MCU_ADC0_AIN5 */
-			J784S4_WKUP_IOPAD(0x0e4, PIN_INPUT, 0) /* (R33) MCU_ADC0_AIN6 */
-			J784S4_WKUP_IOPAD(0x0e8, PIN_INPUT, 0) /* (V38) MCU_ADC0_AIN7 */
-		>;
-	};
-
-	mcu_adc1_pins_default: mcu-adc1-default-pins {
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x0ec, PIN_INPUT, 0) /* (Y38) MCU_ADC1_AIN0 */
-			J784S4_WKUP_IOPAD(0x0f0, PIN_INPUT, 0) /* (Y34) MCU_ADC1_AIN1 */
-			J784S4_WKUP_IOPAD(0x0f4, PIN_INPUT, 0) /* (V34) MCU_ADC1_AIN2 */
-			J784S4_WKUP_IOPAD(0x0f8, PIN_INPUT, 0) /* (W37) MCU_ADC1_AIN3 */
-			J784S4_WKUP_IOPAD(0x0fc, PIN_INPUT, 0) /* (AA37) MCU_ADC1_AIN4 */
-			J784S4_WKUP_IOPAD(0x100, PIN_INPUT, 0) /* (W33) MCU_ADC1_AIN5 */
-			J784S4_WKUP_IOPAD(0x104, PIN_INPUT, 0) /* (U33) MCU_ADC1_AIN6 */
-			J784S4_WKUP_IOPAD(0x108, PIN_INPUT, 0) /* (Y36) MCU_ADC1_AIN7 */
-		>;
-	};
-
-	mcu_mcan0_pins_default: mcu-mcan0-default-pins {
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x050, PIN_OUTPUT, 0) /* (K33) MCU_MCAN0_TX */
-			J784S4_WKUP_IOPAD(0x054, PIN_INPUT, 0) /* (F38) MCU_MCAN0_RX */
-		>;
-	};
-
-	mcu_mcan1_pins_default: mcu-mcan1-default-pins {
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x068, PIN_OUTPUT, 0) /* (H35) WKUP_GPIO0_4.MCU_MCAN1_TX */
-			J784S4_WKUP_IOPAD(0x06c, PIN_INPUT, 0) /* (K36) WKUP_GPIO0_5.MCU_MCAN1_RX */
-		>;
-	};
-
-	mcu_mcan0_gpio_pins_default: mcu-mcan0-gpio-default-pins {
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x040, PIN_INPUT, 7) /* (J38) MCU_SPI0_D1.WKUP_GPIO0_69 */
-		>;
-	};
-
-	mcu_mcan1_gpio_pins_default: mcu-mcan1-gpio-default-pins {
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x060, PIN_INPUT, 7) /* (J35) WKUP_GPIO0_2 */
-		>;
-	};
-};
-
-&wkup_pmx1 {
-	status = "okay";
-
-	pmic_irq_pins_default: pmic-irq-default-pins {
-		pinctrl-single,pins = <
-			/* (G33) MCU_OSPI1_CSn1.WKUP_GPIO0_39 */
-			J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 7)
-		>;
-	};
-};
-
-&wkup_pmx0 {
-	bootph-all;
-	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-default-pins {
-		bootph-all;
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (E32) MCU_OSPI0_CLK */
-			J784S4_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (A32) MCU_OSPI0_CSn0 */
-			J784S4_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (B33) MCU_OSPI0_D0 */
-			J784S4_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (B32) MCU_OSPI0_D1 */
-			J784S4_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (C33) MCU_OSPI0_D2 */
-			J784S4_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (C35) MCU_OSPI0_D3 */
-			J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (D33) MCU_OSPI0_D4 */
-			J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (D34) MCU_OSPI0_D5 */
-			J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (E34) MCU_OSPI0_D6 */
-			J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (E33) MCU_OSPI0_D7 */
-			J784S4_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (C34) MCU_OSPI0_DQS */
-		>;
-	};
-};
-
-&wkup_pmx1 {
-	bootph-all;
-	mcu_fss0_ospi0_1_pins_default: mcu-fss0-ospi0-1-default-pins {
-		bootph-all;
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x004, PIN_OUTPUT, 6) /* (C32) MCU_OSPI0_ECC_FAIL */
-			J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 6) /* (B34) MCU_OSPI0_RESET_OUT0 */
-		>;
-	};
-
-	mcu_fss0_ospi1_pins_default: mcu-fss0-ospi1-default-pins {
-		bootph-all;
-		pinctrl-single,pins = <
-			J784S4_WKUP_IOPAD(0x008, PIN_OUTPUT, 0) /* (F32) MCU_OSPI1_CLK */
-			J784S4_WKUP_IOPAD(0x024, PIN_OUTPUT, 0) /* (G32) MCU_OSPI1_CSn0 */
-			J784S4_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (E35) MCU_OSPI1_D0 */
-			J784S4_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (D31) MCU_OSPI1_D1 */
-			J784S4_WKUP_IOPAD(0x01C, PIN_INPUT, 0) /* (G31) MCU_OSPI1_D2 */
-			J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (F33) MCU_OSPI1_D3 */
-			J784S4_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (F31) MCU_OSPI1_DQS */
-			J784S4_WKUP_IOPAD(0x00C, PIN_INPUT, 0) /* (C31) MCU_OSPI1_LBCLKO */
-		>;
-	};
-};
-
-&wkup_uart0 {
-	/* Firmware usage */
-	status = "reserved";
-	pinctrl-names = "default";
-	pinctrl-0 = <&wkup_uart0_pins_default>;
-};
-
-&wkup_i2c0 {
-	bootph-all;
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&wkup_i2c0_pins_default>;
-	clock-frequency = <400000>;
-
-	eeprom@50 {
-		/* CAV24C256WE-GT3 */
-		compatible = "atmel,24c256";
-		reg = <0x50>;
-	};
-
-	tps659413: pmic@48 {
-		compatible = "ti,tps6594-q1";
-		reg = <0x48>;
-		system-power-controller;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pmic_irq_pins_default>;
-		interrupt-parent = <&wkup_gpio0>;
-		interrupts = <39 IRQ_TYPE_EDGE_FALLING>;
-		gpio-controller;
-		#gpio-cells = <2>;
-		ti,primary-pmic;
-		buck12-supply = <&vsys_3v3>;
-		buck3-supply = <&vsys_3v3>;
-		buck4-supply = <&vsys_3v3>;
-		buck5-supply = <&vsys_3v3>;
-		ldo1-supply = <&vsys_3v3>;
-		ldo2-supply = <&vsys_3v3>;
-		ldo3-supply = <&vsys_3v3>;
-		ldo4-supply = <&vsys_3v3>;
-
-		regulators {
-			bucka12: buck12 {
-				regulator-name = "vdd_ddr_1v1";
-				regulator-min-microvolt = <1100000>;
-				regulator-max-microvolt = <1100000>;
-				regulator-boot-on;
-				regulator-always-on;
-			};
-
-			bucka3: buck3 {
-				regulator-name = "vdd_ram_0v85";
-				regulator-min-microvolt = <850000>;
-				regulator-max-microvolt = <850000>;
-				regulator-boot-on;
-				regulator-always-on;
-			};
-
-			bucka4: buck4 {
-				regulator-name = "vdd_io_1v8";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-boot-on;
-				regulator-always-on;
-			};
-
-			bucka5: buck5 {
-				regulator-name = "vdd_mcu_0v85";
-				regulator-min-microvolt = <850000>;
-				regulator-max-microvolt = <850000>;
-				regulator-boot-on;
-				regulator-always-on;
-			};
-
-			ldoa1: ldo1 {
-				regulator-name = "vdd_mcuio_1v8";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-boot-on;
-				regulator-always-on;
-			};
-
-			ldoa2: ldo2 {
-				regulator-name = "vdd_mcuio_3v3";
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-boot-on;
-				regulator-always-on;
-			};
-
-			ldoa3: ldo3 {
-				regulator-name = "vds_dll_0v8";
-				regulator-min-microvolt = <800000>;
-				regulator-max-microvolt = <800000>;
-				regulator-boot-on;
-				regulator-always-on;
-			};
-
-			ldoa4: ldo4 {
-				regulator-name = "vda_mcu_1v8";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-boot-on;
-				regulator-always-on;
-			};
-		};
-	};
-
-	tps62873a: regulator@40 {
-		compatible = "ti,tps62873";
-		reg = <0x40>;
-		bootph-pre-ram;
-		regulator-name = "VDD_CPU_AVS";
-		regulator-min-microvolt = <750000>;
-		regulator-max-microvolt = <1330000>;
-		regulator-boot-on;
-		regulator-always-on;
-	};
-
-	tps62873b: regulator@43 {
-		compatible = "ti,tps62873";
-		reg = <0x43>;
-		regulator-name = "VDD_CORE_0V8";
-		regulator-min-microvolt = <760000>;
-		regulator-max-microvolt = <840000>;
-		regulator-boot-on;
-		regulator-always-on;
-	};
-};
-
-&mcu_uart0 {
-	bootph-all;
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&mcu_uart0_pins_default>;
-};
-
-&main_uart8 {
-	bootph-all;
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&main_uart8_pins_default>;
-};
-
-&ufs_wrapper {
-	status = "okay";
-};
-
-&fss {
-	bootph-all;
-	status = "okay";
-};
-
-&ospi0 {
-	bootph-all;
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>, <&mcu_fss0_ospi0_1_pins_default>;
-
-	flash@0 {
-		bootph-all;
-		compatible = "jedec,spi-nor";
-		reg = <0x0>;
-		spi-tx-bus-width = <8>;
-		spi-rx-bus-width = <8>;
-		spi-max-frequency = <25000000>;
-		cdns,tshsl-ns = <60>;
-		cdns,tsd2d-ns = <60>;
-		cdns,tchsh-ns = <60>;
-		cdns,tslch-ns = <60>;
-		cdns,read-delay = <4>;
-
-		partitions {
-			compatible = "fixed-partitions";
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			partition@0 {
-				label = "ospi.tiboot3";
-				reg = <0x0 0x80000>;
-			};
-
-			partition@80000 {
-				label = "ospi.tispl";
-				reg = <0x80000 0x200000>;
-			};
-
-			partition@280000 {
-				label = "ospi.u-boot";
-				reg = <0x280000 0x400000>;
-			};
-
-			partition@680000 {
-				label = "ospi.env";
-				reg = <0x680000 0x40000>;
-			};
-
-			partition@6c0000 {
-				label = "ospi.env.backup";
-				reg = <0x6c0000 0x40000>;
-			};
-
-			partition@800000 {
-				label = "ospi.rootfs";
-				reg = <0x800000 0x37c0000>;
-			};
-
-			partition@3fc0000 {
-				bootph-all;
-				label = "ospi.phypattern";
-				reg = <0x3fc0000 0x40000>;
-			};
-		};
-	};
-};
-
-&ospi1 {
-	bootph-all;
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&mcu_fss0_ospi1_pins_default>;
-
-	flash@0 {
-		bootph-all;
-		compatible = "jedec,spi-nor";
-		reg = <0x0>;
-		spi-tx-bus-width = <1>;
-		spi-rx-bus-width = <4>;
-		spi-max-frequency = <40000000>;
-		cdns,tshsl-ns = <60>;
-		cdns,tsd2d-ns = <60>;
-		cdns,tchsh-ns = <60>;
-		cdns,tslch-ns = <60>;
-		cdns,read-delay = <2>;
-
-		partitions {
-			compatible = "fixed-partitions";
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			partition@0 {
-				label = "qspi.tiboot3";
-				reg = <0x0 0x80000>;
-			};
-
-			partition@80000 {
-				label = "qspi.tispl";
-				reg = <0x80000 0x200000>;
-			};
-
-			partition@280000 {
-				label = "qspi.u-boot";
-				reg = <0x280000 0x400000>;
-			};
-
-			partition@680000 {
-				label = "qspi.env";
-				reg = <0x680000 0x40000>;
-			};
-
-			partition@6c0000 {
-				label = "qspi.env.backup";
-				reg = <0x6c0000 0x40000>;
-			};
-
-			partition@800000 {
-				label = "qspi.rootfs";
-				reg = <0x800000 0x37c0000>;
-			};
-
-			partition@3fc0000 {
-				bootph-all;
-				label = "qspi.phypattern";
-				reg = <0x3fc0000 0x40000>;
-			};
-		};
-
-	};
-};
-
-&main_i2c0 {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&main_i2c0_pins_default>;
-
-	clock-frequency = <400000>;
-
-	exp1: gpio@20 {
-		compatible = "ti,tca6416";
-		reg = <0x20>;
-		gpio-controller;
-		#gpio-cells = <2>;
-		gpio-line-names = "PCIE1_2L_MODE_SEL", "PCIE1_4L_PERSTZ", "PCIE1_2L_RC_RSTZ",
-				  "PCIE1_2L_EP_RST_EN", "PCIE0_4L_MODE_SEL", "PCIE0_4L_PERSTZ",
-				  "PCIE0_4L_RC_RSTZ", "PCIE0_4L_EP_RST_EN", "PCIE1_4L_PRSNT#",
-				  "PCIE0_4L_PRSNT#", "CDCI1_OE1/OE4", "CDCI1_OE2/OE3",
-				  "AUDIO_MUX_SEL", "EXP_MUX2", "EXP_MUX3", "GESI_EXP_PHY_RSTZ";
-
-		p12-hog {
-			/* P12 - AUDIO_MUX_SEL */
-			gpio-hog;
-			gpios = <12 GPIO_ACTIVE_HIGH>;
-			output-low;
-			line-name = "AUDIO_MUX_SEL";
-		};
-	};
-
-	exp2: gpio@22 {
-		compatible = "ti,tca6424";
-		reg = <0x22>;
-		gpio-controller;
-		#gpio-cells = <2>;
-		gpio-line-names = "R_GPIO_RGMII1_RST", "ENET2_I2CMUX_SEL", "GPIO_USD_PWR_EN",
-				  "USBC_PWR_EN", "USBC_MODE_SEL1", "USBC_MODE_SEL0",
-				  "GPIO_LIN_EN", "R_CAN_STB", "CTRL_PM_I2C_OE#",
-				  "ENET2_EXP_PWRDN", "ENET2_EXP_SPARE2", "CDCI2_RSTZ",
-				  "USB2.0_MUX_SEL", "CANUART_MUX_SEL0", "CANUART_MUX2_SEL1",
-				  "CANUART_MUX1_SEL1", "ENET1_EXP_PWRDN", "ENET1_EXP_RESETZ",
-				  "ENET1_I2CMUX_SEL", "ENET1_EXP_SPARE2", "ENET2_EXP_RESETZ",
-				  "USER_INPUT1", "USER_LED1", "USER_LED2";
-
-		p13-hog {
-			/* P13 - CANUART_MUX_SEL0 */
-			gpio-hog;
-			gpios = <13 GPIO_ACTIVE_HIGH>;
-			output-high;
-			line-name = "CANUART_MUX_SEL0";
-		};
-
-		p15-hog {
-			/* P15 - CANUART_MUX1_SEL1 */
-			gpio-hog;
-			gpios = <15 GPIO_ACTIVE_HIGH>;
-			output-high;
-			line-name = "CANUART_MUX1_SEL1";
-		};
-	};
-};
-
-&main_i2c5 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&main_i2c5_pins_default>;
-	clock-frequency = <400000>;
-	status = "okay";
-
-	exp5: gpio@20 {
-		compatible = "ti,tca6408";
-		reg = <0x20>;
-		gpio-controller;
-		#gpio-cells = <2>;
-		gpio-line-names = "CSI2_EXP_RSTZ", "CSI2_EXP_A_GPIO0",
-				  "CSI2_EXP_A_GPIO1", "CSI2_EXP_A_GPIO3",
-				  "CSI2_EXP_B_GPIO1", "CSI2_EXP_B_GPIO2",
-				  "CSI2_EXP_B_GPIO3", "CSI2_EXP_B_GPIO4";
-	};
-};
-
-&main_sdhci0 {
-	bootph-all;
-	/* eMMC */
-	status = "okay";
-	non-removable;
-	ti,driver-strength-ohm = <50>;
-	disable-wp;
-};
-
-&main_sdhci1 {
-	bootph-all;
-	/* SD card */
-	status = "okay";
-	pinctrl-0 = <&main_mmc1_pins_default>;
-	pinctrl-names = "default";
-	disable-wp;
-	vmmc-supply = <&vdd_mmc1>;
-	vqmmc-supply = <&vdd_sd_dv>;
-};
-
-&main_gpio0 {
-	status = "okay";
-};
-
-&mcu_cpsw {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&mcu_cpsw_pins_default>;
-};
-
-&davinci_mdio {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mcu_mdio_pins_default>;
-
-	mcu_phy0: ethernet-phy@0 {
-		reg = <0>;
-		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
-		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
-		ti,min-output-impedance;
-	};
-};
-
-&mcu_cpsw_port1 {
-	status = "okay";
-	phy-mode = "rgmii-rxid";
-	phy-handle = <&mcu_phy0>;
-};
-
-&main_cpsw1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&main_cpsw2g_default_pins>;
-	status = "okay";
-};
-
-&main_cpsw1_mdio {
-	pinctrl-names = "default";
-	pinctrl-0 = <&main_cpsw2g_mdio_default_pins>;
-	status = "okay";
-
-	main_cpsw1_phy0: ethernet-phy@0 {
-		reg = <0>;
-		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
-		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
-		ti,min-output-impedance;
-	};
-};
-
-&main_cpsw1_port1 {
-	phy-mode = "rgmii-rxid";
-	phy-handle = <&main_cpsw1_phy0>;
-	status = "okay";
-};
-
-&mailbox0_cluster0 {
-	status = "okay";
-	interrupts = <436>;
-
-	mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
-		ti,mbox-rx = <0 0 0>;
-		ti,mbox-tx = <1 0 0>;
-	};
-
-	mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
-		ti,mbox-rx = <2 0 0>;
-		ti,mbox-tx = <3 0 0>;
-	};
-};
-
-&mailbox0_cluster1 {
-	status = "okay";
-	interrupts = <432>;
-
-	mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
-		ti,mbox-rx = <0 0 0>;
-		ti,mbox-tx = <1 0 0>;
-	};
-
-	mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
-		ti,mbox-rx = <2 0 0>;
-		ti,mbox-tx = <3 0 0>;
-	};
-};
-
-&mailbox0_cluster2 {
-	status = "okay";
-	interrupts = <428>;
-
-	mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
-		ti,mbox-rx = <0 0 0>;
-		ti,mbox-tx = <1 0 0>;
-	};
-
-	mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
-		ti,mbox-rx = <2 0 0>;
-		ti,mbox-tx = <3 0 0>;
-	};
-};
-
-&mailbox0_cluster3 {
-	status = "okay";
-	interrupts = <424>;
-
-	mbox_main_r5fss2_core0: mbox-main-r5fss2-core0 {
-		ti,mbox-rx = <0 0 0>;
-		ti,mbox-tx = <1 0 0>;
-	};
-
-	mbox_main_r5fss2_core1: mbox-main-r5fss2-core1 {
-		ti,mbox-rx = <2 0 0>;
-		ti,mbox-tx = <3 0 0>;
-	};
-};
-
-&mailbox0_cluster4 {
-	status = "okay";
-	interrupts = <420>;
-
-	mbox_c71_0: mbox-c71-0 {
-		ti,mbox-rx = <0 0 0>;
-		ti,mbox-tx = <1 0 0>;
-	};
-
-	mbox_c71_1: mbox-c71-1 {
-		ti,mbox-rx = <2 0 0>;
-		ti,mbox-tx = <3 0 0>;
-	};
 };
 
 &mailbox0_cluster5 {
-	status = "okay";
-	interrupts = <416>;
-
-	mbox_c71_2: mbox-c71-2 {
-		ti,mbox-rx = <0 0 0>;
-		ti,mbox-tx = <1 0 0>;
-	};
-
 	mbox_c71_3: mbox-c71-3 {
 		ti,mbox-rx = <2 0 0>;
 		ti,mbox-tx = <3 0 0>;
 	};
 };
 
-&mcu_r5fss0_core0 {
-	status = "okay";
-	mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>;
-	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
-			<&mcu_r5fss0_core0_memory_region>;
-};
-
-&mcu_r5fss0_core1 {
-	status = "okay";
-	mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core1>;
-	memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
-			<&mcu_r5fss0_core1_memory_region>;
-};
-
-&main_r5fss0 {
-	ti,cluster-mode = <0>;
-};
-
-&main_r5fss1 {
-	ti,cluster-mode = <0>;
-};
-
-&main_r5fss2 {
-	ti,cluster-mode = <0>;
-};
-
-/* Timers are used by Remoteproc firmware */
-&main_timer0 {
-	status = "reserved";
-};
-
-&main_timer1 {
-	status = "reserved";
-};
-
-&main_timer2 {
-	status = "reserved";
-};
-
-&main_timer3 {
-	status = "reserved";
-};
-
-&main_timer4 {
-	status = "reserved";
-};
-
-&main_timer5 {
-	status = "reserved";
-};
-
-&main_timer6 {
-	status = "reserved";
-};
-
-&main_timer7 {
-	status = "reserved";
-};
-
-&main_timer8 {
-	status = "reserved";
-};
-
-&main_timer9 {
-	status = "reserved";
-};
-
-&main_r5fss0_core0 {
-	status = "okay";
-	mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core0>;
-	memory-region = <&main_r5fss0_core0_dma_memory_region>,
-			<&main_r5fss0_core0_memory_region>;
-};
-
-&main_r5fss0_core1 {
-	status = "okay";
-	mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core1>;
-	memory-region = <&main_r5fss0_core1_dma_memory_region>,
-			<&main_r5fss0_core1_memory_region>;
-};
-
-&main_r5fss1_core0 {
-	status = "okay";
-	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core0>;
-	memory-region = <&main_r5fss1_core0_dma_memory_region>,
-			<&main_r5fss1_core0_memory_region>;
-};
-
-&main_r5fss1_core1 {
-	status = "okay";
-	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core1>;
-	memory-region = <&main_r5fss1_core1_dma_memory_region>,
-			<&main_r5fss1_core1_memory_region>;
-};
-
-&main_r5fss2_core0 {
-	status = "okay";
-	mboxes = <&mailbox0_cluster3 &mbox_main_r5fss2_core0>;
-	memory-region = <&main_r5fss2_core0_dma_memory_region>,
-			<&main_r5fss2_core0_memory_region>;
-};
-
-&main_r5fss2_core1 {
-	status = "okay";
-	mboxes = <&mailbox0_cluster3 &mbox_main_r5fss2_core1>;
-	memory-region = <&main_r5fss2_core1_dma_memory_region>,
-			<&main_r5fss2_core1_memory_region>;
-};
-
-&c71_0 {
-	status = "okay";
-	mboxes = <&mailbox0_cluster4 &mbox_c71_0>;
-	memory-region = <&c71_0_dma_memory_region>,
-			<&c71_0_memory_region>;
-};
-
-&c71_1 {
-	status = "okay";
-	mboxes = <&mailbox0_cluster4 &mbox_c71_1>;
-	memory-region = <&c71_1_dma_memory_region>,
-			<&c71_1_memory_region>;
-};
-
-&c71_2 {
-	status = "okay";
-	mboxes = <&mailbox0_cluster5 &mbox_c71_2>;
-	memory-region = <&c71_2_dma_memory_region>,
-			<&c71_2_memory_region>;
-};
-
 &c71_3 {
-	status = "okay";
 	mboxes = <&mailbox0_cluster5 &mbox_c71_3>;
 	memory-region = <&c71_3_dma_memory_region>,
 			<&c71_3_memory_region>;
-};
-
-&tscadc0 {
-	pinctrl-0 = <&mcu_adc0_pins_default>;
-	pinctrl-names = "default";
-	status = "okay";
-	adc {
-		ti,adc-channels = <0 1 2 3 4 5 6 7>;
-	};
-};
-
-&tscadc1 {
-	pinctrl-0 = <&mcu_adc1_pins_default>;
-	pinctrl-names = "default";
-	status = "okay";
-	adc {
-		ti,adc-channels = <0 1 2 3 4 5 6 7>;
-	};
-};
-
-&serdes_refclk {
-	status = "okay";
-	clock-frequency = <100000000>;
-};
-
-&dss {
-	status = "okay";
-	assigned-clocks = <&k3_clks 218 2>,
-			  <&k3_clks 218 5>,
-			  <&k3_clks 218 14>,
-			  <&k3_clks 218 18>;
-	assigned-clock-parents = <&k3_clks 218 3>,
-				 <&k3_clks 218 7>,
-				 <&k3_clks 218 16>,
-				 <&k3_clks 218 22>;
-};
-
-&serdes0 {
-	status = "okay";
-
-	serdes0_pcie1_link: phy@0 {
-		reg = <0>;
-		cdns,num-lanes = <2>;
-		#phy-cells = <0>;
-		cdns,phy-type = <PHY_TYPE_PCIE>;
-		resets = <&serdes_wiz0 1>, <&serdes_wiz0 2>;
-	};
-
-	serdes0_usb_link: phy@3 {
-		reg = <3>;
-		cdns,num-lanes = <1>;
-		#phy-cells = <0>;
-		cdns,phy-type = <PHY_TYPE_USB3>;
-		resets = <&serdes_wiz0 4>;
-	};
-};
-
-&serdes_wiz0 {
-	status = "okay";
-};
-
-&usb_serdes_mux {
-	idle-states = <0>; /* USB0 to SERDES lane 3 */
-};
-
-&usbss0 {
-	status = "okay";
-	pinctrl-0 = <&main_usbss0_pins_default>;
-	pinctrl-names = "default";
-	ti,vbus-divider;
-};
-
-&usb0 {
-	dr_mode = "otg";
-	maximum-speed = "super-speed";
-	phys = <&serdes0_usb_link>;
-	phy-names = "cdns3,usb3-phy";
-};
-
-&serdes_wiz4 {
-	status = "okay";
-};
-
-&serdes4 {
-	status = "okay";
-	serdes4_dp_link: phy@0 {
-		reg = <0>;
-		cdns,num-lanes = <4>;
-		#phy-cells = <0>;
-		cdns,phy-type = <PHY_TYPE_DP>;
-		resets = <&serdes_wiz4 1>, <&serdes_wiz4 2>,
-			 <&serdes_wiz4 3>, <&serdes_wiz4 4>;
-	};
-};
-
-&mhdp {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&dp0_pins_default>;
-	phys = <&serdes4_dp_link>;
-	phy-names = "dpphy";
-};
-
-&dss_ports {
-	/* DP */
-	port {
-		dpi0_out: endpoint {
-			remote-endpoint = <&dp0_in>;
-		};
-	};
-};
-
-&main_i2c4 {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&main_i2c4_pins_default>;
-	clock-frequency = <400000>;
-
-	exp4: gpio@20 {
-		compatible = "ti,tca6408";
-		reg = <0x20>;
-		gpio-controller;
-		#gpio-cells = <2>;
-	};
-};
-
-&dp0_ports {
-	port@0 {
-		reg = <0>;
-
-		dp0_in: endpoint {
-			remote-endpoint = <&dpi0_out>;
-		};
-	};
-
-	port@4 {
-		reg = <4>;
-
-		dp0_out: endpoint {
-			remote-endpoint = <&dp0_connector_in>;
-		};
-	};
-};
-
-&mcu_mcan0 {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&mcu_mcan0_pins_default>;
-	phys = <&transceiver0>;
-};
-
-&mcu_mcan1 {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&mcu_mcan1_pins_default>;
-	phys = <&transceiver1>;
-};
-
-&main_mcan16 {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&main_mcan16_pins_default>;
-	phys = <&transceiver2>;
-};
-
-&main_mcan4 {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&main_mcan4_pins_default>;
-	phys = <&transceiver3>;
-};
-
-&pcie1_rc {
-	status = "okay";
-	num-lanes = <2>;
-	reset-gpios = <&exp1 2 GPIO_ACTIVE_HIGH>;
-	phys = <&serdes0_pcie1_link>;
-	phy-names = "pcie-phy";
-};
-
-&serdes1 {
-	status = "okay";
-
-	serdes1_pcie0_link: phy@0 {
-		reg = <0>;
-		cdns,num-lanes = <4>;
-		#phy-cells = <0>;
-		cdns,phy-type = <PHY_TYPE_PCIE>;
-		resets = <&serdes_wiz1 1>, <&serdes_wiz1 2>,
-			 <&serdes_wiz1 3>, <&serdes_wiz1 4>;
-	};
-};
-
-&serdes_wiz1 {
-	status = "okay";
-};
-
-&pcie0_rc {
-	status = "okay";
-	reset-gpios = <&exp1 6 GPIO_ACTIVE_HIGH>;
-	phys = <&serdes1_pcie0_link>;
-	phy-names = "pcie-phy";
-};
-
-&k3_clks {
-	/* Confiure AUDIO_EXT_REFCLK1 pin as output */
-	pinctrl-names = "default";
-	pinctrl-0 = <&audio_ext_refclk1_pins_default>;
-};
-
-&main_i2c3 {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&main_i2c3_pins_default>;
-	clock-frequency = <400000>;
-
-	exp3: gpio@20 {
-		compatible = "ti,tca6408";
-		reg = <0x20>;
-		gpio-controller;
-		#gpio-cells = <2>;
-	};
-
-	pcm3168a_1: audio-codec@44 {
-		compatible = "ti,pcm3168a";
-		reg = <0x44>;
-		#sound-dai-cells = <1>;
-		reset-gpios = <&exp3 0 GPIO_ACTIVE_LOW>;
-		clocks = <&audio_refclk1>;
-		clock-names = "scki";
-		VDD1-supply = <&vsys_3v3>;
-		VDD2-supply = <&vsys_3v3>;
-		VCCAD1-supply = <&vsys_5v0>;
-		VCCAD2-supply = <&vsys_5v0>;
-		VCCDA1-supply = <&vsys_5v0>;
-		VCCDA2-supply = <&vsys_5v0>;
-	};
-};
-
-&mcasp0 {
 	status = "okay";
-	#sound-dai-cells = <0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&main_mcasp0_pins_default>;
-	op-mode = <0>;          /* MCASP_IIS_MODE */
-	tdm-slots = <2>;
-	auxclk-fs-ratio = <256>;
-	serial-dir = <	/* 0: INACTIVE, 1: TX, 2: RX */
-		0 0 0 1
-		2 0 0 0
-		0 0 0 0
-		0 0 0 0
-	>;
 };
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j784s4-evm-ethfw.dtso b/arch/arm64/boot/dts/ti/k3-j784s4-evm-ethfw.dtso
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm-ethfw.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm-ethfw.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for CPSW9G functionality with Ethernet Switch Firmware (EthFw)
+ * and CPSW Proxy Client driver.
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "k3-serdes.h"
+
+&serdes_ln_ctrl {
+	idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>, <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
+		      <J784S4_SERDES0_LANE2_IP3_UNUSED>, <J784S4_SERDES0_LANE3_USB>,
+		      <J784S4_SERDES1_LANE0_PCIE0_LANE0>, <J784S4_SERDES1_LANE1_PCIE0_LANE1>,
+		      <J784S4_SERDES1_LANE2_PCIE0_LANE2>, <J784S4_SERDES1_LANE3_PCIE0_LANE3>,
+		      <J784S4_SERDES2_LANE0_IP2_UNUSED>, <J784S4_SERDES2_LANE1_IP2_UNUSED>,
+		      <J784S4_SERDES2_LANE2_QSGMII_LANE1>, <J784S4_SERDES2_LANE3_QSGMII_LANE2>,
+		      <J784S4_SERDES4_LANE0_EDP_LANE0>, <J784S4_SERDES4_LANE1_EDP_LANE1>,
+		      <J784S4_SERDES4_LANE2_EDP_LANE2>, <J784S4_SERDES4_LANE3_EDP_LANE3>;
+};
+
+/* uart2 is assigned to EthFw running on remote CPU core */
+&main_uart2 {
+	status = "reserved";
+};
+
+/* Reserve shared memory for inter-core network communication */
+&reserved_memory {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	main_r5fss0_core0_shared_memory_queue_region:r5f-virtual-eth-queues@af000000 {
+		compatible = "shared-dma-pool";
+		reg = <0x00 0xaf000000 0x00 0x200000>;
+		no-map;
+	};
+
+	main_r5fss0_core0_shared_memory_bufpool_region:r5f-virtual-eth-buffers@af200000 {
+		compatible = "shared-dma-pool";
+		reg = <0x00 0xaf200000 0x00 0x1e00000>;
+		no-map;
+	};
+};
+
+&main_r5fss0_core0 {
+	memory-region = <&main_r5fss0_core0_dma_memory_region>,
+			<&main_r5fss0_core0_memory_region>,
+			<&main_r5fss0_core0_shared_memory_queue_region>,
+			<&main_r5fss0_core0_shared_memory_bufpool_region>;
+};
+
+/* EthFw uses timers so mark them reserved */
+&main_timer12 {
+	status = "reserved";
+};
+
+&main_timer13 {
+	status = "reserved";
+};
+
+/*
+ * Disable the following to avoid overloading exp2.
+ * Otherwise it will result in PHY read/write errors.
+ */
+&main_mcan4 {
+	status = "disabled";
+};
+
+&transceiver3 {
+	status = "disabled";
+};
+
+&mux1 {
+	status = "disabled";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j784s4-evm-fpdlink-iv-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j784s4-evm-fpdlink-iv-fusion.dtso
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm-fpdlink-iv-fusion.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm-fpdlink-iv-fusion.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for FPDLink IV UB9702 Deserializer on J784S4 EVM
+ * https://www.ti.com/tool/J7EXPA01EVM
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_fusion_25M_fixed: fixed-clock-25M {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+};
+
+&exp5 {
+	p0-hog{
+		gpio-hog;
+		gpios = <0 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "CSI2_EXP_RSTZ";
+	};
+};
+
+&main_i2c5 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	deser@3d {
+		compatible = "ti,ds90ub9702-q1";
+		reg = <0x3d>;
+		clocks = <&clk_fusion_25M_fixed>;
+		clock-names = "refclk";
+		i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+		deserializer_0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@4 {
+				reg = <4>;
+				ds90ub970_0_csi_out: endpoint {
+					clock-lanes = <0>;
+					data-lanes = <1 2 3 4>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy0>;
+				};
+			};
+		};
+
+		deserializer_0_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	deser@30 {
+		compatible = "ti,ds90ub9702-q1";
+		reg = <0x30>;
+		clocks = <&clk_fusion_25M_fixed>;
+		clock-names = "refclk";
+		i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+		deserializer_1_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@4 {
+				reg = <4>;
+				ds90ub970_1_csi_out: endpoint {
+					clock-lanes = <0>;
+					data-lanes = <1 2 3 4>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy1>;
+				};
+			};
+		};
+
+		deserializer_1_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	deser@32 {
+		compatible = "ti,ds90ub9702-q1";
+		reg = <0x32>;
+		clocks = <&clk_fusion_25M_fixed>;
+		clock-names = "refclk";
+		i2c-alias-pool = <0x6a 0x6b 0x6c 0x6d 0x6e 0x6f>;
+
+		deserializer_2_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* CSI-2 TX */
+			port@4 {
+				reg = <4>;
+				ds90ub970_2_csi_out: endpoint {
+					clock-lanes = <0>;
+					data-lanes = <1 2 3 4>;
+					link-frequencies = /bits/ 64 <800000000>;
+					remote-endpoint = <&csi2_phy2>;
+				};
+			};
+		};
+
+		deserializer_2_links: links {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy0: endpoint {
+				remote-endpoint = <&ds90ub970_0_csi_out>;
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+
+			};
+		};
+	};
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy1: endpoint {
+				remote-endpoint = <&ds90ub970_1_csi_out>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&cdns_csi2rx2 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi2_port0: port@0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2_phy2: endpoint {
+				remote-endpoint = <&ds90ub970_2_csi_out>;
+				bus-type = <4>; /* CSI2 DPHY */
+				clock-lanes = <0>;
+				data-lanes = <1 2 3 4>;
+				link-frequencies = /bits/ 64 <800000000>;
+			};
+		};
+	};
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
+
+&ti_csi2rx2 {
+	status = "okay";
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&dphy1 {
+	status = "okay";
+};
+
+&dphy2 {
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j784s4-evm-quad-port-eth-exp1.dtso b/arch/arm64/boot/dts/ti/k3-j784s4-evm-quad-port-eth-exp1.dtso
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm-quad-port-eth-exp1.dtso	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm-quad-port-eth-exp1.dtso	2025-10-23 09:30:40.283462146 -0400
@@ -102,13 +102,6 @@
 		gpios = <16 GPIO_ACTIVE_HIGH>;
 		output-low;
 	};
-
-	/* Toggle MUX2 for MDIO lines */
-	mux-sel-hog {
-		gpio-hog;
-		gpios = <13 GPIO_ACTIVE_HIGH>, <14 GPIO_ACTIVE_HIGH>, <15 GPIO_ACTIVE_HIGH>;
-		output-high;
-	};
 };
 
 &main_pmx0 {
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-common.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-common.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-common.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-common.dtsi	2025-10-23 09:30:40.284462176 -0400
@@ -80,6 +80,7 @@
 		ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
 			 <0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
 			 <0x00 0x00700000 0x00 0x00700000 0x00 0x00001000>, /* ESM */
+			 <0x00 0x00a40000 0x00 0x00a40000 0x00 0x00000800>, /* Time Sync Router */
 			 <0x00 0x01000000 0x00 0x01000000 0x00 0x0d000000>, /* Most peripherals */
 			 <0x00 0x04210000 0x00 0x04210000 0x00 0x00010000>, /* VPU0 */
 			 <0x00 0x04220000 0x00 0x04220000 0x00 0x00010000>, /* VPU1 */
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,1712 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * EVM Board Schematics(j784s4): https://www.ti.com/lit/zip/sprr458
+ * EVM Board Schematics(j742s2): https://www.ti.com/lit/zip/SPAC001
+ */
+
+#include "k3-timesync-router.h"
+
+/ {
+	chosen {
+		stdout-path = "serial2:115200n8";
+	};
+
+	aliases {
+		serial0 = &wkup_uart0;
+		serial1 = &mcu_uart0;
+		serial2 = &main_uart8;
+		mmc0 = &main_sdhci0;
+		mmc1 = &main_sdhci1;
+		i2c0 = &wkup_i2c0;
+		i2c3 = &main_i2c0;
+		ethernet0 = &mcu_cpsw_port1;
+		ethernet1 = &main_cpsw1_port1;
+	};
+
+	reserved_memory: reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		 /* global cma region */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x00 0x70000000>;
+			linux,cma-default;
+		};
+
+		secure_ddr: optee@9e800000 {
+			reg = <0x00 0x9e800000 0x00 0x01800000>;
+			no-map;
+		};
+
+		mcu_r5fss0_core0_dma_memory_region: r5f-dma-memory@a0000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0000000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_r5fss0_core0_memory_region: r5f-memory@a0100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		mcu_r5fss0_core1_dma_memory_region: r5f-dma-memory@a1000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1000000 0x00 0x100000>;
+			no-map;
+		};
+
+		mcu_r5fss0_core1_memory_region: r5f-memory@a1100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss0_core0_dma_memory_region: r5f-dma-memory@a2000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core0_memory_region: r5f-memory@a2100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss0_core1_dma_memory_region: r5f-dma-memory@a3000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core1_memory_region: r5f-memory@a3100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss1_core0_dma_memory_region: r5f-dma-memory@a4000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa4000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss1_core0_memory_region: r5f-memory@a4100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa4100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss1_core1_dma_memory_region: r5f-dma-memory@a5000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa5000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss1_core1_memory_region: r5f-memory@a5100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa5100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss2_core0_dma_memory_region: r5f-dma-memory@a6000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa6000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss2_core0_memory_region: r5f-memory@a6100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa6100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss2_core1_dma_memory_region: r5f-dma-memory@a7000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa7000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss2_core1_memory_region: r5f-memory@a7100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa7100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		c71_0_dma_memory_region: c71-dma-memory@a8000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa8000000 0x00 0x100000>;
+			no-map;
+		};
+
+		c71_0_memory_region: c71-memory@a8100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa8100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		c71_1_dma_memory_region: c71-dma-memory@a9000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa9000000 0x00 0x100000>;
+			no-map;
+		};
+
+		c71_1_memory_region: c71-memory@a9100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa9100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		c71_2_dma_memory_region: c71-dma-memory@aa000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xaa000000 0x00 0x100000>;
+			no-map;
+		};
+
+		c71_2_memory_region: c71-memory@aa100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xaa100000 0x00 0xf00000>;
+			no-map;
+		};
+	};
+
+	evm_12v0: regulator-evm12v0 {
+		/* main supply */
+		compatible = "regulator-fixed";
+		regulator-name = "evm_12v0";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vsys_3v3: regulator-vsys3v3 {
+		/* Output of LM5140 */
+		compatible = "regulator-fixed";
+		regulator-name = "vsys_3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&evm_12v0>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vsys_5v0: regulator-vsys5v0 {
+		/* Output of LM5140 */
+		compatible = "regulator-fixed";
+		regulator-name = "vsys_5v0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&evm_12v0>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vdd_mmc1: regulator-sd {
+		/* Output of TPS22918 */
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_mmc1";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		enable-active-high;
+		vin-supply = <&vsys_3v3>;
+		gpio = <&exp2 2 GPIO_ACTIVE_HIGH>;
+	};
+
+	vdd_sd_dv: regulator-TLV71033 {
+		/* Output of TLV71033 */
+		compatible = "regulator-gpio";
+		regulator-name = "tlv71033";
+		pinctrl-names = "default";
+		pinctrl-0 = <&vdd_sd_dv_pins_default>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		vin-supply = <&vsys_5v0>;
+		gpios = <&main_gpio0 8 GPIO_ACTIVE_HIGH>;
+		states = <1800000 0x0>,
+			 <3300000 0x1>;
+	};
+
+	dp0_pwr_3v3: regulator-dp0-prw {
+		compatible = "regulator-fixed";
+		regulator-name = "dp0-pwr";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&exp4 0 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	dp0: connector-dp0 {
+		compatible = "dp-connector";
+		label = "DP0";
+		type = "full-size";
+		dp-pwr-supply = <&dp0_pwr_3v3>;
+
+		port {
+			dp0_connector_in: endpoint {
+				remote-endpoint = <&dp0_out>;
+			};
+		};
+	};
+
+	vsys_io_1v8: regulator-vsys-io-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vsys_io_1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vsys_io_1v2: regulator-vsys-io-1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "vsys_io_1v2";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	edp1_refclk: clock-edp1-refclk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <19200000>;
+	};
+
+	dp1_pwr_3v3: regulator-dp1-prw {
+		compatible = "regulator-fixed";
+		regulator-name = "dp1-pwr";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&exp4 1 GPIO_ACTIVE_HIGH>; /* P1 - DP1_PWR_SW_EN */
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	transceiver0: can-phy0 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mcu_mcan0_gpio_pins_default>;
+		standby-gpios = <&wkup_gpio0 69 GPIO_ACTIVE_HIGH>;
+	};
+
+	transceiver1: can-phy1 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mcu_mcan1_gpio_pins_default>;
+		standby-gpios = <&wkup_gpio0 2 GPIO_ACTIVE_HIGH>;
+	};
+
+	transceiver2: can-phy2 {
+		/* standby pin has been grounded by default */
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
+	transceiver3: can-phy3 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+		standby-gpios = <&exp2 7 GPIO_ACTIVE_HIGH>;
+		mux-states = <&mux1 1>;
+	};
+
+	mux1: mux-controller {
+		compatible = "gpio-mux";
+		#mux-state-cells = <1>;
+		mux-gpios = <&exp2 14 GPIO_ACTIVE_HIGH>;
+		idle-state = <1>;
+	};
+
+	codec_audio: sound {
+		compatible = "ti,j7200-cpb-audio";
+		model = "j784s4-cpb";
+
+		ti,cpb-mcasp = <&mcasp0>;
+		ti,cpb-codec = <&pcm3168a_1>;
+
+		clocks = <&k3_clks 265 0>, <&k3_clks 265 1>,
+			 <&k3_clks 157 34>, <&k3_clks 157 63>;
+		clock-names = "cpb-mcasp-auxclk", "cpb-mcasp-auxclk-48000",
+			      "cpb-codec-scki", "cpb-codec-scki-48000";
+	};
+};
+
+&wkup_gpio0 {
+	status = "okay";
+};
+
+&main_pmx0 {
+	bootph-all;
+	main_cpsw2g_default_pins: main-cpsw2g-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x0b8, PIN_INPUT, 6) /* (AC34) MCASP1_ACLKX.RGMII1_RD0 */
+			J784S4_IOPAD(0x0a0, PIN_INPUT, 6) /* (AD34) MCASP0_AXR12.RGMII1_RD1 */
+			J784S4_IOPAD(0x0a4, PIN_INPUT, 6) /* (AJ36) MCASP0_AXR13.RGMII1_RD2 */
+			J784S4_IOPAD(0x0a8, PIN_INPUT, 6) /* (AF34) MCASP0_AXR14.RGMII1_RD3 */
+			J784S4_IOPAD(0x0b0, PIN_INPUT, 6) /* (AL33) MCASP1_AXR3.RGMII1_RXC */
+			J784S4_IOPAD(0x0ac, PIN_INPUT, 6) /* (AE34) MCASP0_AXR15.RGMII1_RX_CTL */
+			J784S4_IOPAD(0x08c, PIN_INPUT, 6) /* (AE35) MCASP0_AXR7.RGMII1_TD0 */
+			J784S4_IOPAD(0x090, PIN_INPUT, 6) /* (AC35) MCASP0_AXR8.RGMII1_TD1 */
+			J784S4_IOPAD(0x094, PIN_INPUT, 6) /* (AG35) MCASP0_AXR9.RGMII1_TD2 */
+			J784S4_IOPAD(0x098, PIN_INPUT, 6) /* (AH36) MCASP0_AXR10.RGMII1_TD3 */
+			J784S4_IOPAD(0x0b4, PIN_INPUT, 6) /* (AL34) MCASP1_AXR4.RGMII1_TXC */
+			J784S4_IOPAD(0x09c, PIN_INPUT, 6) /* (AF35) MCASP0_AXR11.RGMII1_TX_CTL */
+		>;
+	};
+
+	main_cpsw2g_mdio_default_pins: main-cpsw2g-mdio-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x0c0, PIN_INPUT, 6) /* (AD38) MCASP1_AXR0.MDIO0_MDC */
+			J784S4_IOPAD(0x0bc, PIN_INPUT, 6) /* (AD33) MCASP1_AFSX.MDIO0_MDIO */
+		>;
+	};
+
+	main_uart8_pins_default: main-uart8-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x040, PIN_INPUT, 14) /* (AF37) MCASP0_AXR0.UART8_CTSn */
+			J784S4_IOPAD(0x044, PIN_OUTPUT, 14) /* (AG37) MCASP0_AXR1.UART8_RTSn */
+			J784S4_IOPAD(0x0d0, PIN_INPUT, 11) /* (AP38) SPI0_CS1.UART8_RXD */
+			J784S4_IOPAD(0x0d4, PIN_OUTPUT, 11) /* (AN38) SPI0_CLK.UART8_TXD */
+		>;
+	};
+
+	main_i2c0_pins_default: main-i2c0-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x0e0, PIN_INPUT_PULLUP, 0) /* (AN36) I2C0_SCL */
+			J784S4_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AP37) I2C0_SDA */
+		>;
+	};
+
+	main_i2c5_pins_default: main-i2c5-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x01c, PIN_INPUT, 8) /* (AG34) MCAN15_TX.I2C5_SCL */
+			J784S4_IOPAD(0x018, PIN_INPUT, 8) /* (AK36) MCAN14_RX.I2C5_SDA */
+		>;
+	};
+
+	main_mmc1_pins_default: main-mmc1-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x104, PIN_INPUT, 0) /* (AB38) MMC1_CLK */
+			J784S4_IOPAD(0x108, PIN_INPUT, 0) /* (AB36) MMC1_CMD */
+			J784S4_IOPAD(0x100, PIN_INPUT, 0) /* (No Pin) MMC1_CLKLB */
+			J784S4_IOPAD(0x0fc, PIN_INPUT, 0) /* (AA33) MMC1_DAT0 */
+			J784S4_IOPAD(0x0f8, PIN_INPUT, 0) /* (AB34) MMC1_DAT1 */
+			J784S4_IOPAD(0x0f4, PIN_INPUT, 0) /* (AA32) MMC1_DAT2 */
+			J784S4_IOPAD(0x0f0, PIN_INPUT, 0) /* (AC38) MMC1_DAT3 */
+			J784S4_IOPAD(0x0e8, PIN_INPUT, 8) /* (AR38) TIMER_IO0.MMC1_SDCD */
+		>;
+	};
+
+	vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x020, PIN_INPUT, 7) /* (AJ35) MCAN15_RX.GPIO0_8 */
+		>;
+	};
+
+	dp0_pins_default: dp0-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x0cc, PIN_INPUT, 12) /* (AM37) SPI0_CS0.DP0_HPD */
+		>;
+	};
+
+	main_i2c4_pins_default: main-i2c4-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x014, PIN_INPUT_PULLUP, 8) /* (AG33) MCAN14_TX.I2C4_SCL */
+			J784S4_IOPAD(0x010, PIN_INPUT_PULLUP, 8) /* (AH33) MCAN13_RX.I2C4_SDA */
+		>;
+	};
+
+	main_mcan4_pins_default: main-mcan4-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x088, PIN_INPUT, 0) /* (AF36) MCAN4_RX */
+			J784S4_IOPAD(0x084, PIN_OUTPUT, 0) /* (AG38) MCAN4_TX */
+		>;
+	};
+
+	main_mcan16_pins_default: main-mcan16-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x028, PIN_INPUT, 0) /* (AE33) MCAN16_RX */
+			J784S4_IOPAD(0x024, PIN_OUTPUT, 0) /* (AH34) MCAN16_TX */
+		>;
+	};
+
+	main_usbss0_pins_default: main-usbss0-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x0ec, PIN_OUTPUT, 6) /* (AN37) TIMER_IO1.USB0_DRVVBUS */
+		>;
+	};
+
+	main_i2c3_pins_default: main-i2c3-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x064, PIN_INPUT, 13) /* (AF38) MCAN0_TX.I2C3_SCL */
+			J784S4_IOPAD(0x060, PIN_INPUT, 13) /* (AE36) MCASP2_AXR1.I2C3_SDA */
+		>;
+	};
+
+	main_mcasp0_pins_default: main-mcasp0-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x038, PIN_OUTPUT_PULLDOWN, 1) /* (AK35) MCASP0_ACLKX */
+			J784S4_IOPAD(0x03c, PIN_OUTPUT_PULLDOWN, 1) /* (AK38) MCASP0_AFSX */
+			J784S4_IOPAD(0x07c, PIN_OUTPUT_PULLDOWN, 1) /* (AJ38) MCASP0_AXR3 */
+			J784S4_IOPAD(0x080, PIN_INPUT_PULLDOWN, 1) /* (AK34) MCASP0_AXR4 */
+		>;
+	};
+
+	audio_ext_refclk1_pins_default: audio-ext-refclk1-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x078, PIN_OUTPUT, 1) /* (AH37) MCAN2_RX.AUDIO_EXT_REFCLK1 */
+		>;
+	};
+};
+
+&wkup_pmx2 {
+	bootph-all;
+	wkup_uart0_pins_default: wkup-uart0-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
+			J784S4_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (K34) WKUP_UART0_TXD */
+		>;
+	};
+
+	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x98, PIN_INPUT, 0) /* (N33) WKUP_I2C0_SCL */
+			J784S4_WKUP_IOPAD(0x9c, PIN_INPUT, 0) /* (N35) WKUP_I2C0_SDA */
+		>;
+	};
+
+	mcu_uart0_pins_default: mcu-uart0-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x090, PIN_INPUT, 0) /* (H37) WKUP_GPIO0_14.MCU_UART0_CTSn */
+			J784S4_WKUP_IOPAD(0x094, PIN_OUTPUT, 0) /* (K37) WKUP_GPIO0_15.MCU_UART0_RTSn */
+			J784S4_WKUP_IOPAD(0x08c, PIN_INPUT, 0) /* (K38) WKUP_GPIO0_13.MCU_UART0_RXD */
+			J784S4_WKUP_IOPAD(0x088, PIN_OUTPUT, 0) /* (J37) WKUP_GPIO0_12.MCU_UART0_TXD */
+		>;
+	};
+
+	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x02c, PIN_INPUT, 0) /* (A35) MCU_RGMII1_RD0 */
+			J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (B36) MCU_RGMII1_RD1 */
+			J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (C36) MCU_RGMII1_RD2 */
+			J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (D36) MCU_RGMII1_RD3 */
+			J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (B37) MCU_RGMII1_RXC */
+			J784S4_WKUP_IOPAD(0x004, PIN_INPUT, 0) /* (C37) MCU_RGMII1_RX_CTL */
+			J784S4_WKUP_IOPAD(0x014, PIN_OUTPUT, 0) /* (D37) MCU_RGMII1_TD0 */
+			J784S4_WKUP_IOPAD(0x010, PIN_OUTPUT, 0) /* (D38) MCU_RGMII1_TD1 */
+			J784S4_WKUP_IOPAD(0x00c, PIN_OUTPUT, 0) /* (E37) MCU_RGMII1_TD2 */
+			J784S4_WKUP_IOPAD(0x008, PIN_OUTPUT, 0) /* (E38) MCU_RGMII1_TD3 */
+			J784S4_WKUP_IOPAD(0x018, PIN_OUTPUT, 0) /* (E36) MCU_RGMII1_TXC */
+			J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (C38) MCU_RGMII1_TX_CTL */
+		>;
+	};
+
+	mcu_mdio_pins_default: mcu-mdio-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x034, PIN_OUTPUT, 0) /* (A36) MCU_MDIO0_MDC */
+			J784S4_WKUP_IOPAD(0x030, PIN_INPUT, 0) /* (B35) MCU_MDIO0_MDIO */
+		>;
+	};
+
+	mcu_adc0_pins_default: mcu-adc0-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x0cc, PIN_INPUT, 0) /* (P36) MCU_ADC0_AIN0 */
+			J784S4_WKUP_IOPAD(0x0d0, PIN_INPUT, 0) /* (V36) MCU_ADC0_AIN1 */
+			J784S4_WKUP_IOPAD(0x0d4, PIN_INPUT, 0) /* (T34) MCU_ADC0_AIN2 */
+			J784S4_WKUP_IOPAD(0x0d8, PIN_INPUT, 0) /* (T36) MCU_ADC0_AIN3 */
+			J784S4_WKUP_IOPAD(0x0dc, PIN_INPUT, 0) /* (P34) MCU_ADC0_AIN4 */
+			J784S4_WKUP_IOPAD(0x0e0, PIN_INPUT, 0) /* (R37) MCU_ADC0_AIN5 */
+			J784S4_WKUP_IOPAD(0x0e4, PIN_INPUT, 0) /* (R33) MCU_ADC0_AIN6 */
+			J784S4_WKUP_IOPAD(0x0e8, PIN_INPUT, 0) /* (V38) MCU_ADC0_AIN7 */
+		>;
+	};
+
+	mcu_adc1_pins_default: mcu-adc1-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x0ec, PIN_INPUT, 0) /* (Y38) MCU_ADC1_AIN0 */
+			J784S4_WKUP_IOPAD(0x0f0, PIN_INPUT, 0) /* (Y34) MCU_ADC1_AIN1 */
+			J784S4_WKUP_IOPAD(0x0f4, PIN_INPUT, 0) /* (V34) MCU_ADC1_AIN2 */
+			J784S4_WKUP_IOPAD(0x0f8, PIN_INPUT, 0) /* (W37) MCU_ADC1_AIN3 */
+			J784S4_WKUP_IOPAD(0x0fc, PIN_INPUT, 0) /* (AA37) MCU_ADC1_AIN4 */
+			J784S4_WKUP_IOPAD(0x100, PIN_INPUT, 0) /* (W33) MCU_ADC1_AIN5 */
+			J784S4_WKUP_IOPAD(0x104, PIN_INPUT, 0) /* (U33) MCU_ADC1_AIN6 */
+			J784S4_WKUP_IOPAD(0x108, PIN_INPUT, 0) /* (Y36) MCU_ADC1_AIN7 */
+		>;
+	};
+
+	mcu_mcan0_pins_default: mcu-mcan0-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x050, PIN_OUTPUT, 0) /* (K33) MCU_MCAN0_TX */
+			J784S4_WKUP_IOPAD(0x054, PIN_INPUT, 0) /* (F38) MCU_MCAN0_RX */
+		>;
+	};
+
+	mcu_mcan1_pins_default: mcu-mcan1-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x068, PIN_OUTPUT, 0) /* (H35) WKUP_GPIO0_4.MCU_MCAN1_TX */
+			J784S4_WKUP_IOPAD(0x06c, PIN_INPUT, 0) /* (K36) WKUP_GPIO0_5.MCU_MCAN1_RX */
+		>;
+	};
+
+	mcu_mcan0_gpio_pins_default: mcu-mcan0-gpio-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x040, PIN_INPUT, 7) /* (J38) MCU_SPI0_D1.WKUP_GPIO0_69 */
+		>;
+	};
+
+	mcu_mcan1_gpio_pins_default: mcu-mcan1-gpio-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x060, PIN_INPUT, 7) /* (J35) WKUP_GPIO0_2 */
+		>;
+	};
+
+	wkup_gpio_pins_default: wkup_gpio_pins_default {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x070, PIN_INPUT, 7) /* (L37) WKUP_GPIO0_6 */
+		>;
+	};
+};
+
+&wkup_pmx1 {
+	status = "okay";
+
+	pmic_irq_pins_default: pmic-irq-default-pins {
+		pinctrl-single,pins = <
+			/* (G33) MCU_OSPI1_CSn1.WKUP_GPIO0_39 */
+			J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 7)
+		>;
+	};
+};
+
+&wkup_pmx0 {
+	bootph-all;
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (E32) MCU_OSPI0_CLK */
+			J784S4_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (A32) MCU_OSPI0_CSn0 */
+			J784S4_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (B33) MCU_OSPI0_D0 */
+			J784S4_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (B32) MCU_OSPI0_D1 */
+			J784S4_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (C33) MCU_OSPI0_D2 */
+			J784S4_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (C35) MCU_OSPI0_D3 */
+			J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (D33) MCU_OSPI0_D4 */
+			J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (D34) MCU_OSPI0_D5 */
+			J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (E34) MCU_OSPI0_D6 */
+			J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (E33) MCU_OSPI0_D7 */
+			J784S4_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (C34) MCU_OSPI0_DQS */
+		>;
+	};
+};
+
+&wkup_pmx1 {
+	bootph-all;
+	mcu_fss0_ospi0_1_pins_default: mcu-fss0-ospi0-1-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x004, PIN_OUTPUT, 6) /* (C32) MCU_OSPI0_ECC_FAIL */
+			J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 6) /* (B34) MCU_OSPI0_RESET_OUT0 */
+		>;
+	};
+
+	mcu_fss0_ospi1_pins_default: mcu-fss0-ospi1-default-pins {
+		bootph-all;
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x008, PIN_OUTPUT, 0) /* (F32) MCU_OSPI1_CLK */
+			J784S4_WKUP_IOPAD(0x024, PIN_OUTPUT, 0) /* (G32) MCU_OSPI1_CSn0 */
+			J784S4_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (E35) MCU_OSPI1_D0 */
+			J784S4_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (D31) MCU_OSPI1_D1 */
+			J784S4_WKUP_IOPAD(0x01C, PIN_INPUT, 0) /* (G31) MCU_OSPI1_D2 */
+			J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (F33) MCU_OSPI1_D3 */
+			J784S4_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (F31) MCU_OSPI1_DQS */
+			J784S4_WKUP_IOPAD(0x00C, PIN_INPUT, 0) /* (C31) MCU_OSPI1_LBCLKO */
+		>;
+	};
+};
+
+&wkup_uart0 {
+	/* Firmware usage */
+	status = "reserved";
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_uart0_pins_default>;
+};
+
+&wkup_i2c0 {
+	bootph-all;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_i2c0_pins_default>;
+	clock-frequency = <400000>;
+
+	eeprom@50 {
+		/* CAV24C256WE-GT3 */
+		compatible = "atmel,24c256";
+		reg = <0x50>;
+	};
+
+	tps659413: pmic@48 {
+		compatible = "ti,tps6594-q1";
+		reg = <0x48>;
+		system-power-controller;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_irq_pins_default>;
+		interrupt-parent = <&wkup_gpio0>;
+		interrupts = <39 IRQ_TYPE_EDGE_FALLING>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		ti,primary-pmic;
+		buck12-supply = <&vsys_3v3>;
+		buck3-supply = <&vsys_3v3>;
+		buck4-supply = <&vsys_3v3>;
+		buck5-supply = <&vsys_3v3>;
+		ldo1-supply = <&vsys_3v3>;
+		ldo2-supply = <&vsys_3v3>;
+		ldo3-supply = <&vsys_3v3>;
+		ldo4-supply = <&vsys_3v3>;
+
+		regulators {
+			bucka12: buck12 {
+				regulator-name = "vdd_ddr_1v1";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-boot-on;
+				regulator-always-on;
+				bootph-all;
+			};
+
+			bucka3: buck3 {
+				regulator-name = "vdd_ram_0v85";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-boot-on;
+				regulator-always-on;
+				bootph-all;
+			};
+
+			bucka4: buck4 {
+				regulator-name = "vdd_io_1v8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+				bootph-all;
+			};
+
+			bucka5: buck5 {
+				regulator-name = "vdd_mcu_0v85";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-boot-on;
+				regulator-always-on;
+				bootph-all;
+			};
+
+			ldoa1: ldo1 {
+				regulator-name = "vdd_mcuio_1v8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+				bootph-all;
+			};
+
+			ldoa2: ldo2 {
+				regulator-name = "vdd_mcuio_3v3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+				bootph-all;
+			};
+
+			ldoa3: ldo3 {
+				regulator-name = "vds_dll_0v8";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <800000>;
+				regulator-boot-on;
+				regulator-always-on;
+				bootph-all;
+			};
+
+			ldoa4: ldo4 {
+				regulator-name = "vda_mcu_1v8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+				regulator-always-on;
+				bootph-all;
+			};
+		};
+	};
+
+	tps62873a: regulator@40 {
+		compatible = "ti,tps62873";
+		reg = <0x40>;
+		bootph-pre-ram;
+		regulator-name = "VDD_CPU_AVS";
+		regulator-min-microvolt = <750000>;
+		regulator-max-microvolt = <1330000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	tps62873b: regulator@43 {
+		compatible = "ti,tps62873";
+		reg = <0x43>;
+		regulator-name = "VDD_CORE_0V8";
+		regulator-min-microvolt = <760000>;
+		regulator-max-microvolt = <840000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&mcu_uart0 {
+	bootph-all;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_uart0_pins_default>;
+};
+
+&main_uart8 {
+	bootph-all;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart8_pins_default>;
+};
+
+&ufs_wrapper {
+	status = "okay";
+};
+
+&wkup_gpio0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_gpio_pins_default>;
+};
+
+&fss {
+	bootph-all;
+	status = "okay";
+};
+
+&ospi0 {
+	bootph-all;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>, <&mcu_fss0_ospi0_1_pins_default>;
+
+	ospi0_nor: flash@0 {
+		bootph-all;
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <4>;
+		cdns,phy-mode;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "ospi.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition@80000 {
+				label = "ospi.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition@280000 {
+				label = "ospi.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition@680000 {
+				label = "ospi.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition@6c0000 {
+				label = "ospi.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition@800000 {
+				label = "ospi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition@3fc0000 {
+				bootph-all;
+				label = "ospi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
+	};
+
+	ospi0_nand: nand@0 {
+		compatible = "spi-nand";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <2>;
+		cdns,phy-mode;
+		status = "disabled";
+		bootph-pre-ram;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "ospi_nand.tiboot3";
+				reg = <0x0 0x100000>;
+			};
+
+			partition@100000 {
+				label = "ospi_nand.tispl";
+				reg = <0x100000 0x200000>;
+			};
+
+			partition@300000 {
+				label = "ospi_nand.u-boot";
+				reg = <0x300000 0x400000>;
+			};
+
+			partition@700000 {
+				label = "ospi_nand.env";
+				reg = <0x700000 0x40000>;
+			};
+
+			partition@740000 {
+				label = "ospi_nand.env.backup";
+				reg = <0x740000 0x40000>;
+			};
+
+			partition@2000000 {
+				label = "ospi_nand.rootfs";
+				reg = <0x2000000 0x5fc0000>;
+			};
+
+			partition@7fc0000 {
+				bootph-all;
+				label = "ospi_nand.phypattern";
+				reg = <0x7fc0000 0x40000>;
+			};
+		};
+	};
+};
+
+&ospi1 {
+	bootph-all;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi1_pins_default>;
+
+	ospi1_nor: flash@0 {
+		bootph-all;
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "qspi.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition@80000 {
+				label = "qspi.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition@280000 {
+				label = "qspi.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition@680000 {
+				label = "qspi.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition@6c0000 {
+				label = "qspi.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition@800000 {
+				label = "qspi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition@3fc0000 {
+				bootph-all;
+				label = "qspi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
+
+	};
+};
+
+&main_i2c0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+
+	clock-frequency = <400000>;
+
+	exp1: gpio@20 {
+		compatible = "ti,tca6416";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "PCIE1_2L_MODE_SEL", "PCIE1_4L_PERSTZ", "PCIE1_2L_RC_RSTZ",
+				  "PCIE1_2L_EP_RST_EN", "PCIE0_4L_MODE_SEL", "PCIE0_4L_PERSTZ",
+				  "PCIE0_4L_RC_RSTZ", "PCIE0_4L_EP_RST_EN", "PCIE1_4L_PRSNT#",
+				  "PCIE0_4L_PRSNT#", "CDCI1_OE1/OE4", "CDCI1_OE2/OE3",
+				  "AUDIO_MUX_SEL", "EXP_MUX2", "EXP_MUX3", "GESI_EXP_PHY_RSTZ";
+
+		p12-hog {
+			/* P12 - AUDIO_MUX_SEL */
+			gpio-hog;
+			gpios = <12 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "AUDIO_MUX_SEL";
+		};
+	};
+
+	exp2: gpio@22 {
+		compatible = "ti,tca6424";
+		reg = <0x22>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "R_GPIO_RGMII1_RST", "ENET2_I2CMUX_SEL", "GPIO_USD_PWR_EN",
+				  "USBC_PWR_EN", "USBC_MODE_SEL1", "USBC_MODE_SEL0",
+				  "GPIO_LIN_EN", "R_CAN_STB", "CTRL_PM_I2C_OE#",
+				  "ENET2_EXP_PWRDN", "ENET2_EXP_SPARE2", "CDCI2_RSTZ",
+				  "USB2.0_MUX_SEL", "CANUART_MUX_SEL0", "CANUART_MUX2_SEL1",
+				  "CANUART_MUX1_SEL1", "ENET1_EXP_PWRDN", "ENET1_EXP_RESETZ",
+				  "ENET1_I2CMUX_SEL", "ENET1_EXP_SPARE2", "ENET2_EXP_RESETZ",
+				  "USER_INPUT1", "USER_LED1", "USER_LED2";
+
+		p13-hog {
+			/* P13 - CANUART_MUX_SEL0 */
+			gpio-hog;
+			gpios = <13 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "CANUART_MUX_SEL0";
+		};
+
+		p15-hog {
+			/* P15 - CANUART_MUX1_SEL1 */
+			gpio-hog;
+			gpios = <15 GPIO_ACTIVE_HIGH>;
+			output-high;
+			line-name = "CANUART_MUX1_SEL1";
+		};
+	};
+};
+
+&main_i2c5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c5_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	exp5: gpio@20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI2_EXP_RSTZ", "CSI2_EXP_A_GPIO0",
+				  "CSI2_EXP_A_GPIO1", "CSI2_EXP_A_GPIO3",
+				  "CSI2_EXP_B_GPIO1", "CSI2_EXP_B_GPIO2",
+				  "CSI2_EXP_B_GPIO3", "CSI2_EXP_B_GPIO4";
+	};
+};
+
+&main_sdhci0 {
+	bootph-all;
+	/* eMMC */
+	status = "okay";
+	non-removable;
+	ti,driver-strength-ohm = <50>;
+	disable-wp;
+};
+
+&main_sdhci1 {
+	bootph-all;
+	/* SD card */
+	status = "okay";
+	pinctrl-0 = <&main_mmc1_pins_default>;
+	pinctrl-names = "default";
+	disable-wp;
+	vmmc-supply = <&vdd_mmc1>;
+	vqmmc-supply = <&vdd_sd_dv>;
+};
+
+&main_gpio0 {
+	status = "okay";
+};
+
+&mcu_cpsw {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_cpsw_pins_default>;
+
+	cpts@3d000 {
+		/* Map HW4_TS_PUSH to GENF1 */
+		ti,pps = <3 1>;
+	};
+};
+
+&davinci_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mdio_pins_default>;
+
+	mcu_phy0: ethernet-phy@0 {
+		reg = <0>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		ti,min-output-impedance;
+	};
+};
+
+&mcu_cpsw_port1 {
+	status = "okay";
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&mcu_phy0>;
+};
+
+&main_cpsw1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_cpsw2g_default_pins>;
+	status = "okay";
+};
+
+&main_cpsw1_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_cpsw2g_mdio_default_pins>;
+	status = "okay";
+
+	main_cpsw1_phy0: ethernet-phy@0 {
+		reg = <0>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		ti,min-output-impedance;
+	};
+};
+
+&main_cpsw1_port1 {
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&main_cpsw1_phy0>;
+	status = "okay";
+};
+
+&mailbox0_cluster0 {
+	status = "okay";
+	interrupts = <436>;
+
+	mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+
+	mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
+		ti,mbox-rx = <2 0 0>;
+		ti,mbox-tx = <3 0 0>;
+	};
+};
+
+&mailbox0_cluster1 {
+	status = "okay";
+	interrupts = <432>;
+
+	mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+
+	mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
+		ti,mbox-rx = <2 0 0>;
+		ti,mbox-tx = <3 0 0>;
+	};
+};
+
+&mailbox0_cluster2 {
+	status = "okay";
+	interrupts = <428>;
+
+	mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+
+	mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
+		ti,mbox-rx = <2 0 0>;
+		ti,mbox-tx = <3 0 0>;
+	};
+};
+
+&mailbox0_cluster3 {
+	status = "okay";
+	interrupts = <424>;
+
+	mbox_main_r5fss2_core0: mbox-main-r5fss2-core0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+
+	mbox_main_r5fss2_core1: mbox-main-r5fss2-core1 {
+		ti,mbox-rx = <2 0 0>;
+		ti,mbox-tx = <3 0 0>;
+	};
+};
+
+&mailbox0_cluster4 {
+	status = "okay";
+	interrupts = <420>;
+
+	mbox_c71_0: mbox-c71-0 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+
+	mbox_c71_1: mbox-c71-1 {
+		ti,mbox-rx = <2 0 0>;
+		ti,mbox-tx = <3 0 0>;
+	};
+};
+
+&mailbox0_cluster5 {
+	status = "okay";
+	interrupts = <416>;
+
+	mbox_c71_2: mbox-c71-2 {
+		ti,mbox-rx = <0 0 0>;
+		ti,mbox-tx = <1 0 0>;
+	};
+};
+
+&mcu_r5fss0_core0 {
+	status = "okay";
+	mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>;
+	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
+			<&mcu_r5fss0_core0_memory_region>;
+};
+
+&mcu_r5fss0_core1 {
+	status = "okay";
+	mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core1>;
+	memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
+			<&mcu_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss0 {
+	ti,cluster-mode = <0>;
+};
+
+&main_r5fss1 {
+	ti,cluster-mode = <0>;
+};
+
+&main_r5fss2 {
+	ti,cluster-mode = <0>;
+};
+
+/* Timers are used by Remoteproc firmware */
+&main_timer0 {
+	status = "reserved";
+};
+
+&main_timer1 {
+	status = "reserved";
+};
+
+&main_timer2 {
+	status = "reserved";
+};
+
+&main_timer3 {
+	status = "reserved";
+};
+
+&main_timer4 {
+	status = "reserved";
+};
+
+&main_timer5 {
+	status = "reserved";
+};
+
+&main_timer6 {
+	status = "reserved";
+};
+
+&main_timer7 {
+	status = "reserved";
+};
+
+&main_timer8 {
+	status = "reserved";
+};
+
+&main_timer9 {
+	status = "reserved";
+};
+
+&main_r5fss0_core0 {
+	status = "okay";
+	mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core0>;
+	memory-region = <&main_r5fss0_core0_dma_memory_region>,
+			<&main_r5fss0_core0_memory_region>;
+};
+
+&main_r5fss0_core1 {
+	status = "okay";
+	mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core1>;
+	memory-region = <&main_r5fss0_core1_dma_memory_region>,
+			<&main_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss1_core0 {
+	status = "okay";
+	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core0>;
+	memory-region = <&main_r5fss1_core0_dma_memory_region>,
+			<&main_r5fss1_core0_memory_region>;
+};
+
+&main_r5fss1_core1 {
+	status = "okay";
+	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core1>;
+	memory-region = <&main_r5fss1_core1_dma_memory_region>,
+			<&main_r5fss1_core1_memory_region>;
+};
+
+&main_r5fss2_core0 {
+	status = "okay";
+	mboxes = <&mailbox0_cluster3 &mbox_main_r5fss2_core0>;
+	memory-region = <&main_r5fss2_core0_dma_memory_region>,
+			<&main_r5fss2_core0_memory_region>;
+};
+
+&main_r5fss2_core1 {
+	status = "okay";
+	mboxes = <&mailbox0_cluster3 &mbox_main_r5fss2_core1>;
+	memory-region = <&main_r5fss2_core1_dma_memory_region>,
+			<&main_r5fss2_core1_memory_region>;
+};
+
+&c71_0 {
+	status = "okay";
+	mboxes = <&mailbox0_cluster4 &mbox_c71_0>;
+	memory-region = <&c71_0_dma_memory_region>,
+			<&c71_0_memory_region>;
+};
+
+&c71_1 {
+	status = "okay";
+	mboxes = <&mailbox0_cluster4 &mbox_c71_1>;
+	memory-region = <&c71_1_dma_memory_region>,
+			<&c71_1_memory_region>;
+};
+
+&c71_2 {
+	status = "okay";
+	mboxes = <&mailbox0_cluster5 &mbox_c71_2>;
+	memory-region = <&c71_2_dma_memory_region>,
+			<&c71_2_memory_region>;
+};
+
+&tscadc0 {
+	pinctrl-0 = <&mcu_adc0_pins_default>;
+	pinctrl-names = "default";
+	status = "okay";
+	adc {
+		ti,adc-channels = <0 1 2 3 4 5 6 7>;
+	};
+};
+
+&tscadc1 {
+	pinctrl-0 = <&mcu_adc1_pins_default>;
+	pinctrl-names = "default";
+	status = "okay";
+	adc {
+		ti,adc-channels = <0 1 2 3 4 5 6 7>;
+	};
+};
+
+&serdes_refclk {
+	status = "okay";
+	clock-frequency = <100000000>;
+};
+
+&dss {
+	status = "okay";
+	assigned-clocks = <&k3_clks 218 2>,
+			  <&k3_clks 218 5>,
+			  <&k3_clks 218 14>,
+			  <&k3_clks 218 18>;
+	assigned-clock-parents = <&k3_clks 218 3>,
+				 <&k3_clks 218 7>,
+				 <&k3_clks 218 16>,
+				 <&k3_clks 218 22>;
+};
+
+&serdes0 {
+	status = "okay";
+
+	serdes0_pcie1_link: phy@0 {
+		reg = <0>;
+		cdns,num-lanes = <2>;
+		#phy-cells = <0>;
+		cdns,phy-type = <PHY_TYPE_PCIE>;
+		resets = <&serdes_wiz0 1>, <&serdes_wiz0 2>;
+	};
+
+	serdes0_usb_link: phy@3 {
+		bootph-all;
+		reg = <3>;
+		cdns,num-lanes = <1>;
+		#phy-cells = <0>;
+		cdns,phy-type = <PHY_TYPE_USB3>;
+		resets = <&serdes_wiz0 4>;
+	};
+};
+
+&serdes_wiz0 {
+	status = "okay";
+};
+
+&usb_serdes_mux {
+	idle-states = <0>; /* USB0 to SERDES lane 3 */
+};
+
+&usbss0 {
+	status = "okay";
+	pinctrl-0 = <&main_usbss0_pins_default>;
+	pinctrl-names = "default";
+	ti,vbus-divider;
+};
+
+&usb0 {
+	dr_mode = "otg";
+	maximum-speed = "super-speed";
+	phys = <&serdes0_usb_link>;
+	phy-names = "cdns3,usb3-phy";
+};
+
+&serdes_wiz4 {
+	status = "okay";
+};
+
+&serdes4 {
+	status = "okay";
+	serdes4_dp_link: phy@0 {
+		reg = <0>;
+		cdns,num-lanes = <4>;
+		#phy-cells = <0>;
+		cdns,phy-type = <PHY_TYPE_DP>;
+		cdns,max-bit-rate = <2700>;
+		resets = <&serdes_wiz4 1>, <&serdes_wiz4 2>,
+			 <&serdes_wiz4 3>, <&serdes_wiz4 4>;
+	};
+};
+
+&mhdp {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&dp0_pins_default>;
+	phys = <&serdes4_dp_link>;
+	phy-names = "dpphy";
+};
+
+&dphy_tx0 {
+	status = "okay";
+};
+
+&dsi0 {
+	status = "okay";
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* DP */
+	port@0 {
+		reg = <0>;
+		dpi0_out: endpoint {
+			remote-endpoint = <&dp0_in>;
+		};
+	};
+
+	/* DSI */
+	port@2 {
+		reg = <2>;
+		dpi2_out: endpoint {
+			remote-endpoint = <&dsi0_in>;
+		};
+	};
+};
+
+&main_i2c4 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c4_pins_default>;
+	clock-frequency = <400000>;
+
+	exp4: gpio@20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	dsi_edp_bridge: dsi-edp-bridge@2c {
+		compatible = "ti,sn65dsi86";
+		reg = <0x2c>;
+
+		clock-names = "refclk";
+		clocks = <&edp1_refclk>;
+
+		enable-gpios = <&exp4 2 GPIO_ACTIVE_HIGH>;
+
+		vpll-supply = <&vsys_io_1v8>;
+		vccio-supply = <&vsys_io_1v8>;
+		vcca-supply = <&vsys_io_1v2>;
+		vcc-supply = <&vsys_io_1v2>;
+
+		dsi_edp_bridge_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				dp1_in: endpoint {
+					remote-endpoint = <&dsi0_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				dp1_out: endpoint {
+					remote-endpoint = <&dp1_panel_in>;
+				};
+			};
+		};
+
+		aux-bus {
+			panel {
+				compatible = "ti,panel-edp";
+				power-supply = <&dp1_pwr_3v3>;
+
+				port {
+					dp1_panel_in: endpoint {
+						remote-endpoint = <&dp1_out>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&dsi0_ports {
+	port@0 {
+		reg = <0>;
+		dsi0_out: endpoint {
+			remote-endpoint = <&dp1_in>;
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		dsi0_in: endpoint {
+			remote-endpoint = <&dpi2_out>;
+		};
+	};
+};
+
+&dp0_ports {
+	port@0 {
+		reg = <0>;
+
+		dp0_in: endpoint {
+			remote-endpoint = <&dpi0_out>;
+		};
+	};
+
+	port@4 {
+		reg = <4>;
+
+		dp0_out: endpoint {
+			remote-endpoint = <&dp0_connector_in>;
+		};
+	};
+};
+
+&mcu_mcan0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mcan0_pins_default>;
+	phys = <&transceiver0>;
+};
+
+&mcu_mcan1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mcan1_pins_default>;
+	phys = <&transceiver1>;
+};
+
+&main_mcan16 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan16_pins_default>;
+	phys = <&transceiver2>;
+};
+
+&main_mcan4 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan4_pins_default>;
+	phys = <&transceiver3>;
+};
+
+&pcie1_rc {
+	status = "okay";
+	num-lanes = <2>;
+	reset-gpios = <&exp1 2 GPIO_ACTIVE_HIGH>;
+	phys = <&serdes0_pcie1_link>;
+	phy-names = "pcie-phy";
+};
+
+&serdes1 {
+	status = "okay";
+
+	serdes1_pcie0_link: phy@0 {
+		reg = <0>;
+		cdns,num-lanes = <4>;
+		#phy-cells = <0>;
+		cdns,phy-type = <PHY_TYPE_PCIE>;
+		resets = <&serdes_wiz1 1>, <&serdes_wiz1 2>,
+			 <&serdes_wiz1 3>, <&serdes_wiz1 4>;
+	};
+};
+
+&serdes_wiz1 {
+	status = "okay";
+};
+
+&pcie0_rc {
+	status = "okay";
+	reset-gpios = <&exp1 6 GPIO_ACTIVE_HIGH>;
+	phys = <&serdes1_pcie0_link>;
+	phy-names = "pcie-phy";
+};
+
+&k3_clks {
+	/* Confiure AUDIO_EXT_REFCLK1 pin as output */
+	pinctrl-names = "default";
+	pinctrl-0 = <&audio_ext_refclk1_pins_default>;
+};
+
+&main_i2c3 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c3_pins_default>;
+	clock-frequency = <400000>;
+
+	exp3: gpio@20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	pcm3168a_1: audio-codec@44 {
+		compatible = "ti,pcm3168a";
+		reg = <0x44>;
+		#sound-dai-cells = <1>;
+		reset-gpios = <&exp3 0 GPIO_ACTIVE_LOW>;
+		clocks = <&audio_refclk1>;
+		clock-names = "scki";
+		VDD1-supply = <&vsys_3v3>;
+		VDD2-supply = <&vsys_3v3>;
+		VCCAD1-supply = <&vsys_5v0>;
+		VCCAD2-supply = <&vsys_5v0>;
+		VCCDA1-supply = <&vsys_5v0>;
+		VCCDA2-supply = <&vsys_5v0>;
+	};
+};
+
+&mcasp0 {
+	status = "okay";
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcasp0_pins_default>;
+	op-mode = <0>;          /* MCASP_IIS_MODE */
+	tdm-slots = <2>;
+	auxclk-fs-ratio = <256>;
+	serial-dir = <	/* 0: INACTIVE, 1: TX, 2: RX */
+		0 0 0 1
+		2 0 0 0
+		0 0 0 0
+		0 0 0 0
+	>;
+};
+
+&timesync_router {
+       /* Use Time Sync Router to map GENF1 input to HW4_TS_PUSH output */
+	mux-reg-masks-state = <
+		/* pps [mcu cpsw cpts genf1] in17 -> out25 [mcu cpsw cpts hw4_push] */
+		K3_TS_OFFSET(25, 0x0001ffff, 17)
+		>;
+	status = "okay";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-pcie-ntb.dtso b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-pcie-ntb.dtso
--- a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-pcie-ntb.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-pcie-ntb.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for enabling NTB functionality using PCIE0 and PCIE1 instances of
+ * PCIe on the J784S4 EVM and the J742S2 EVM.
+ *
+ * J784S4 EVM Product Link: https://www.ti.com/tool/J784S4XEVM
+ * J742S2 EVM Product Link: https://www.ti.com/tool/J742S2XH01EVM
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+#include "k3-pinctrl.h"
+
+&{/} {
+	epf_bus {
+		compatible = "pci-epf-bus";
+
+		ntb {
+			compatible = "pci-epf-ntb";
+			epcs = <&pcie0_ep>, <&pcie1_ep>;
+			epc-names = "primary", "secondary";
+			vendor-id = /bits/ 16 <0x104c>;
+			device-id = /bits/ 16 <0xb012>;
+			num-mws = <4>;
+			mws-size = <0x100000>, <0x100000>, <0x100000>, <0x100000>;
+		};
+	};
+};
+
+&pcie0_rc {
+	status = "disabled";
+};
+
+&pcie1_rc {
+	status = "disabled";
+};
+
+&cbass_main {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&gic500>;
+
+	pcie0_ep: pcie-ep@2900000 {
+		compatible = "ti,j784s4-pcie-ep";
+		reg = <0x00 0x02900000 0x00 0x1000>,
+		      <0x00 0x02907000 0x00 0x400>,
+		      <0x00 0x0d000000 0x00 0x00800000>,
+		      <0x00 0x10000000 0x00 0x08000000>;
+		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+		interrupt-names = "link_state";
+		interrupts = <GIC_SPI 318 IRQ_TYPE_EDGE_RISING>;
+		ti,syscon-pcie-ctrl = <&pcie0_ctrl 0x0>;
+		max-link-speed = <3>;
+		num-lanes = <4>;
+		power-domains = <&k3_pds 332 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 332 0>;
+		clock-names = "fck";
+		max-functions = /bits/ 8 <6>;
+		max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+		dma-coherent;
+		phys = <&serdes1_pcie0_link>;
+		phy-names = "pcie-phy";
+	};
+
+	pcie1_ep: pcie-ep@2910000 {
+		compatible = "ti,j784s4-pcie-ep";
+		reg = <0x00 0x02910000 0x00 0x1000>,
+		      <0x00 0x02917000 0x00 0x400>,
+		      <0x00 0x0d800000 0x00 0x00800000>,
+		      <0x00 0x18000000 0x00 0x08000000>;
+		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+		interrupt-names = "link_state";
+		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
+		ti,syscon-pcie-ctrl = <&pcie1_ctrl 0x0>;
+		max-link-speed = <3>;
+		num-lanes = <2>;
+		power-domains = <&k3_pds 333 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 333 0>;
+		clock-names = "fck";
+		max-functions = /bits/ 8 <6>;
+		max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+		dma-coherent;
+		phys = <&serdes0_pcie1_link>;
+		phy-names = "pcie-phy";
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-usb0-type-a.dtso b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-usb0-type-a.dtso
--- a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-usb0-type-a.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-usb0-type-a.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for enabling USB0 instance of USB on J784S4 and J742S2 EVMs for
+ * Host Mode of operation with the Type-A Connector.
+ *
+ * J784S4 EVM Product Link: https://www.ti.com/tool/J784S4XEVM
+ * J742S2 EVM Product Link: https://www.ti.com/tool/J742S2XH01EVM
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&exp2 {
+	p12-hog {
+		/* P12 - USB2.0_MUX_SEL */
+		gpio-hog;
+		gpios = <12 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "USB2.0_MUX_SEL";
+	};
+};
+
+&usb0 {
+	dr_mode = "host";
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-main-common.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-main-common.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-main-common.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-main-common.dtsi	2025-10-23 09:30:40.284462176 -0400
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/mux/mux.h>
 #include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-cadence.h>
 #include <dt-bindings/phy/phy-ti.h>
 
 #include "k3-serdes.h"
@@ -126,6 +127,11 @@
 			assigned-clock-parents = <&k3_clks 157 63>;
 			#clock-cells = <0>;
 		};
+
+		acspcie0_proxy_ctrl: clock-controller@1a090 {
+			compatible = "ti,j784s4-acspcie-proxy-ctrl", "syscon";
+			reg = <0x1a090 0x4>;
+		};
 	};
 
 	main_ehrpwm0: pwm@3000000 {
@@ -226,7 +232,7 @@
 	};
 
 	main_pmx0: pinctrl@11c000 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		/* Proxy 0 addressing */
 		reg = <0x00 0x11c000 0x00 0x120>;
 		#pinctrl-cells = <1>;
@@ -236,7 +242,7 @@
 
 	/* TIMERIO pad input CTRLMMR_TIMER*_CTRL registers */
 	main_timerio_input: pinctrl@104200 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		reg = <0x00 0x104200 0x00 0x50>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
@@ -245,7 +251,7 @@
 
 	/* TIMERIO pad output CTCTRLMMR_TIMERIO*_CTRL registers */
 	main_timerio_output: pinctrl@104280 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		reg = <0x00 0x104280 0x00 0x20>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
@@ -801,14 +807,20 @@
 		ranges;
 		#address-cells = <2>;
 		#size-cells = <2>;
-		dmas = <&main_bcdma_csi 0 0x4940 0>;
-		dma-names = "rx0";
+		dmas = <&main_bcdma_csi 0 0x4940 0>, <&main_bcdma_csi 0 0x4941 0>,
+		       <&main_bcdma_csi 0 0x4942 0>, <&main_bcdma_csi 0 0x4943 0>,
+		       <&main_bcdma_csi 0 0x4944 0>, <&main_bcdma_csi 0 0x4945 0>,
+		       <&main_bcdma_csi 0 0x4946 0>, <&main_bcdma_csi 0 0x4947 0>;
+		dma-names = "rx0", "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7";
 		power-domains = <&k3_pds 72 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 
 		cdns_csi2rx0: csi-bridge@4504000 {
 			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
 			reg = <0x00 0x04504000 0x00 0x00001000>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
 			clocks = <&k3_clks 72 2>, <&k3_clks 72 0>, <&k3_clks 72 2>,
 				<&k3_clks 72 2>, <&k3_clks 72 3>, <&k3_clks 72 3>;
 			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
@@ -854,14 +866,20 @@
 		ranges;
 		#address-cells = <2>;
 		#size-cells = <2>;
-		dmas = <&main_bcdma_csi 0 0x4960 0>;
-		dma-names = "rx0";
+		dmas = <&main_bcdma_csi 0 0x4960 0>, <&main_bcdma_csi 0 0x4961 0>,
+		       <&main_bcdma_csi 0 0x4962 0>, <&main_bcdma_csi 0 0x4963 0>,
+		       <&main_bcdma_csi 0 0x4964 0>, <&main_bcdma_csi 0 0x4965 0>,
+		       <&main_bcdma_csi 0 0x4966 0>, <&main_bcdma_csi 0 0x4967 0>;
+		dma-names = "rx0", "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7";
 		power-domains = <&k3_pds 73 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 
 		cdns_csi2rx1: csi-bridge@4514000 {
 			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
 			reg = <0x00 0x04514000 0x00 0x00001000>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
 			clocks = <&k3_clks 73 2>, <&k3_clks 73 0>, <&k3_clks 73 2>,
 				<&k3_clks 73 2>, <&k3_clks 73 3>, <&k3_clks 73 3>;
 			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
@@ -906,14 +924,20 @@
 		ranges;
 		#address-cells = <2>;
 		#size-cells = <2>;
-		dmas = <&main_bcdma_csi 0 0x4980 0>;
-		dma-names = "rx0";
+		dmas = <&main_bcdma_csi 0 0x4980 0>, <&main_bcdma_csi 0 0x4981 0>,
+		       <&main_bcdma_csi 0 0x4982 0>, <&main_bcdma_csi 0 0x4983 0>,
+		       <&main_bcdma_csi 0 0x4984 0>, <&main_bcdma_csi 0 0x4985 0>,
+		       <&main_bcdma_csi 0 0x4986 0>, <&main_bcdma_csi 0 0x4987 0>;
+		dma-names = "rx0", "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7";
 		power-domains = <&k3_pds 74 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 
 		cdns_csi2rx2: csi-bridge@4524000 {
 			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
 			reg = <0x00 0x04524000 0x00 0x00001000>;
+			interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error_irq", "irq";
 			clocks = <&k3_clks 74 2>, <&k3_clks 74 0>, <&k3_clks 74 2>,
 				<&k3_clks 74 2>, <&k3_clks 74 3>, <&k3_clks 74 3>;
 			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
@@ -983,6 +1007,7 @@
 		interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&k3_clks 241 2>;
 		power-domains = <&k3_pds 241 TI_SCI_PD_EXCLUSIVE>;
+		sram = <&main_navss_sram>;
 	};
 
 	vpu1: video-codec@4220000 {
@@ -991,6 +1016,7 @@
 		interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&k3_clks 242 2>;
 		power-domains = <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>;
+		sram = <&main_navss_sram>;
 	};
 
 	main_sdhci0: mmc@4f80000 {
@@ -1055,7 +1081,7 @@
 		reg = <0x00 0x02900000 0x00 0x1000>,
 		      <0x00 0x02907000 0x00 0x400>,
 		      <0x00 0x0d000000 0x00 0x00800000>,
-		      <0x00 0x10000000 0x00 0x00001000>;
+		      <0x40 0x00000000 0x00 0x00001000>; /* ECAM (4 KB) */
 		reg-names = "intd_cfg", "user_cfg", "reg", "cfg";
 		interrupt-names = "link_state";
 		interrupts = <GIC_SPI 318 IRQ_TYPE_EDGE_RISING>;
@@ -1073,8 +1099,8 @@
 		device-id = <0xb012>;
 		msi-map = <0x0 &gic_its 0x0 0x10000>;
 		dma-coherent;
-		ranges = <0x01000000 0x0 0x10001000 0x0 0x10001000 0x0 0x0010000>,
-			 <0x02000000 0x0 0x10011000 0x0 0x10011000 0x0 0x7fef000>;
+		ranges = <0x01000000 0x00 0x00001000 0x40 0x00001000 0x00 0x00100000>, /* IO (1 MB) */
+			 <0x02000000 0x00 0x00101000 0x40 0x00101000 0x00 0xffeff000>; /* 32-bit Non-Prefetchable MEM (4 GB - 1 MB - 4 KB) */
 		dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
 		status = "disabled";
 	};
@@ -1084,7 +1110,7 @@
 		reg = <0x00 0x02910000 0x00 0x1000>,
 		      <0x00 0x02917000 0x00 0x400>,
 		      <0x00 0x0d800000 0x00 0x00800000>,
-		      <0x00 0x18000000 0x00 0x00001000>;
+		      <0x41 0x00000000 0x00 0x00001000>; /* ECAM (4 KB) */
 		reg-names = "intd_cfg", "user_cfg", "reg", "cfg";
 		interrupt-names = "link_state";
 		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
@@ -1093,8 +1119,8 @@
 		max-link-speed = <3>;
 		num-lanes = <4>;
 		power-domains = <&k3_pds 333 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 333 0>;
-		clock-names = "fck";
+		clocks = <&k3_clks 333 0>, <&serdes0 CDNS_TORRENT_REFCLK_DRIVER>;
+		clock-names = "fck", "pcie_refclk";
 		#address-cells = <3>;
 		#size-cells = <2>;
 		bus-range = <0x0 0xff>;
@@ -1102,9 +1128,10 @@
 		device-id = <0xb012>;
 		msi-map = <0x0 &gic_its 0x10000 0x10000>;
 		dma-coherent;
-		ranges = <0x01000000 0x0 0x18001000  0x00 0x18001000  0x0 0x0010000>,
-			 <0x02000000 0x0 0x18011000  0x00 0x18011000  0x0 0x7fef000>;
+		ranges = <0x01000000 0x00 0x00001000 0x41 0x00001000 0x00 0x00100000>, /* IO (1 MB) */
+			 <0x02000000 0x00 0x00101000 0x41 0x00101000 0x00 0xffeff000>; /* 32-bit Non-Prefetchable MEM (4 GB - 1 MB - 4 KB) */
 		dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
+		ti,syscon-acspcie-proxy-ctrl = <&acspcie0_proxy_ctrl 0x1>;
 		status = "disabled";
 	};
 
@@ -1235,6 +1262,14 @@
 		dma-coherent;
 		dma-ranges;
 
+		main_navss_sram: navss-sram@30000000{
+			compatible = "mmio-sram";
+			reg = <0x00 0x30000000 0x00 0x10000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x00 0x30000000 0x10000>;
+		};
+
 		main_navss_intr: interrupt-controller@310e0000 {
 			compatible = "ti,sci-intr";
 			reg = <0x00 0x310e0000 0x00 0x4000>;
@@ -2042,7 +2077,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 376 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 376 1>;
+		clocks = <&k3_clks 376 0>;
 		status = "disabled";
 	};
 
@@ -2053,7 +2088,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 377 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 377 1>;
+		clocks = <&k3_clks 377 0>;
 		status = "disabled";
 	};
 
@@ -2064,7 +2099,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 378 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 378 1>;
+		clocks = <&k3_clks 378 0>;
 		status = "disabled";
 	};
 
@@ -2075,7 +2110,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 379 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 379 1>;
+		clocks = <&k3_clks 379 0>;
 		status = "disabled";
 	};
 
@@ -2086,7 +2121,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 380 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 380 1>;
+		clocks = <&k3_clks 380 0>;
 		status = "disabled";
 	};
 
@@ -2097,7 +2132,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 381 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 381 1>;
+		clocks = <&k3_clks 381 0>;
 		status = "disabled";
 	};
 
@@ -2108,7 +2143,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 382 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 382 1>;
+		clocks = <&k3_clks 382 0>;
 		status = "disabled";
 	};
 
@@ -2119,7 +2154,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 383 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 383 1>;
+		clocks = <&k3_clks 383 0>;
 		status = "disabled";
 	};
 
@@ -2512,6 +2547,50 @@
 		status = "reserved";
 	};
 
+	dphy_tx0: phy@4480000 {
+		compatible = "ti,j721e-dphy";
+		reg = <0x0 0x04480000 0x0 0x1000>;
+		clocks = <&k3_clks 402 20>, <&k3_clks 402 3>;
+		clock-names = "psm", "pll_ref";
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 402 TI_SCI_PD_EXCLUSIVE>;
+		assigned-clocks = <&k3_clks 402 3>;
+		assigned-clock-parents = <&k3_clks 402 4>;
+		assigned-clock-rates = <19200000>;
+		status = "disabled";
+	};
+
+	dsi0: dsi@4800000 {
+		compatible = "ti,j721e-dsi";
+		reg = <0x0 0x04800000 0x0 0x100000>, <0x0 0x04710000 0x0 0x100>;
+		clocks = <&k3_clks 215 2>, <&k3_clks 215 5>;
+		clock-names = "dsi_p_clk", "dsi_sys_clk";
+		power-domains = <&k3_pds 215 TI_SCI_PD_EXCLUSIVE>;
+		interrupt-parent = <&gic500>;
+		interrupts = <GIC_SPI 600 IRQ_TYPE_LEVEL_HIGH>;
+		phys = <&dphy_tx0>;
+		phy-names = "dphy";
+		status = "disabled";
+
+		dsi0_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+			};
+			port@1 {
+				reg = <1>;
+			};
+		};
+	};
+
+	timesync_router: mux-controller@a40000 {
+		compatible = "reg-mux";
+		reg = <0x0 0xa40000 0x0 0x800>;
+		#mux-control-cells = <1>;
+		status = "disabled";
+	};
+
 	mhdp: bridge@a000000 {
 		compatible = "ti,j721e-mhdp8546";
 		reg = <0x0 0xa000000 0x0 0x30a00>,
@@ -2670,4 +2749,17 @@
 		power-domains = <&k3_pds 269 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 	};
+
+	gpu: gpu@4e20000000 {
+		compatible = "ti,j721s2-pvr", "img,pvr-bxs64";
+		reg = <0x4e 0x20000000 0x00 0x80000>;
+		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&k3_pds 181 TI_SCI_PD_EXCLUSIVE>,
+		                <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
+		power-domain-names = "firmware", "dust";
+		clocks = <&k3_clks 181 1>;
+		assigned-clocks = <&k3_clks 181 1>;
+		assigned-clock-rates = <800000000>;
+		clock-names = "core";
+	};
 };
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-mcu-wakeup-common.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-mcu-wakeup-common.dtsi
--- a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-mcu-wakeup-common.dtsi	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-mcu-wakeup-common.dtsi	2025-10-23 09:30:40.284462176 -0400
@@ -7,7 +7,6 @@
 
 &cbass_mcu_wakeup {
 	sms: system-controller@44083000 {
-		bootph-all;
 		compatible = "ti,k2g-sci";
 		ti,host-id = <12>;
 
@@ -39,7 +38,6 @@
 	};
 
 	wkup_conf: bus@43000000 {
-		bootph-all;
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -59,6 +57,8 @@
 		reg = <0x00 0x43600000 0x00 0x10000>,
 		      <0x00 0x44880000 0x00 0x20000>,
 		      <0x00 0x44860000 0x00 0x20000>;
+		bootph-pre-ram;
+
 		/*
 		 * Marked Disabled:
 		 * Node is incomplete as it is meant for bootloaders and
@@ -76,7 +76,7 @@
 	};
 
 	wkup_pmx0: pinctrl@4301c000 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		/* Proxy 0 addressing */
 		reg = <0x00 0x4301c000 0x00 0x034>;
 		#pinctrl-cells = <1>;
@@ -85,7 +85,7 @@
 	};
 
 	wkup_pmx1: pinctrl@4301c038 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		/* Proxy 0 addressing */
 		reg = <0x00 0x4301c038 0x00 0x02c>;
 		#pinctrl-cells = <1>;
@@ -94,7 +94,7 @@
 	};
 
 	wkup_pmx2: pinctrl@4301c068 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		/* Proxy 0 addressing */
 		reg = <0x00 0x4301c068 0x00 0x120>;
 		#pinctrl-cells = <1>;
@@ -103,7 +103,7 @@
 	};
 
 	wkup_pmx3: pinctrl@4301c190 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		/* Proxy 0 addressing */
 		reg = <0x00 0x4301c190 0x00 0x004>;
 		#pinctrl-cells = <1>;
@@ -125,7 +125,7 @@
 
 	/* MCU_TIMERIO pad input CTRLMMR_MCU_TIMER*_CTRL registers */
 	mcu_timerio_input: pinctrl@40f04200 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		reg = <0x00 0x40f04200 0x00 0x28>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
@@ -136,7 +136,7 @@
 
 	/* MCU_TIMERIO pad output CTRLMMR_MCU_TIMERIO*_CTRL registers */
 	mcu_timerio_output: pinctrl@40f04280 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		reg = <0x00 0x40f04280 0x00 0x28>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
@@ -172,13 +172,13 @@
 		assigned-clocks = <&k3_clks 35 2>;
 		assigned-clock-parents = <&k3_clks 35 3>;
 		power-domains = <&k3_pds 35 TI_SCI_PD_EXCLUSIVE>;
+		bootph-all;
 		ti,timer-pwm;
 		/* Non-MPU Firmware usage */
 		status = "reserved";
 	};
 
 	mcu_timer1: timer@40410000 {
-		bootph-all;
 		compatible = "ti,am654-timer";
 		reg = <0x00 0x40410000 0x00 0x400>;
 		interrupts = <GIC_SPI 817 IRQ_TYPE_LEVEL_HIGH>;
@@ -458,7 +458,6 @@
 	};
 
 	mcu_navss: bus@28380000 {
-		bootph-all;
 		compatible = "simple-bus";
 		#address-cells = <2>;
 		#size-cells = <2>;
@@ -515,6 +514,8 @@
 		reg = <0x00 0x2a480000 0x00 0x80000>,
 		      <0x00 0x2a380000 0x00 0x80000>,
 		      <0x00 0x2a400000 0x00 0x80000>;
+		bootph-pre-ram;
+
 		/*
 		 * Marked Disabled:
 		 * Node is incomplete as it is meant for bootloaders and
@@ -588,7 +589,7 @@
 
 	mcu_r5fss0: r5fss@41000000 {
 		compatible = "ti,j721s2-r5fss";
-		ti,cluster-mode = <1>;
+		ti,cluster-mode = <0>;
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges = <0x41000000 0x00 0x41000000 0x20000>,
@@ -632,6 +633,7 @@
 		      <0x00 0x42050000 0x00 0x350>;
 		power-domains = <&k3_pds 243 TI_SCI_PD_SHARED>;
 		#thermal-sensor-cells = <1>;
+		bootph-pre-ram;
 	};
 
 	tscadc0: tscadc@40200000 {
@@ -692,6 +694,7 @@
 			cdns,fifo-depth = <256>;
 			cdns,fifo-width = <4>;
 			cdns,trigger-address = <0x0>;
+			cdns,phase-detect-selector = <2>;
 			clocks = <&k3_clks 161 7>;
 			assigned-clocks = <&k3_clks 161 7>;
 			assigned-clock-parents = <&k3_clks 161 9>;
@@ -710,6 +713,7 @@
 			cdns,fifo-depth = <256>;
 			cdns,fifo-width = <4>;
 			cdns,trigger-address = <0x0>;
+			cdns,phase-detect-selector = <2>;
 			clocks = <&k3_clks 162 7>;
 			power-domains = <&k3_pds 162 TI_SCI_PD_EXCLUSIVE>;
 			#address-cells = <1>;
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-pinctrl.h b/arch/arm64/boot/dts/ti/k3-pinctrl.h
--- a/arch/arm64/boot/dts/ti/k3-pinctrl.h	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/k3-pinctrl.h	2025-10-23 09:30:40.284462176 -0400
@@ -12,6 +12,14 @@
 #define PULLTYPESEL_SHIFT	(17)
 #define RXACTIVE_SHIFT		(18)
 #define DEBOUNCE_SHIFT		(11)
+#define FORCE_DS_EN_SHIFT	(15)
+#define TXDISABLE_SHIFT		(21)
+#define DS_EN_SHIFT		(24)
+#define DS_OUT_DIS_SHIFT	(25)
+#define DS_OUT_VAL_SHIFT	(26)
+#define DS_PULLUD_EN_SHIFT	(27)
+#define DS_PULLTYPE_SEL_SHIFT	(28)
+#define WKUP_EN_SHIFT		(29)
 
 #define PULL_DISABLE		(1 << PULLUDEN_SHIFT)
 #define PULL_ENABLE		(0 << PULLUDEN_SHIFT)
@@ -29,6 +37,7 @@
 #define PIN_INPUT		(INPUT_EN | PULL_DISABLE)
 #define PIN_INPUT_PULLUP	(INPUT_EN | PULL_UP)
 #define PIN_INPUT_PULLDOWN	(INPUT_EN | PULL_DOWN)
+#define PIN_DISABLE		(1 << TXDISABLE_SHIFT)
 
 #define PIN_DEBOUNCE_DISABLE	(0 << DEBOUNCE_SHIFT)
 #define PIN_DEBOUNCE_CONF1	(1 << DEBOUNCE_SHIFT)
@@ -38,15 +47,35 @@
 #define PIN_DEBOUNCE_CONF5	(5 << DEBOUNCE_SHIFT)
 #define PIN_DEBOUNCE_CONF6	(6 << DEBOUNCE_SHIFT)
 
+#define PIN_DS_FORCE_DISABLE		(0 << FORCE_DS_EN_SHIFT)
+#define PIN_DS_FORCE_ENABLE		(1 << FORCE_DS_EN_SHIFT)
+#define PIN_DS_IO_OVERRIDE_DISABLE	(0 << DS_IO_OVERRIDE_EN_SHIFT)
+#define PIN_DS_IO_OVERRIDE_ENABLE	(1 << DS_IO_OVERRIDE_EN_SHIFT)
+#define PIN_DS_OUT_ENABLE		(0 << DS_OUT_DIS_SHIFT)
+#define PIN_DS_OUT_DISABLE		(1 << DS_OUT_DIS_SHIFT)
+#define PIN_DS_OUT_VALUE_ZERO		(0 << DS_OUT_VAL_SHIFT)
+#define PIN_DS_OUT_VALUE_ONE		(1 << DS_OUT_VAL_SHIFT)
+#define PIN_DS_PULLUD_ENABLE		(0 << DS_PULLUD_EN_SHIFT)
+#define PIN_DS_PULLUD_DISABLE		(1 << DS_PULLUD_EN_SHIFT)
+#define PIN_DS_PULL_DOWN		(0 << DS_PULLTYPE_SEL_SHIFT)
+#define PIN_DS_PULL_UP			(1 << DS_PULLTYPE_SEL_SHIFT)
+
+#define WKUP_EN			(1 << WKUP_EN_SHIFT)
+
 /* Default mux configuration for gpio-ranges to use with pinctrl */
 #define PIN_GPIO_RANGE_IOPAD	(PIN_INPUT | 7)
 
 #define AM62AX_IOPAD(pa, val, muxmode)		(((pa) & 0x1fff)) ((val) | (muxmode))
 #define AM62AX_MCU_IOPAD(pa, val, muxmode)	(((pa) & 0x1fff)) ((val) | (muxmode))
 
+#define AM62DX_IOPAD(pa, val, muxmode)		(((pa) & 0x1fff)) ((val) | (muxmode))
+#define AM62DX_MCU_IOPAD(pa, val, muxmode)	(((pa) & 0x1fff)) ((val) | (muxmode))
+
 #define AM62PX_IOPAD(pa, val, muxmode)		(((pa) & 0x1fff)) ((val) | (muxmode))
 #define AM62PX_MCU_IOPAD(pa, val, muxmode)	(((pa) & 0x1fff)) ((val) | (muxmode))
 
+#define AM62LX_IOPAD(pa, val, muxmode)		(((pa) & 0x1fff)) ((val) | (muxmode))
+
 #define AM62X_IOPAD(pa, val, muxmode)		(((pa) & 0x1fff)) ((val) | (muxmode))
 #define AM62X_MCU_IOPAD(pa, val, muxmode)	(((pa) & 0x1fff)) ((val) | (muxmode))
 
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-timesync-router.h b/arch/arm64/boot/dts/ti/k3-timesync-router.h
--- a/arch/arm64/boot/dts/ti/k3-timesync-router.h	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-timesync-router.h	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/*
+ * This header provides headers for Timesync Router
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef DTS_ARM64_TI_K3_TIMESYNC_ROUTER
+#define DTS_ARM64_TI_K3_TIMESYNC_ROUTER
+
+/*
+ * The value of the input to be mapped to an output has to be written in
+ * the register corresponding to the output.
+ * INT_ENABLE which is BIT(16) i.e. 0x10000 has to be set in addition to
+ * writing the value of the input in order to begin generating the output
+ * signal.
+ */
+#define K3_TS_OFFSET(output_index, mask, input_index)   (((0x4 + ((output_index) * 4)))) ((mask)) ((0x10000 | (input_index)))
+
+#endif /* DTS_ARM64_TI_K3_TIMESYNC_ROUTER */
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-0.dtso b/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-0.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-0.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX219 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_00: imx219-xclk-00 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 0 */
+	port@0 {
+		reg = <0>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@0 {
+		reg = <0>;
+		i2c-alias = <0x44>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@10 {
+					compatible = "sony,imx219";
+					reg = <0x10>;
+
+					clocks = <&clk_imx219_fixed_00>;
+					clock-names = "xclk";
+					reset-gpios = <&serializer 1 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							link-frequencies = /bits/ 64 <456000000>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-1.dtso b/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-1.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-1.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX219 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_01: imx219-xclk-01 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 1 */
+	port@1 {
+		reg = <1>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@1 {
+		reg = <1>;
+		i2c-alias = <0x45>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@10 {
+					compatible = "sony,imx219";
+					reg = <0x10>;
+
+					clocks = <&clk_imx219_fixed_01>;
+					clock-names = "xclk";
+					reset-gpios = <&serializer 1 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							link-frequencies = /bits/ 64 <456000000>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-2.dtso b/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-2.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-2.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX219 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_02: imx219-xclk-02 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 2 */
+	port@2 {
+		reg = <2>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@2 {
+		reg = <2>;
+		i2c-alias = <0x46>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@10 {
+					compatible = "sony,imx219";
+					reg = <0x10>;
+
+					clocks = <&clk_imx219_fixed_02>;
+					clock-names = "xclk";
+					reset-gpios = <&serializer 1 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							link-frequencies = /bits/ 64 <456000000>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-3.dtso b/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-3.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-3.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-3.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX219 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_03: imx219-xclk-03 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 3 */
+	port@3 {
+		reg = <3>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@3 {
+		reg = <3>;
+		i2c-alias = <0x47>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@10 {
+					compatible = "sony,imx219";
+					reg = <0x10>;
+
+					clocks = <&clk_imx219_fixed_03>;
+					clock-names = "xclk";
+					reset-gpios = <&serializer 1 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							link-frequencies = /bits/ 64 <456000000>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-0.dtso b/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-0.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-0.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX219 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_10: imx219-xclk-10 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 0 */
+	port@0 {
+		reg = <0>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_1_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@0 {
+		reg = <0>;
+		i2c-alias = <0x54>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@10 {
+					compatible = "sony,imx219";
+					reg = <0x10>;
+
+					clocks = <&clk_imx219_fixed_10>;
+					clock-names = "xclk";
+					reset-gpios = <&serializer 1 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							link-frequencies = /bits/ 64 <456000000>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-1.dtso b/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-1.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-1.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX219 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_11: imx219-xclk-11 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 1 */
+	port@1 {
+		reg = <1>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_1_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@1 {
+		reg = <1>;
+		i2c-alias = <0x55>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@10 {
+					compatible = "sony,imx219";
+					reg = <0x10>;
+
+					clocks = <&clk_imx219_fixed_11>;
+					clock-names = "xclk";
+					reset-gpios = <&serializer 1 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							link-frequencies = /bits/ 64 <456000000>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-2.dtso b/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-2.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-2.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX219 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_12: imx219-xclk-12 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 2 */
+	port@2 {
+		reg = <2>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_1_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@2 {
+		reg = <2>;
+		i2c-alias = <0x56>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@10 {
+					compatible = "sony,imx219";
+					reg = <0x10>;
+
+					clocks = <&clk_imx219_fixed_12>;
+					clock-names = "xclk";
+					reset-gpios = <&serializer 1 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							link-frequencies = /bits/ 64 <456000000>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-3.dtso b/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-3.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-3.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-imx219-1-3.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX219 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_13: imx219-xclk-13 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_1_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 3 */
+	port@3 {
+		reg = <3>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_1_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@3 {
+		reg = <3>;
+		i2c-alias = <0x57>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@10 {
+					compatible = "sony,imx219";
+					reg = <0x10>;
+
+					clocks = <&clk_imx219_fixed_13>;
+					clock-names = "xclk";
+					reset-gpios = <&serializer 1 GPIO_ACTIVE_HIGH>;
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							link-frequencies = /bits/ 64 <456000000>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-0.dtso b/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-0.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-0.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OV5640 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_00: imx219-xclk-00 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 0 */
+	port@0 {
+		reg = <0>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@0 {
+		reg = <0>;
+		i2c-alias = <0x44>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			p0-hog {
+				gpio-hog;
+				gpios = <0 GPIO_ACTIVE_HIGH>;
+				output-high;
+				line-name = "MIPI_CSI_INPUT_GPIO0";
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@3c {
+					compatible = "ovti,ov5640";
+					reg = <0x3c>;
+
+					clocks = <&clk_imx219_fixed_00>;
+					clock-names = "xclk";
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-1.dtso b/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-1.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-1.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OV5640 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_01: imx219-xclk-01 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 1 */
+	port@1 {
+		reg = <1>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@1 {
+		reg = <1>;
+		i2c-alias = <0x45>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			p0-hog {
+				gpio-hog;
+				gpios = <0 GPIO_ACTIVE_HIGH>;
+				output-high;
+				line-name = "MIPI_CSI_INPUT_GPIO0";
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@3c {
+					compatible = "ovti,ov5640";
+					reg = <0x3c>;
+
+					clocks = <&clk_imx219_fixed_01>;
+					clock-names = "xclk";
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-2.dtso b/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-2.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-2.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OV5640 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_02: imx219-xclk-02 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 2 */
+	port@2 {
+		reg = <2>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@2 {
+		reg = <2>;
+		i2c-alias = <0x46>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			p0-hog {
+				gpio-hog;
+				gpios = <0 GPIO_ACTIVE_HIGH>;
+				output-high;
+				line-name = "MIPI_CSI_INPUT_GPIO0";
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@3c {
+					compatible = "ovti,ov5640";
+					reg = <0x3c>;
+
+					clocks = <&clk_imx219_fixed_02>;
+					clock-names = "xclk";
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-3.dtso b/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-3.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-3.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-ov5640-0-3.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OV5640 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_03: imx219-xclk-03 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 3 */
+	port@3 {
+		reg = <3>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@3 {
+		reg = <3>;
+		i2c-alias = <0x47>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			p0-hog {
+				gpio-hog;
+				gpios = <0 GPIO_ACTIVE_HIGH>;
+				output-high;
+				line-name = "MIPI_CSI_INPUT_GPIO0";
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@3c {
+					compatible = "ovti,ov5640";
+					reg = <0x3c>;
+
+					clocks = <&clk_imx219_fixed_03>;
+					clock-names = "xclk";
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-0.dtso b/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-0.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-0.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-0.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OV5640 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_00: imx219-xclk-00 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 0 */
+	port@0 {
+		reg = <0>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@0 {
+		reg = <0>;
+		i2c-alias = <0x44>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			p0-hog {
+				gpio-hog;
+				gpios = <0 GPIO_ACTIVE_HIGH>;
+				output-high;
+				line-name = "MIPI_CSI_INPUT_GPIO0";
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@3c {
+					compatible = "ovti,ov5640";
+					reg = <0x3c>;
+
+					clocks = <&clk_imx219_fixed_00>;
+					clock-names = "xclk";
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-1.dtso b/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-1.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-1.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-1.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OV5640 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_01: imx219-xclk-01 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 1 */
+	port@1 {
+		reg = <1>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@1 {
+		reg = <1>;
+		i2c-alias = <0x45>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			p0-hog {
+				gpio-hog;
+				gpios = <0 GPIO_ACTIVE_HIGH>;
+				output-high;
+				line-name = "MIPI_CSI_INPUT_GPIO0";
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@3c {
+					compatible = "ovti,ov5640";
+					reg = <0x3c>;
+
+					clocks = <&clk_imx219_fixed_01>;
+					clock-names = "xclk";
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-2.dtso b/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-2.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-2.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-2.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OV5640 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_02: imx219-xclk-02 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 2 */
+	port@2 {
+		reg = <2>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@2 {
+		reg = <2>;
+		i2c-alias = <0x46>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			p0-hog {
+				gpio-hog;
+				gpios = <0 GPIO_ACTIVE_HIGH>;
+				output-high;
+				line-name = "MIPI_CSI_INPUT_GPIO0";
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@3c {
+					compatible = "ovti,ov5640";
+					reg = <0x3c>;
+
+					clocks = <&clk_imx219_fixed_02>;
+					clock-names = "xclk";
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-3.dtso b/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-3.dtso
--- a/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-3.dtso	1969-12-31 19:00:00.000000000 -0500
+++ b/arch/arm64/boot/dts/ti/k3-v3link-tevi-ov5640-0-3.dtso	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OV5640 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	clk_imx219_fixed_03: imx219-xclk-03 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&deserializer_0_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	/* FPDLink RX 3 */
+	port@3 {
+		reg = <3>;
+
+		ub960_fpd3_1_in: endpoint {
+			remote-endpoint = <&ub953_1_out>;
+		};
+	};
+};
+
+&deserializer_0_links {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	link@3 {
+		reg = <3>;
+		i2c-alias = <0x47>;
+
+		ti,rx-mode = <3>;
+
+		serializer: serializer {
+			compatible = "ti,ds90ub953-q1";
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			#clock-cells = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ub953_1_in: endpoint {
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						remote-endpoint = <&sensor_1_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ub953_1_out: endpoint {
+						remote-endpoint = <&ub960_fpd3_1_in>;
+					};
+				};
+			};
+
+			p0-hog {
+				gpio-hog;
+				gpios = <0 GPIO_ACTIVE_HIGH>;
+				output-high;
+				line-name = "MIPI_CSI_INPUT_GPIO0";
+			};
+
+			i2c {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sensor@3c {
+					compatible = "ovti,ov5640";
+					reg = <0x3c>;
+
+					clocks = <&clk_imx219_fixed_03>;
+					clock-names = "xclk";
+
+					port {
+						sensor_1_out: endpoint {
+							remote-endpoint = <&ub953_1_in>;
+							clock-lanes = <0>;
+							data-lanes = <1 2>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff -Naur --no-dereference a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
--- a/arch/arm64/boot/dts/ti/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/boot/dts/ti/Makefile	2025-10-23 09:30:40.282462115 -0400
@@ -12,47 +12,107 @@
 dtb-$(CONFIG_ARCH_K3) += k3-am625-beagleplay.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-beagleplay-csi2-ov5640.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am625-beagleplay-csi2-tevi-ov5640.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am625-beagleplay-lincolntech-lcd185-panel.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am625-phyboard-lyra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am625-sk-lincolntech-lcd185-panel.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am625-sk-microtips-mf101hie-panel.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am625-sk-m2-cc3351.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am625-sk-rpi-hdr-ehrpwm.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-nonwifi-dahlia.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-nonwifi-dev.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-nonwifi-ivy.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-nonwifi-mallow.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-nonwifi-yavia.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dahlia.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dev.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-ivy.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-mallow.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-yavia.dtb
-dtb-$(CONFIG_ARCH_K3) += k3-am625-phyboard-lyra-1-4-ghz-opp.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am62x-phyboard-lyra-gpio-fan.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk-e3-max-opp.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk-lincolntech-lcd185-panel.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk-microtips-mf101hie-panel.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk-nand.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am625-sk-mcspi-loopback.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am6254xxl-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62-pocketbeagle2.dtb
 
 # Boards with AM62Ax SoC
+k3-am62a7-sk-ub954-evm-ov2312-dtbs := k3-am62a7-sk.dtb \
+				      k3-am62a7-sk-ub954-evm.dtbo \
+				      k3-fpdlink-ov2312-0-0.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk-csi2-ox05b1s.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk-m2-cc3351.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am62a7-phyboard-lyra-rdk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk-ethernet-dc01.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk-fusion.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk-rpi-hdr-ehrpwm.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk-fusion-2.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk-edgeai.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk-ub954-evm-ov2312.dtb
+
+# Boards with AM62Dx SoC
+dtb-$(CONFIG_ARCH_K3) += k3-am62d2-evm.dtb
+
+# Boards with AM62Lx SoCs
+dtb-$(CONFIG_ARCH_K3) += k3-am62l3-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62l3-evm-lpmdemo.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62l3-evm-dsi-rpi-7inch-panel.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62l3-evm-ecap-capture.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62l3-evm-eqep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62l3-evm-m2-cc3351.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62l3-evm-nand.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62l3-evm-pwm.dtbo
 
 # Boards with AM62Px SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk-ecap-capture.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk-eqep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk-ethfw.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk-m2-cc3351.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk-dsi-rpi-7inch-panel.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk-dss-shared-mode.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk-mcan.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk-microtips-mf101hie-panel.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk-microtips-mf103hie-lcd2.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk-microtips-mf070zima-lcd3.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk-rpi-hdr-ehrpwm.dtbo
 
 # Common overlays for SK-AM62* family of boards
 dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-csi2-ov5640.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-csi2-tevi-ov5640.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-csi2-imx219.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-csi2-v3link-fusion.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-dmtimer-pwm.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-ecap-capture.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-eqep.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-hdmi-audio.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-microtips-mf103hie-lcd2.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-mcan.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-pwm.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-lpm-wkup-sources.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-lpm-io-ddr-wkup-sources.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-fastboot-disable-hdmi.dtbo
 
 # Boards with AM64x SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-icssg1-dualemac.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-icssg1-dualemac-mii.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-pcie0-ep.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-pcie.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-usb3.dtb
 k3-am642-evm-nand-dtbs := k3-am642-evm.dtb k3-am642-evm-nand.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-nand.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-sk-cpsw3g-pps.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-gpio-fan.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-pcie-usb2.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-sk-pwm.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
@@ -82,6 +142,7 @@
 dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-pg2.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-sm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am654-evm-oldi-lcd1evm.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am654-gp-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-idk.dtb
@@ -92,43 +153,83 @@
 # Boards with J7200 SoC
 k3-j7200-evm-dtbs := k3-j7200-common-proc-board.dtb k3-j7200-evm-quad-port-eth-exp.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j7200-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j7200-evm-ethfw.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j7200-evm-pcie1-ep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j7200-evm-mcspi-loopback.dtbo
 
 # Boards with J721e SoC
 k3-j721e-evm-dtbs := k3-j721e-common-proc-board.dtb k3-j721e-evm-quad-port-eth-exp.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-dsi-rpi-7inch-panel.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-microtips-mf070zima-lcd3.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-common-proc-board-infotainment.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-ethfw.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-fusion.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-csi2-ov5640.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-gesi-exp-board.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie-ntb.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-ep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie1-ep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-ub954.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-csi2-ov5640.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-csi2-dual-imx219.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-fpdlink-fusion.dtbo
 
 # Boards with J721s2 SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-bb-csi2-ov5640.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board-pcie1-ep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-v3link-fusion.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-v3link-fusion-dual-csitx.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721s2-common-proc-board.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-fusion.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-csi2-ov5640.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-gesi-exp-board.dtbo
 k3-j721s2-evm-dtbs := k3-j721s2-common-proc-board.dtb k3-j721s2-evm-gesi-exp-board.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-pcie1-ep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-ub954.dtbo
 
 # Boards with J722s SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-csi2-quad-tevi-ov5640.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-dsi-rpi-7inch-panel.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-fpdlink-fusion.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-fpdlink-iv-fusion.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-microtips-mf101hie-panel.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-pwm.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-v3link-fusion.dtbo
 
 # Boards with J784s4 SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am69-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am69-sk-csi2-ov5640.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am69-sk-fpdlink-fusion-auxport.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am69-sk-pcie0-ep.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-csi2-ov5640.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-ethfw.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-fpdlink-iv-fusion.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-pcie0-pcie1-ep.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-quad-port-eth-exp1.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-usxgmii-exp1-exp2.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j784s4-j742s2-evm-pcie-ntb.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j784s4-j742s2-evm-usb0-type-a.dtbo
+
+# Boards with J742S2 SoC
+dtb-$(CONFIG_ARCH_K3) += k3-j742s2-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j742s2-evm-ethfw.dtbo
 
 # Build time test only, enabled by CONFIG_OF_ALL_DTBS
 k3-am625-beagleplay-csi2-ov5640-dtbs := k3-am625-beagleplay.dtb \
 	k3-am625-beagleplay-csi2-ov5640.dtbo
 k3-am625-beagleplay-csi2-tevi-ov5640-dtbs := k3-am625-beagleplay.dtb \
 	k3-am625-beagleplay-csi2-tevi-ov5640.dtbo
-k3-am625-phyboard-lyra-1-4-ghz-opp.dtbs := k3-am625-phyboard-lyra-rdk.dtb \
-	k3-am625-phyboard-lyra-1-4-ghz-opp.dtbo
+k3-am625-beagleplay-lincolntech-lcd185-panel-dtbs := k3-am625-beagleplay.dtb \
+	k3-am625-beagleplay-lincolntech-lcd185-panel.dtbo
 k3-am625-phyboard-lyra-disable-eth-phy-dtbs := k3-am625-phyboard-lyra-rdk.dtb \
 	k3-am6xx-phycore-disable-eth-phy.dtbo
 k3-am625-phyboard-lyra-disable-rtc-dtbs := k3-am625-phyboard-lyra-rdk.dtb \
@@ -145,14 +246,34 @@
 	k3-am62x-sk-csi2-ov5640.dtbo
 k3-am625-sk-csi2-tevi-ov5640-dtbs := k3-am625-sk.dtb \
 	k3-am62x-sk-csi2-tevi-ov5640.dtbo
+k3-am625-sk-fastboot-disable-hdmi-dtbs := k3-am625-sk.dtb \
+	k3-am62x-sk-fastboot-disable-hdmi.dtbo
 k3-am625-sk-hdmi-audio-dtbs := k3-am625-sk.dtb k3-am62x-sk-hdmi-audio.dtbo
+k3-am625-sk-lincolntech-lcd185-panel-dtbs := k3-am625-sk.dtb \
+	k3-am625-sk-lincolntech-lcd185-panel.dtbo
+k3-am625-sk-microtips-mf101hie-panel-dtbs := k3-am625-sk.dtb \
+	k3-am625-sk-microtips-mf101hie-panel.dtbo
+k3-am625-sk-microtips-mf103hie-lcd2-dtbs := k3-am625-sk.dtb \
+	k3-am62x-sk-microtips-mf103hie-lcd2.dtbo
+k3-am62-lp-sk-fastboot-disable-hdmi-dtbs := k3-am62-lp-sk.dtb \
+	k3-am62x-sk-fastboot-disable-hdmi.dtbo
 k3-am62-lp-sk-hdmi-audio-dtbs := k3-am62-lp-sk.dtb k3-am62x-sk-hdmi-audio.dtbo
+k3-am62-lp-sk-lincolntech-lcd185-panel-dtbs := k3-am62-lp-sk.dtb \
+	k3-am62-lp-sk-lincolntech-lcd185-panel.dtbo
+k3-am62-lp-sk-microtips-mf101hie-panel-dtbs := k3-am62-lp-sk.dtb \
+	k3-am62-lp-sk-microtips-mf101hie-panel.dtbo
+k3-am62-lp-sk-microtips-mf103hie-lcd2-dtbs := k3-am62-lp-sk.dtb \
+	k3-am62x-sk-microtips-mf103hie-lcd2.dtbo
 k3-am62a7-sk-csi2-imx219-dtbs := k3-am62a7-sk.dtb \
 	k3-am62x-sk-csi2-imx219.dtbo
 k3-am62a7-sk-csi2-ov5640-dtbs := k3-am62a7-sk.dtb \
 	k3-am62x-sk-csi2-ov5640.dtbo
 k3-am62a7-sk-csi2-tevi-ov5640-dtbs := k3-am62a7-sk.dtb \
 	k3-am62x-sk-csi2-tevi-ov5640.dtbo
+k3-am62a7-sk-ethernet-dc01-dtbs := k3-am62a7-sk.dtb \
+	k3-am62a7-sk-ethernet-dc01.dtbo
+k3-am62a7-sk-fastboot-disable-hdmi-dtbs := k3-am62a7-sk.dtb \
+	k3-am62x-sk-fastboot-disable-hdmi.dtbo
 k3-am62a7-sk-hdmi-audio-dtbs := k3-am62a7-sk.dtb k3-am62x-sk-hdmi-audio.dtbo
 k3-am62p5-sk-csi2-imx219-dtbs := k3-am62p5-sk.dtb \
 	k3-am62x-sk-csi2-imx219.dtbo
@@ -160,10 +281,26 @@
 	k3-am62x-sk-csi2-ov5640.dtbo
 k3-am62p5-sk-csi2-tevi-ov5640-dtbs := k3-am62p5-sk.dtb \
 	k3-am62x-sk-csi2-tevi-ov5640.dtbo
+k3-am62p5-sk-ethfw-dtbs := k3-am62p5-sk.dtb \
+	k3-am62p5-sk-ethfw.dtbo
+k3-am62p5-sk-dsi-rpi-7inch-panel-dtbs := k3-am62p5-sk.dtb \
+	k3-am62p5-sk-dsi-rpi-7inch-panel.dtbo
+k3-am62p5-sk-dss-shared-mode-dtbs := k3-am62p5-sk.dtb \
+	k3-am62p5-sk-dss-shared-mode.dtbo
+k3-am62p5-sk-fastboot-disable-hdmi-dtbs := k3-am62p5-sk.dtb \
+	k3-am62x-sk-fastboot-disable-hdmi.dtbo
+k3-am62p5-sk-microtips-mf101hie-panel-dtbs := k3-am62p5-sk.dtb \
+	k3-am62p5-sk-microtips-mf101hie-panel.dtbo
+k3-am62p5-sk-microtips-mf103hie-lcd2-dtbs := k3-am62p5-sk.dtb \
+	k3-am62p5-sk-microtips-mf103hie-lcd2.dtbo
+k3-am62p5-sk-microtips-mf070zima-lcd3-dtbs := k3-am62p5-sk.dtb \
+	k3-am62p5-sk-microtips-mf070zima-lcd3.dtbo
 k3-am642-evm-icssg1-dualemac-dtbs := \
 	k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac.dtbo
 k3-am642-evm-icssg1-dualemac-mii-dtbs := \
 	k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac-mii.dtbo
+k3-am642-evm-pcie0-ep-dtbs := \
+	k3-am642-evm.dtb k3-am642-evm-pcie0-ep.dtbo
 k3-am642-phyboard-electra-disable-eth-phy-dtbs := \
 	k3-am642-phyboard-electra-rdk.dtb k3-am6xx-phycore-disable-eth-phy.dtbo
 k3-am642-phyboard-electra-disable-rtc-dtbs := \
@@ -176,61 +313,282 @@
 	k3-am642-phyboard-electra-rdk.dtb k3-am642-phyboard-electra-gpio-fan.dtbo
 k3-am642-phyboard-electra-pcie-usb2-dtbs := \
 	k3-am642-phyboard-electra-rdk.dtb k3-am642-phyboard-electra-pcie-usb2.dtbo
+k3-am642-evm-cpsw3g-pps-dtbs := \
+	k3-am642-evm.dtb k3-am642-evm-sk-cpsw3g-pps.dtbo
+k3-am642-sk-cpsw3g-pps-dtbs := \
+	k3-am642-sk.dtb k3-am642-evm-sk-cpsw3g-pps.dtbo
 k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
 k3-am68-sk-base-board-csi2-dual-imx219-dtbs := k3-am68-sk-base-board.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtbo
+k3-am68-sk-base-board-pcie1-ep-dtbs := k3-am68-sk-base-board.dtb \
+	k3-am68-sk-base-board-pcie1-ep.dtbo
+k3-am68-sk-base-board-v3link-fusion-dual-csitx-dtbs := k3-am68-sk-base-board.dtb \
+	k3-am68-sk-v3link-fusion-dual-csitx.dtbo
 k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtbo
+k3-am69-sk-pcie0-ep-dtbs := k3-am69-sk.dtb \
+	k3-am69-sk-pcie0-ep.dtbo
+k3-am69-sk-v3link-fusion-dual-csitx-dtbs := k3-am69-sk.dtb \
+	k3-am68-sk-v3link-fusion-dual-csitx.dtbo
+k3-j7200-evm-ethfw-dtbs := k3-j7200-common-proc-board.dtb \
+	k3-j7200-evm-ethfw.dtbo
+k3-j7200-evm-mcspi-loopback-dtbs := k3-j7200-common-proc-board.dtb \
+	k3-j7200-evm-mcspi-loopback.dtbo
+k3-j7200-evm-pcie1-ep-dtbs := k3-j7200-common-proc-board.dtb \
+	k3-j7200-evm-pcie1-ep.dtbo
+k3-j721e-beagleboneai64-dsi-rpi-7inch-panel-dtbs := k3-j721e-beagleboneai64.dtb \
+	k3-j721e-beagleboneai64-dsi-rpi-7inch-panel.dtbo
+k3-j721e-beagleboneai64-microtips-mf070zima-lcd3-dtbs := k3-j721e-beagleboneai64.dtb \
+	k3-j721e-beagleboneai64-microtips-mf070zima-lcd3.dtbo
 k3-j721e-common-proc-board-infotainment-dtbs := k3-j721e-common-proc-board.dtb \
 	k3-j721e-common-proc-board-infotainment.dtbo
+k3-j721e-evm-ethfw-dtbs := k3-j721e-common-proc-board.dtb \
+	k3-j721e-evm-ethfw.dtbo
+k3-j721e-evm-mcspi-loopback-dtbs := k3-j721e-common-proc-board.dtb \
+	k3-j7200-evm-mcspi-loopback.dtbo
+k3-j721e-evm-pcie-ntb-dtbs := k3-j721e-common-proc-board.dtb \
+	k3-j721e-evm-pcie-ntb.dtbo
 k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
 	k3-j721e-evm-pcie0-ep.dtbo
+k3-j721e-evm-pcie1-ep-dtbs := k3-j721e-common-proc-board.dtb \
+	k3-j721e-evm-pcie1-ep.dtbo
 k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtbo
 k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
 	k3-j721s2-evm-pcie1-ep.dtbo
+k3-j721s2-evm-mcspi-loopback-dtbs := k3-j721s2-common-proc-board.dtb \
+	k3-j7200-evm-mcspi-loopback.dtbo
+k3-j722s-evm-fpdlink-fusion-dtbs := k3-j722s-evm.dtb \
+	k3-j722s-evm-fpdlink-fusion.dtbo
+k3-j722s-evm-fpdlink-iv-fusion-dtbs := k3-j722s-evm.dtb \
+	k3-j722s-evm-fpdlink-iv-fusion.dtbo
+k3-j722s-evm-csi2-quad-rpi-cam-imx219-dtbs := k3-j722s-evm.dtb \
+	k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtbo
+k3-j722s-evm-csi2-quad-tevi-ov5640-dtbs := k3-j722s-evm.dtb \
+	k3-j722s-evm-csi2-quad-tevi-ov5640.dtbo
+k3-j722s-evm-dsi-rpi-7inch-panel-dtbs := k3-j722s-evm.dtb \
+	k3-j722s-evm-dsi-rpi-7inch-panel.dtbo
+k3-j722s-evm-microtips-mf101hie-panel-dtbs := k3-j722s-evm.dtb \
+	k3-j722s-evm-microtips-mf101hie-panel.dtbo
+k3-j722s-evm-v3link-fusion-dtbs := k3-j722s-evm.dtb \
+	k3-j722s-evm-v3link-fusion.dtbo
+k3-j742s2-evm-ethfw-dtbs := k3-j742s2-evm.dtb \
+	k3-j742s2-evm-ethfw.dtbo
+k3-j742s2-evm-mcspi-loopback-dtbs := k3-j742s2-evm.dtb \
+	k3-j7200-evm-mcspi-loopback.dtbo
+k3-j784s4-evm-mcspi-loopback-dtbs := k3-j784s4-evm.dtb \
+	k3-j7200-evm-mcspi-loopback.dtbo
+k3-j742s2-evm-pcie-ntb-dtbs := k3-j742s2-evm.dtb \
+	k3-j784s4-j742s2-evm-pcie-ntb.dtbo
+k3-j742s2-evm-usb0-type-a-dtbs := k3-j742s2-evm.dtb \
+	k3-j784s4-j742s2-evm-usb0-type-a.dtbo
+k3-j784s4-evm-ethfw-dtbs := k3-j784s4-evm.dtb \
+	k3-j784s4-evm-ethfw.dtbo
+k3-j784s4-evm-fpdlink-iv-fusion-dtbs := k3-j784s4-evm.dtb \
+	k3-j784s4-evm-fpdlink-iv-fusion.dtbo
+k3-j784s4-evm-pcie-ntb-dtbs := k3-j784s4-evm.dtb \
+	k3-j784s4-j742s2-evm-pcie-ntb.dtbo
 k3-j784s4-evm-pcie0-pcie1-ep-dtbs := k3-j784s4-evm.dtb \
 	k3-j784s4-evm-pcie0-pcie1-ep.dtbo
 k3-j784s4-evm-quad-port-eth-exp1-dtbs := k3-j784s4-evm.dtb \
 	k3-j784s4-evm-quad-port-eth-exp1.dtbo
+k3-j784s4-evm-usb0-type-a-dtbs := k3-j784s4-evm.dtb \
+	k3-j784s4-j742s2-evm-usb0-type-a.dtbo
 k3-j784s4-evm-usxgmii-exp1-exp2-dtbs := k3-j784s4-evm.dtb \
 	k3-j784s4-evm-usxgmii-exp1-exp2.dtbo
+k3-am62l3-evm-dsi-rpi-7inch-panel-dtbs := k3-am62l3-evm.dtb \
+	k3-am62l3-evm-dsi-rpi-7inch-panel.dtbo
+k3-am62l3-evm-nand-dtbs := k3-am62l3-evm.dtb \
+	k3-am62l3-evm-nand.dtbo
+
 dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am625-beagleplay-csi2-tevi-ov5640.dtb \
+	k3-am625-beagleplay-lincolntech-lcd185-panel.dtb \
 	k3-am625-sk-csi2-imx219.dtb \
 	k3-am625-sk-csi2-ov5640.dtb \
 	k3-am625-sk-csi2-tevi-ov5640.dtb \
+	k3-am625-sk-fastboot-disable-hdmi.dtb \
 	k3-am625-sk-hdmi-audio.dtb \
+	k3-am625-sk-lincolntech-lcd185-panel.dtb \
+	k3-am625-sk-microtips-mf101hie-panel.dtb \
+	k3-am625-sk-microtips-mf103hie-lcd2.dtb \
+	k3-am62-lp-sk-fastboot-disable-hdmi.dtb \
 	k3-am62-lp-sk-hdmi-audio.dtb \
+	k3-am62-lp-sk-lincolntech-lcd185-panel.dtb \
+	k3-am62-lp-sk-microtips-mf101hie-panel.dtb \
+	k3-am62-lp-sk-microtips-mf103hie-lcd2.dtb \
 	k3-am62a7-sk-csi2-imx219.dtb \
 	k3-am62a7-sk-csi2-ov5640.dtb \
+	k3-am62a7-sk-fastboot-disable-hdmi.dtb \
 	k3-am62a7-sk-hdmi-audio.dtb \
 	k3-am62p5-sk-csi2-imx219.dtb \
 	k3-am62p5-sk-csi2-ov5640.dtb \
 	k3-am62p5-sk-csi2-tevi-ov5640.dtb \
+	k3-am62p5-sk-ethfw.dtb \
+	k3-am62p5-sk-dsi-rpi-7inch-panel.dtb \
+	k3-am62p5-sk-dss-shared-mode.dtb \
+	k3-am62p5-sk-fastboot-disable-hdmi.dtb \
+	k3-am62p5-sk-microtips-mf101hie-panel.dtb \
+	k3-am62p5-sk-microtips-mf103hie-lcd2.dtb \
+	k3-am62p5-sk-microtips-mf070zima-lcd3.dtb \
 	k3-am642-evm-icssg1-dualemac.dtb \
 	k3-am642-evm-icssg1-dualemac-mii.dtb \
+	k3-am642-evm-pcie0-ep.dtb \
+	k3-am642-evm-cpsw3g-pps.dtb \
+	k3-am642-sk-cpsw3g-pps.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
 	k3-am68-sk-base-board-csi2-dual-imx219.dtb \
+	k3-am68-sk-base-board-pcie1-ep.dtb \
 	k3-am69-sk-csi2-dual-imx219.dtb \
+	k3-am69-sk-pcie0-ep.dtb \
+	k3-j7200-evm-ethfw.dtb \
+	k3-j7200-evm-mcspi-loopback.dtb \
+	k3-j7200-evm-pcie1-ep.dtb \
+	k3-j721e-beagleboneai64-dsi-rpi-7inch-panel.dtb \
+	k3-j721e-beagleboneai64-microtips-mf070zima-lcd3.dtb \
 	k3-j721e-common-proc-board-infotainment.dtb \
+	k3-j721e-evm-ethfw.dtb \
+	k3-j721e-evm-mcspi-loopback.dtb \
+	k3-j721e-evm-pcie-ntb.dtb \
 	k3-j721e-evm-pcie0-ep.dtb \
+	k3-j721e-evm-pcie1-ep.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtb \
 	k3-j721s2-evm-pcie1-ep.dtb \
+	k3-j721s2-evm-mcspi-loopback.dtb \
+	k3-j722s-evm-fpdlink-fusion.dtb \
+	k3-j722s-evm-fpdlink-iv-fusion.dtb \
+	k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtb \
+	k3-j722s-evm-csi2-quad-tevi-ov5640.dtb \
+	k3-j722s-evm-dsi-rpi-7inch-panel.dtb \
+	k3-j722s-evm-microtips-mf101hie-panel.dtb \
+	k3-j722s-evm-v3link-fusion.dtb \
+	k3-j742s2-evm-ethfw.dtb \
+	k3-j742s2-evm-pcie-ntb.dtb \
+	k3-j742s2-evm-usb0-type-a.dtb \
+	k3-j742s2-evm-mcspi-loopback.dtb \
+	k3-j784s4-evm-ethfw.dtb \
+	k3-j784s4-evm-fpdlink-iv-fusion.dtb \
+	k3-j784s4-evm-pcie-ntb.dtb \
+	k3-j784s4-evm-mcspi-loopback.dtb \
 	k3-j784s4-evm-pcie0-pcie1-ep.dtb \
 	k3-j784s4-evm-quad-port-eth-exp1.dtb \
-	k3-j784s4-evm-usxgmii-exp1-exp2.dtb
+	k3-j784s4-evm-usb0-type-a.dtb \
+	k3-j784s4-evm-usxgmii-exp1-exp2.dtb \
+	k3-am62l3-evm-dsi-rpi-7inch-panel.dtb \
+	k3-am62l3-evm-nand.dtb
+
+# FPDLink Sensors
+dtb-$(CONFIG_ARCH_K3) += k3-fpdlink-imx728-rcm-0-0.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-fpdlink-imx390-cm-0-0.dtbo \
+			 k3-fpdlink-imx390-cm-0-1.dtbo \
+			 k3-fpdlink-imx390-rcm-0-0.dtbo \
+			 k3-fpdlink-imx390-rcm-0-1.dtbo \
+			 k3-fpdlink-imx390-rcm-0-2.dtbo \
+			 k3-fpdlink-imx390-rcm-0-3.dtbo \
+			 k3-fpdlink-imx390-rcm-1-0.dtbo \
+			 k3-fpdlink-imx390-rcm-1-1.dtbo \
+			 k3-fpdlink-imx390-rcm-1-2.dtbo \
+			 k3-fpdlink-imx390-rcm-1-3.dtbo \
+			 k3-fpdlink-imx390-rcm-2-0.dtbo \
+			 k3-fpdlink-imx390-rcm-2-1.dtbo \
+			 k3-fpdlink-imx390-rcm-2-2.dtbo \
+			 k3-fpdlink-imx390-rcm-2-3.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-fpdlink-ov2312-0-0.dtbo \
+			 k3-fpdlink-ov2312-0-1.dtbo \
+			 k3-fpdlink-ov2312-0-2.dtbo \
+			 k3-fpdlink-ov2312-0-3.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-v3link-imx219-0-0.dtbo \
+			 k3-v3link-imx219-0-1.dtbo \
+			 k3-v3link-imx219-0-2.dtbo \
+			 k3-v3link-imx219-0-3.dtbo \
+			 k3-v3link-imx219-1-0.dtbo \
+			 k3-v3link-imx219-1-1.dtbo \
+			 k3-v3link-imx219-1-2.dtbo \
+			 k3-v3link-imx219-1-3.dtbo \
+			 k3-v3link-ov5640-0-0.dtbo \
+			 k3-v3link-ov5640-0-1.dtbo \
+			 k3-v3link-ov5640-0-2.dtbo \
+			 k3-v3link-ov5640-0-3.dtbo \
+			 k3-v3link-tevi-ov5640-0-0.dtbo \
+			 k3-v3link-tevi-ov5640-0-1.dtbo \
+			 k3-v3link-tevi-ov5640-0-2.dtbo \
+			 k3-v3link-tevi-ov5640-0-3.dtbo
+
+dtb-$(CONFIG_ARCH_K3) += BONE-I2C1.dtbo
+dtb-$(CONFIG_ARCH_K3) += BONE-I2C2.dtbo
+dtb-$(CONFIG_ARCH_K3) += BONE-I2C3.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am6232-pocketbeagle2.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62-pocketbeagle2-ardupilot-cape.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62-pocketbeagle2-leds-off.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am62-pocketbeagle2-techlab-cape.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am6232-pocketbeagle2-techlab-cape.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am625-beagleplay-bcfserial-no-firmware.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-i2c1-400000.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-i2c1-ads1115.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-i2c1-rtc-rv3028.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-i2c1-ssd1306.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-mikroe-eth.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-mikroe-microsd.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pps-gpio18.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-ecap0-gpio12.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-ecap1-gpio16.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-ecap1-gpio21.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-ecap2-gpio17.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-ecap2-gpio18.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm0-gpio12.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm0-gpio14.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm0-gpio15.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm0-gpio15-gpio12.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm0-gpio15-gpio14.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm0-gpio5.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm0-gpio5-gpio12.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm0-gpio5-gpio14.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm1-gpio13.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm1-gpio20.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm1-gpio21.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm1-gpio21-gpio13.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm1-gpio21-gpio20.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm1-gpio6.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm1-gpio6-gpio13.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-pwm-epwm1-gpio6-gpio20.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-spi0-1cs.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-spi0-2cs.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-spidev0.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-uart-ttyama0.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-BBORG_MOTOR.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-pwm-epwm0-p8_13.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-pwm-epwm0-p8_13-p8_19.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-pwm-epwm0-p8_19.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-pwm-epwm2-p9_14.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-pwm-epwm2-p9_14-p9_16.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-pwm-epwm2-p9_16.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-pwm-epwm4-p9_25.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-spi-mcspi1-cs0.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-spi-mcspi1-cs0-no-miso.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-spi-mcspi2-cs0.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-spi-mcspi3-cs0-no-miso.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-spi-mcspi6-cs0-cs1.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-spi-mcspi6-cs0.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-spi-mcspi6-cs1-no-miso.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64-spi-mcspi7-cs0.dtbo
 
 # Enable support for device-tree overlays
 DTC_FLAGS_k3-am625-beagleplay += -@
 DTC_FLAGS_k3-am625-phyboard-lyra-rdk += -@
 DTC_FLAGS_k3-am62a7-phyboard-lyra-rdk += -@
 DTC_FLAGS_k3-am625-sk += -@
+DTC_FLAGS_k3-am62l3-evm += -@
+DTC_FLAGS_k3-am6254xxl-sk += -@
 DTC_FLAGS_k3-am62-lp-sk += -@
+DTC_FLAGS_k3-am654-base-board += -@
+DTC_FLAGS_k3-am62x-sk-csi2-v3link-fusion += -@
+DTC_FLAGS_k3-am62a7-sk-fusion += -@
+DTC_FLAGS_k3-am62a7-sk-ub954-evm += -@
 DTC_FLAGS_k3-am62a7-sk += -@
 DTC_FLAGS_k3-am62p5-sk += -@
 DTC_FLAGS_k3-am642-evm += -@
@@ -238,8 +596,28 @@
 DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
 DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
 DTC_FLAGS_k3-am68-sk-base-board += -@
+DTC_FLAGS_k3-am68-sk-v3link-fusion += -@
+DTC_FLAGS_k3-am68-sk-v3link-fusion-dual-csitx += -@
 DTC_FLAGS_k3-am69-sk += -@
+DTC_FLAGS_k3-am69-sk-fpdlink-fusion-auxport += -@
+DTC_FLAGS_k3-j7200-common-proc-board += -@
+DTC_FLAGS_k3-j721e-beagleboneai64 += -@
+DTC_FLAGS_k3-j721e-evm-fusion += -@
 DTC_FLAGS_k3-j721e-common-proc-board += -@
+DTC_FLAGS_k3-j721e-evm-pcie0-ep += -@
+DTC_FLAGS_k3-j721e-evm-ub954 += -@
 DTC_FLAGS_k3-j721e-sk += -@
+DTC_FLAGS_k3-j721e-sk-fpdlink-fusion += -@
 DTC_FLAGS_k3-j721s2-common-proc-board += -@
+DTC_FLAGS_k3-j721s2-evm-fusion += -@
+DTC_FLAGS_k3-j721s2-evm-ub954 += -@
+DTC_FLAGS_k3-j722s-evm += -@
+DTC_FLAGS_k3-j722s-evm-fpdlink-fusion += -@
+DTC_FLAGS_k3-j722s-evm-fpdlink-iv-fusion += -@
 DTC_FLAGS_k3-j784s4-evm += -@
+DTC_FLAGS_k3-j784s4-evm-fpdlink-iv-fusion += -@
+DTC_FLAGS_k3-j742s2-evm += -@
+DTC_FLAGS_k3-am62-pocketbeagle2 += -@
+DTC_FLAGS_k3-am6232-pocketbeagle2 += -@
+DTC_FLAGS_k3-am67a-beagley-ai += -@
+DTC_FLAGS_k3-j721e-beagleboneai64 += -@
diff -Naur --no-dereference a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
--- a/arch/arm64/configs/defconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/arch/arm64/configs/defconfig	2025-10-23 09:30:40.284462176 -0400
@@ -1,6 +1,7 @@
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_AUDIT=y
+CONFIG_DUMMY=m
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_BPF_SYSCALL=y
@@ -16,7 +17,9 @@
 CONFIG_IKCONFIG_PROC=y
 CONFIG_NUMA_BALANCING=y
 CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
 CONFIG_BLK_CGROUP=y
+CONFIG_CFS_BANDWIDTH=y
 CONFIG_CGROUP_PIDS=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_HUGETLB=y
@@ -25,6 +28,7 @@
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_CGROUP_PERF=y
 CONFIG_CGROUP_BPF=y
+CONFIG_CGROUP_NET_PRIO=y
 CONFIG_USER_NS=y
 CONFIG_SCHED_AUTOGROUP=y
 CONFIG_BLK_DEV_INITRD=y
@@ -93,6 +97,7 @@
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_ACPI_CPPC_CPUFREQ=m
 CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m
@@ -129,6 +134,7 @@
 CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_XDP_SOCKETS=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -136,20 +142,31 @@
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IPV6=m
+CONFIG_IPVLAN=m
 CONFIG_NETFILTER=y
 CONFIG_BRIDGE_NETFILTER=m
 CONFIG_NF_CONNTRACK=m
 CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_TFTP=m
 CONFIG_NETFILTER_XT_MARK=m
 CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_IP_VS=m
+CONFIG_IP_VS_NFCT=y
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_RR=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_MANGLE=m
@@ -172,11 +189,36 @@
 CONFIG_NET_SCH_MQPRIO=m
 CONFIG_NET_SCH_INGRESS=m
 CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
 CONFIG_NET_CLS_FLOWER=m
+CONFIG_NET_CLS_CGROUP=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
 CONFIG_NET_CLS_ACT=y
 CONFIG_NET_ACT_GACT=m
+CONFIG_NET_ACT_POLICE=m
+CONFIG_GACT_PROB=y
 CONFIG_NET_ACT_MIRRED=m
+CONFIG_HSR=m
 CONFIG_NET_ACT_GATE=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_ACT_CSUM=m
 CONFIG_QRTR_SMD=m
 CONFIG_QRTR_TUN=m
 CONFIG_CAN=m
@@ -219,6 +261,8 @@
 CONFIG_PCI_HOST_THUNDER_PEM=y
 CONFIG_PCI_HOST_THUNDER_ECAM=y
 CONFIG_PCI_HOST_GENERIC=y
+CONFIG_PCI_J721E_EP=y
+CONFIG_PCI_J721E_HOST=y
 CONFIG_PCIE_MEDIATEK_GEN3=m
 CONFIG_PCI_TEGRA=y
 CONFIG_PCIE_RCAR_HOST=y
@@ -231,6 +275,8 @@
 CONFIG_PCIE_KIRIN=y
 CONFIG_PCIE_HISI_STB=y
 CONFIG_PCIE_ARMADA_8K=y
+CONFIG_PCI_KEYSTONE_HOST=y
+CONFIG_PCI_KEYSTONE_EP=y
 CONFIG_PCIE_TEGRA194_HOST=m
 CONFIG_PCIE_TEGRA194_EP=m
 CONFIG_PCIE_QCOM=y
@@ -249,6 +295,9 @@
 CONFIG_TEGRA_ACONNECT=m
 CONFIG_MHI_BUS_PCI_GENERIC=m
 CONFIG_ARM_SCMI_PROTOCOL=y
+CONFIG_ARM_SCMI_NEED_DEBUGFS=y
+CONFIG_ARM_SCMI_RAW_MODE_SUPPORT=y
+CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX=y
 CONFIG_ARM_SCPI_PROTOCOL=y
 CONFIG_RASPBERRYPI_FIRMWARE=y
 CONFIG_INTEL_STRATIX10_SERVICE=y
@@ -282,16 +331,20 @@
 CONFIG_MTD_NAND_FSL_IFC=y
 CONFIG_MTD_NAND_QCOM=y
 CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_UBI=m
+CONFIG_MTD_SPI_NAND=y
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
+CONFIG_MTD_UBI=y
 CONFIG_MTD_HYPERBUS=m
 CONFIG_HBMC_AM654=m
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_THROTTLING=y
 CONFIG_VIRTIO_BLK=y
 CONFIG_BLK_DEV_NVME=m
 CONFIG_QCOM_COINCELL=m
 CONFIG_QCOM_FASTRPC=m
 CONFIG_SRAM=y
+CONFIG_SRAM_DMA_HEAP=y
 CONFIG_PCI_ENDPOINT_TEST=m
 CONFIG_EEPROM_AT24=m
 CONFIG_EEPROM_AT25=m
@@ -374,7 +427,11 @@
 CONFIG_SNI_NETSEC=y
 CONFIG_STMMAC_ETH=m
 CONFIG_DWMAC_TEGRA=m
+CONFIG_TI_CPSW_PROXY_CLIENT=m
 CONFIG_TI_K3_AM65_CPSW_NUSS=y
+CONFIG_TI_K3_AM65_CPSW_SWITCHDEV=y
+CONFIG_TI_K3_AM65_CPTS=y
+CONFIG_TI_AM65_CPSW_QOS=y
 CONFIG_TI_ICSSG_PRUETH=m
 CONFIG_QCOM_IPA=m
 CONFIG_MESON_GXL_PHY=m
@@ -432,6 +489,8 @@
 CONFIG_RSI_91X=m
 CONFIG_WL18XX=m
 CONFIG_WLCORE_SDIO=m
+CONFIG_CC33XX=m
+CONFIG_CC33XX_SDIO=m
 CONFIG_WWAN=m
 CONFIG_MHI_WWAN_CTRL=m
 CONFIG_MHI_WWAN_MBIM=m
@@ -448,6 +507,7 @@
 CONFIG_TOUCHSCREEN_ATMEL_MXT=m
 CONFIG_TOUCHSCREEN_GOODIX=m
 CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI=m
+CONFIG_TOUCHSCREEN_ILI210X=m
 CONFIG_TOUCHSCREEN_ELAN=m
 CONFIG_TOUCHSCREEN_EDT_FT5X06=m
 CONFIG_INPUT_MISC=y
@@ -474,6 +534,7 @@
 CONFIG_SERIAL_8250_OMAP=y
 CONFIG_SERIAL_8250_MT6577=y
 CONFIG_SERIAL_8250_UNIPHIER=y
+CONFIG_SERIAL_8250_PRUSS=m
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
@@ -659,6 +720,7 @@
 CONFIG_GPIO_PCA953X=y
 CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_ADP5585=m
+CONFIG_GPIO_PCF857X=m
 CONFIG_GPIO_BD9571MWV=m
 CONFIG_GPIO_MAX77620=y
 CONFIG_GPIO_SL28CPLD=m
@@ -761,7 +823,7 @@
 CONFIG_MFD_TI_AM335X_TSCADC=m
 CONFIG_MFD_TI_LP873X=m
 CONFIG_MFD_TPS65219=y
-CONFIG_MFD_TPS6594_I2C=m
+CONFIG_MFD_TPS6594_I2C=y
 CONFIG_MFD_ROHM_BD718XX=y
 CONFIG_MFD_WCD934X=m
 CONFIG_MFD_KHADAS_MCU=m
@@ -796,6 +858,7 @@
 CONFIG_REGULATOR_QCOM_SPMI=y
 CONFIG_REGULATOR_QCOM_USB_VBUS=m
 CONFIG_REGULATOR_RAA215300=y
+CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=m
 CONFIG_REGULATOR_RK808=y
 CONFIG_REGULATOR_S2MPS11=y
 CONFIG_REGULATOR_TPS65132=m
@@ -823,6 +886,8 @@
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_AMPHION_VPU=m
 CONFIG_VIDEO_CADENCE_CSI2RX=m
+CONFIG_VIDEO_DS90UB960=m
+CONFIG_VIDEO_DS90UB953=m
 CONFIG_VIDEO_MEDIATEK_JPEG=m
 CONFIG_VIDEO_MEDIATEK_VCODEC=m
 CONFIG_VIDEO_WAVE_VPU=m
@@ -850,9 +915,13 @@
 CONFIG_VIDEO_TI_J721E_CSI2RX=m
 CONFIG_VIDEO_HANTRO=m
 CONFIG_VIDEO_IMX219=m
+CONFIG_VIDEO_IMX390=m
 CONFIG_VIDEO_IMX412=m
+CONFIG_VIDEO_IMX728=m
+CONFIG_VIDEO_OV2312=m
 CONFIG_VIDEO_OV5640=m
 CONFIG_VIDEO_OV5645=m
+CONFIG_VIDEO_OX05B1S=m
 CONFIG_DRM=m
 CONFIG_DRM_I2C_NXP_TDA998X=m
 CONFIG_DRM_HDLCD=m
@@ -911,12 +980,15 @@
 CONFIG_DRM_THINE_THC63LVD1024=m
 CONFIG_DRM_TOSHIBA_TC358767=m
 CONFIG_DRM_TOSHIBA_TC358768=m
+CONFIG_DRM_TOSHIBA_TC358762=m
 CONFIG_DRM_TI_TFP410=m
 CONFIG_DRM_TI_SN65DSI83=m
 CONFIG_DRM_TI_SN65DSI86=m
 CONFIG_DRM_ANALOGIX_ANX7625=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
+CONFIG_DRM_CDNS_DSI=m
+CONFIG_DRM_CDNS_DSI_J721E=y
 CONFIG_DRM_CDNS_MHDP8546=m
 CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE=m
 CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
@@ -941,6 +1013,7 @@
 CONFIG_DRM_POWERVR=m
 CONFIG_FB=y
 CONFIG_FB_EFI=y
+CONFIG_FB_SIMPLE=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_BACKLIGHT_PWM=m
 CONFIG_BACKLIGHT_LP855X=m
@@ -993,6 +1066,7 @@
 CONFIG_SND_SOC_SOF_OF=y
 CONFIG_SND_SOC_SOF_MTK_TOPLEVEL=y
 CONFIG_SND_SOC_SOF_MT8195=m
+CONFIG_SND_SOC_PCM6240=m
 CONFIG_SND_SUN8I_CODEC=m
 CONFIG_SND_SUN8I_CODEC_ANALOG=m
 CONFIG_SND_SUN50I_CODEC_ANALOG=m
@@ -1053,6 +1127,7 @@
 CONFIG_SND_SOC_LPASS_TX_MACRO=m
 CONFIG_SND_SIMPLE_CARD=m
 CONFIG_SND_AUDIO_GRAPH_CARD=m
+CONFIG_SND_USB_AUDIO=m
 CONFIG_SND_AUDIO_GRAPH_CARD2=m
 CONFIG_HID_MULTITOUCH=m
 CONFIG_I2C_HID_ACPI=m
@@ -1093,6 +1168,7 @@
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_CP210X=m
 CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_PL2303=m
 CONFIG_USB_SERIAL_OPTION=m
 CONFIG_USB_QCOM_EUD=m
 CONFIG_USB_HSIC_USB3503=y
@@ -1115,6 +1191,12 @@
 CONFIG_USB_CONFIGFS_EEM=y
 CONFIG_USB_CONFIGFS_MASS_STORAGE=y
 CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_G_NCM=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_USB_G_MULTI=m
 CONFIG_USB_MASS_STORAGE=m
 CONFIG_TYPEC=m
 CONFIG_TYPEC_TCPM=m
@@ -1243,7 +1325,12 @@
 CONFIG_RENESAS_USB_DMAC=m
 CONFIG_RZ_DMAC=y
 CONFIG_TI_K3_UDMA=y
+CONFIG_TI_K3_UDMA_AM62L=y
 CONFIG_TI_K3_UDMA_GLUE_LAYER=y
+CONFIG_DMABUF_HEAPS=y
+CONFIG_DMABUF_HEAPS_SYSTEM=y
+CONFIG_DMABUF_HEAPS_CMA=y
+CONFIG_DMABUF_HEAPS_CARVEOUT=y
 CONFIG_VFIO=y
 CONFIG_VFIO_PCI=y
 CONFIG_VIRTIO_PCI=y
@@ -1367,6 +1454,7 @@
 CONFIG_CLK_GFM_LPASS_SM8250=m
 CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
 CONFIG_HWSPINLOCK=y
+CONFIG_HWSPINLOCK_OMAP=m
 CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_TEGRA186_TIMER=y
 CONFIG_RENESAS_OSTM=y
@@ -1385,6 +1473,7 @@
 CONFIG_MTK_IOMMU=y
 CONFIG_QCOM_IOMMU=y
 CONFIG_REMOTEPROC=y
+CONFIG_REMOTEPROC_CDEV=y
 CONFIG_IMX_REMOTEPROC=y
 CONFIG_MTK_SCP=m
 CONFIG_QCOM_Q6V5_ADSP=m
@@ -1393,6 +1482,7 @@
 CONFIG_QCOM_SYSMON=m
 CONFIG_QCOM_WCNSS_PIL=m
 CONFIG_TI_K3_DSP_REMOTEPROC=m
+CONFIG_TI_K3_M4_REMOTEPROC=m
 CONFIG_TI_K3_R5_REMOTEPROC=m
 CONFIG_RPMSG_CHAR=m
 CONFIG_RPMSG_CTRL=m
@@ -1400,6 +1490,7 @@
 CONFIG_RPMSG_QCOM_GLINK_SMEM=m
 CONFIG_RPMSG_QCOM_SMD=y
 CONFIG_RPMSG_VIRTIO=y
+CONFIG_RPMSG_PRU=m
 CONFIG_SOUNDWIRE=m
 CONFIG_SOUNDWIRE_QCOM=m
 CONFIG_FSL_DPAA=y
@@ -1471,6 +1562,9 @@
 CONFIG_EXTCON_PTN5150=m
 CONFIG_EXTCON_USB_GPIO=y
 CONFIG_EXTCON_USBC_CROS_EC=y
+CONFIG_OMAP_GPMC=y
+CONFIG_MTD_NAND_OMAP2=y
+CONFIG_MTD_NAND_OMAP_BCH=y
 CONFIG_RENESAS_RPCIF=m
 CONFIG_IIO=y
 CONFIG_EXYNOS_ADC=y
@@ -1502,6 +1596,7 @@
 CONFIG_PWM_MESON=m
 CONFIG_PWM_MTK_DISP=m
 CONFIG_PWM_MEDIATEK=m
+CONFIG_PWM_OMAP_DMTIMER=m
 CONFIG_PWM_RCAR=m
 CONFIG_PWM_RENESAS_TPU=m
 CONFIG_PWM_ROCKCHIP=y
@@ -1525,9 +1620,10 @@
 CONFIG_PHY_XGENE=y
 CONFIG_PHY_CAN_TRANSCEIVER=m
 CONFIG_PHY_SUN4I_USB=y
-CONFIG_PHY_CADENCE_TORRENT=m
+CONFIG_PHY_CADENCE_TORRENT=y
+CONFIG_PHY_CADENCE_DPHY=m
 CONFIG_PHY_CADENCE_DPHY_RX=m
-CONFIG_PHY_CADENCE_SIERRA=m
+CONFIG_PHY_CADENCE_SIERRA=y
 CONFIG_PHY_CADENCE_SALVO=m
 CONFIG_PHY_MIXEL_MIPI_DPHY=m
 CONFIG_PHY_FSL_IMX8M_PCIE=y
@@ -1569,8 +1665,8 @@
 CONFIG_PHY_UNIPHIER_USB2=y
 CONFIG_PHY_UNIPHIER_USB3=y
 CONFIG_PHY_TEGRA_XUSB=y
-CONFIG_PHY_AM654_SERDES=m
-CONFIG_PHY_J721E_WIZ=m
+CONFIG_PHY_AM654_SERDES=y
+CONFIG_PHY_J721E_WIZ=y
 CONFIG_ARM_CCI_PMU=m
 CONFIG_ARM_CCN=m
 CONFIG_ARM_CMN=m
@@ -1644,6 +1740,8 @@
 CONFIG_INTERCONNECT_QCOM_SM8650=y
 CONFIG_INTERCONNECT_QCOM_X1E80100=y
 CONFIG_COUNTER=m
+CONFIG_TI_ECAP_CAPTURE=m
+CONFIG_TI_EQEP=m
 CONFIG_RZ_MTU3_CNT=m
 CONFIG_HTE=y
 CONFIG_HTE_TEGRA194=y
@@ -1651,6 +1749,7 @@
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_EXT4_FS_SECURITY=y
+CONFIG_VXLAN=m
 CONFIG_BTRFS_FS=m
 CONFIG_BTRFS_FS_POSIX_ACL=y
 CONFIG_FANOTIFY=y
@@ -1665,7 +1764,7 @@
 CONFIG_HUGETLBFS=y
 CONFIG_CONFIGFS_FS=y
 CONFIG_EFIVAR_FS=y
-CONFIG_UBIFS_FS=m
+CONFIG_UBIFS_FS=y
 CONFIG_SQUASHFS=y
 CONFIG_PSTORE_RAM=m
 CONFIG_NFS_FS=y
@@ -1677,11 +1776,14 @@
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_SECURITY=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_APPARMOR=y
 CONFIG_CRYPTO_USER=y
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_ECHAINIV=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_CHACHA20_NEON=m
 CONFIG_CRYPTO_GHASH_ARM64_CE=y
@@ -1706,6 +1808,13 @@
 CONFIG_CRYPTO_DEV_HISI_HPRE=m
 CONFIG_CRYPTO_DEV_HISI_TRNG=m
 CONFIG_CRYPTO_DEV_SA2UL=m
+CONFIG_CRYPTO_DEV_TI_DTHEV2=m
+CONFIG_CRYPTO_DEV_TI_MCRC64=m
+CONFIG_CRYPTO_SEQIV=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_ALGO=y
+CONFIG_INET_ESP=y
 CONFIG_DMA_RESTRICTED_POOL=y
 CONFIG_CMA_SIZE_MBYTES=32
 CONFIG_PRINTK_TIME=y
diff -Naur --no-dereference a/crypto/crc64_iso3309_generic.c b/crypto/crc64_iso3309_generic.c
--- a/crypto/crc64_iso3309_generic.c	1969-12-31 19:00:00.000000000 -0500
+++ b/crypto/crc64_iso3309_generic.c	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/crc64.h>
+#include <linux/module.h>
+#include <crypto/internal/hash.h>
+
+static int chksum_cra_init(struct crypto_tfm *tfm)
+{
+	u64 *key = crypto_tfm_ctx(tfm);
+
+	*key = 0;
+	return 0;
+}
+
+static int chksum_init(struct shash_desc *desc)
+{
+	u64 *key = crypto_shash_ctx(desc->tfm);
+	u64 *crc = shash_desc_ctx(desc);
+
+	*crc = *key;
+	return 0;
+}
+
+static int chksum_update(struct shash_desc *desc, const u8 *data,
+			 unsigned int length)
+{
+	u64 *crc = shash_desc_ctx(desc);
+
+	*crc = crc64_iso3309_generic(*crc, data, length);
+	return 0;
+}
+
+static int chksum_final(struct shash_desc *desc, u8 *out)
+{
+	u64 *crc = shash_desc_ctx(desc);
+
+	put_unaligned_le64(*crc, out);
+	return 0;
+}
+
+static int __chksum_finup(u64 crc, const u8 *data, unsigned int len, u8 *out)
+{
+	crc = crc64_iso3309_generic(crc, data, len);
+
+	put_unaligned_le64(crc, out);
+	return 0;
+}
+
+static int chksum_finup(struct shash_desc *desc, const u8 *data,
+			unsigned int len, u8 *out)
+{
+	u64 *crc = shash_desc_ctx(desc);
+
+	return __chksum_finup(*crc, data, len, out);
+}
+
+static int chksum_digest(struct shash_desc *desc, const u8 *data,
+			 unsigned int length, u8 *out)
+{
+	u64 *key = crypto_shash_ctx(desc->tfm);
+
+	return __chksum_finup(*key, data, length, out);
+}
+
+/*
+ * Setting the seed allows arbitrary accumulators and flexible XOR policy
+ */
+static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
+			 unsigned int keylen)
+{
+	u64 *mctx = crypto_shash_ctx(tfm);
+
+	if (keylen != sizeof(u64))
+		return -EINVAL;
+
+	*mctx = get_unaligned_le64(key);
+	return 0;
+}
+
+static struct shash_alg alg = {
+	.digestsize	=	sizeof(u64),
+	.setkey		=	chksum_setkey,
+	.init		=	chksum_init,
+	.update		=	chksum_update,
+	.final		=	chksum_final,
+	.finup		=	chksum_finup,
+	.digest		=	chksum_digest,
+	.descsize	=	sizeof(u64),
+	.base		=	{
+		.cra_name		=	CRC64_ISO3309_STRING,
+		.cra_driver_name	=	"crc64-iso3309-generic",
+		.cra_priority		=	200,
+		.cra_flags		=       CRYPTO_ALG_OPTIONAL_KEY,
+		.cra_blocksize		=	1,
+		.cra_ctxsize		=       sizeof(u64),
+		.cra_module		=	THIS_MODULE,
+		.cra_init		=       chksum_cra_init,
+	}
+};
+
+static int __init crc64_iso3309_init(void)
+{
+	return crypto_register_shash(&alg);
+}
+
+static void __exit crc64_iso3309_exit(void)
+{
+	crypto_unregister_shash(&alg);
+}
+
+module_init(crc64_iso3309_init);
+module_exit(crc64_iso3309_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kamlesh Gurudasani <kamlesh@ti.com>");
+MODULE_DESCRIPTION("ISO3309 model CRC64 calculation");
+MODULE_ALIAS_CRYPTO("crc64-iso3309");
+MODULE_ALIAS_CRYPTO("crc64-iso3309-generic");
diff -Naur --no-dereference a/crypto/Kconfig b/crypto/Kconfig
--- a/crypto/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/crypto/Kconfig	2025-10-23 09:30:40.284462176 -0400
@@ -1109,6 +1109,17 @@
 
 	  CRC algorithm used by the SCSI Block Commands standard.
 
+config CRYPTO_CRC64_ISO3309
+	tristate "CRC64 based on ISO 3309 Model algorithm"
+	depends on CRC64
+	select CRYPTO_HASH
+	help
+	  CRC64 CRC algorithm based on the ISO 3309 Model CRC Algorithm
+
+	  Generator polynomial: x^64 + x^4 + x^3 + x + 1
+	  Polynomial value: 0x000000000000001b
+	  See https://en.wikipedia.org/wiki/Cyclic_redundancy_check
+
 config CRYPTO_CRC64_ROCKSOFT
 	tristate "CRC64 based on Rocksoft Model algorithm"
 	depends on CRC64
diff -Naur --no-dereference a/crypto/Makefile b/crypto/Makefile
--- a/crypto/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/crypto/Makefile	2025-10-23 09:30:40.284462176 -0400
@@ -153,6 +153,7 @@
 obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o
 obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o
 obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o
+obj-$(CONFIG_CRYPTO_CRC64_ISO3309) += crc64_iso3309_generic.o
 obj-$(CONFIG_CRYPTO_CRC64_ROCKSOFT) += crc64_rocksoft_generic.o
 obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
 obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o
diff -Naur --no-dereference a/crypto/tcrypt.c b/crypto/tcrypt.c
--- a/crypto/tcrypt.c	2025-06-19 09:32:38.000000000 -0400
+++ b/crypto/tcrypt.c	2025-10-23 09:30:40.284462176 -0400
@@ -2314,6 +2314,12 @@
 				generic_hash_speed_template);
 		if (mode > 300 && mode < 400) break;
 		fallthrough;
+	case 329:
+		test_hash_speed("crc64-iso3309", sec,
+				generic_hash_speed_template);
+		if (mode > 300 && mode < 400)
+			break;
+		fallthrough;
 	case 399:
 		break;
 
diff -Naur --no-dereference a/crypto/testmgr.c b/crypto/testmgr.c
--- a/crypto/testmgr.c	2025-06-19 09:32:38.000000000 -0400
+++ b/crypto/testmgr.c	2025-10-23 09:30:40.284462176 -0400
@@ -4704,6 +4704,13 @@
 			.hash = __VECS(crc32c_tv_template)
 		}
 	}, {
+		.alg = "crc64-iso3309",
+		.test = alg_test_hash,
+		.fips_allowed = 1,
+		.suite = {
+			.hash = __VECS(crc64_iso3309_tv_template)
+		}
+	}, {
 		.alg = "crc64-rocksoft",
 		.test = alg_test_hash,
 		.fips_allowed = 1,
diff -Naur --no-dereference a/crypto/testmgr.h b/crypto/testmgr.h
--- a/crypto/testmgr.h	2025-06-19 09:32:38.000000000 -0400
+++ b/crypto/testmgr.h	2025-10-23 09:30:40.284462176 -0400
@@ -5355,6 +5355,410 @@
 	}
 };
 
+static const struct hash_testvec crc64_iso3309_tv_template[] = {
+	{
+		.psize = 0,
+		.digest = "\x00\x00\x00\x00\x00\x00\x00\x00",
+	},
+	{
+		.plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08"
+			     "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+			     "\x11\x12\x13\x14\x15\x16\x17\x18"
+			     "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+			     "\x21\x22\x23\x24\x25\x26\x27\x28",
+		.psize = 40,
+		.digest = "\xaf\x45\xba\x7d\xf2\xda\xa0\xaa",
+	},
+	{
+		.plaintext = "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+			     "\x31\x32\x33\x34\x35\x36\x37\x38"
+			     "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+			     "\x41\x42\x43\x44\x45\x46\x47\x48"
+			     "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50",
+		.psize = 40,
+		.digest = "\x81\x55\x2e\x76\xf8\xd0\xaa\xa0",
+	},
+	{
+		.plaintext = "\x51\x52\x53\x54\x55\x56\x57\x58"
+			     "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+			     "\x61\x62\x63\x64\x65\x66\x67\x68"
+			     "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+			     "\x71\x72\x73\x74\x75\x76\x77\x78",
+		.psize = 40,
+		.digest = "\xc6\xb6\x26\x82\x0d\x25\x5f\x55",
+	},
+	{
+		.plaintext = "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+			     "\x81\x82\x83\x84\x85\x86\x87\x88"
+			     "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+			     "\x91\x92\x93\x94\x95\x96\x97\x98"
+			     "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0",
+		.psize = 40,
+		.digest = "\x20\x8a\xe6\x59\xdf\xf7\x8d\x87",
+	},
+	{
+		.plaintext = "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+			     "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+			     "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+			     "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+			     "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8",
+		.psize = 40,
+		.digest = "\x19\x9e\xba\xff\x70\x58\x22\x28",
+
+	},
+	{
+		.plaintext = "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+			     "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+			     "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+			     "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+			     "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
+		.psize = 40,
+		.digest = "\xa3\xdc\x11\x98\x16\x3e\x44\x4e",
+	},
+	{
+		.plaintext = "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+			     "\x31\x32\x33\x34\x35\x36\x37\x38"
+			     "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+			     "\x41\x42\x43\x44\x45\x46\x47\x48"
+			     "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50",
+		.psize = 40,
+		.digest = "\x81\x55\x2e\x76\xf8\xd0\xaa\xa0",
+	},
+	{
+		.plaintext = "\x51\x52\x53\x54\x55\x56\x57\x58"
+			     "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+			     "\x61\x62\x63\x64\x65\x66\x67\x68"
+			     "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+			     "\x71\x72\x73\x74\x75\x76\x77\x78",
+		.psize = 40,
+		.digest = "\xc6\xb6\x26\x82\x0d\x25\x5f\x55",
+	},
+	{
+		.plaintext = "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+			     "\x81\x82\x83\x84\x85\x86\x87\x88"
+			     "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+			     "\x91\x92\x93\x94\x95\x96\x97\x98"
+			     "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0",
+		.psize = 40,
+		.digest = "\x20\x8a\xe6\x59\xdf\xf7\x8d\x87",
+	},
+	{
+		.plaintext = "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+			     "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+			     "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+			     "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+			     "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8",
+		.psize = 40,
+		.digest = "\x19\x9e\xba\xff\x70\x58\x22\x28",
+	},
+	{
+		.plaintext = "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+			     "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+			     "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+			     "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+			     "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
+		.psize = 40,
+		.digest = "\xa3\xdc\x11\x98\x16\x3e\x44\x4e",
+	},
+	{
+		.key = "\xff\xff\xff\xff\xff\xff\xff\xff",
+		.ksize = 8,
+		.plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08"
+			     "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+			     "\x11\x12\x13\x14\x15\x16\x17\x18"
+			     "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+			     "\x21\x22\x23\x24\x25\x26\x27\x28"
+			     "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+			     "\x31\x32\x33\x34\x35\x36\x37\x38"
+			     "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+			     "\x41\x42\x43\x44\x45\x46\x47\x48"
+			     "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
+			     "\x51\x52\x53\x54\x55\x56\x57\x58"
+			     "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+			     "\x61\x62\x63\x64\x65\x66\x67\x68"
+			     "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+			     "\x71\x72\x73\x74\x75\x76\x77\x78"
+			     "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+			     "\x81\x82\x83\x84\x85\x86\x87\x88"
+			     "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+			     "\x91\x92\x93\x94\x95\x96\x97\x98"
+			     "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
+			     "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+			     "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+			     "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+			     "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+			     "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8"
+			     "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+			     "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+			     "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+			     "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+			     "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
+		.psize = 240,
+		.digest = "\x8b\xa6\xd7\x91\xb4\x74\x96\x84",
+	}, {
+		.key = "\xff\xff\xff\xff\xff\xff\xff\xff",
+		.ksize = 8,
+		.plaintext = "\x6e\x05\x79\x10\xa7\x1b\xb2\x49"
+			     "\xe0\x54\xeb\x82\x19\x8d\x24\xbb"
+			     "\x2f\xc6\x5d\xf4\x68\xff\x96\x0a"
+			     "\xa1\x38\xcf\x43\xda\x71\x08\x7c"
+			     "\x13\xaa\x1e\xb5\x4c\xe3\x57\xee"
+			     "\x85\x1c\x90\x27\xbe\x32\xc9\x60"
+			     "\xf7\x6b\x02\x99\x0d\xa4\x3b\xd2"
+			     "\x46\xdd\x74\x0b\x7f\x16\xad\x21"
+			     "\xb8\x4f\xe6\x5a\xf1\x88\x1f\x93"
+			     "\x2a\xc1\x35\xcc\x63\xfa\x6e\x05"
+			     "\x9c\x10\xa7\x3e\xd5\x49\xe0\x77"
+			     "\x0e\x82\x19\xb0\x24\xbb\x52\xe9"
+			     "\x5d\xf4\x8b\x22\x96\x2d\xc4\x38"
+			     "\xcf\x66\xfd\x71\x08\x9f\x13\xaa"
+			     "\x41\xd8\x4c\xe3\x7a\x11\x85\x1c"
+			     "\xb3\x27\xbe\x55\xec\x60\xf7\x8e"
+			     "\x02\x99\x30\xc7\x3b\xd2\x69\x00"
+			     "\x74\x0b\xa2\x16\xad\x44\xdb\x4f"
+			     "\xe6\x7d\x14\x88\x1f\xb6\x2a\xc1"
+			     "\x58\xef\x63\xfa\x91\x05\x9c\x33"
+			     "\xca\x3e\xd5\x6c\x03\x77\x0e\xa5"
+			     "\x19\xb0\x47\xde\x52\xe9\x80\x17"
+			     "\x8b\x22\xb9\x2d\xc4\x5b\xf2\x66"
+			     "\xfd\x94\x08\x9f\x36\xcd\x41\xd8"
+			     "\x6f\x06\x7a\x11\xa8\x1c\xb3\x4a"
+			     "\xe1\x55\xec\x83\x1a\x8e\x25\xbc"
+			     "\x30\xc7\x5e\xf5\x69\x00\x97\x0b"
+			     "\xa2\x39\xd0\x44\xdb\x72\x09\x7d"
+			     "\x14\xab\x1f\xb6\x4d\xe4\x58\xef"
+			     "\x86\x1d\x91\x28\xbf\x33\xca\x61"
+			     "\xf8\x6c\x03\x9a\x0e\xa5\x3c\xd3"
+			     "\x47\xde\x75\x0c\x80\x17\xae\x22"
+			     "\xb9\x50\xe7\x5b\xf2\x89\x20\x94"
+			     "\x2b\xc2\x36\xcd\x64\xfb\x6f\x06"
+			     "\x9d\x11\xa8\x3f\xd6\x4a\xe1\x78"
+			     "\x0f\x83\x1a\xb1\x25\xbc\x53\xea"
+			     "\x5e\xf5\x8c\x00\x97\x2e\xc5\x39"
+			     "\xd0\x67\xfe\x72\x09\xa0\x14\xab"
+			     "\x42\xd9\x4d\xe4\x7b\x12\x86\x1d"
+			     "\xb4\x28\xbf\x56\xed\x61\xf8\x8f"
+			     "\x03\x9a\x31\xc8\x3c\xd3\x6a\x01"
+			     "\x75\x0c\xa3\x17\xae\x45\xdc\x50"
+			     "\xe7\x7e\x15\x89\x20\xb7\x2b\xc2"
+			     "\x59\xf0\x64\xfb\x92\x06\x9d\x34"
+			     "\xcb\x3f\xd6\x6d\x04\x78\x0f\xa6"
+			     "\x1a\xb1\x48\xdf\x53\xea\x81\x18"
+			     "\x8c\x23\xba\x2e\xc5\x5c\xf3\x67"
+			     "\xfe\x95\x09\xa0\x37\xce\x42\xd9"
+			     "\x70\x07\x7b\x12\xa9\x1d\xb4\x4b"
+			     "\xe2\x56\xed\x84\x1b\x8f\x26\xbd"
+			     "\x31\xc8\x5f\xf6\x6a\x01\x98\x0c"
+			     "\xa3\x3a\xd1\x45\xdc\x73\x0a\x7e"
+			     "\x15\xac\x20\xb7\x4e\xe5\x59\xf0"
+			     "\x87\x1e\x92\x29\xc0\x34\xcb\x62"
+			     "\xf9\x6d\x04\x9b\x0f\xa6\x3d\xd4"
+			     "\x48\xdf\x76\x0d\x81\x18\xaf\x23"
+			     "\xba\x51\xe8\x5c\xf3\x8a\x21\x95"
+			     "\x2c\xc3\x37\xce\x65\xfc\x70\x07"
+			     "\x9e\x12\xa9\x40\xd7\x4b\xe2\x79"
+			     "\x10\x84\x1b\xb2\x26\xbd\x54\xeb"
+			     "\x5f\xf6\x8d\x01\x98\x2f\xc6\x3a"
+			     "\xd1\x68\xff\x73\x0a\xa1\x15\xac"
+			     "\x43\xda\x4e\xe5\x7c\x13\x87\x1e"
+			     "\xb5\x29\xc0\x57\xee\x62\xf9\x90"
+			     "\x04\x9b\x32\xc9\x3d\xd4\x6b\x02"
+			     "\x76\x0d\xa4\x18\xaf\x46\xdd\x51"
+			     "\xe8\x7f\x16\x8a\x21\xb8\x2c\xc3"
+			     "\x5a\xf1\x65\xfc\x93\x07\x9e\x35"
+			     "\xcc\x40\xd7\x6e\x05\x79\x10\xa7"
+			     "\x1b\xb2\x49\xe0\x54\xeb\x82\x19"
+			     "\x8d\x24\xbb\x2f\xc6\x5d\xf4\x68"
+			     "\xff\x96\x0a\xa1\x38\xcf\x43\xda"
+			     "\x71\x08\x7c\x13\xaa\x1e\xb5\x4c"
+			     "\xe3\x57\xee\x85\x1c\x90\x27\xbe"
+			     "\x32\xc9\x60\xf7\x6b\x02\x99\x0d"
+			     "\xa4\x3b\xd2\x46\xdd\x74\x0b\x7f"
+			     "\x16\xad\x21\xb8\x4f\xe6\x5a\xf1"
+			     "\x88\x1f\x93\x2a\xc1\x35\xcc\x63"
+			     "\xfa\x6e\x05\x9c\x10\xa7\x3e\xd5"
+			     "\x49\xe0\x77\x0e\x82\x19\xb0\x24"
+			     "\xbb\x52\xe9\x5d\xf4\x8b\x22\x96"
+			     "\x2d\xc4\x38\xcf\x66\xfd\x71\x08"
+			     "\x9f\x13\xaa\x41\xd8\x4c\xe3\x7a"
+			     "\x11\x85\x1c\xb3\x27\xbe\x55\xec"
+			     "\x60\xf7\x8e\x02\x99\x30\xc7\x3b"
+			     "\xd2\x69\x00\x74\x0b\xa2\x16\xad"
+			     "\x44\xdb\x4f\xe6\x7d\x14\x88\x1f"
+			     "\xb6\x2a\xc1\x58\xef\x63\xfa\x91"
+			     "\x05\x9c\x33\xca\x3e\xd5\x6c\x03"
+			     "\x77\x0e\xa5\x19\xb0\x47\xde\x52"
+			     "\xe9\x80\x17\x8b\x22\xb9\x2d\xc4"
+			     "\x5b\xf2\x66\xfd\x94\x08\x9f\x36"
+			     "\xcd\x41\xd8\x6f\x06\x7a\x11\xa8"
+			     "\x1c\xb3\x4a\xe1\x55\xec\x83\x1a"
+			     "\x8e\x25\xbc\x30\xc7\x5e\xf5\x69"
+			     "\x00\x97\x0b\xa2\x39\xd0\x44\xdb"
+			     "\x72\x09\x7d\x14\xab\x1f\xb6\x4d"
+			     "\xe4\x58\xef\x86\x1d\x91\x28\xbf"
+			     "\x33\xca\x61\xf8\x6c\x03\x9a\x0e"
+			     "\xa5\x3c\xd3\x47\xde\x75\x0c\x80"
+			     "\x17\xae\x22\xb9\x50\xe7\x5b\xf2"
+			     "\x89\x20\x94\x2b\xc2\x36\xcd\x64"
+			     "\xfb\x6f\x06\x9d\x11\xa8\x3f\xd6"
+			     "\x4a\xe1\x78\x0f\x83\x1a\xb1\x25"
+			     "\xbc\x53\xea\x5e\xf5\x8c\x00\x97"
+			     "\x2e\xc5\x39\xd0\x67\xfe\x72\x09"
+			     "\xa0\x14\xab\x42\xd9\x4d\xe4\x7b"
+			     "\x12\x86\x1d\xb4\x28\xbf\x56\xed"
+			     "\x61\xf8\x8f\x03\x9a\x31\xc8\x3c"
+			     "\xd3\x6a\x01\x75\x0c\xa3\x17\xae"
+			     "\x45\xdc\x50\xe7\x7e\x15\x89\x20"
+			     "\xb7\x2b\xc2\x59\xf0\x64\xfb\x92"
+			     "\x06\x9d\x34\xcb\x3f\xd6\x6d\x04"
+			     "\x78\x0f\xa6\x1a\xb1\x48\xdf\x53"
+			     "\xea\x81\x18\x8c\x23\xba\x2e\xc5"
+			     "\x5c\xf3\x67\xfe\x95\x09\xa0\x37"
+			     "\xce\x42\xd9\x70\x07\x7b\x12\xa9"
+			     "\x1d\xb4\x4b\xe2\x56\xed\x84\x1b"
+			     "\x8f\x26\xbd\x31\xc8\x5f\xf6\x6a"
+			     "\x01\x98\x0c\xa3\x3a\xd1\x45\xdc"
+			     "\x73\x0a\x7e\x15\xac\x20\xb7\x4e"
+			     "\xe5\x59\xf0\x87\x1e\x92\x29\xc0"
+			     "\x34\xcb\x62\xf9\x6d\x04\x9b\x0f"
+			     "\xa6\x3d\xd4\x48\xdf\x76\x0d\x81"
+			     "\x18\xaf\x23\xba\x51\xe8\x5c\xf3"
+			     "\x8a\x21\x95\x2c\xc3\x37\xce\x65"
+			     "\xfc\x70\x07\x9e\x12\xa9\x40\xd7"
+			     "\x4b\xe2\x79\x10\x84\x1b\xb2\x26"
+			     "\xbd\x54\xeb\x5f\xf6\x8d\x01\x98"
+			     "\x2f\xc6\x3a\xd1\x68\xff\x73\x0a"
+			     "\xa1\x15\xac\x43\xda\x4e\xe5\x7c"
+			     "\x13\x87\x1e\xb5\x29\xc0\x57\xee"
+			     "\x62\xf9\x90\x04\x9b\x32\xc9\x3d"
+			     "\xd4\x6b\x02\x76\x0d\xa4\x18\xaf"
+			     "\x46\xdd\x51\xe8\x7f\x16\x8a\x21"
+			     "\xb8\x2c\xc3\x5a\xf1\x65\xfc\x93"
+			     "\x07\x9e\x35\xcc\x40\xd7\x6e\x05"
+			     "\x79\x10\xa7\x1b\xb2\x49\xe0\x54"
+			     "\xeb\x82\x19\x8d\x24\xbb\x2f\xc6"
+			     "\x5d\xf4\x68\xff\x96\x0a\xa1\x38"
+			     "\xcf\x43\xda\x71\x08\x7c\x13\xaa"
+			     "\x1e\xb5\x4c\xe3\x57\xee\x85\x1c"
+			     "\x90\x27\xbe\x32\xc9\x60\xf7\x6b"
+			     "\x02\x99\x0d\xa4\x3b\xd2\x46\xdd"
+			     "\x74\x0b\x7f\x16\xad\x21\xb8\x4f"
+			     "\xe6\x5a\xf1\x88\x1f\x93\x2a\xc1"
+			     "\x35\xcc\x63\xfa\x6e\x05\x9c\x10"
+			     "\xa7\x3e\xd5\x49\xe0\x77\x0e\x82"
+			     "\x19\xb0\x24\xbb\x52\xe9\x5d\xf4"
+			     "\x8b\x22\x96\x2d\xc4\x38\xcf\x66"
+			     "\xfd\x71\x08\x9f\x13\xaa\x41\xd8"
+			     "\x4c\xe3\x7a\x11\x85\x1c\xb3\x27"
+			     "\xbe\x55\xec\x60\xf7\x8e\x02\x99"
+			     "\x30\xc7\x3b\xd2\x69\x00\x74\x0b"
+			     "\xa2\x16\xad\x44\xdb\x4f\xe6\x7d"
+			     "\x14\x88\x1f\xb6\x2a\xc1\x58\xef"
+			     "\x63\xfa\x91\x05\x9c\x33\xca\x3e"
+			     "\xd5\x6c\x03\x77\x0e\xa5\x19\xb0"
+			     "\x47\xde\x52\xe9\x80\x17\x8b\x22"
+			     "\xb9\x2d\xc4\x5b\xf2\x66\xfd\x94"
+			     "\x08\x9f\x36\xcd\x41\xd8\x6f\x06"
+			     "\x7a\x11\xa8\x1c\xb3\x4a\xe1\x55"
+			     "\xec\x83\x1a\x8e\x25\xbc\x30\xc7"
+			     "\x5e\xf5\x69\x00\x97\x0b\xa2\x39"
+			     "\xd0\x44\xdb\x72\x09\x7d\x14\xab"
+			     "\x1f\xb6\x4d\xe4\x58\xef\x86\x1d"
+			     "\x91\x28\xbf\x33\xca\x61\xf8\x6c"
+			     "\x03\x9a\x0e\xa5\x3c\xd3\x47\xde"
+			     "\x75\x0c\x80\x17\xae\x22\xb9\x50"
+			     "\xe7\x5b\xf2\x89\x20\x94\x2b\xc2"
+			     "\x36\xcd\x64\xfb\x6f\x06\x9d\x11"
+			     "\xa8\x3f\xd6\x4a\xe1\x78\x0f\x83"
+			     "\x1a\xb1\x25\xbc\x53\xea\x5e\xf5"
+			     "\x8c\x00\x97\x2e\xc5\x39\xd0\x67"
+			     "\xfe\x72\x09\xa0\x14\xab\x42\xd9"
+			     "\x4d\xe4\x7b\x12\x86\x1d\xb4\x28"
+			     "\xbf\x56\xed\x61\xf8\x8f\x03\x9a"
+			     "\x31\xc8\x3c\xd3\x6a\x01\x75\x0c"
+			     "\xa3\x17\xae\x45\xdc\x50\xe7\x7e"
+			     "\x15\x89\x20\xb7\x2b\xc2\x59\xf0"
+			     "\x64\xfb\x92\x06\x9d\x34\xcb\x3f"
+			     "\xd6\x6d\x04\x78\x0f\xa6\x1a\xb1"
+			     "\x48\xdf\x53\xea\x81\x18\x8c\x23"
+			     "\xba\x2e\xc5\x5c\xf3\x67\xfe\x95"
+			     "\x09\xa0\x37\xce\x42\xd9\x70\x07"
+			     "\x7b\x12\xa9\x1d\xb4\x4b\xe2\x56"
+			     "\xed\x84\x1b\x8f\x26\xbd\x31\xc8"
+			     "\x5f\xf6\x6a\x01\x98\x0c\xa3\x3a"
+			     "\xd1\x45\xdc\x73\x0a\x7e\x15\xac"
+			     "\x20\xb7\x4e\xe5\x59\xf0\x87\x1e"
+			     "\x92\x29\xc0\x34\xcb\x62\xf9\x6d"
+			     "\x04\x9b\x0f\xa6\x3d\xd4\x48\xdf"
+			     "\x76\x0d\x81\x18\xaf\x23\xba\x51"
+			     "\xe8\x5c\xf3\x8a\x21\x95\x2c\xc3"
+			     "\x37\xce\x65\xfc\x70\x07\x9e\x12"
+			     "\xa9\x40\xd7\x4b\xe2\x79\x10\x84"
+			     "\x1b\xb2\x26\xbd\x54\xeb\x5f\xf6"
+			     "\x8d\x01\x98\x2f\xc6\x3a\xd1\x68"
+			     "\xff\x73\x0a\xa1\x15\xac\x43\xda"
+			     "\x4e\xe5\x7c\x13\x87\x1e\xb5\x29"
+			     "\xc0\x57\xee\x62\xf9\x90\x04\x9b"
+			     "\x32\xc9\x3d\xd4\x6b\x02\x76\x0d"
+			     "\xa4\x18\xaf\x46\xdd\x51\xe8\x7f"
+			     "\x16\x8a\x21\xb8\x2c\xc3\x5a\xf1"
+			     "\x65\xfc\x93\x07\x9e\x35\xcc\x40"
+			     "\xd7\x6e\x05\x79\x10\xa7\x1b\xb2"
+			     "\x49\xe0\x54\xeb\x82\x19\x8d\x24"
+			     "\xbb\x2f\xc6\x5d\xf4\x68\xff\x96"
+			     "\x0a\xa1\x38\xcf\x43\xda\x71\x08"
+			     "\x7c\x13\xaa\x1e\xb5\x4c\xe3\x57"
+			     "\xee\x85\x1c\x90\x27\xbe\x32\xc9"
+			     "\x60\xf7\x6b\x02\x99\x0d\xa4\x3b"
+			     "\xd2\x46\xdd\x74\x0b\x7f\x16\xad"
+			     "\x21\xb8\x4f\xe6\x5a\xf1\x88\x1f"
+			     "\x93\x2a\xc1\x35\xcc\x63\xfa\x6e"
+			     "\x05\x9c\x10\xa7\x3e\xd5\x49\xe0"
+			     "\x77\x0e\x82\x19\xb0\x24\xbb\x52"
+			     "\xe9\x5d\xf4\x8b\x22\x96\x2d\xc4"
+			     "\x38\xcf\x66\xfd\x71\x08\x9f\x13"
+			     "\xaa\x41\xd8\x4c\xe3\x7a\x11\x85"
+			     "\x1c\xb3\x27\xbe\x55\xec\x60\xf7"
+			     "\x8e\x02\x99\x30\xc7\x3b\xd2\x69"
+			     "\x00\x74\x0b\xa2\x16\xad\x44\xdb"
+			     "\x4f\xe6\x7d\x14\x88\x1f\xb6\x2a"
+			     "\xc1\x58\xef\x63\xfa\x91\x05\x9c"
+			     "\x33\xca\x3e\xd5\x6c\x03\x77\x0e"
+			     "\xa5\x19\xb0\x47\xde\x52\xe9\x80"
+			     "\x17\x8b\x22\xb9\x2d\xc4\x5b\xf2"
+			     "\x66\xfd\x94\x08\x9f\x36\xcd\x41"
+			     "\xd8\x6f\x06\x7a\x11\xa8\x1c\xb3"
+			     "\x4a\xe1\x55\xec\x83\x1a\x8e\x25"
+			     "\xbc\x30\xc7\x5e\xf5\x69\x00\x97"
+			     "\x0b\xa2\x39\xd0\x44\xdb\x72\x09"
+			     "\x7d\x14\xab\x1f\xb6\x4d\xe4\x58"
+			     "\xef\x86\x1d\x91\x28\xbf\x33\xca"
+			     "\x61\xf8\x6c\x03\x9a\x0e\xa5\x3c"
+			     "\xd3\x47\xde\x75\x0c\x80\x17\xae"
+			     "\x22\xb9\x50\xe7\x5b\xf2\x89\x20"
+			     "\x94\x2b\xc2\x36\xcd\x64\xfb\x6f"
+			     "\x06\x9d\x11\xa8\x3f\xd6\x4a\xe1"
+			     "\x78\x0f\x83\x1a\xb1\x25\xbc\x53"
+			     "\xea\x5e\xf5\x8c\x00\x97\x2e\xc5"
+			     "\x39\xd0\x67\xfe\x72\x09\xa0\x14"
+			     "\xab\x42\xd9\x4d\xe4\x7b\x12\x86"
+			     "\x1d\xb4\x28\xbf\x56\xed\x61\xf8"
+			     "\x8f\x03\x9a\x31\xc8\x3c\xd3\x6a"
+			     "\x01\x75\x0c\xa3\x17\xae\x45\xdc"
+			     "\x50\xe7\x7e\x15\x89\x20\xb7\x2b"
+			     "\xc2\x59\xf0\x64\xfb\x92\x06\x9d"
+			     "\x34\xcb\x3f\xd6\x6d\x04\x78\x0f"
+			     "\xa6\x1a\xb1\x48\xdf\x53\xea\x81"
+			     "\x18\x8c\x23\xba\x2e\xc5\x5c\xf3"
+			     "\x67\xfe\x95\x09\xa0\x37\xce\x42"
+			     "\xd9\x70\x07\x7b\x12\xa9\x1d\xb4"
+			     "\x4b\xe2\x56\xed\x84\x1b\x8f\x26"
+			     "\xbd\x31\xc8\x5f\xf6\x6a\x01\x98",
+		.psize = 2048,
+		.digest = "\x4b\x82\xa5\x0e\x72\x01\x0b\xc6",
+	}
+};
+
 static const u8 zeroes[4096] = { [0 ... 4095] = 0 };
 static const u8 ones[4096] = { [0 ... 4095] = 0xff };
 
diff -Naur --no-dereference a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
--- a/Documentation/devicetree/bindings/arm/ti/k3.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -31,6 +31,18 @@
           - const: phytec,am62a-phycore-som
           - const: ti,am62a7
 
+       - description: K3 AM62D2 SoC and Boards
+         items:
+           - enum:
+               - ti,am62d2-evm
+        - const: ti,am62d2
+
+      - description: K3 AM62L3 SoC and Boards
+        items:
+          - enum:
+              - ti,am62l3-evm
+          - const: ti,am62l3
+
       - description: K3 AM62P5 SoC and Boards
         items:
           - enum:
@@ -46,16 +58,24 @@
       - description: K3 AM625 SoC
         items:
           - enum:
+              - beagle,am62-pocketbeagle2
               - beagle,am625-beagleplay
               - ti,am625-sk
               - ti,am62-lp-sk
           - const: ti,am625
 
+      - description: K3 AM6254xxl SiP
+        items:
+          - enum:
+              - ti,am6254xxl-sk
+          - const: ti,am6254xxl
+
       - description: K3 AM62x SoC Toradex Verdin Modules and Carrier Boards
         items:
           - enum:
               - toradex,verdin-am62-nonwifi-dahlia # Verdin AM62 Module on Dahlia
               - toradex,verdin-am62-nonwifi-dev    # Verdin AM62 Module on Verdin Development Board
+              - toradex,verdin-am62-nonwifi-ivy    # Verdin AM62 Module on Ivy
               - toradex,verdin-am62-nonwifi-mallow # Verdin AM62 Module on Mallow
               - toradex,verdin-am62-nonwifi-yavia  # Verdin AM62 Module on Yavia
           - const: toradex,verdin-am62-nonwifi     # Verdin AM62 Module without Wi-Fi / BT
@@ -67,6 +87,7 @@
           - enum:
               - toradex,verdin-am62-wifi-dahlia # Verdin AM62 Wi-Fi / BT Module on Dahlia
               - toradex,verdin-am62-wifi-dev    # Verdin AM62 Wi-Fi / BT M. on Verdin Development B.
+              - toradex,verdin-am62-wifi-ivy    # Verdin AM62 Wi-Fi / BT Module on Ivy
               - toradex,verdin-am62-wifi-mallow # Verdin AM62 Wi-Fi / BT Module on Mallow
               - toradex,verdin-am62-wifi-yavia  # Verdin AM62 Wi-Fi / BT Module on Yavia
           - const: toradex,verdin-am62-wifi     # Verdin AM62 Wi-Fi / BT Module
@@ -144,6 +165,12 @@
               - ti,j722s-evm
           - const: ti,j722s
 
+      - description: K3 J742S2 SoC
+        items:
+          - enum:
+              - ti,j742s2-evm
+          - const: ti,j742s2
+
       - description: K3 J784s4 SoC
         items:
           - enum:
diff -Naur --no-dereference a/Documentation/devicetree/bindings/arm/ti/omap.yaml b/Documentation/devicetree/bindings/arm/ti/omap.yaml
--- a/Documentation/devicetree/bindings/arm/ti/omap.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/arm/ti/omap.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -107,6 +107,7 @@
               - compulab,cm-t335
               - moxa,uc-8100-me-t
               - novatech,am335x-lxm
+              - seeed,am335x-bone-green-eco
               - ti,am335x-bone
               - ti,am335x-evm
               - ti,am3359-icev2
diff -Naur --no-dereference a/Documentation/devicetree/bindings/crypto/ti,dthev2.yaml b/Documentation/devicetree/bindings/crypto/ti,dthev2.yaml
--- a/Documentation/devicetree/bindings/crypto/ti,dthev2.yaml	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/devicetree/bindings/crypto/ti,dthev2.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/crypto/ti,dthev2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: K3 SoC DTHE V2 crypto module
+
+maintainers:
+  - T Pratham <t-pratham@ti.com>
+
+properties:
+  compatible:
+    enum:
+      - ti,am62l-dthev2
+
+  reg:
+    maxItems: 1
+
+  dmas:
+    items:
+      - description: AES Engine RX DMA Channel
+      - description: AES Engine TX DMA Channel
+      - description: SHA Engine TX DMA Channel
+
+  dma-names:
+    items:
+      - const: rx
+      - const: tx1
+      - const: tx2
+
+required:
+  - compatible
+  - reg
+  - dmas
+  - dma-names
+
+additionalProperties: false
+
+examples:
+  - |
+    crypto@40800000 {
+      compatible = "ti,am62l-dthev2";
+      reg = <0x00 0x40800000 0x00 0x10000>;
+
+      dmas = <&main_bcdma 0 0 0x4700 0>,
+             <&main_bcdma 0 0 0xc701 0>,
+             <&main_bcdma 0 0 0xc700 0>;
+      dma-names = "rx", "tx1", "tx2";
+    };
diff -Naur --no-dereference a/Documentation/devicetree/bindings/crypto/ti,mcrc64.yaml b/Documentation/devicetree/bindings/crypto/ti,mcrc64.yaml
--- a/Documentation/devicetree/bindings/crypto/ti,mcrc64.yaml	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/devicetree/bindings/crypto/ti,mcrc64.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/crypto/ti,mcrc64.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments MCRC64
+
+description:
+  The MCRC64 engine calculates 64-bit cyclic redundancy checks
+  (CRC) according to the ISO 3309 standard.
+
+maintainers:
+  - Kamlesh Gurudasani <kamlesh@ti.com>
+
+properties:
+  compatible:
+    const: ti,am62-mcrc64
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+    crc@30300000 {
+      compatible = "ti,am62-mcrc64";
+      reg = <0x30300000 0x1000>;
+      clocks = <&k3_clks 116 0>;
+      power-domains = <&k3_pds 116 TI_SCI_PD_EXCLUSIVE>;
+    };
+
+...
diff -Naur --no-dereference a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml
--- a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8546.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -57,6 +57,12 @@
   interrupts:
     maxItems: 1
 
+  cdns,no-hpd:
+    type: boolean
+    description:
+      Set if the HPD line on the bridge isn't hooked up to anything or is
+      otherwise unusable.
+
   ports:
     $ref: /schemas/graph.yaml#/properties/ports
 
diff -Naur --no-dereference a/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml b/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml
--- a/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -19,6 +19,7 @@
   compatible:
     enum:
       - ite,it66121
+      - ite,it66122
       - ite,it6610
 
   reg:
diff -Naur --no-dereference a/Documentation/devicetree/bindings/display/panel/panel-edp.yaml b/Documentation/devicetree/bindings/display/panel/panel-edp.yaml
--- a/Documentation/devicetree/bindings/display/panel/panel-edp.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/display/panel/panel-edp.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -86,7 +86,11 @@
 
 properties:
   compatible:
-    const: edp-panel
+    enum:
+        # Generic Panel EDP
+      - edp-panel
+        # TI Simple Panel EDP
+      - ti,panel-edp
 
   hpd-reliable-delay-ms:
     description:
diff -Naur --no-dereference a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -248,6 +248,8 @@
       - qiaodian,qd43003c0-40
         # Shenzhen QiShenglong Industrialist Co., Ltd. Gopher 2b 4.3" 480(RGB)x272 TFT LCD panel
       - qishenglong,gopher2b-lcd
+        # Raspberry Pi 7" 800x600 LCD Panel
+      - raspberrypi,7inch-dsi
         # Rocktech Displays Ltd. RK101II01D-CT 10.1" TFT 1280x800
       - rocktech,rk101ii01d-ct
         # Rocktech Display Ltd. RK070ER9427 800(RGB)x480 TFT LCD panel
diff -Naur --no-dereference a/Documentation/devicetree/bindings/display/ti/ti,am625-oldi.yaml b/Documentation/devicetree/bindings/display/ti/ti,am625-oldi.yaml
--- a/Documentation/devicetree/bindings/display/ti/ti,am625-oldi.yaml	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/devicetree/bindings/display/ti/ti,am625-oldi.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/ti/ti,am625-oldi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments AM625 OLDI Transmitter
+
+maintainers:
+  - Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+  - Aradhya Bhatia <aradhya.bhatia@linux.dev>
+
+description:
+  The AM625 TI Keystone OpenLDI transmitter (OLDI TX) supports serialized RGB
+  pixel data transmission between host and flat panel display over LVDS (Low
+  Voltage Differential Sampling) interface. The OLDI TX consists of 7-to-1 data
+  serializers, and 4-data and 1-clock LVDS outputs. It supports the LVDS output
+  formats "jeida-18", "jeida-24" and "vesa-18", and can accept 24-bit RGB or
+  padded and un-padded 18-bit RGB bus formats as input.
+
+properties:
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: serial clock input for the OLDI transmitters
+
+  clock-names:
+    const: serial
+
+  ti,companion-oldi:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      phandle to companion OLDI transmitter. This property is mandatory for the
+      primarty OLDI TX if the OLDI TXes are expected to work either in dual-lvds
+      mode or in clone mode. This property should point to the secondary OLDI
+      TX.
+
+  ti,secondary-oldi:
+    type: boolean
+    description:
+      Boolean property to mark the OLDI transmitter as the secondary one, when the
+      OLDI hardware is expected to run as a companion HW, in cases of dual-lvds
+      mode or clone mode. The primary OLDI hardware is responsible for all the
+      hardware configuration.
+
+  ti,oldi-io-ctrl:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      phandle to syscon device node mapping OLDI IO_CTRL registers found in the
+      control MMR region. These registers are required to toggle the I/O lane
+      power, and control its electrical characteristics.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Parallel RGB input port
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: LVDS output port
+
+    required:
+      - port@0
+      - port@1
+
+allOf:
+  - if:
+      required:
+        - ti,secondary-oldi
+    then:
+      properties:
+        ti,companion-oldi: false
+
+required:
+  - reg
+  - clocks
+  - clock-names
+  - ti,oldi-io-ctrl
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+    oldi-transmitters {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        oldi: oldi@0 {
+            reg = <0>;
+            clocks = <&k3_clks 186 0>;
+            clock-names = "serial";
+            ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+                port@0 {
+                    reg = <0>;
+                    oldi_in: endpoint {
+                        remote-endpoint = <&dpi_out>;
+                    };
+                };
+                port@1 {
+                    reg = <1>;
+                    oldi_out: endpoint {
+                        remote-endpoint = <&panel_in>;
+                    };
+                };
+            };
+        };
+    };
+
+...
diff -Naur --no-dereference a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
--- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -12,19 +12,32 @@
   - Tomi Valkeinen <tomi.valkeinen@ti.com>
 
 description: |
-  The AM625 and AM65x TI Keystone Display SubSystem with two output
+  The AM625 and AM65x TI Keystone Display SubSystem has two output
   ports and two video planes. In AM65x DSS, the first video port
   supports 1 OLDI TX and in AM625 DSS, the first video port output is
   internally routed to 2 OLDI TXes. The second video port supports DPI
   format. The first plane is full video plane with all features and the
   second is a "lite plane" without scaling support.
+  The AM62A7 display subsystem has a single output port supporting DPI format
+  although similar to AM625 and AM65x Socs, it has two video planes where first
+  is full video plane with all features and second is a video "lite" plane which
+  does not support scaling.
+  The AM62L display subsystem also has a single output port which supports DPI
+  format but it only supports single video "lite plane" which does not support
+  scaling. The output port is routed to SoC boundary via DPI interface and same
+  DPI signals are also routed internally to DSI Tx controller present within the
+  SoC. Due to clocking limitations only one of the interface i.e. either DSI or
+  DPI can be used at once.
 
 properties:
   compatible:
     enum:
       - ti,am625-dss
-      - ti,am62a7,dss
+      - ti,am62a7-dss
+      - ti,am62p51-dss
+      - ti,am62p52-dss
       - ti,am65x-dss
+      - ti,am62l-dss
 
   reg:
     description:
@@ -74,7 +87,8 @@
     maxItems: 1
 
   power-domains:
-    maxItems: 1
+    minItems: 1
+    maxItems: 3
     description: phandle to the associated power domain
 
   dma-coherent:
@@ -88,14 +102,37 @@
         $ref: /schemas/graph.yaml#/properties/port
         description:
           For AM65x DSS, the OLDI output port node from video port 1.
-          For AM625 DSS, the internal DPI output port node from video
-          port 1.
+          For AM625, and AM62P5-1/2 DSS, the internal DPI output port
+          node from video port 1.
           For AM62A7 DSS, the port is tied off inside the SoC.
+          For AM62L DSS, the DSS DPI output port node from video port 1
+          or DSI Tx controller node connected to video port 1.
+
+        properties:
+          endpoint@0:
+            $ref: /schemas/graph.yaml#/properties/endpoint
+            description:
+              For AM625/AM62P5-1 DSS, VP Connection to OLDI0.
+              For AM62P5-2 DSS, VP Connection to OLDI1 or the DPI pipe.
+              For AM65X DSS, OLDI output from the SoC.
+
+          endpoint@1:
+            $ref: /schemas/graph.yaml#/properties/endpoint
+            description:
+              For AM625/AM62P5-1 DSS, VP Connection to OLDI1.
+
+        anyOf:
+          - required:
+              - endpoint
+          - required:
+              - endpoint@0
+              - endpoint@1
 
       port@1:
         $ref: /schemas/graph.yaml#/properties/port
         description:
-          The DSS DPI output port node from video port 2
+          The DSS DPI output port node from video port 2.
+          For AM62P5-2 DSS, VP Connection to DSI Tx or the DPI pipe.
 
   ti,am65x-oldi-io-ctrl:
     $ref: /schemas/types.yaml#/definitions/phandle
@@ -112,6 +149,26 @@
       Input memory (from main memory to dispc) bandwidth limit in
       bytes per second
 
+  oldi-transmitters:
+    description:
+      Child node under the DSS, to describe all the OLDI transmitters connected
+      to the DSS videoports.
+    type: object
+    additionalProperties: false
+    properties:
+      "#address-cells":
+        const: 1
+
+      "#size-cells":
+        const: 0
+
+    patternProperties:
+      '^oldi@[0-1]$':
+        type: object
+        $ref: ti,am625-oldi.yaml#
+        unevaluatedProperties: false
+        description: OLDI transmitters connected to the DSS VPs
+
 allOf:
   - if:
       properties:
@@ -123,6 +180,32 @@
         ports:
           properties:
             port@0: false
+            oldi-transmitters: false
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - ti,am65x-dss
+              - ti,am62p52-dss
+    then:
+      properties:
+        oldi-transmitters: false
+        port@0:
+          properties:
+            endpoint@1: false
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: ti,am62l-dss
+    then:
+      properties:
+        ports:
+          properties:
+            port@1: false
 
 required:
   - compatible
@@ -142,32 +225,134 @@
     #include <dt-bindings/soc/ti,sci_pm_domain.h>
 
     dss: dss@4a00000 {
-            compatible = "ti,am65x-dss";
-            reg =   <0x04a00000 0x1000>, /* common */
-                    <0x04a02000 0x1000>, /* vidl1 */
-                    <0x04a06000 0x1000>, /* vid */
-                    <0x04a07000 0x1000>, /* ovr1 */
-                    <0x04a08000 0x1000>, /* ovr2 */
-                    <0x04a0a000 0x1000>, /* vp1 */
-                    <0x04a0b000 0x1000>, /* vp2 */
-                    <0x04a01000 0x1000>; /* common1 */
+        compatible = "ti,am65x-dss";
+        reg = <0x04a00000 0x1000>, /* common */
+              <0x04a02000 0x1000>, /* vidl1 */
+              <0x04a06000 0x1000>, /* vid */
+              <0x04a07000 0x1000>, /* ovr1 */
+              <0x04a08000 0x1000>, /* ovr2 */
+              <0x04a0a000 0x1000>, /* vp1 */
+              <0x04a0b000 0x1000>, /* vp2 */
+              <0x04a01000 0x1000>; /* common1 */
+        reg-names = "common", "vidl1", "vid",
+                "ovr1", "ovr2", "vp1", "vp2", "common1";
+        ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+        power-domains = <&k3_pds 67 TI_SCI_PD_EXCLUSIVE>;
+        clocks =        <&k3_clks 67 1>,
+                        <&k3_clks 216 1>,
+                        <&k3_clks 67 2>;
+        clock-names = "fck", "vp1", "vp2";
+        interrupts = <GIC_SPI 166 IRQ_TYPE_EDGE_RISING>;
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+            port@0 {
+                reg = <0>;
+                oldi_out0: endpoint {
+                    remote-endpoint = <&lcd_in0>;
+                };
+            };
+        };
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+        dss1: dss@30200000 {
+            compatible = "ti,am625-dss";
+            reg = <0x00 0x30200000 0x00 0x1000>, /* common */
+                  <0x00 0x30202000 0x00 0x1000>, /* vidl1 */
+                  <0x00 0x30206000 0x00 0x1000>, /* vid */
+                  <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
+                  <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
+                  <0x00 0x3020a000 0x00 0x1000>, /* vp1 */
+                  <0x00 0x3020b000 0x00 0x1000>, /* vp2 */
+                  <0x00 0x30201000 0x00 0x1000>; /* common1 */
             reg-names = "common", "vidl1", "vid",
-                    "ovr1", "ovr2", "vp1", "vp2", "common1";
-            ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
-            power-domains = <&k3_pds 67 TI_SCI_PD_EXCLUSIVE>;
-            clocks =        <&k3_clks 67 1>,
-                            <&k3_clks 216 1>,
-                            <&k3_clks 67 2>;
+                        "ovr1", "ovr2", "vp1", "vp2", "common1";
+            power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
+            clocks =        <&k3_clks 186 6>,
+                            <&vp1_clock>,
+                            <&k3_clks 186 2>;
             clock-names = "fck", "vp1", "vp2";
-            interrupts = <GIC_SPI 166 IRQ_TYPE_EDGE_RISING>;
+            interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+            oldi-transmitters {
+                #address-cells = <1>;
+                #size-cells = <0>;
+                oldi0: oldi@0 {
+                    reg = <0>;
+                    clocks = <&k3_clks 186 0>;
+                    clock-names = "serial";
+                    ti,companion-oldi = <&oldi1>;
+                    ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+                    ports {
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+                        port@0 {
+                            reg = <0>;
+                            oldi0_in: endpoint {
+                                remote-endpoint = <&dpi0_out0>;
+                            };
+                        };
+                        port@1 {
+                            reg = <1>;
+                            oldi0_out: endpoint {
+                                remote-endpoint = <&panel_in0>;
+                            };
+                        };
+                    };
+                };
+                oldi1: oldi@1 {
+                    reg = <1>;
+                    clocks = <&k3_clks 186 0>;
+                    clock-names = "serial";
+                    ti,secondary-oldi;
+                    ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+                    ports {
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+                        port@0 {
+                            reg = <0>;
+                            oldi1_in: endpoint {
+                                remote-endpoint = <&dpi0_out1>;
+                            };
+                        };
+                        port@1 {
+                            reg = <1>;
+                            oldi1_out: endpoint {
+                                remote-endpoint = <&panel_in1>;
+                            };
+                        };
+                    };
+                };
+            };
             ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+                port@0 {
                     #address-cells = <1>;
                     #size-cells = <0>;
-                    port@0 {
-                            reg = <0>;
-                            oldi_out0: endpoint {
-                                    remote-endpoint = <&lcd_in0>;
-                            };
+                    reg = <0>;
+                    dpi0_out0: endpoint@0 {
+                        reg = <0>;
+                        remote-endpoint = <&oldi0_in>;
+                    };
+                    dpi0_out1: endpoint@1 {
+                        reg = <1>;
+                        remote-endpoint = <&oldi1_in>;
+                    };
+                };
+                port@1 {
+                    reg = <1>;
+                    dpi1_out: endpoint {
+                        remote-endpoint = <&hdmi_bridge>;
                     };
+                };
             };
+        };
     };
diff -Naur --no-dereference a/Documentation/devicetree/bindings/dma/ti/k3-bcdma-v2.yaml b/Documentation/devicetree/bindings/dma/ti/k3-bcdma-v2.yaml
--- a/Documentation/devicetree/bindings/dma/ti/k3-bcdma-v2.yaml	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/devicetree/bindings/dma/ti/k3-bcdma-v2.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2024-2025 Texas Instruments Incorporated
+# Author: Sai Sree Kartheek Adivi <s-adivi@ti.com>
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/ti/k3-bcdma-v2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments K3 DMSS BCDMA V2
+
+maintainers:
+  - Sai Sree Kartheek Adivi <s-adivi@ti.com>
+
+description: |
+  The BCDMA V2 is intended to perform similar functions as the TR
+  mode channels of K3 UDMA-P.
+  BCDMA V2 includes block copy channels and Split channels.
+
+  Block copy channels mainly used for memory to memory transfers, but with
+  optional triggers a block copy channel can service peripherals by accessing
+  directly to memory mapped registers or area.
+
+  Split channels can be used to service PSI-L based peripherals.
+  The peripherals can be PSI-L native or legacy, non PSI-L native peripherals
+  with PDMAs. PDMA is tasked to act as a bridge between the PSI-L fabric and the
+  legacy peripheral.
+
+allOf:
+  - $ref: /schemas/dma/dma-controller.yaml#
+
+properties:
+  compatible:
+    const: ti,am62l-dmss-bcdma
+
+  reg:
+    items:
+      - description: BCDMA Control /Status Registers region
+      - description: Block Copy Channel Realtime Registers region
+      - description: Channel Realtime Registers region
+      - description: Ring Realtime Registers region
+
+  reg-names:
+    items:
+      - const: gcfg
+      - const: bchanrt
+      - const: chanrt
+      - const: ringrt
+
+  "#dma-cells":
+    const: 4
+    description: |
+      cell 1: Trigger type for the channel
+        0 - disable / no trigger
+        1 - internal channel event
+        2 - external signal
+        3 - timer manager event
+
+      cell 2: parameter for the trigger:
+        if cell 1 is 0 (disable / no trigger):
+          Unused, ignored
+        if cell 1 is 1 (internal channel event):
+          channel number whose TR event should trigger the current channel.
+        if cell 1 is 2 or 3 (external signal or timer manager event):
+          index of global interfaces that come into the DMA.
+
+          Please refer to the device documentation for global interface indexes.
+
+      cell 3: Channel number for the peripheral
+
+        Please refer to the device documentation for the channel map.
+
+      cell 4: ASEL value for the channel
+
+required:
+  - compatible
+  - "#dma-cells"
+  - reg
+  - reg-names
+
+unevaluatedProperties: false
+
+examples:
+  - |+
+    cbass_main {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+      main_bcdma: dma-controller@485c4000 {
+          compatible = "ti,am62l-dmss-bcdma";
+          reg = <0x00 0x485c4000 0x00 0x4000>,
+                <0x00 0x48880000 0x00 0x10000>,
+                <0x00 0x48800000 0x00 0x80000>,
+                <0x00 0x47000000 0x00 0x200000>;
+          reg-names = "gcfg", "bchanrt", "chanrt", "ringrt";
+          #dma-cells = <4>;
+        };
+    };
diff -Naur --no-dereference a/Documentation/devicetree/bindings/dma/ti/k3-bcdma.yaml b/Documentation/devicetree/bindings/dma/ti/k3-bcdma.yaml
--- a/Documentation/devicetree/bindings/dma/ti/k3-bcdma.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/dma/ti/k3-bcdma.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -34,6 +34,7 @@
       - ti,am62a-dmss-bcdma-csirx
       - ti,am64-dmss-bcdma
       - ti,j721s2-dmss-bcdma-csi
+      - ti,j722s-dmss-bcdma-csi
 
   reg:
     minItems: 3
@@ -196,7 +197,9 @@
       properties:
         compatible:
           contains:
-            const: ti,j721s2-dmss-bcdma-csi
+            enum:
+              - ti,j721s2-dmss-bcdma-csi
+              - ti,j722s-dmss-bcdma-csi
     then:
       properties:
         ti,sci-rm-range-bchan: false
diff -Naur --no-dereference a/Documentation/devicetree/bindings/dma/ti/k3-pktdma-v2.yaml b/Documentation/devicetree/bindings/dma/ti/k3-pktdma-v2.yaml
--- a/Documentation/devicetree/bindings/dma/ti/k3-pktdma-v2.yaml	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/devicetree/bindings/dma/ti/k3-pktdma-v2.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2024-2025 Texas Instruments Incorporated
+# Author: Sai Sree Kartheek Adivi <s-adivi@ti.com>
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/ti/k3-pktdma-v2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments K3 DMSS PKTDMA V2
+
+maintainers:
+  - Sai Sree Kartheek Adivi <s-adivi@ti.com>
+
+description: |
+  The PKTDMA V2 is intended to perform similar functions as the packet
+  mode channels of K3 UDMA-P.
+  PKTDMA V2 only includes Split channels to service PSI-L based peripherals.
+
+  The peripherals can be PSI-L native or legacy, non PSI-L native peripherals
+  with PDMAs. PDMA is tasked to act as a bridge between the PSI-L fabric and the
+  legacy peripheral.
+
+allOf:
+  - $ref: /schemas/dma/dma-controller.yaml#
+
+properties:
+  compatible:
+    const: ti,am62l-dmss-pktdma
+
+  "#dma-cells":
+    const: 2
+    description: |
+      cell 1: Channel number for the peripheral
+
+        Please refer to the device documentation for the channel map.
+
+      cell 2: ASEL value for the channel
+
+  reg:
+    items:
+      - description: Packet DMA Control /Status Registers region
+      - description: Channel Realtime Registers region
+      - description: Ring Realtime Registers region
+
+  reg-names:
+    items:
+      - const: gcfg
+      - const: chanrt
+      - const: ringrt
+
+required:
+  - compatible
+  - "#dma-cells"
+  - reg
+  - reg-names
+
+unevaluatedProperties: false
+
+examples:
+  - |+
+    cbass_main {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+      main_pktdma: dma-controller@485c0000 {
+        compatible = "ti,am62l-dmss-pktdma";
+        reg = <0x00 0x485c0000 0x00 0x4000>,
+          <0x00 0x48900000 0x00 0x80000>,
+          <0x00 0x47200000 0x00 0x100000>;
+        reg-names = "gcfg", "chanrt", "ringrt";
+        #dma-cells = <2>;
+      };
+    };
diff -Naur --no-dereference a/Documentation/devicetree/bindings/gpu/ti,rogue.yaml b/Documentation/devicetree/bindings/gpu/ti,rogue.yaml
--- a/Documentation/devicetree/bindings/gpu/ti,rogue.yaml	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/devicetree/bindings/gpu/ti,rogue.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,191 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpu/ti,rogue.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments PowerVR Rogue GPU
+
+description: |
+  PowerVR Rogue is a family of 3D graphics processing units from Imagination
+  Technologies. Texas Instruments SoCs have integrated different generations of
+  PowerVR GPUs and this binding describes the GPU's integrated in Texas
+  Instruments SoCs in the K3 generation.
+
+maintainers:
+  - Darren Etheridge <detheridge@ti.com>
+  - Randolph Sapp <rs@ti.com>
+  - Antonios Christidis <a-christidis@ti.com>
+
+properties:
+  $nodename:
+    pattern: '^gpu@[a-f0-9]+$'
+
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - ti,j721s2-pvr
+          - const: img,pvr-bxs64
+      - items:
+          - enum:
+              - ti,j721e-pvr
+          - const: img,pvr-ge8430
+      - items:
+          - enum:
+              - ti,am62p-pvr
+          - const: img,pvr-bxs64
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    maxItems: 1
+
+  power-domains:
+    minItems: 1
+    maxItems: 2
+
+  power-domain-names:
+    maxItems: 2
+
+  assigned-clocks:
+    maxItems: 1
+
+  assigned-clock-rates:
+    maxItems: 1
+    description: |
+      Allows users to override the default clock value used for the GPU.
+      Currently ignored on devices other than ti,am62p-pvr. This will be ported
+      to other devices soon.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - ti,am62p-pvr
+              - ti,j721e-pvr
+              - ti,j721s2-pvr
+    then:
+      required:
+        - power-domain-names
+        - assigned-clocks
+        - clock-names
+      properties:
+        reg:
+          minItems: 1
+        interrupts:
+          minItems: 1
+        clocks:
+          minItems: 1
+        clock-names:
+          items:
+            - const: core
+        power-domains:
+          minItems: 2
+        power-domain-names:
+          items:
+            - const: firmware
+            - const: dust
+        assigned-clocks:
+          minItems: 1
+        assigned-clock-rates:
+          default: [800000000]
+    else:
+      properties:
+        assigned-clocks: false
+        assigned-clock-rates: false
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - ti,j721e-pvr
+    then:
+      properties:
+        assigned-clock-rates:
+          default: [750000000]
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+        gpu@4e20000000 {
+            compatible = "ti,j721s2-pvr", "img,pvr-bxs64";
+            reg = <0x4e 0x20000000 0x00 0x80000>;
+            interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+            power-domains = <&k3_pds 130 TI_SCI_PD_EXCLUSIVE>,
+                            <&k3_pds 373 TI_SCI_PD_EXCLUSIVE>;
+            power-domain-names = "firmware", "dust";
+            clocks = <&k3_clks 130 1>;
+            assigned-clocks = <&k3_clks 130 1>;
+            assigned-clock-rates = <800000000>;
+            clock-names = "core";
+        };
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+        gpu@4e20000000 {
+            compatible = "ti,j721e-pvr", "img,pvr-ge8430";
+            reg = <0x4e 0x20000000 0x00 0x80000>;
+            interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+            power-domains = <&k3_pds 125 TI_SCI_PD_EXCLUSIVE>,
+                            <&k3_pds 126 TI_SCI_PD_EXCLUSIVE>;
+            power-domain-names = "firmware", "dust";
+            clocks = <&k3_clks 125 0>;
+            assigned-clocks = <&k3_clks 125 0>;
+            assigned-clock-rates = <750000000>;
+            clock-names = "core";
+        };
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+        gpu@fd80000 {
+            compatible = "ti,am62p-pvr", "img,pvr-bxs64";
+            reg = <0x00 0x0fd80000 0x00 0x80000>;
+            interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>;
+            power-domains = <&k3_pds 237 TI_SCI_PD_EXCLUSIVE>,
+                            <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>;
+            assigned-clocks = <&k3_clks 237 3>;
+            assigned-clock-rates = <720000000>;
+            power-domain-names = "firmware", "dust";
+            clocks = <&k3_clks 237 3>;
+            clock-names = "core";
+        };
+    };
diff -Naur --no-dereference a/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml b/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml
--- a/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -47,6 +47,11 @@
     $ref: /schemas/types.yaml#/definitions/string
     deprecated: true
 
+  mux-states:
+    description:
+      mux controller node to route the I2C signals form SoC to clients.
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff -Naur --no-dereference a/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
--- a/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -24,6 +24,14 @@
   reg:
     maxItems: 1
 
+  interrupts:
+    maxItems: 2
+
+  interrupt-names:
+    items:
+      - const: error_irq
+      - const: irq
+
   clocks:
     items:
       - description: CSI2Rx system clock
diff -Naur --no-dereference a/Documentation/devicetree/bindings/media/i2c/ovti,ov1063x.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov1063x.yaml
--- a/Documentation/devicetree/bindings/media/i2c/ovti,ov1063x.yaml	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/devicetree/bindings/media/i2c/ovti,ov1063x.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,104 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2025 Texas Instruments Incorporated -  http://www.ti.com/
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/ovti,ov1063x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: OmniVision OV10633/OV10635 8/10 bit digital Camera Sensor
+
+maintainers:
+  - Benoit Parrot   <bparrot@ti.com>
+  - Sukrut Bellary  <sbellary@baylibre.com>
+                    <x1125864@ti.com>
+
+description: |-
+  The OmniVision OV1063x is a 720p(HD) camera sensor which supports resolutions
+  up to 1280x800(WXGA) and 8/10-bit YUV output formats.
+
+  Each camera nodes should contain a 'port' child node with child
+  'endpoint' node. Please refer to the bindings defined in
+  Documentation/devicetree/bindings/media/video-interfaces.yaml.
+
+properties:
+  compatible:
+    enum:
+      - ovti,ov10633
+      - ovti,ov10635
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: xvclk
+
+  reset-gpios:
+    maxItems: 1
+    description:
+      phandle to the GPIO connected to the RESETB pin, if any.
+
+  powerdown-gpios:
+    maxItems: 1
+    description:
+      phandle for the GPIO connected to the PWDN pin, if any.
+
+  port:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    additionalProperties: false
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          hsync-active: true
+          vsync-active: true
+          pclk-sample: true
+          bus-width:
+            enum: [ 8, 10 ]
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+        clock-frequency = <400000>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        camera@30 {
+            compatible = "ovti,ov10635";
+            reg = <0x30>;
+
+            clocks = <&fixed_clock>;
+            clock-names = "xvclk";
+
+            reset-gpios = <&gpio4 17 GPIO_ACTIVE_HIGH>;
+            powerdown-gpios = <&gpio5 11 GPIO_ACTIVE_HIGH>;
+
+            port {
+                camera1: endpoint {
+                     remote-endpoint = <&vin1a_ep>;
+                     hsync-active = <1>;
+                     vsync-active = <1>;
+                     pclk-sample = <0>;
+                     bus-width = <8>;
+                };
+            };
+        };
+    };
+
+...
diff -Naur --no-dereference a/Documentation/devicetree/bindings/media/i2c/ovti,ox05b.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ox05b.yaml
--- a/Documentation/devicetree/bindings/media/i2c/ovti,ox05b.yaml	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/devicetree/bindings/media/i2c/ovti,ox05b.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,87 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/ovti,ox05b.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: OmniVision OX05B1S Camera Sensor
+
+maintainers:
+  - Abhishek Sharma <abhishek.sharma@ti.com>
+
+description: |-
+  Omnivision OX05B1S is an RGBIR camera sensor with an active array size of
+  2592x1944. It is programmable through the I2C interface. The i2c client
+  address is fixed at 0x36 as per the sensor datasheet. Every alternate frame,
+  the sensor changes the exposure/gain registers to stream an -
+  A. IR-dominant frame on CSI-2 virtual channel 0
+  B. RGB-dominant frame on CSI-2 virtual channel 1
+
+  Both streams are captured at a resolution 2592x1944, 30 fps each
+  (60 fps total). The sensor also supports a few v4l2 controls like
+  exposure and gain controls.
+
+properties:
+  compatible:
+    enum:
+      - ovti,ox05b
+
+  reg:
+    description: I2C address
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: inck
+
+  pwdn-gpios:
+    maxItems: 1
+    description:
+      Specifier for the GPIO connected to the PWDN pin.
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    additionalProperties: false
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      ox05b1s: camera@36 {
+        compatible = "ovti,ox05b";
+        reg = <0x36>;
+
+        clocks = <&clk_ox05b1s_fixed>;
+        clock-names = "inck";
+
+        pwdn-gpios = <&exp1 13 GPIO_ACTIVE_LOW>;
+
+        port {
+          csi2_cam0: endpoint {
+            remote-endpoint = <&csi2rx0_in_sensor>;
+          };
+        };
+      };
+    };
+
+...
diff -Naur --no-dereference a/Documentation/devicetree/bindings/media/i2c/sony,imx728.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx728.yaml
--- a/Documentation/devicetree/bindings/media/i2c/sony,imx728.yaml	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/devicetree/bindings/media/i2c/sony,imx728.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/sony,imx728.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sony IMX728 Camera Sensor
+
+maintainers:
+  - Stuart Burtner <sburtner@d3embedded.com>
+
+description:
+  The Sony IMX728 is a 1/1.72-Inch CMOS Solid-state image sensor with a
+  color square pixel array and 8.39M active pixels. It is programmed
+  through an I2C interface.
+
+  The sensor can output up to 3840x2160 at a maximum of 45 frames/s over
+  a CSI-2 serial interface. It supports RAW24/20/16/12 and 10.
+
+properties:
+  compatible:
+    enum:
+      - sony,imx728
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    description: Clock frequency from 18 to 30MHz
+    maxItems: 1
+
+  clock-names:
+    const: inck
+
+  reset-gpios:
+    maxItems: 1
+    description:
+      XCLR (System Reset) pin.
+
+  error0-gpios:
+    maxItems: 1
+    description:
+      XWRN pin.
+
+  error1-gpios:
+    maxItems: 1
+    description:
+      XERR pin.
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    additionalProperties: false
+
+    properties:
+      endpoint:
+        $ref: ../video-interfaces.yaml#
+        unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        camera@1a {
+            compatible = "sony,imx728";
+            reg = <0x1a>;
+
+            clocks = <&fixed_clock>;
+            clock-names = "inck";
+
+            reset-gpios = <&gpio4 17 GPIO_ACTIVE_LOW>;
+            error0-gpios = <&sens_exp 1 GPIO_ACTIVE_HIGH>;
+            error1-gpios = <&sens_exp 2 GPIO_ACTIVE_HIGH>;
+
+            port {
+                camera1: endpoint {
+                    remote-endpoint = <&vin1a_ep>;
+                };
+            };
+        };
+    };
+
+...
diff -Naur --no-dereference a/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml b/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml
--- a/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -19,6 +19,7 @@
 properties:
   compatible:
     enum:
+      - ti,ds90ub954-q1
       - ti,ds90ub960-q1
       - ti,ds90ub9702-q1
 
diff -Naur --no-dereference a/Documentation/devicetree/bindings/media/ti,j721e-csi2rx-shim.yaml b/Documentation/devicetree/bindings/media/ti,j721e-csi2rx-shim.yaml
--- a/Documentation/devicetree/bindings/media/ti,j721e-csi2rx-shim.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/media/ti,j721e-csi2rx-shim.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -20,11 +20,44 @@
     const: ti,j721e-csi2rx-shim
 
   dmas:
-    maxItems: 1
+    minItems: 1
+    maxItems: 32
 
   dma-names:
+    minItems: 1
     items:
       - const: rx0
+      - const: rx1
+      - const: rx2
+      - const: rx3
+      - const: rx4
+      - const: rx5
+      - const: rx6
+      - const: rx7
+      - const: rx8
+      - const: rx9
+      - const: rx10
+      - const: rx11
+      - const: rx12
+      - const: rx13
+      - const: rx14
+      - const: rx15
+      - const: rx16
+      - const: rx17
+      - const: rx18
+      - const: rx19
+      - const: rx20
+      - const: rx21
+      - const: rx22
+      - const: rx23
+      - const: rx24
+      - const: rx25
+      - const: rx26
+      - const: rx27
+      - const: rx28
+      - const: rx29
+      - const: rx30
+      - const: rx31
 
   reg:
     maxItems: 1
@@ -62,8 +95,8 @@
 
     ti_csi2rx0: ticsi2rx@4500000 {
         compatible = "ti,j721e-csi2rx-shim";
-        dmas = <&main_udmap 0x4940>;
-        dma-names = "rx0";
+        dmas = <&main_udmap 0x4940>, <&main_udmap 0x4941>;
+        dma-names = "rx0", "rx1";
         reg = <0x4500000 0x1000>;
         power-domains = <&k3_pds 26 TI_SCI_PD_EXCLUSIVE>;
         #address-cells = <1>;
diff -Naur --no-dereference a/Documentation/devicetree/bindings/media/ti,vip.yaml b/Documentation/devicetree/bindings/media/ti,vip.yaml
--- a/Documentation/devicetree/bindings/media/ti,vip.yaml	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/devicetree/bindings/media/ti,vip.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,311 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2025 Texas Instruments Incorporated -  http://www.ti.com/
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/ti,vip.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments DRA7x VIDEO INPUT PORT (VIP).
+
+maintainers:
+  - Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
+
+description: |-
+  The Video Input Port (VIP) is a key component for image capture
+  applications. The capture module provides the system interface and the
+  processing capability to connect parallel image-sensor as well as
+  BT.656/1120 capable encoder chip to DRA7x device.
+
+  Each VIP instance supports 2 independently configurable external video
+  input capture slices (Slice 0 and Slice 1) each providing up to two video
+  input ports (Port A and Port B) where Port A can be configured as
+  24/16/8-bit port and Port B is fixed as 8-bit port.
+  Here these ports a represented as follows
+    port@0 -> Slice 0 Port A
+    port@1 -> Slice 0 Port B
+    port@2 -> Slice 1 Port A
+    port@3 -> Slice 1 Port B
+
+  Each camera port nodes should contain a 'port' child node with child
+  'endpoint' node. Please refer to the bindings defined in
+  Documentation/devicetree/bindings/media/video-interfaces.yaml.
+
+properties:
+  compatible:
+    enum:
+      - ti,dra7-vip
+
+  label:
+    description: Instance name
+
+  reg:
+    items:
+      - description: The VIP main register region
+      - description: Video Data Parser (PARSER) register region for Slice0
+      - description: Color Space Conversion (CSC) register region for Slice0
+      - description: Scaler (SC) register region for Slice0
+      - description: Video Data Parser (PARSER) register region for Slice1
+      - description: Color Space Conversion (CSC) register region for Slice1
+      - description: Scaler (SC) register region for Slice1
+      - description: Video Port Direct Memory Access (VPDMA) register region
+
+  reg-names:
+    items:
+      - const: vip
+      - const: parser0
+      - const: csc0
+      - const: sc0
+      - const: parser1
+      - const: csc1
+      - const: sc1
+      - const: vpdma
+
+  interrupts:
+    minItems: 2
+    description:
+      IRQ index 0 is used for Slice0 interrupts
+      IRQ index 1 is used for Slice1 interrupts
+
+  ti,vip-clk-polarity:
+    $ref: "/schemas/types.yaml#/definitions/phandle-array"
+    description:
+      phandle to the device control module. The 1st argument should
+      contain the register offset to the CTRL_CORE_SMA_SW_1 register.
+      2nd argument contains the bit field to slice 0 port A,
+      3rd argument contains the bit field to slice 0 port B,
+      4th argument contains the bit field to slice 1 port A,
+      5th argument contains the bit field to slice 1 port B.
+
+  ports:
+    type: object
+    additionalProperties: false
+
+    properties:
+      "#address-cells":
+        const: 1
+
+      "#size-cells":
+        const: 0
+
+      port@0:
+        type: object
+        additionalProperties: false
+
+        properties:
+          reg:
+            const: 0
+            description: Slice 0 Port A
+
+          label:
+            description: Port name. Usually the pin group name
+
+          endpoint:
+            $ref: video-interfaces.yaml#
+            type: object
+            unevaluatedProperties: false
+
+            properties:
+              hsync-active: true
+              vsync-active: true
+              pclk-sample: true
+              bus-width:
+                enum: [8, 24]
+                default: 8
+
+              remote-endpoint: true
+
+        required:
+          - reg
+          - label
+
+      port@1:
+        type: object
+        additionalProperties: false
+
+        properties:
+          reg:
+            const: 1
+            description: Slice 0 Port B
+
+          label:
+            description: Port name. Usually the pin group name
+
+          endpoint:
+            $ref: /schemas/graph.yaml#/properties/endpoint
+            type: object
+            additionalProperties: false
+
+            properties:
+              hsync-active: true
+              vsync-active: true
+              pclk-sample: true
+              bus-width:
+                enum: [8, 24]
+                default: 8
+
+              remote-endpoint: true
+
+        required:
+          - reg
+          - label
+
+      port@2:
+        type: object
+        additionalProperties: false
+
+        properties:
+          reg:
+            const: 2
+            description: Slice 1 Port A
+
+          label:
+            description: Port name. Usually the pin group name
+
+          endpoint:
+            $ref: /schemas/graph.yaml#/properties/endpoint
+            type: object
+            additionalProperties: false
+
+            properties:
+              hsync-active: true
+              vsync-active: true
+              pclk-sample: true
+              bus-width:
+                enum: [8, 24]
+                default: 8
+
+              remote-endpoint: true
+
+        required:
+          - reg
+          - label
+
+      port@3:
+        type: object
+        additionalProperties: false
+
+        properties:
+          reg:
+            const: 3
+            description: Slice 1 Port B
+
+          label:
+            description: Port name. Usually the pin group name
+
+          endpoint:
+            $ref: /schemas/graph.yaml#/properties/endpoint
+            type: object
+            additionalProperties: false
+
+            properties:
+              hsync-active: true
+              vsync-active: true
+              pclk-sample: true
+              bus-width:
+                enum: [8, 24]
+                default: 8
+
+              remote-endpoint: true
+
+        required:
+          - reg
+          - label
+
+    required:
+      - "#address-cells"
+      - "#size-cells"
+      - port@0
+
+required:
+  - compatible
+  - label
+  - reg
+  - reg-names
+  - interrupts
+  - ti,vip-clk-polarity
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    vip1: vip@48970000 {
+        compatible = "ti,dra7-vip1";
+        label = "vip1";
+        reg = <0x48970000 0x114>,
+              <0x48975500 0xD8>,
+              <0x48975700 0x18>,
+              <0x48975800 0x80>,
+              <0x48975a00 0xD8>,
+              <0x48975c00 0x18>,
+              <0x48975d00 0x80>,
+              <0x4897d000 0x400>;
+        reg-names = "vip",
+                    "parser0",
+                    "csc0",
+                    "sc0",
+                    "parser1",
+                    "csc1",
+                    "sc1",
+                    "vpdma";
+        interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH>;
+        ti,vip-clk-polarity = <&scm_conf 0x534 0x1 0x4 0x2 0x8>;
+
+        ports {
+              #address-cells = <1>;
+              #size-cells = <0>;
+
+              vin1a: port@0 {
+                    reg = <0>;
+                    label = "vin1a";
+
+                    vin1a_ep: endpoint {
+                           remote-endpoint = <&camera1>;
+                           hsync-active = <1>;
+                           vsync-active = <1>;
+                           pclk-sample = <0>;
+                           bus-width = <8>;
+                    };
+              };
+              vin1b: port@1 {
+                    reg = <1>;
+                    label = "vin1b";
+              };
+              vin2a: port@2 {
+                    reg = <2>;
+                    label = "vin2a";
+              };
+              vin2b: port@3 {
+                    reg = <3>;
+                    label = "vin2b";
+              };
+         };
+    };
+
+    i2c {
+        clock-frequency = <400000>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+         camera@37 {
+              compatible = "ovti,ov10633";
+              reg = <0x37>;
+
+              clocks = <&fixed_clock>;
+              clocks-names = "xvclk";
+
+              port {
+                   camera1: endpoint {
+                           remote-endpoint = <&vin1a_ep>;
+                           hsync-active = <1>;
+                           vsync-active = <1>;
+                           pclk-sample = <0>;
+                           bus-width = <8>;
+                   };
+              };
+         };
+    };
+
+...
diff -Naur --no-dereference a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -109,6 +109,8 @@
           - st,spear1340-misc
           - stericsson,nomadik-pmu
           - starfive,jh7100-sysmain
+          - ti,am62-canuart-wake
+          - ti,am62-ddr-pmctrl
           - ti,am62-opp-efuse-table
           - ti,am62-usb-phy-ctrl
           - ti,am625-dss-oldi-io-ctrl
@@ -206,6 +208,8 @@
           - st,spear1340-misc
           - stericsson,nomadik-pmu
           - starfive,jh7100-sysmain
+          - ti,am62-canuart-wake
+          - ti,am62-ddr-pmctrl
           - ti,am62-opp-efuse-table
           - ti,am62-usb-phy-ctrl
           - ti,am625-dss-oldi-io-ctrl
diff -Naur --no-dereference a/Documentation/devicetree/bindings/mux/reg-mux.yaml b/Documentation/devicetree/bindings/mux/reg-mux.yaml
--- a/Documentation/devicetree/bindings/mux/reg-mux.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/mux/reg-mux.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -32,11 +32,34 @@
         - description: pre-shifted bitfield mask
     description: Each entry pair describes a single mux control.
 
-  idle-states: true
+  idle-states:
+    description: Each entry describes mux register state.
+
+  mux-reg-masks-state:
+    $ref: /schemas/types.yaml#/definitions/uint32-matrix
+    items:
+      items:
+        - description: register offset
+        - description: pre-shifted bitfield mask
+        - description: register value to be set
+    description: This property is an extension of mux-reg-masks which
+                 allows specifying register offset, mask and register
+                 value to be set in a single property.
+
+oneOf:
+  - required: [ mux-reg-masks ]
+  - required: [ mux-reg-masks-state ]
+
+allOf:
+  - if:
+      required:
+        - mux-reg-masks-state
+    then:
+      properties:
+        idle-states: false
 
 required:
   - compatible
-  - mux-reg-masks
   - '#mux-control-cells'
 
 additionalProperties: false
diff -Naur --no-dereference a/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml b/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
--- a/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -106,6 +106,22 @@
         maximum: 32
     minItems: 1
 
+  pinctrl-0:
+    description: Default pinctrl state
+
+  pinctrl-1:
+    description: Wakeup pinctrl state
+
+  pinctrl-names:
+    description:
+      When present should contain at least "default" describing the default pin
+      states. The second state called "wakeup" describes the pins in their
+      wakeup configuration required to exit sleep states.
+    minItems: 1
+    items:
+      - const: default
+      - const: wakeup
+
   power-domains:
     description:
       Power domain provider node and an args specifier containing
@@ -122,6 +138,17 @@
     minItems: 1
     maxItems: 2
 
+  wakeup-source:
+    oneOf:
+      - description: This device is capable of wakeup.
+        type: boolean
+      - description: This device is capable of wakeup from the defined power
+          states.
+        $ref: /schemas/types.yaml#/definitions/string-array
+        enum:
+          - suspend
+          - poweroff
+
 required:
   - compatible
   - reg
diff -Naur --no-dereference a/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml b/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml
--- a/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -96,7 +96,7 @@
           Specifies the type of PHY for which the group of PHY lanes is used.
           Refer include/dt-bindings/phy/phy.h. Constants from the header should be used.
         $ref: /schemas/types.yaml#/definitions/uint32
-        enum: [2, 4]
+        enum: [2, 4, 8, 9]
 
       cdns,num-lanes:
         description:
diff -Naur --no-dereference a/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml b/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml
--- a/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/regulator/ti,tps65219.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/regulator/ti,tps65219.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: TI tps65219 Power Management Integrated Circuit regulators
+title: TI TPS65214/TPS65215/TPS65219 Power Management Integrated Circuit
 
 maintainers:
   - Jerome Neanne <jerome.neanne@baylibre.com>
@@ -12,9 +12,20 @@
 description: |
   Regulator nodes should be named to buck<number> and ldo<number>.
 
+  TI TPS65219 is a Power Management IC with 3 Buck regulators, 4 Low
+  Drop-out Regulators (LDOs), 1 GPIO, 2 GPOs, and power-button.
+
+  TI TPS65215 is a derivative of TPS65219 with 3 Buck regulators, 2 Low
+  Drop-out Regulators (LDOs), 1 GPIO, 1 GPO, and power-button.
+
+  TI TPS65214 is a derivative of TPS65219 with 3 Buck regulators, 2 Low
+  Drop-out Regulators (LDOs), 1 GPIO, 1 GPO, and power-button.
+
 properties:
   compatible:
     enum:
+      - ti,tps65214
+      - ti,tps65215
       - ti,tps65219
 
   reg:
@@ -90,6 +101,20 @@
 
 additionalProperties: false
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - ti,tps65214
+              - ti,tps65215
+    then:
+      properties:
+        regulators:
+          patternProperties:
+            "^ldo[3-4]$": false
+
 examples:
   - |
     #include <dt-bindings/interrupt-controller/arm-gic.h>
diff -Naur --no-dereference a/Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml
--- a/Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -29,11 +29,13 @@
   compatible:
     enum:
       - ti,am62a-c7xv-dsp
+      - ti,j722s-c7xv-dsp
       - ti,j721e-c66-dsp
       - ti,j721e-c71-dsp
       - ti,j721s2-c71-dsp
     description:
       Use "ti,am62a-c7xv-dsp" for AM62A Deep learning DSPs on K3 AM62A SoCs
+      Use "ti,j722s-c7xv-dsp" for J722S Deep learning DSPs on K3 J722S SoCs
       Use "ti,j721e-c66-dsp" for C66x DSPs on K3 J721E SoCs
       Use "ti,j721e-c71-dsp" for C71x DSPs on K3 J721E SoCs
       Use "ti,j721s2-c71-dsp" for C71x DSPs on K3 J721S2 SoCs
@@ -127,6 +129,7 @@
         compatible:
           enum:
             - ti,am62a-c7xv-dsp
+            - ti,j722s-c7xv-dsp
     then:
       properties:
         reg:
diff -Naur --no-dereference a/Documentation/devicetree/bindings/serial/ti,pruss-uart.yaml b/Documentation/devicetree/bindings/serial/ti,pruss-uart.yaml
--- a/Documentation/devicetree/bindings/serial/ti,pruss-uart.yaml	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/devicetree/bindings/serial/ti,pruss-uart.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/serial/ti,pruss-uart.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI PRUSS serial UART
+
+maintainers:
+  - Bin Liu <b-liu@ti.com>
+
+description: |
+  The PRU-ICSS module has a serial UART peripheral, which is based on
+  industry standard TL16C550, with 16-bytes TX/RX FIFOs.
+
+allOf:
+  - $ref: /schemas/serial.yaml#
+
+properties:
+  compatible:
+    items:
+      - const: ti,pruss-uart
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    minItems: 3
+    maxItems: 3
+    description: |
+      PRU UART interrupt mappings, containing an entry of 3 cell-values.
+      The first is the PRU System Event id for PRU UART Interrupt Request.
+      The second is the PRU interrupt channel id.
+      The third is the PRU host interrupt id.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupt-parent
+  - interrupts
+
+examples:
+  - |
+    pruss_uart: serial@28000 {
+        compatible = "ti,pruss-uart";
+        reg = <0x28000 0x38>;
+        clocks = <&dpll_per_m2_ck>;
+        interrupt-parent = <&pruss_intc>;
+        interrupts = <6 2 2>;
+    };
diff -Naur --no-dereference a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
--- a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -68,6 +68,11 @@
     description:
       The node corresponding to SoC chip identification.
 
+  "^pcie-ctrl@[0-9a-f]+$":
+    type: object
+    description:
+      This is the PCIe control region.
+
 required:
   - compatible
   - reg
diff -Naur --no-dereference a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
--- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -92,6 +92,16 @@
     description: |
       This property is as per sci-pm-domain.txt.
 
+  clocks:
+    items:
+      - description: ICSSG_CORE Clock
+      - description: ICSSG_IEP Clock
+      - description: ICSSG_RGMII_MHZ_250 Clock
+      - description: ICSSG_RGMII_MHZ_50 Clock
+      - description: ICSSG_RGMII_MHZ_5 Clock
+      - description: ICSSG_UART Clock
+      - description: ICSSG_ICLK Clock
+
 patternProperties:
 
   memories@[a-f0-9]+$:
diff -Naur --no-dereference a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
--- a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -115,6 +115,14 @@
     description:
       32-bit indirect AHB trigger address.
 
+  cdns,phase-detect-selector:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      DLL Phase Detect Selector for sampling clock generation to handle the
+      clock domain crossing between the reference clock and sampling clock.
+      Refer SoC datasheet for the Phase Detect Selector value and assign
+      (Phase Detect Selector value - 1) to cdns,phase-detect-selector.
+
   cdns,is-decoded-cs:
     type: boolean
     description:
diff -Naur --no-dereference a/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml b/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml
--- a/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml	2025-10-23 09:30:40.281462084 -0400
@@ -24,6 +24,7 @@
   compatible:
     enum:
       - ti,j7-rti-wdt
+      - ti,am62l-rti-wdt
 
   reg:
     maxItems: 1
diff -Naur --no-dereference a/Documentation/networking/device_drivers/ethernet/ti/cpsw_proxy_client.rst b/Documentation/networking/device_drivers/ethernet/ti/cpsw_proxy_client.rst
--- a/Documentation/networking/device_drivers/ethernet/ti/cpsw_proxy_client.rst	1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/networking/device_drivers/ethernet/ti/cpsw_proxy_client.rst	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,182 @@
+.. SPDX-License-Identifier: GPL-2.0-only or MIT
+
+==========================================
+Texas Instruments CPSW Proxy Client driver
+==========================================
+
+Introduction
+============
+
+The CPSW (Common Platform Switch) Ethernet Switch on TI's K3 SoCs provides
+Ethernet functionality. There may be multiple instances of CPSW on a single
+SoC. The term "CPSWnG" is used to indicate the number of MAC Ports supported
+by a specific instance of CPSW. CPSWnG indicates that the peripheral has
+(n-1) MAC Ports and 1 Host Port. Examples of existing instances are:
+CPSW2G => 1 MAC Port and 1 Host Port
+CPSW3G => 2 MAC Ports and 1 Host Port
+CPSW5G => 4 MAC Ports and 1 Host Port
+CPSW9G => 8 MAC Ports and 1 Host Port
+
+The presence of 2 or more MAC Ports implies that Hardware Switching can
+be enabled between the MAC Ports if required.
+
+The "am65-cpsw-nuss.c" driver in Linux at:
+drivers/net/ethernet/ti/am65-cpsw-nuss.c
+provides Ethernet functionality for applications on Linux.
+It also handles both the control-path and data-path, namely:
+Control => Configuration of the CPSW Peripheral
+Data => Configuration of the DMA Channels to transmit/receive data
+
+The aforementioned configuration supports use-cases where all applications
+which require Ethernet functionality are only running on Linux.
+
+However, there are use-cases where applications running on different
+Operating Systems across multiple cores on the SoC require Ethernet
+functionality. Such use-cases can be supported by implementing a
+Client-Server model to share the data-path among Clients while the Server
+owns the control-path.
+
+On TI's K3 SoCs (J721E, J7200 and J784S4 in particular), the Ethernet Switch
+Firmware (EthFw) running on the MAIN R5F core acts as the Server and
+configures the CPSWnG instance (CPSW5G on J7200 and CPSW9G on J721E, J784S4)
+of the CPSW Ethernet Switch on the SoC. The Clients running on various cores
+communicate with EthFw via RPMsg (Remote Processor Messaging) to request
+resource allocation details during initialization, followed by requesting
+EthFw to enable features supported by CPSW based on the features required
+by the applications running on the respective cores.
+
+EthFw handles requests from the Clients and evaluates them before configuring
+CPSW based on the request. Since no Client is actually in control of CPSW and
+only requests EthFw for configuring CPSW, EthFw acts as the proxy for the
+Clients. Thus, the Linux Client which interfaces with EthFw is named:
+CPSW Proxy Client
+
+The data-path for the CPSW Proxy Client driver remains identical to the
+"am65-cpsw-nuss.c" driver which happens to be DMA. It is only the control-path
+that is different.
+
+Client-Server discovery occurs over the RPMsg-Bus. EthFw announces its
+RPMsg Endpoint name over the RPMsg-Bus. The CPSW Proxy Client driver
+registers itself with the Linux RPMsg framework to be probed for the same
+Endpoint name. Following probe, the Linux Client driver begins communicating
+with EthFw and queries details of the resources available for the Linux Client.
+
+Terminology
+===========
+
+Virtual Port
+        A Virtual Port refers to the Software View of an Ethernet MAC Port.
+        There are two types of Virtual Ports:
+        1. Virtual MAC Only Port
+        2. Virtual Switch Port
+
+Virtual MAC Only Port
+        A Virtual MAC only Port refers to a dedicated physical MAC Port for
+        a Client. This corresponds to MAC Mode of operation in Ethernet
+        Terminology. All traffic sent to or received from the Physical
+        MAC Port is that of the Client to which the Virtual MAC Only Port
+        has been allocated.
+
+Virtual Switch Port
+        A Virtual Switch Port refers to a group of physical MAC ports with
+        Switching enabled across them. This implies that any traffic sent
+        to the Port from a Client could potentially exit a Physical MAC
+        Port along with the traffic from other Clients. Similarly, the traffic
+        received on the Port by a Client could have potentially ingressed
+        on a Physical MAC Port along with the traffic meant for other Clients.
+        While the ALE (Address Lookup Engine) handles segregating the traffic,
+        and the CPSW Ethernet Switch places traffic on dedicated RX DMA Flows
+        meant for a single Client, it is worth noting that the bandwidths
+        of the Physical MAC Port are shared by Clients when traffic is sent to
+        or received from a Virtual Switch Port.
+
+Network Interface
+        The user-visible interface in Linux userspace exposed to applications
+        that serves as the entry/exit point for traffic to/from the Virtual
+        Ports. A single network interface (ethX) maps to either a Virtual
+        MAC Only Port or a Virtual Switch Port.
+
+C2S
+        RPMsg source is Client and destination is Server.
+
+S2C
+        RPMsg source is Server and destination is Client.
+
+Initialization Sequence
+=======================
+
+The sequence of message exchanges between the Client driver and EthFw starting
+from the driver probe and ending with the interfaces being brought up is as
+follows:
+1. C2S ETHFW_VIRT_PORT_INFO requesting details of Virtual Ports available
+   for the Linux Client.
+2. S2C response containing requested details
+3. C2S ETHFW_VIRT_PORT_ATTACH request for each Virtual Port allocated during
+   step 2.
+4. S2C response containing details of the MTU Size, number of Tx DMA Channels
+   and RX DMA Flows for the specified Virtual Port. The *Features* associated
+   with the Virtual Port are also shared such as Multicast Filtering capability.
+5. C2S ETHFW_ALLOC_RX request for each RX DMA Flow for a Virtual Port.
+6. S2C response containing details of the RX PSI-L Thread ID, Flow base and
+   Flow offset.
+7. C2S ETHFW_ALLOC_TX request for each TX DMA Channel for a Virtual Port.
+8. S2C response containing details of the TX PSI-L Thread ID.
+9. C2S ETHFW_ALLOC_MAC request for each Virtual Port.
+10. S2C response containing the MAC Address corresponding to the Virtual Port.
+11. C2S ETHFW_MAC_REGISTER request for each Virtual Port with the MAC Address
+    allocated in step 10. This is necessary to steer packets that ingress on
+    the MAC Ports of CPSW onto the RX DMA Flow for the Virtual Port in order
+    to allow the Client to receive the packets.
+12. S2C response indicating status of request.
+13. C2S ETHFW_IPv4_REGISTER request *only* for Virtual Switch Port interface.
+    The IPv4 address assigned to the "ethX" network interface in Linux
+    corresponding to the Virtual Switch Port interface has to be registered
+    with EthFw. This is due to the reason that all Broadcast requests including
+    ARP requests received by the MAC Ports corresponding to the Virtual Switch
+    Port are consumed solely be EthFw. Such traffic is sent to Clients by
+    alternate methods. Therefore EthFw needs to know the IPv4 address for the
+    "ethX" network interface in Linux in order to automatically respond to
+    ARP requests, thereby enabling Unicast communication.
+14. S2C response indicating status of request.
+15. C2S ETHFW_MCAST_FILTER_ADD request to register the Multicast Addresses
+    associated with the network interface corresponding to the Virtual Port
+    which has the Multicast Filtering capability.
+16. S2C response indicating status of request.
+17. C2S ETHFW_MCAST_FILTER_DEL request to deregister the Multicast Addresses
+    associated with the network interface corresponding to the Virtual Port
+    which has the Multicast Filtering capability.
+18. S2C response indicating status of request.
+
+Shutdown Sequence
+=================
+
+The sequence of message exchanges between the Client driver and EthFw on module
+removal are as follows:
+1. C2S ETHFW_MAC_DEREGISTER request to deregister the MAC Address for each
+   Virtual Port.
+2. S2C response indicating status of request.
+3. C2S ETHFW_MCAST_FILTER_DEL request to deregister the Multicast Addresses
+   associated with the network interface corresponding to the Virtual Port
+   which has the Multicast Filtering capability.
+4. S2C response indicating status of request.
+5. C2S ETHFW_FREE_MAC request to release the MAC Address allocated to each
+   Virtual Port.
+6. S2C response indicating status of request.
+7. C2S ETHFW_FREE_TX request to release the TX DMA Channel for each TX Channel
+   for every Virtual Port.
+8. S2C response indicating status of request.
+9. C2S ETHFW_FREE_RX request to release the RX DMA Flow for each RX Channel
+   for every Virtual Port.
+10. S2C response indicating status of request.
+11. C2S ETHFW_VIRT_PORT_DETACH request to release each Virtual Port.
+12. S2C response indicating status of request.
+
+Features Supported
+==================
+
+The set of features supported in addition to providing basic Ethernet
+Functionality are:
+1. Multicast Filtering
+2. Determining Link Status of the network interface corresponding to the
+   Virtual MAC Only port via ethtool.
+3. Interrupt Pacing/Coalescing
diff -Naur --no-dereference a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst	2025-06-19 09:32:38.000000000 -0400
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst	2025-10-23 09:30:40.281462084 -0400
@@ -604,6 +604,11 @@
     chosen data limit then the frame will be skipped. Possible values
     are:
 
+``V4L2_CID_MPEG_VIDEO_BACKGROUND_DETECTION (boolean)``
+    If enabled then, the encoder detect a background region in frame and
+    use low bits or skip mode to encode the background region.
+    If a lot of scenes are stationary or background, It may help to
+    reduce the video bitrate. Applicable to the encoder.
 
 .. tabularcolumns:: |p{8.2cm}|p{9.3cm}|
 
diff -Naur --no-dereference a/drivers/base/power/qos.c b/drivers/base/power/qos.c
--- a/drivers/base/power/qos.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/base/power/qos.c	2025-10-23 09:30:40.284462176 -0400
@@ -137,6 +137,7 @@
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(dev_pm_qos_read_value);
 
 /**
  * apply_constraint - Add/modify/remove device PM QoS request.
diff -Naur --no-dereference a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
--- a/drivers/cpufreq/cpufreq-dt-platdev.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c	2025-10-23 09:30:40.284462176 -0400
@@ -183,6 +183,7 @@
 	{ .compatible = "ti,dra7", },
 	{ .compatible = "ti,omap3", },
 	{ .compatible = "ti,am625", },
+	{ .compatible = "ti,am6254xxl", },
 	{ .compatible = "ti,am62a7", },
 	{ .compatible = "ti,am62p5", },
 
diff -Naur --no-dereference a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
--- a/drivers/cpufreq/ti-cpufreq.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/cpufreq/ti-cpufreq.c	2025-10-23 09:30:40.284462176 -0400
@@ -93,6 +93,8 @@
 	bool multi_regulator;
 /* Backward compatibility hack: Might have missing syscon */
 #define TI_QUIRK_SYSCON_MAY_BE_MISSING	0x1
+/* Backward compatibility hack: new syscon size is 1 register wide */
+#define TI_QUIRK_SYSCON_IS_SINGLE_REG	0x2
 	u8 quirks;
 };
 
@@ -316,8 +318,8 @@
 	.efuse_offset = 0x0018,
 	.efuse_mask = 0x07c0,
 	.efuse_shift = 0x6,
-	.rev_offset = 0x0014,
 	.multi_regulator = false,
+	.quirks = TI_QUIRK_SYSCON_IS_SINGLE_REG,
 };
 
 static struct ti_cpufreq_soc_data am62a7_soc_data = {
@@ -325,7 +327,6 @@
 	.efuse_offset = 0x0,
 	.efuse_mask = 0x07c0,
 	.efuse_shift = 0x6,
-	.rev_offset = 0x0014,
 	.multi_regulator = false,
 };
 
@@ -334,7 +335,6 @@
 	.efuse_offset = 0x0,
 	.efuse_mask = 0x07c0,
 	.efuse_shift = 0x6,
-	.rev_offset = 0x0014,
 	.multi_regulator = false,
 };
 
@@ -354,6 +354,10 @@
 
 	ret = regmap_read(opp_data->syscon, opp_data->soc_data->efuse_offset,
 			  &efuse);
+
+	if (opp_data->soc_data->quirks & TI_QUIRK_SYSCON_IS_SINGLE_REG && ret == -EIO)
+		ret = regmap_read(opp_data->syscon, 0x0, &efuse);
+
 	if (opp_data->soc_data->quirks & TI_QUIRK_SYSCON_MAY_BE_MISSING && ret == -EIO) {
 		/* not a syscon register! */
 		void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
@@ -452,6 +456,7 @@
 	{ .compatible = "ti,omap34xx", .data = &omap34xx_soc_data, },
 	{ .compatible = "ti,omap36xx", .data = &omap36xx_soc_data, },
 	{ .compatible = "ti,am625", .data = &am625_soc_data, },
+	{ .compatible = "ti,am6254xxl", .data = &am625_soc_data, },
 	{ .compatible = "ti,am62a7", .data = &am62a7_soc_data, },
 	{ .compatible = "ti,am62p5", .data = &am62p5_soc_data, },
 	/* legacy */
diff -Naur --no-dereference a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
--- a/drivers/crypto/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/crypto/Kconfig	2025-10-23 09:30:40.284462176 -0400
@@ -851,5 +851,6 @@
 
 source "drivers/crypto/aspeed/Kconfig"
 source "drivers/crypto/starfive/Kconfig"
+source "drivers/crypto/ti/Kconfig"
 
 endif # CRYPTO_HW
diff -Naur --no-dereference a/drivers/crypto/Makefile b/drivers/crypto/Makefile
--- a/drivers/crypto/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/crypto/Makefile	2025-10-23 09:30:40.284462176 -0400
@@ -42,6 +42,7 @@
 obj-y += stm32/
 obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
 obj-$(CONFIG_CRYPTO_DEV_TEGRA) += tegra/
+obj-$(CONFIG_CRYPTO_DEV_TI_MCRC64) += ti/
 obj-$(CONFIG_CRYPTO_DEV_VIRTIO) += virtio/
 #obj-$(CONFIG_CRYPTO_DEV_VMX) += vmx/
 obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/
@@ -52,3 +53,4 @@
 obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/
 obj-y += intel/
 obj-y += starfive/
+obj-$(CONFIG_ARCH_K3) += ti/
diff -Naur --no-dereference a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c
--- a/drivers/crypto/sa2ul.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/crypto/sa2ul.c	2025-10-23 09:30:40.284462176 -0400
@@ -13,6 +13,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
 #include <linux/dmapool.h>
+#include <linux/fips.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -23,6 +24,7 @@
 #include <crypto/aes.h>
 #include <crypto/authenc.h>
 #include <crypto/des.h>
+#include <crypto/hmac.h>
 #include <crypto/internal/aead.h>
 #include <crypto/internal/hash.h>
 #include <crypto/internal/skcipher.h>
@@ -81,6 +83,9 @@
 	SA_ALG_SHA512,
 	SA_ALG_AUTHENC_SHA1_AES,
 	SA_ALG_AUTHENC_SHA256_AES,
+	SA_ALG_HMAC_SHA1,
+	SA_ALG_HMAC_SHA256,
+	SA_ALG_HMAC_SHA512,
 };
 
 struct sa_match_data {
@@ -93,21 +98,15 @@
 
 /**
  * struct sa_cmdl_cfg - Command label configuration descriptor
- * @aalg: authentication algorithm ID
  * @enc_eng_id: Encryption Engine ID supported by the SA hardware
  * @auth_eng_id: Authentication Engine ID
  * @iv_size: Initialization Vector size
- * @akey: Authentication key
- * @akey_len: Authentication key length
  * @enc: True, if this is an encode request
  */
 struct sa_cmdl_cfg {
-	int aalg;
 	u8 enc_eng_id;
 	u8 auth_eng_id;
 	u8 iv_size;
-	const u8 *akey;
-	u16 akey_len;
 	bool enc;
 };
 
@@ -142,8 +141,9 @@
 	bool inv_key;
 	struct sa_tfm_ctx *ctx;
 	bool keyed_mac;
-	void (*prep_iopad)(struct algo_data *algo, const u8 *key,
-			   u16 key_sz, __be32 *ipad, __be32 *opad);
+	int (*prep_iopad)(struct algo_data *algo, const u8 *key,
+			   u16 key_sz, __be32 *lower_ipad, __be32 *lower_opad,
+			   __be32 *upper_ipad, __be32 *upper_opad);
 };
 
 /**
@@ -380,86 +380,134 @@
 	}
 }
 
-/* Prepare the ipad and opad from key as per SHA algorithm step 1*/
-static void prepare_kipad(u8 *k_ipad, const u8 *key, u16 key_sz)
+static int sa_export_shash(struct shash_desc *hash, int digest_size,
+		void *lower_out, void *upper_out)
 {
-	int i;
-
-	for (i = 0; i < key_sz; i++)
-		k_ipad[i] = key[i] ^ 0x36;
-
-	/* Instead of XOR with 0 */
-	for (; i < SHA1_BLOCK_SIZE; i++)
-		k_ipad[i] = 0x36;
-}
-
-static void prepare_kopad(u8 *k_opad, const u8 *key, u16 key_sz)
-{
-	int i;
-
-	for (i = 0; i < key_sz; i++)
-		k_opad[i] = key[i] ^ 0x5c;
+	u32 *result;
+	u64 *result64;
+	int ret = 0;
 
-	/* Instead of XOR with 0 */
-	for (; i < SHA1_BLOCK_SIZE; i++)
-		k_opad[i] = 0x5c;
-}
+	union {
+		struct sha1_state sha1;
+		struct sha256_state sha256;
+		struct sha512_state sha512;
+	} sha;
 
-static void sa_export_shash(void *state, struct shash_desc *hash,
-			    int digest_size, __be32 *out)
-{
-	struct sha1_state *sha1;
-	struct sha256_state *sha256;
-	u32 *result;
+	/* Export the intermediate digest to program into SA2UL */
+	ret = crypto_shash_export(hash, &sha);
+	if (ret) {
+		dev_err(sa_k3_dev, "%s: crypto_shash_export failed\n",
+			__func__);
+		return ret;
+	}
 
 	switch (digest_size) {
 	case SHA1_DIGEST_SIZE:
-		sha1 = state;
-		result = sha1->state;
+		result = sha.sha1.state;
+		cpu_to_be32_array(lower_out, result, digest_size / 4);
 		break;
 	case SHA256_DIGEST_SIZE:
-		sha256 = state;
-		result = sha256->state;
+		result = sha.sha256.state;
+		cpu_to_be32_array(lower_out, result, digest_size / 4);
+		break;
+	case SHA512_DIGEST_SIZE:
+		result64 = sha.sha512.state;
+		cpu_to_be64_array(upper_out, result64, digest_size / 8 / 2);
+		cpu_to_be64_array(lower_out, result64 + digest_size / 8 / 2, digest_size / 8 / 2);
 		break;
 	default:
 		dev_err(sa_k3_dev, "%s: bad digest_size=%d\n", __func__,
 			digest_size);
-		return;
+		return -EINVAL;
 	}
 
-	crypto_shash_export(hash, state);
 
-	cpu_to_be32_array(out, result, digest_size / 4);
+	return ret;
 }
 
-static void sa_prepare_iopads(struct algo_data *data, const u8 *key,
-			      u16 key_sz, __be32 *ipad, __be32 *opad)
+static int sa_prepare_iopads(struct algo_data *data, const u8 *key,
+			     u16 key_sz, __be32 *lower_ipad, __be32 *lower_opad,
+			     __be32 *upper_ipad, __be32 *upper_opad)
 {
 	SHASH_DESC_ON_STACK(shash, data->ctx->shash);
 	int block_size = crypto_shash_blocksize(data->ctx->shash);
 	int digest_size = crypto_shash_digestsize(data->ctx->shash);
-	union {
-		struct sha1_state sha1;
-		struct sha256_state sha256;
-		u8 k_pad[SHA1_BLOCK_SIZE];
-	} sha;
+	int ret = 0;
+	int i = 0;
+	u8 k_ipad[SHA512_BLOCK_SIZE];
+	u8 k_opad[SHA512_BLOCK_SIZE];
+
+	if (fips_enabled && (key_sz < 112 / 8))
+		return -EINVAL;
 
 	shash->tfm = data->ctx->shash;
 
-	prepare_kipad(sha.k_pad, key, key_sz);
+	if (key_sz > block_size) {
+		int err;
 
-	crypto_shash_init(shash);
-	crypto_shash_update(shash, sha.k_pad, block_size);
-	sa_export_shash(&sha, shash, digest_size, ipad);
+		err = crypto_shash_digest(shash, key, key_sz, k_ipad);
+		if (err)
+			return err;
 
-	prepare_kopad(sha.k_pad, key, key_sz);
+		key_sz = digest_size;
+	} else
+		memcpy(k_ipad, key, key_sz);
+
+	memset(k_ipad + key_sz, 0, block_size - key_sz);
+	memcpy(k_opad, k_ipad, block_size);
+
+	for (i = 0; i < block_size; i++) {
+		k_ipad[i] ^= HMAC_IPAD_VALUE;
+		k_opad[i] ^= HMAC_OPAD_VALUE;
+	}
+
+	memset(lower_ipad, 0, digest_size / 2);
+	memset(lower_opad, 0, digest_size / 2);
+	memset(upper_ipad, 0, digest_size / 2);
+	memset(upper_opad, 0, digest_size / 2);
+
+	ret = crypto_shash_init(shash);
+	if (ret) {
+		dev_err(sa_k3_dev, "%s: %d: crypto_shash_init for ipad failed, ret=%d\n",
+			__func__, __LINE__, ret);
+		return ret;
+	}
+	ret = crypto_shash_update(shash, k_ipad, block_size);
+	if (ret) {
+		dev_err(sa_k3_dev, "%s: %d: crypto_shash_update for ipad failed, ret=%d\n",
+			__func__, __LINE__, ret);
+		return ret;
+	}
+	ret = sa_export_shash(shash, digest_size, lower_ipad, upper_ipad);
+	if (ret) {
+		dev_err(sa_k3_dev, "%s: %d: sa_export_shash for ipad failed, ret=%d\n",
+			__func__, __LINE__, ret);
+		return ret;
+	}
 
-	crypto_shash_init(shash);
-	crypto_shash_update(shash, sha.k_pad, block_size);
+	ret = crypto_shash_init(shash);
+	if (ret) {
+		dev_err(sa_k3_dev, "%s: %d: crypto_shash_init for opad failed, ret=%d\n",
+			__func__, __LINE__, ret);
+		return ret;
+	}
+	ret = crypto_shash_update(shash, k_opad, block_size);
+	if (ret) {
+		dev_err(sa_k3_dev, "%s: %d: crypto_shash_update for opad failed, ret=%d\n",
+			__func__, __LINE__, ret);
+		return ret;
+	}
+	ret = sa_export_shash(shash, digest_size, lower_opad, upper_opad);
+	if (ret) {
+		dev_err(sa_k3_dev, "%s: %d: sa_export_shash for opad failed, ret=%d\n",
+			__func__, __LINE__, ret);
+		return ret;
+	}
 
-	sa_export_shash(&sha, shash, digest_size, opad);
+	memzero_explicit(k_ipad, sizeof(SHA1_BLOCK_SIZE));
+	memzero_explicit(k_opad, sizeof(SHA1_BLOCK_SIZE));
 
-	memzero_explicit(&sha, sizeof(sha));
+	return ret;
 }
 
 /* Derive the inverse key used in AES-CBC decryption operation */
@@ -529,11 +577,14 @@
 }
 
 /* Set Security context for the authentication engine */
-static void sa_set_sc_auth(struct algo_data *ad, const u8 *key, u16 key_sz,
+static int sa_set_sc_auth(struct algo_data *ad, const u8 *key, u16 key_sz,
 			   u8 *sc_buf)
 {
-	__be32 *ipad = (void *)(sc_buf + 32);
-	__be32 *opad = (void *)(sc_buf + 64);
+	__be32 *lower_ipad = (void *)(sc_buf + 32);
+	__be32 *lower_opad = (void *)(sc_buf + 64);
+	__be32 *upper_ipad = (void *)(sc_buf + 96);
+	__be32 *upper_opad = (void *)(sc_buf + 128);
+	int ret = 0;
 
 	/* Set Authentication mode selector to hash processing */
 	sc_buf[0] = SA_HASH_PROCESSING;
@@ -542,12 +593,21 @@
 	sc_buf[1] |= ad->auth_ctrl;
 
 	/* Copy the keys or ipad/opad */
-	if (ad->keyed_mac)
-		ad->prep_iopad(ad, key, key_sz, ipad, opad);
+	if (ad->keyed_mac) {
+		ret = ad->prep_iopad(ad, key, key_sz, lower_ipad,
+				lower_opad, upper_ipad, upper_opad);
+		if (ret) {
+			dev_err(sa_k3_dev, "%s: %d: sa_prepare_iopads failed, ret=%d\n",
+				__func__, __LINE__, ret);
+			return ret;
+		}
+	}
 	else {
 		/* basic hash */
 		sc_buf[1] |= SA_BASIC_HASH;
 	}
+
+	return 0;
 }
 
 static inline void sa_copy_iv(__be32 *out, const u8 *iv, bool size16)
@@ -723,26 +783,26 @@
 	u8 *sc_buf = ctx->sc;
 	u16 sc_id = ctx->sc_id;
 	u8 first_engine = 0;
+	int ret = 0;
 
 	memzero_explicit(sc_buf, SA_CTX_MAX_SZ);
 
+	sc_buf[1] = SA_SCCTL_FE_AUTH_ENC;
+	enc_sc_offset = SA_CTX_PHP_PE_CTX_SZ;
+	auth_sc_offset = enc_sc_offset + ad->enc_eng.sc_size;
+
 	if (ad->auth_eng.eng_id) {
 		if (enc)
 			first_engine = ad->enc_eng.eng_id;
 		else
 			first_engine = ad->auth_eng.eng_id;
 
-		enc_sc_offset = SA_CTX_PHP_PE_CTX_SZ;
-		auth_sc_offset = enc_sc_offset + ad->enc_eng.sc_size;
-		sc_buf[1] = SA_SCCTL_FE_AUTH_ENC;
 		if (!ad->hash_size)
 			return -EINVAL;
 		ad->hash_size = roundup(ad->hash_size, 8);
 
-	} else if (ad->enc_eng.eng_id && !ad->auth_eng.eng_id) {
-		enc_sc_offset = SA_CTX_PHP_PE_CTX_SZ;
+	} else if (ad->enc_eng.eng_id) {
 		first_engine = ad->enc_eng.eng_id;
-		sc_buf[1] = SA_SCCTL_FE_ENC;
 		ad->hash_size = ad->iv_out_size;
 	}
 
@@ -762,9 +822,15 @@
 	}
 
 	/* Prepare context for authentication engine */
-	if (ad->auth_eng.sc_size)
-		sa_set_sc_auth(ad, auth_key, auth_key_sz,
+	if (ad->auth_eng.sc_size) {
+		ret = sa_set_sc_auth(ad, auth_key, auth_key_sz,
 			       &sc_buf[auth_sc_offset]);
+		if (ret) {
+			dev_err(sa_k3_dev, "%s: Error in setting authentication context\n",
+					__func__);
+			return ret;
+		}
+	}
 
 	/* Set the ownership of context to CP_ACE */
 	sc_buf[SA_CTX_SCCTL_OWNER_OFFSET] = 0x80;
@@ -896,7 +962,7 @@
 		return -EINVAL;
 
 	ad->enc_eng.eng_id = SA_ENG_ID_EM1;
-	ad->enc_eng.sc_size = SA_CTX_ENC_TYPE1_SZ;
+	ad->enc_eng.sc_size = SA_CTX_ENC_TYPE_SZ;
 
 	memzero_explicit(&cfg, sizeof(cfg));
 	cfg.enc_eng_id = ad->enc_eng.eng_id;
@@ -1377,29 +1443,7 @@
 	ahash_request_complete(req, 0);
 }
 
-static int zero_message_process(struct ahash_request *req)
-{
-	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-	int sa_digest_size = crypto_ahash_digestsize(tfm);
-
-	switch (sa_digest_size) {
-	case SHA1_DIGEST_SIZE:
-		memcpy(req->result, sha1_zero_message_hash, sa_digest_size);
-		break;
-	case SHA256_DIGEST_SIZE:
-		memcpy(req->result, sha256_zero_message_hash, sa_digest_size);
-		break;
-	case SHA512_DIGEST_SIZE:
-		memcpy(req->result, sha512_zero_message_hash, sa_digest_size);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int sa_sha_run(struct ahash_request *req)
+static int sa_sha_digest(struct ahash_request *req)
 {
 	struct sa_tfm_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
 	struct sa_sha_req_ctx *rctx = ahash_request_ctx(req);
@@ -1408,10 +1452,7 @@
 
 	auth_len = req->nbytes;
 
-	if (!auth_len)
-		return zero_message_process(req);
-
-	if (auth_len > SA_MAX_DATA_SZ ||
+	if (!auth_len || auth_len > SA_MAX_DATA_SZ ||
 	    (auth_len >= SA_UNSAFE_DATA_SZ_MIN &&
 	     auth_len <= SA_UNSAFE_DATA_SZ_MAX)) {
 		struct ahash_request *subreq = &rctx->fallback_req;
@@ -1449,29 +1490,41 @@
 	return sa_run(&sa_req);
 }
 
-static int sa_sha_setup(struct sa_tfm_ctx *ctx, struct  algo_data *ad)
+static int sa_sha_setup(struct sa_tfm_ctx *ctx, struct algo_data *ad,
+		const u8 *key, u8 key_sz)
 {
-	int bs = crypto_shash_blocksize(ctx->shash);
 	int cmdl_len;
 	struct sa_cmdl_cfg cfg;
+	int ret;
 
-	ad->enc_eng.sc_size = SA_CTX_ENC_TYPE1_SZ;
+	ad->ctx = ctx;
+	ad->enc_eng.sc_size = SA_CTX_ENC_TYPE_SZ;
 	ad->auth_eng.eng_id = SA_ENG_ID_AM1;
-	ad->auth_eng.sc_size = SA_CTX_AUTH_TYPE2_SZ;
+	ad->auth_eng.sc_size = SA_CTX_AUTH_TYPE_SZ;
+
+	if (key_sz) {
+		/* Initialize fallback setkey */
+		ret = crypto_ahash_setkey(ad->ctx->fallback.ahash,
+				key, key_sz);
+		if (ret) {
+			dev_err(sa_k3_dev, "%s: Failed to set fallback.ahash setkey=%d",
+					__func__, ret);
+			return ret;
+		}
+
+		ad->keyed_mac = true;
+		ad->prep_iopad = sa_prepare_iopads;
+	}
 
-	memset(ctx->authkey, 0, bs);
 	memset(&cfg, 0, sizeof(cfg));
-	cfg.aalg = ad->aalg_id;
 	cfg.enc_eng_id = ad->enc_eng.eng_id;
 	cfg.auth_eng_id = ad->auth_eng.eng_id;
 	cfg.iv_size = 0;
-	cfg.akey = NULL;
-	cfg.akey_len = 0;
 
 	ctx->dev_data = dev_get_drvdata(sa_k3_dev);
 	/* Setup Encryption Security Context & Command label template */
-	if (sa_init_sc(&ctx->enc, ctx->dev_data->match_data, NULL, 0, NULL, 0,
-		       ad, 0, &ctx->enc.epib[1]))
+	if (sa_init_sc(&ctx->enc, ctx->dev_data->match_data, NULL, 0, key,
+			key_sz, ad, 0, &ctx->enc.epib[1]))
 		goto badkey;
 
 	cmdl_len = sa_format_cmdl_gen(&cfg,
@@ -1489,7 +1542,7 @@
 	return -EINVAL;
 }
 
-static int sa_sha_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base)
+static int sa_sha_cra_init_alg(struct crypto_tfm *tfm, const char *hash, const char *alg_base)
 {
 	struct sa_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
 	struct sa_crypto_data *data = dev_get_drvdata(sa_k3_dev);
@@ -1501,23 +1554,31 @@
 	if (ret)
 		return ret;
 
-	if (alg_base) {
-		ctx->shash = crypto_alloc_shash(alg_base, 0,
+	if (!alg_base)
+		dev_err(sa_k3_dev, "alg_base is NULL\n");
+
+	if (hash) {
+		/* Allocating fallback for intermediate setkey calculations */
+		ctx->shash = crypto_alloc_shash(hash, 0,
 						CRYPTO_ALG_NEED_FALLBACK);
 		if (IS_ERR(ctx->shash)) {
 			dev_err(sa_k3_dev, "base driver %s couldn't be loaded\n",
 				alg_base);
 			return PTR_ERR(ctx->shash);
 		}
-		/* for fallback */
-		ctx->fallback.ahash =
-			crypto_alloc_ahash(alg_base, 0,
-					   CRYPTO_ALG_NEED_FALLBACK);
-		if (IS_ERR(ctx->fallback.ahash)) {
-			dev_err(ctx->dev_data->dev,
-				"Could not load fallback driver\n");
-			return PTR_ERR(ctx->fallback.ahash);
-		}
+	} else {
+		dev_dbg(sa_k3_dev, "%s: hash is NULL so not allocating ctx->shash\n",
+				__func__);
+	}
+
+	/* for fallback */
+	ctx->fallback.ahash =
+		crypto_alloc_ahash(alg_base, 0,
+				   CRYPTO_ALG_NEED_FALLBACK);
+	if (IS_ERR(ctx->fallback.ahash)) {
+		dev_err(ctx->dev_data->dev,
+			"Could not load fallback driver\n");
+		return PTR_ERR(ctx->fallback.ahash);
 	}
 
 	dev_dbg(sa_k3_dev, "%s(0x%p) sc-ids(0x%x(0x%pad), 0x%x(0x%pad))\n",
@@ -1531,11 +1592,6 @@
 	return 0;
 }
 
-static int sa_sha_digest(struct ahash_request *req)
-{
-	return sa_sha_run(req);
-}
-
 static int sa_sha_init(struct ahash_request *req)
 {
 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
@@ -1629,13 +1685,13 @@
 	struct algo_data ad = { 0 };
 	struct sa_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
 
-	sa_sha_cra_init_alg(tfm, "sha1");
+	sa_sha_cra_init_alg(tfm, NULL, "sha1");
 
 	ad.aalg_id = SA_AALG_ID_SHA1;
 	ad.hash_size = SHA1_DIGEST_SIZE;
 	ad.auth_ctrl = SA_AUTH_SW_CTRL_SHA1;
 
-	sa_sha_setup(ctx, &ad);
+	sa_sha_setup(ctx, &ad, NULL, 0);
 
 	return 0;
 }
@@ -1645,13 +1701,13 @@
 	struct algo_data ad = { 0 };
 	struct sa_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
 
-	sa_sha_cra_init_alg(tfm, "sha256");
+	sa_sha_cra_init_alg(tfm, NULL, "sha256");
 
 	ad.aalg_id = SA_AALG_ID_SHA2_256;
 	ad.hash_size = SHA256_DIGEST_SIZE;
 	ad.auth_ctrl = SA_AUTH_SW_CTRL_SHA256;
 
-	sa_sha_setup(ctx, &ad);
+	sa_sha_setup(ctx, &ad, NULL, 0);
 
 	return 0;
 }
@@ -1661,17 +1717,63 @@
 	struct algo_data ad = { 0 };
 	struct sa_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
 
-	sa_sha_cra_init_alg(tfm, "sha512");
+	sa_sha_cra_init_alg(tfm, NULL, "sha512");
 
 	ad.aalg_id = SA_AALG_ID_SHA2_512;
 	ad.hash_size = SHA512_DIGEST_SIZE;
 	ad.auth_ctrl = SA_AUTH_SW_CTRL_SHA512;
 
-	sa_sha_setup(ctx, &ad);
+	sa_sha_setup(ctx, &ad, NULL, 0);
 
 	return 0;
 }
 
+static int sa_hmac_cra_init(struct crypto_tfm *tfm)
+{
+	const char *alg_name = crypto_tfm_alg_name(tfm);
+	int ret = -EINVAL;
+
+	if (!strcmp(alg_name, "hmac(sha1)"))
+		ret = sa_sha_cra_init_alg(tfm, "sha1", alg_name);
+	else if (!strcmp(alg_name, "hmac(sha256)"))
+		ret = sa_sha_cra_init_alg(tfm, "sha256", alg_name);
+	else if (!strcmp(alg_name, "hmac(sha512)"))
+		ret = sa_sha_cra_init_alg(tfm, "sha512", alg_name);
+	else
+		dev_err(sa_k3_dev, "%s: unsupported algo %s\n", __func__, alg_name);
+
+	return ret;
+}
+
+
+static int sa_hmac_sha_setkey(struct crypto_ahash *ahash, const u8 *key,
+			     unsigned int keylen)
+{
+	struct crypto_tfm *tfm = crypto_ahash_tfm(ahash);
+	const char *alg_name = crypto_tfm_alg_name(tfm);
+	struct sa_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct algo_data ad = { 0 };
+
+	if (!strcmp(alg_name, "hmac(sha1)")) {
+		ad.aalg_id = SA_AALG_ID_SHA1;
+		ad.hash_size = SHA1_DIGEST_SIZE;
+		ad.auth_ctrl = SA_AUTH_SW_CTRL_SHA1;
+	} else if (!strcmp(alg_name, "hmac(sha256)")) {
+		ad.aalg_id = SA_AALG_ID_SHA2_256;
+		ad.hash_size = SHA256_DIGEST_SIZE;
+		ad.auth_ctrl = SA_AUTH_SW_CTRL_SHA256;
+	} else if (!strcmp(alg_name, "hmac(sha512)")) {
+		ad.aalg_id = SA_AALG_ID_SHA2_512;
+		ad.hash_size = SHA512_DIGEST_SIZE;
+		ad.auth_ctrl = SA_AUTH_SW_CTRL_SHA512;
+	} else {
+		dev_err(sa_k3_dev, "%s: unsupported algo %s\n", __func__, alg_name);
+		return -EINVAL;
+	}
+
+	return sa_sha_setup(ctx, &ad, key, keylen);
+}
+
 static void sa_sha_cra_exit(struct crypto_tfm *tfm)
 {
 	struct sa_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
@@ -1817,9 +1919,9 @@
 
 	ad->ctx = ctx;
 	ad->enc_eng.eng_id = SA_ENG_ID_EM1;
-	ad->enc_eng.sc_size = SA_CTX_ENC_TYPE1_SZ;
+	ad->enc_eng.sc_size = SA_CTX_ENC_TYPE_SZ;
 	ad->auth_eng.eng_id = SA_ENG_ID_AM1;
-	ad->auth_eng.sc_size = SA_CTX_AUTH_TYPE2_SZ;
+	ad->auth_eng.sc_size = SA_CTX_AUTH_TYPE_SZ;
 	ad->mci_enc = mci_cbc_enc_no_iv_array[key_idx];
 	ad->mci_dec = mci_cbc_dec_no_iv_array[key_idx];
 	ad->inv_key = true;
@@ -1829,12 +1931,9 @@
 
 	memset(&cfg, 0, sizeof(cfg));
 	cfg.enc = true;
-	cfg.aalg = ad->aalg_id;
 	cfg.enc_eng_id = ad->enc_eng.eng_id;
 	cfg.auth_eng_id = ad->auth_eng.eng_id;
 	cfg.iv_size = crypto_aead_ivsize(authenc);
-	cfg.akey = keys.authkey;
-	cfg.akey_len = keys.authkeylen;
 
 	/* Setup Encryption Security Context & Command label template */
 	if (sa_init_sc(&ctx->enc, ctx->dev_data->match_data, keys.enckey,
@@ -2201,6 +2300,96 @@
 			.decrypt = sa_aead_decrypt,
 		},
 	},
+	[SA_ALG_HMAC_SHA256] = {
+		.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.ahash = {
+		       .halg.base = {
+			       .cra_name       = "hmac(sha256)",
+			       .cra_driver_name        = "hmac(sha256-sa2ul)",
+			       .cra_priority   = 1000,
+			       .cra_flags      = CRYPTO_ALG_TYPE_AHASH |
+						 CRYPTO_ALG_ASYNC |
+						 CRYPTO_ALG_KERN_DRIVER_ONLY |
+						 CRYPTO_ALG_NEED_FALLBACK,
+			       .cra_blocksize  = SHA256_BLOCK_SIZE,
+			       .cra_ctxsize    = sizeof(struct sa_tfm_ctx),
+			       .cra_module     = THIS_MODULE,
+			       .cra_init       = sa_hmac_cra_init,
+			       .cra_exit       = sa_sha_cra_exit,
+		       },
+		       .halg.digestsize        = SHA256_DIGEST_SIZE,
+		       .halg.statesize	       = sizeof(struct sa_sha_req_ctx) +
+						 sizeof(struct sha256_state),
+		       .init		       = sa_sha_init,
+		       .update		       = sa_sha_update,
+		       .final		       = sa_sha_final,
+		       .finup		       = sa_sha_finup,
+		       .setkey		       = sa_hmac_sha_setkey,
+		       .digest		       = sa_sha_digest,
+		       .export		       = sa_sha_export,
+		       .import		       = sa_sha_import,
+	       },
+	},
+	[SA_ALG_HMAC_SHA1] = {
+		.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.ahash = {
+			.halg.base = {
+				.cra_name	= "hmac(sha1)",
+				.cra_driver_name	= "hmac(sha1-sa2ul)",
+				.cra_priority	= 400,
+				.cra_flags	= CRYPTO_ALG_TYPE_AHASH |
+						  CRYPTO_ALG_ASYNC |
+						  CRYPTO_ALG_KERN_DRIVER_ONLY |
+						  CRYPTO_ALG_NEED_FALLBACK,
+				.cra_blocksize	= SHA1_BLOCK_SIZE,
+				.cra_ctxsize	= sizeof(struct sa_tfm_ctx),
+				.cra_module	= THIS_MODULE,
+				.cra_init	= sa_hmac_cra_init,
+				.cra_exit	= sa_sha_cra_exit,
+			},
+			.halg.digestsize	= SHA1_DIGEST_SIZE,
+			.halg.statesize		= sizeof(struct sa_sha_req_ctx) +
+						  sizeof(struct sha1_state),
+			.init			= sa_sha_init,
+			.update			= sa_sha_update,
+			.final			= sa_sha_final,
+			.finup			= sa_sha_finup,
+			.setkey		        = sa_hmac_sha_setkey,
+			.digest			= sa_sha_digest,
+			.export			= sa_sha_export,
+			.import			= sa_sha_import,
+		},
+	},
+	[SA_ALG_HMAC_SHA512] = {
+		.type = CRYPTO_ALG_TYPE_AHASH,
+		.alg.ahash = {
+			.halg.base = {
+				.cra_name	= "hmac(sha512)",
+				.cra_driver_name	= "hmac(sha512-sa2ul)",
+				.cra_priority	= 400,
+				.cra_flags	= CRYPTO_ALG_TYPE_AHASH |
+						  CRYPTO_ALG_ASYNC |
+						  CRYPTO_ALG_KERN_DRIVER_ONLY |
+						  CRYPTO_ALG_NEED_FALLBACK,
+				.cra_blocksize	= SHA512_BLOCK_SIZE,
+				.cra_ctxsize	= sizeof(struct sa_tfm_ctx),
+				.cra_module	= THIS_MODULE,
+				.cra_init	= sa_hmac_cra_init,
+				.cra_exit	= sa_sha_cra_exit,
+			},
+			.halg.digestsize	= SHA512_DIGEST_SIZE,
+			.halg.statesize		= sizeof(struct sa_sha_req_ctx) +
+						  sizeof(struct sha512_state),
+			.init			= sa_sha_init,
+			.update			= sa_sha_update,
+			.final			= sa_sha_final,
+			.finup			= sa_sha_finup,
+			.setkey		        = sa_hmac_sha_setkey,
+			.digest			= sa_sha_digest,
+			.export			= sa_sha_export,
+			.import			= sa_sha_import,
+		},
+	},
 };
 
 /* Register the algorithms in crypto framework */
@@ -2262,9 +2451,12 @@
 	}
 }
 
-static int sa_init_mem(struct sa_crypto_data *dev_data)
+static int sa_dma_init(struct sa_crypto_data *dev_data)
 {
+	int ret;
+	struct dma_slave_config cfg;
 	struct device *dev = &dev_data->pdev->dev;
+
 	/* Setup dma pool for security context buffers */
 	dev_data->sc_pool = dma_pool_create("keystone-sc", dev,
 					    SA_CTX_MAX_SZ, 64, 0);
@@ -2273,37 +2465,29 @@
 		return -ENOMEM;
 	}
 
-	return 0;
-}
-
-static int sa_dma_init(struct sa_crypto_data *dd)
-{
-	int ret;
-	struct dma_slave_config cfg;
-
-	dd->dma_rx1 = NULL;
-	dd->dma_tx = NULL;
-	dd->dma_rx2 = NULL;
+	dev_data->dma_rx1 = NULL;
+	dev_data->dma_tx = NULL;
+	dev_data->dma_rx2 = NULL;
 
-	ret = dma_coerce_mask_and_coherent(dd->dev, DMA_BIT_MASK(48));
+	ret = dma_coerce_mask_and_coherent(dev_data->dev, DMA_BIT_MASK(48));
 	if (ret)
-		return ret;
+		goto err_dma_coerce;
 
-	dd->dma_rx1 = dma_request_chan(dd->dev, "rx1");
-	if (IS_ERR(dd->dma_rx1))
-		return dev_err_probe(dd->dev, PTR_ERR(dd->dma_rx1),
+	dev_data->dma_rx1 = dma_request_chan(dev_data->dev, "rx1");
+	if (IS_ERR(dev_data->dma_rx1))
+		return dev_err_probe(dev_data->dev, PTR_ERR(dev_data->dma_rx1),
 				     "Unable to request rx1 DMA channel\n");
 
-	dd->dma_rx2 = dma_request_chan(dd->dev, "rx2");
-	if (IS_ERR(dd->dma_rx2)) {
-		ret = dev_err_probe(dd->dev, PTR_ERR(dd->dma_rx2),
+	dev_data->dma_rx2 = dma_request_chan(dev_data->dev, "rx2");
+	if (IS_ERR(dev_data->dma_rx2)) {
+		ret = dev_err_probe(dev_data->dev, PTR_ERR(dev_data->dma_rx2),
 				    "Unable to request rx2 DMA channel\n");
 		goto err_dma_rx2;
 	}
 
-	dd->dma_tx = dma_request_chan(dd->dev, "tx");
-	if (IS_ERR(dd->dma_tx)) {
-		ret = dev_err_probe(dd->dev, PTR_ERR(dd->dma_tx),
+	dev_data->dma_tx = dma_request_chan(dev_data->dev, "tx");
+	if (IS_ERR(dev_data->dma_tx)) {
+		ret = dev_err_probe(dev_data->dev, PTR_ERR(dev_data->dma_tx),
 				    "Unable to request tx DMA channel\n");
 		goto err_dma_tx;
 	}
@@ -2315,23 +2499,23 @@
 	cfg.src_maxburst = 4;
 	cfg.dst_maxburst = 4;
 
-	ret = dmaengine_slave_config(dd->dma_rx1, &cfg);
+	ret = dmaengine_slave_config(dev_data->dma_rx1, &cfg);
 	if (ret) {
-		dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n",
+		dev_err(dev_data->dev, "can't configure IN dmaengine slave: %d\n",
 			ret);
 		goto err_dma_config;
 	}
 
-	ret = dmaengine_slave_config(dd->dma_rx2, &cfg);
+	ret = dmaengine_slave_config(dev_data->dma_rx2, &cfg);
 	if (ret) {
-		dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n",
+		dev_err(dev_data->dev, "can't configure IN dmaengine slave: %d\n",
 			ret);
 		goto err_dma_config;
 	}
 
-	ret = dmaengine_slave_config(dd->dma_tx, &cfg);
+	ret = dmaengine_slave_config(dev_data->dma_tx, &cfg);
 	if (ret) {
-		dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n",
+		dev_err(dev_data->dev, "can't configure OUT dmaengine slave: %d\n",
 			ret);
 		goto err_dma_config;
 	}
@@ -2339,15 +2523,25 @@
 	return 0;
 
 err_dma_config:
-	dma_release_channel(dd->dma_tx);
+	dma_release_channel(dev_data->dma_tx);
 err_dma_tx:
-	dma_release_channel(dd->dma_rx2);
+	dma_release_channel(dev_data->dma_rx2);
 err_dma_rx2:
-	dma_release_channel(dd->dma_rx1);
+	dma_release_channel(dev_data->dma_rx1);
+err_dma_coerce:
+	dma_pool_destroy(dev_data->sc_pool);
 
 	return ret;
 }
 
+static void sa_dma_cleanup(struct sa_crypto_data *dev_data)
+{
+	dma_release_channel(dev_data->dma_rx2);
+	dma_release_channel(dev_data->dma_rx1);
+	dma_release_channel(dev_data->dma_tx);
+	dma_pool_destroy(dev_data->sc_pool);
+}
+
 static int sa_link_child(struct device *dev, void *data)
 {
 	struct device *parent = data;
@@ -2368,7 +2562,10 @@
 			   BIT(SA_ALG_SHA256) |
 			   BIT(SA_ALG_SHA512) |
 			   BIT(SA_ALG_AUTHENC_SHA1_AES) |
-			   BIT(SA_ALG_AUTHENC_SHA256_AES),
+			   BIT(SA_ALG_AUTHENC_SHA256_AES) |
+			   BIT(SA_ALG_HMAC_SHA1) |
+			   BIT(SA_ALG_HMAC_SHA256)  |
+			   BIT(SA_ALG_HMAC_SHA512),
 };
 
 static struct sa_match_data am64_match_data = {
@@ -2426,10 +2623,9 @@
 		return ret;
 	}
 
-	sa_init_mem(dev_data);
 	ret = sa_dma_init(dev_data);
 	if (ret)
-		goto destroy_dma_pool;
+		goto disable_pm_runtime;
 
 	spin_lock_init(&dev_data->scid_lock);
 
@@ -2453,14 +2649,9 @@
 
 release_dma:
 	sa_unregister_algos(dev);
+	sa_dma_cleanup(dev_data);
 
-	dma_release_channel(dev_data->dma_rx2);
-	dma_release_channel(dev_data->dma_rx1);
-	dma_release_channel(dev_data->dma_tx);
-
-destroy_dma_pool:
-	dma_pool_destroy(dev_data->sc_pool);
-
+disable_pm_runtime:
 	pm_runtime_put_sync(dev);
 	pm_runtime_disable(dev);
 
@@ -2474,12 +2665,7 @@
 	of_platform_depopulate(&pdev->dev);
 
 	sa_unregister_algos(&pdev->dev);
-
-	dma_release_channel(dev_data->dma_rx2);
-	dma_release_channel(dev_data->dma_rx1);
-	dma_release_channel(dev_data->dma_tx);
-
-	dma_pool_destroy(dev_data->sc_pool);
+	sa_dma_cleanup(dev_data);
 
 	platform_set_drvdata(pdev, NULL);
 
diff -Naur --no-dereference a/drivers/crypto/sa2ul.h b/drivers/crypto/sa2ul.h
--- a/drivers/crypto/sa2ul.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/crypto/sa2ul.h	2025-10-23 09:30:40.284462176 -0400
@@ -110,15 +110,12 @@
 #define SA_CTX_PE_PKT_TYPE_IPSEC_ESP   3
 /* Indicates that it is in data mode, It may not be used by PHP */
 #define SA_CTX_PE_PKT_TYPE_NONE        4
-#define SA_CTX_ENC_TYPE1_SZ     64      /* Encryption SC with Key only */
-#define SA_CTX_ENC_TYPE2_SZ     96      /* Encryption SC with Key and Aux1 */
-
-#define SA_CTX_AUTH_TYPE1_SZ    64      /* Auth SC with Key only */
-#define SA_CTX_AUTH_TYPE2_SZ    96      /* Auth SC with Key and Aux1 */
+#define SA_CTX_ENC_TYPE_SZ     128      /* Encryption SC with Key and Aux1 */
+#define SA_CTX_AUTH_TYPE_SZ    160      /* Auth SC with Key and Aux1 and Aux2 */
 /* Size of security context for PHP engine */
 #define SA_CTX_PHP_PE_CTX_SZ    64
 
-#define SA_CTX_MAX_SZ (64 + SA_CTX_ENC_TYPE2_SZ + SA_CTX_AUTH_TYPE2_SZ)
+#define SA_CTX_MAX_SZ (64 + SA_CTX_ENC_TYPE_SZ + SA_CTX_AUTH_TYPE_SZ)
 
 /*
  * Encoding of F/E control in SCCTL
@@ -149,8 +146,7 @@
 #define SA_CTX_ENC_AUX3_OFFSET  112
 #define SA_CTX_ENC_AUX4_OFFSET  128
 
-#define SA_SCCTL_FE_AUTH_ENC	0x65
-#define SA_SCCTL_FE_ENC		0x8D
+#define SA_SCCTL_FE_AUTH_ENC	0x6D
 
 #define SA_ALIGN_MASK		(sizeof(u32) - 1)
 #define SA_ALIGNED		__aligned(32)
@@ -308,10 +304,7 @@
 	struct sa_ctx_info enc;
 	struct sa_ctx_info dec;
 	struct sa_ctx_info auth;
-	int keylen;
 	int iv_idx;
-	u32 key[AES_KEYSIZE_256 / sizeof(u32)];
-	u8 authkey[SHA512_BLOCK_SIZE];
 	struct crypto_shash	*shash;
 	/* for fallback */
 	union {
diff -Naur --no-dereference a/drivers/crypto/ti/dthev2-aes.c b/drivers/crypto/ti/dthev2-aes.c
--- a/drivers/crypto/ti/dthev2-aes.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/crypto/ti/dthev2-aes.c	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,428 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * K3 DTHE V2 crypto accelerator driver
+ *
+ * Copyright (C) Texas Instruments 2025 - https://www.ti.com
+ * Author: T Pratham <t-pratham@ti.com>
+ */
+
+#include <crypto/aead.h>
+#include <crypto/aes.h>
+#include <crypto/algapi.h>
+#include <crypto/internal/aead.h>
+#include <crypto/internal/skcipher.h>
+
+#include "dthev2-common.h"
+
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/scatterlist.h>
+
+/* Registers */
+
+// AES Engine
+#define DTHE_P_AES_BASE		0x7000
+#define DTHE_P_AES_KEY1_0	0x0038
+#define DTHE_P_AES_KEY1_1	0x003C
+#define DTHE_P_AES_KEY1_2	0x0030
+#define DTHE_P_AES_KEY1_3	0x0034
+#define DTHE_P_AES_KEY1_4	0x0028
+#define DTHE_P_AES_KEY1_5	0x002C
+#define DTHE_P_AES_KEY1_6	0x0020
+#define DTHE_P_AES_KEY1_7	0x0024
+#define DTHE_P_AES_IV_IN_0	0x0040
+#define DTHE_P_AES_IV_IN_1	0x0044
+#define DTHE_P_AES_IV_IN_2	0x0048
+#define DTHE_P_AES_IV_IN_3	0x004C
+#define DTHE_P_AES_CTRL		0x0050
+#define DTHE_P_AES_C_LENGTH_0	0x0054
+#define DTHE_P_AES_C_LENGTH_1	0x0058
+#define DTHE_P_AES_AUTH_LENGTH	0x005C
+#define DTHE_P_AES_DATA_IN_OUT	0x0060
+
+#define DTHE_P_AES_SYSCONFIG	0x0084
+#define DTHE_P_AES_IRQSTATUS	0x008C
+#define DTHE_P_AES_IRQENABLE	0x0090
+
+/* Register write values and macros */
+
+enum aes_ctrl_mode_masks {
+	AES_CTRL_ECB_MASK = 0x00,
+	AES_CTRL_CBC_MASK = BIT(5),
+};
+
+#define DTHE_AES_CTRL_MODE_CLEAR_MASK		~GENMASK(28, 5)
+
+#define DTHE_AES_CTRL_DIR_ENC			BIT(2)
+
+#define DTHE_AES_CTRL_KEYSIZE_16B		BIT(3)
+#define DTHE_AES_CTRL_KEYSIZE_24B		BIT(4)
+#define DTHE_AES_CTRL_KEYSIZE_32B		(BIT(3) | BIT(4))
+
+#define DTHE_AES_CTRL_SAVE_CTX_SET		BIT(29)
+
+#define DTHE_AES_CTRL_OUTPUT_READY		BIT_MASK(0)
+#define DTHE_AES_CTRL_INPUT_READY		BIT_MASK(1)
+#define DTHE_AES_CTRL_SAVED_CTX_READY		BIT_MASK(30)
+#define DTHE_AES_CTRL_CTX_READY			BIT_MASK(31)
+
+#define DTHE_AES_SYSCONFIG_DMA_DATA_IN_OUT_EN	GENMASK(6, 5)
+#define DTHE_AES_IRQENABLE_EN_ALL		GENMASK(3, 0)
+
+/* Misc */
+#define AES_IV_SIZE				AES_BLOCK_SIZE
+#define AES_BLOCK_WORDS				(AES_BLOCK_SIZE / sizeof(u32))
+#define AES_IV_WORDS				AES_BLOCK_WORDS
+
+static int cnt;
+
+static int dthe_cipher_cra_init(struct crypto_skcipher *tfm)
+{
+	struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+
+	void __iomem *aes_base_reg = dev_data->regs + DTHE_P_AES_BASE;
+	u32 aes_irqenable_val = readl_relaxed(aes_base_reg + DTHE_P_AES_IRQENABLE);
+	u32 aes_sysconfig_val = readl_relaxed(aes_base_reg + DTHE_P_AES_SYSCONFIG);
+
+	memzero_explicit(ctx, sizeof(*ctx));
+	ctx->dev_data = dev_data;
+	ctx->ctx_info.aes_ctx = kzalloc(sizeof(*ctx->ctx_info.aes_ctx), GFP_KERNEL);
+	if (!ctx->ctx_info.aes_ctx)
+		return -ENOMEM;
+
+	aes_sysconfig_val |= DTHE_AES_SYSCONFIG_DMA_DATA_IN_OUT_EN;
+	writel_relaxed(aes_sysconfig_val, aes_base_reg + DTHE_P_AES_SYSCONFIG);
+
+	aes_irqenable_val |= DTHE_AES_IRQENABLE_EN_ALL;
+	writel_relaxed(aes_irqenable_val, aes_base_reg + DTHE_P_AES_IRQENABLE);
+
+	return 0;
+}
+
+static void dthe_cipher_cra_exit(struct crypto_skcipher *tfm)
+{
+	struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+
+	void __iomem *aes_base_reg = dev_data->regs + DTHE_P_AES_BASE;
+
+	kfree(ctx->ctx_info.aes_ctx);
+	writel_relaxed(0, aes_base_reg + DTHE_P_AES_IRQENABLE);
+}
+
+static int dthe_ecb_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen)
+{
+	struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+	if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 && keylen != AES_KEYSIZE_256)
+		return -EINVAL;
+
+	ctx->ctx_info.aes_ctx->mode = DTHE_AES_ECB;
+	ctx->ctx_info.aes_ctx->keylen = keylen;
+	memcpy(ctx->ctx_info.aes_ctx->key, key, keylen);
+
+	return 0;
+}
+
+static int dthe_cbc_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen)
+{
+	struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+	if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 && keylen != AES_KEYSIZE_256)
+		return -EINVAL;
+
+	ctx->ctx_info.aes_ctx->mode = DTHE_AES_CBC;
+	ctx->ctx_info.aes_ctx->keylen = keylen;
+	memcpy(ctx->ctx_info.aes_ctx->key, key, keylen);
+
+	return 0;
+}
+
+static void dthe_aes_set_ctrl_key(struct dthe_tfm_ctx *ctx, u32 *iv_in)
+{
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+	struct dthe_aes_ctx *actx = ctx->ctx_info.aes_ctx;
+	void __iomem *aes_base_reg = dev_data->regs + DTHE_P_AES_BASE;
+	u32 ctrl_val = 0;
+
+	writel_relaxed(actx->key[0], aes_base_reg + DTHE_P_AES_KEY1_0);
+	writel_relaxed(actx->key[1], aes_base_reg + DTHE_P_AES_KEY1_1);
+	writel_relaxed(actx->key[2], aes_base_reg + DTHE_P_AES_KEY1_2);
+	writel_relaxed(actx->key[3], aes_base_reg + DTHE_P_AES_KEY1_3);
+
+	if (actx->keylen > AES_KEYSIZE_128) {
+		writel_relaxed(actx->key[4], aes_base_reg + DTHE_P_AES_KEY1_4);
+		writel_relaxed(actx->key[5], aes_base_reg + DTHE_P_AES_KEY1_5);
+	}
+	if (actx->keylen == AES_KEYSIZE_256) {
+		writel_relaxed(actx->key[6], aes_base_reg + DTHE_P_AES_KEY1_6);
+		writel_relaxed(actx->key[7], aes_base_reg + DTHE_P_AES_KEY1_7);
+	}
+
+	if (actx->enc)
+		ctrl_val |= DTHE_AES_CTRL_DIR_ENC;
+
+	if (actx->keylen == AES_KEYSIZE_128)
+		ctrl_val |= DTHE_AES_CTRL_KEYSIZE_16B;
+	else if (actx->keylen == AES_KEYSIZE_192)
+		ctrl_val |= DTHE_AES_CTRL_KEYSIZE_24B;
+	else
+		ctrl_val |= DTHE_AES_CTRL_KEYSIZE_32B;
+
+	// Write AES mode
+	ctrl_val &= DTHE_AES_CTRL_MODE_CLEAR_MASK;
+	switch (ctx->ctx_info.aes_ctx->mode) {
+	case DTHE_AES_ECB:
+		ctrl_val |= AES_CTRL_ECB_MASK;
+		break;
+	case DTHE_AES_CBC:
+		ctrl_val |= AES_CTRL_CBC_MASK;
+		break;
+	}
+
+	if (iv_in) {
+		ctrl_val |= DTHE_AES_CTRL_SAVE_CTX_SET;
+		for (int i = 0; i < AES_IV_WORDS; ++i)
+			writel_relaxed(iv_in[i],
+				       aes_base_reg + DTHE_P_AES_IV_IN_0 + (DTHE_REG_SIZE * i));
+	}
+
+	writel_relaxed(ctrl_val, aes_base_reg + DTHE_P_AES_CTRL);
+}
+
+static void dthe_aes_dma_in_callback(void *data)
+{
+	struct skcipher_request *req = (struct skcipher_request *)data;
+	struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+
+	// For modes other than ECB, read IV_OUT
+	if (ctx->ctx_info.aes_ctx->mode != DTHE_AES_ECB) {
+		void __iomem *aes_base_reg = dev_data->regs + DTHE_P_AES_BASE;
+		u32 *iv_out = (u32 *)req->iv;
+
+		for (int i = 0; i < AES_IV_WORDS; ++i)
+			iv_out[i] = readl_relaxed(aes_base_reg +
+						  DTHE_P_AES_IV_IN_0 +
+						  (DTHE_REG_SIZE * i));
+	}
+
+	complete(&ctx->ctx_info.aes_ctx->aes_compl);
+}
+
+static int dthe_aes_run(struct skcipher_request *req)
+{
+	struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+	struct dthe_aes_ctx *actx = ctx->ctx_info.aes_ctx;
+
+	unsigned int len = req->cryptlen;
+	struct scatterlist *src = req->src;
+	struct scatterlist *dst = req->dst;
+
+	int src_nents = sg_nents_for_len(src, len);
+	int dst_nents;
+
+	int src_mapped_nents;
+	int dst_mapped_nents;
+
+	bool diff_dst;
+	enum dma_data_direction src_dir, dst_dir;
+
+	struct device *tx_dev, *rx_dev;
+	struct dma_async_tx_descriptor *desc_in, *desc_out;
+
+	int ret;
+
+	void __iomem *aes_base_reg = dev_data->regs + DTHE_P_AES_BASE;
+
+	if (src == dst) {
+		diff_dst = false;
+		src_dir = DMA_BIDIRECTIONAL;
+		dst_dir = DMA_BIDIRECTIONAL;
+	} else {
+		diff_dst = true;
+		src_dir = DMA_TO_DEVICE;
+		dst_dir  = DMA_FROM_DEVICE;
+	}
+
+	tx_dev = dmaengine_get_dma_device(dev_data->dma_aes_tx);
+	rx_dev = dmaengine_get_dma_device(dev_data->dma_aes_rx);
+
+	src_mapped_nents = dma_map_sg(tx_dev, src, src_nents, src_dir);
+	if (src_mapped_nents == 0) {
+		ret = -EINVAL;
+		goto aes_err;
+	}
+
+	if (!diff_dst) {
+		dst_nents = src_nents;
+		dst_mapped_nents = src_mapped_nents;
+	} else {
+		dst_nents = sg_nents_for_len(dst, len);
+		dst_mapped_nents = dma_map_sg(rx_dev, dst, dst_nents, dst_dir);
+		if (dst_mapped_nents == 0) {
+			dma_unmap_sg(tx_dev, src, src_nents, src_dir);
+			ret = -EINVAL;
+			goto aes_err;
+		}
+	}
+
+	// HACK: Delay to workaround DMA driver issue
+	cnt++;
+	if (cnt % 50 == 0) {
+		unsigned long delay = jiffies + usecs_to_jiffies(100);
+
+		while (time_before(jiffies, delay))
+			cond_resched();
+		cnt = 0;
+	}
+
+	desc_in = dmaengine_prep_slave_sg(dev_data->dma_aes_rx, dst, dst_mapped_nents,
+					  DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc_in) {
+		dev_err(dev_data->dev, "IN prep_slave_sg() failed\n");
+		ret = -EINVAL;
+		goto aes_prep_err;
+	}
+
+	desc_out = dmaengine_prep_slave_sg(dev_data->dma_aes_tx, src, src_mapped_nents,
+					   DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc_out) {
+		dev_err(dev_data->dev, "OUT prep_slave_sg() failed\n");
+		ret = -EINVAL;
+		goto aes_prep_err;
+	}
+
+	desc_in->callback = dthe_aes_dma_in_callback;
+	desc_in->callback_param = req;
+
+	init_completion(&actx->aes_compl);
+
+	mutex_lock(&dev_data->aes_mutex);
+
+	if (actx->mode == DTHE_AES_ECB)
+		dthe_aes_set_ctrl_key(ctx, NULL);
+	else
+		dthe_aes_set_ctrl_key(ctx, (u32 *)req->iv);
+
+	writel_relaxed(req->cryptlen, aes_base_reg + DTHE_P_AES_C_LENGTH_0);
+
+	dmaengine_submit(desc_in);
+	dmaengine_submit(desc_out);
+
+	dma_async_issue_pending(dev_data->dma_aes_rx);
+	dma_async_issue_pending(dev_data->dma_aes_tx);
+
+	// Need to do a timeout to ensure mutex gets unlocked if DMA callback fails for any reason
+	ret = wait_for_completion_timeout(&actx->aes_compl, msecs_to_jiffies(DTHE_DMA_TIMEOUT_MS));
+	if (!ret) {
+		ret = -ETIMEDOUT;
+
+		for (int i = 0; i < AES_BLOCK_WORDS; ++i)
+			readl_relaxed(aes_base_reg + DTHE_P_AES_DATA_IN_OUT + (DTHE_REG_SIZE * i));
+		for (int i = 0; i < AES_IV_WORDS; ++i)
+			readl_relaxed(aes_base_reg + DTHE_P_AES_IV_IN_0 + (DTHE_REG_SIZE * i));
+	} else {
+		ret = 0;
+	}
+
+	mutex_unlock(&dev_data->aes_mutex);
+
+aes_prep_err:
+	dma_unmap_sg(tx_dev, src, src_nents, src_dir);
+	if (dst_dir != DMA_BIDIRECTIONAL)
+		dma_unmap_sg(rx_dev, dst, dst_nents, dst_dir);
+
+aes_err:
+	skcipher_request_complete(req, ret);
+	return ret;
+}
+
+static int dthe_aes_crypt(struct skcipher_request *req, int enc)
+{
+	struct dthe_tfm_ctx *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
+
+	/*
+	 * If data is not a multiple of AES_BLOCK_SIZE, need to return -EINVAL
+	 * If data length input is zero, no need to do any operation.
+	 */
+	if (req->cryptlen % AES_BLOCK_SIZE) {
+		skcipher_request_complete(req, -EINVAL);
+		return -EINVAL;
+	}
+	if (req->cryptlen == 0) {
+		skcipher_request_complete(req, 0);
+		return 0;
+	}
+
+	ctx->ctx_info.aes_ctx->enc = enc;
+	return dthe_aes_run(req);
+}
+
+static int dthe_aes_encrypt(struct skcipher_request *req)
+{
+	return dthe_aes_crypt(req, 1);
+}
+
+static int dthe_aes_decrypt(struct skcipher_request *req)
+{
+	return dthe_aes_crypt(req, 0);
+}
+
+static struct skcipher_alg cipher_algs[] = {
+	{
+		.setkey	= dthe_ecb_aes_setkey,
+		.encrypt	= dthe_aes_encrypt,
+		.decrypt	= dthe_aes_decrypt,
+		.min_keysize	= AES_MIN_KEY_SIZE,
+		.max_keysize	= AES_MAX_KEY_SIZE,
+		.base	= {
+			.cra_name	= "ecb(aes)",
+			.cra_driver_name	= "ecb-aes-dthev2",
+			.cra_priority	= 30000,
+			.cra_flags	= CRYPTO_ALG_TYPE_SKCIPHER |
+					  CRYPTO_ALG_KERN_DRIVER_ONLY,
+			.cra_alignmask	= AES_BLOCK_SIZE - 1,
+			.cra_blocksize	= AES_BLOCK_SIZE,
+			.cra_ctxsize	= sizeof(struct dthe_tfm_ctx),
+			.cra_module	= THIS_MODULE,
+		},
+		.init	= dthe_cipher_cra_init,
+		.exit	= dthe_cipher_cra_exit
+	}, /* ECB AES*/
+	{
+		.setkey = dthe_cbc_aes_setkey,
+		.encrypt	= dthe_aes_encrypt,
+		.decrypt	= dthe_aes_decrypt,
+		.min_keysize	= AES_MIN_KEY_SIZE,
+		.max_keysize	= AES_MAX_KEY_SIZE,
+		.ivsize		= AES_BLOCK_SIZE,
+		.base	= {
+			.cra_name	= "cbc(aes)",
+			.cra_driver_name	 = "cbc-aes-dthev2",
+			.cra_priority	= 30000,
+			.cra_flags	= CRYPTO_ALG_TYPE_SKCIPHER |
+					  CRYPTO_ALG_KERN_DRIVER_ONLY,
+			.cra_alignmask	= AES_BLOCK_SIZE - 1,
+			.cra_blocksize	= AES_BLOCK_SIZE,
+			.cra_ctxsize	= sizeof(struct dthe_tfm_ctx),
+			.cra_module	= THIS_MODULE,
+		},
+		.init	= dthe_cipher_cra_init,
+		.exit	= dthe_cipher_cra_exit
+	}, /* CBC AES */
+};
+
+int dthe_register_aes_algs(void)
+{
+	return crypto_register_skciphers(cipher_algs, ARRAY_SIZE(cipher_algs));
+}
+
+void dthe_unregister_aes_algs(void)
+{
+	crypto_unregister_skciphers(cipher_algs, ARRAY_SIZE(cipher_algs));
+}
diff -Naur --no-dereference a/drivers/crypto/ti/dthev2-common.c b/drivers/crypto/ti/dthev2-common.c
--- a/drivers/crypto/ti/dthev2-common.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/crypto/ti/dthev2-common.c	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * K3 DTHE V2 crypto accelerator driver
+ *
+ * Copyright (C) Texas Instruments 2025 - https://www.ti.com
+ * Author: T Pratham <t-pratham@ti.com>
+ */
+
+#include <crypto/aes.h>
+#include <crypto/algapi.h>
+#include <crypto/internal/aead.h>
+#include <crypto/internal/skcipher.h>
+
+#include "dthev2-common.h"
+
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/scatterlist.h>
+
+#define DRIVER_NAME	"dthev2"
+
+static struct dthe_list dthe_dev_list = {
+	.dev_list = LIST_HEAD_INIT(dthe_dev_list.dev_list),
+	.lock = __SPIN_LOCK_UNLOCKED(dthe_dev_list.lock),
+};
+
+struct dthe_data *dthe_get_dev(struct dthe_tfm_ctx *ctx)
+{
+	struct dthe_data *dev_data;
+
+	if (ctx->dev_data)
+		return ctx->dev_data;
+
+	spin_lock_bh(&dthe_dev_list.lock);
+	dev_data = list_first_entry(&dthe_dev_list.dev_list, struct dthe_data, list);
+	if (dev_data)
+		list_move_tail(&dev_data->list, &dthe_dev_list.dev_list);
+	spin_unlock_bh(&dthe_dev_list.lock);
+
+	return dev_data;
+}
+
+static int dthe_dma_init(struct dthe_data *dev_data)
+{
+	int ret;
+	struct dma_slave_config cfg;
+
+	dev_data->dma_aes_rx = NULL;
+	dev_data->dma_aes_tx = NULL;
+	dev_data->dma_sha_tx = NULL;
+
+	dev_data->dma_aes_rx = dma_request_chan(dev_data->dev, "rx");
+	if (IS_ERR(dev_data->dma_aes_rx)) {
+		return dev_err_probe(dev_data->dev, PTR_ERR(dev_data->dma_aes_rx),
+				     "Unable to request rx DMA channel\n");
+	}
+
+	dev_data->dma_aes_tx = dma_request_chan(dev_data->dev, "tx1");
+	if (IS_ERR(dev_data->dma_aes_tx)) {
+		ret = dev_err_probe(dev_data->dev, PTR_ERR(dev_data->dma_aes_tx),
+				    "Unable to request tx1 DMA channel\n");
+		goto err_dma_aes_tx;
+	}
+
+	dev_data->dma_sha_tx = dma_request_chan(dev_data->dev, "tx2");
+	if (IS_ERR(dev_data->dma_sha_tx)) {
+		ret = dev_err_probe(dev_data->dev, PTR_ERR(dev_data->dma_sha_tx),
+				    "Unable to request tx2 DMA channel\n");
+		goto err_dma_sha_tx;
+	}
+
+	// Do AES Rx and Tx channel config here because it is invariant of AES mode
+	// SHA Tx channel config is done before DMA transfer depending on hashing algorithm
+
+	memzero_explicit(&cfg, sizeof(cfg));
+
+	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	cfg.src_maxburst = 4;
+
+	ret = dmaengine_slave_config(dev_data->dma_aes_rx, &cfg);
+	if (ret) {
+		dev_err(dev_data->dev, "Can't configure IN dmaengine slave: %d\n", ret);
+		goto err_dma_config;
+	}
+
+	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	cfg.dst_maxburst = 4;
+
+	ret = dmaengine_slave_config(dev_data->dma_aes_tx, &cfg);
+	if (ret) {
+		dev_err(dev_data->dev, "Can't configure OUT dmaengine slave: %d\n", ret);
+		goto err_dma_config;
+	}
+
+	return 0;
+
+err_dma_config:
+	dma_release_channel(dev_data->dma_sha_tx);
+err_dma_sha_tx:
+	dma_release_channel(dev_data->dma_aes_tx);
+err_dma_aes_tx:
+	dma_release_channel(dev_data->dma_aes_rx);
+
+	return ret;
+}
+
+static int dthe_register_algs(void)
+{
+	int ret = 0;
+
+	ret |= dthe_register_hash_algs();
+	ret |= dthe_register_aes_algs();
+
+	return ret;
+}
+
+static void dthe_unregister_algs(void)
+{
+	dthe_unregister_hash_algs();
+	dthe_unregister_aes_algs();
+}
+
+static int dthe_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct dthe_data *dev_data;
+	int ret;
+
+	dev_data = devm_kzalloc(dev, sizeof(*dev_data), GFP_KERNEL);
+	if (!dev_data)
+		return -ENOMEM;
+
+	dev_data->dev = dev;
+	dev_data->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(dev_data->regs))
+		return PTR_ERR(dev_data->regs);
+
+	platform_set_drvdata(pdev, dev_data);
+
+	spin_lock(&dthe_dev_list.lock);
+	list_add(&dev_data->list, &dthe_dev_list.dev_list);
+	spin_unlock(&dthe_dev_list.lock);
+
+	mutex_init(&dev_data->aes_mutex);
+	mutex_init(&dev_data->hash_mutex);
+
+	ret = dthe_dma_init(dev_data);
+	if (ret)
+		goto probe_dma_err;
+
+	ret = dthe_register_algs();
+	if (ret) {
+		dev_err(dev, "Failed to register algs\n");
+		goto probe_reg_err;
+	}
+
+	return 0;
+
+probe_reg_err:
+	dma_release_channel(dev_data->dma_aes_rx);
+	dma_release_channel(dev_data->dma_aes_tx);
+	dma_release_channel(dev_data->dma_sha_tx);
+probe_dma_err:
+	spin_lock(&dthe_dev_list.lock);
+	list_del(&dev_data->list);
+	spin_unlock(&dthe_dev_list.lock);
+
+	mutex_destroy(&dev_data->aes_mutex);
+	mutex_destroy(&dev_data->hash_mutex);
+
+	return ret;
+}
+
+static void dthe_remove(struct platform_device *pdev)
+{
+	struct dthe_data *dev_data = platform_get_drvdata(pdev);
+
+	spin_lock(&dthe_dev_list.lock);
+	list_del(&dev_data->list);
+	spin_unlock(&dthe_dev_list.lock);
+
+	mutex_destroy(&dev_data->aes_mutex);
+	mutex_destroy(&dev_data->hash_mutex);
+
+	dthe_unregister_algs();
+
+	dma_release_channel(dev_data->dma_aes_rx);
+	dma_release_channel(dev_data->dma_aes_tx);
+	dma_release_channel(dev_data->dma_sha_tx);
+}
+
+static const struct of_device_id dthe_of_match[] = {
+	{ .compatible = "ti,am62l-dthev2", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, dthe_of_match);
+
+static struct platform_driver dthe_driver = {
+	.probe	= dthe_probe,
+	.remove	= dthe_remove,
+	.driver = {
+		.name		= DRIVER_NAME,
+		.of_match_table	= dthe_of_match,
+	},
+};
+
+module_platform_driver(dthe_driver);
+
+MODULE_AUTHOR("T Pratham <t-pratham@ti.com>");
+MODULE_DESCRIPTION("Texas Instruments DTHE V2 driver");
+MODULE_LICENSE("GPL");
diff -Naur --no-dereference a/drivers/crypto/ti/dthev2-common.h b/drivers/crypto/ti/dthev2-common.h
--- a/drivers/crypto/ti/dthev2-common.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/crypto/ti/dthev2-common.h	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * K3 DTHE V2 crypto accelerator driver
+ *
+ * Copyright (C) Texas Instruments 2025 - https://www.ti.com
+ * Author: T Pratham <t-pratham@ti.com>
+ */
+
+#ifndef __TI_DTHEV2_H__
+#define __TI_DTHE2V_H__
+
+#include <crypto/aead.h>
+#include <crypto/aes.h>
+#include <crypto/algapi.h>
+#include <crypto/hash.h>
+#include <crypto/internal/aead.h>
+#include <crypto/internal/hash.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/md5.h>
+#include <crypto/sha2.h>
+
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/scatterlist.h>
+
+#define DTHE_REG_SIZE		4
+#define DTHE_DMA_TIMEOUT_MS	2000
+
+enum dthe_hash_alg_sel {
+	DTHE_HASH_MD5		= 0,
+	DTHE_HASH_SHA1		= BIT(1),
+	DTHE_HASH_SHA224	= BIT(2),
+	DTHE_HASH_SHA256	= BIT(1) | BIT(2),
+	DTHE_HASH_SHA384	= BIT(0),
+	DTHE_HASH_SHA512	= BIT(0) | BIT(1)
+};
+
+enum dthe_aes_mode {
+	DTHE_AES_ECB = 0,
+	DTHE_AES_CBC,
+};
+
+/* Driver specific struct definitions */
+
+struct dthe_tfm_ctx;
+
+/**
+ * struct dthe_data - DTHE_V2 driver instance data
+ * @dev: Device pointer
+ * @regs: Base address of the register space
+ * @list: list node for dev
+ * @dma_aes_rx: AES Rx DMA Channel
+ * @dma_aes_tx: AES Tx DMA Channel
+ * @dma_sha_tx: SHA Tx DMA Channel
+ * @aes_mutex: Mutex protecting access to AES engine
+ * @hash_mutex: Mutex protecting access to HASH engine
+ * @ctx: Transform context struct
+ */
+struct dthe_data {
+	struct device *dev;
+	void __iomem *regs;
+	struct list_head list;
+
+	struct dma_chan *dma_aes_rx;
+	struct dma_chan *dma_aes_tx;
+
+	struct dma_chan *dma_sha_tx;
+
+	struct mutex aes_mutex;
+	struct mutex hash_mutex;
+
+	struct dthe_tfm_ctx *ctx;
+};
+
+/**
+ * struct dthe_list - device data list head
+ * @dev_list: linked list head
+ * @lock: Spinlock protecting accesses to the list
+ */
+struct dthe_list {
+	struct list_head dev_list;
+	spinlock_t lock;
+};
+
+/**
+ * struct dthe_hash_ctx - Hashing engine ctx struct
+ * @mode: Hashing Engine mode
+ * @block_size: block size of hash algorithm selected
+ * @digest_size: digest size of hash algorithm selected
+ * @phash_available: flag indicating if a partial hash from a previous operation is available
+ * @phash: buffer to store a partial hash from a previous operation
+ * @phash_size: partial hash size of the hash algorithm selected
+ * @digestcnt: stores the digest count from a previous operation
+ * @data_buf: buffer to store part of input data to be carried over to next operation
+ * @buflen: length of input data stored in data_buf
+ * @flags: flags for internal use
+ * @hash_compl: Completion variable for use in manual completion in case of DMA callback failure
+ */
+struct dthe_hash_ctx {
+	enum dthe_hash_alg_sel mode;
+	u16 block_size;
+	u8 digest_size;
+	u8 phash_available;
+	u32 phash[SHA512_DIGEST_SIZE / sizeof(u32)];
+	u32 phash_size;
+	u32 digestcnt;
+	u8 data_buf[SHA512_BLOCK_SIZE];
+	u8 buflen;
+	u8 flags;
+	struct completion hash_compl;
+};
+
+/**
+ * struct dthe_aes_ctx - AES engine ctx struct
+ * @mode: AES mode
+ * @keylen: AES key length
+ * @key: AES key
+ * @enc: flag indicating encryption or decryption operation
+ * @aes_compl: Completion variable for use in manual completion in case of DMA callback failure
+ */
+struct dthe_aes_ctx {
+	enum dthe_aes_mode mode;
+	unsigned int keylen;
+	u32 key[AES_KEYSIZE_256 / sizeof(u32)];
+	int enc;
+	struct completion aes_compl;
+};
+
+/**
+ * struct dthe_tfm_ctx - Transform ctx struct containing ctx for all sub-components of DTHE V2
+ * @dev_data: Device data struct pointer
+ * @ctx_info: Union of ctx structs of various sub-components of DTHE_V2
+ */
+struct dthe_tfm_ctx {
+	struct dthe_data *dev_data;
+	union {
+		struct dthe_aes_ctx *aes_ctx;
+		struct dthe_hash_ctx *hash_ctx;
+	} ctx_info;
+};
+
+/* Struct definitions end */
+
+struct dthe_data *dthe_get_dev(struct dthe_tfm_ctx *ctx);
+
+int dthe_register_aes_algs(void);
+void dthe_unregister_aes_algs(void);
+
+int dthe_register_hash_algs(void);
+void dthe_unregister_hash_algs(void);
+
+#endif
diff -Naur --no-dereference a/drivers/crypto/ti/dthev2-hash.c b/drivers/crypto/ti/dthev2-hash.c
--- a/drivers/crypto/ti/dthev2-hash.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/crypto/ti/dthev2-hash.c	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,764 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * K3 DTHE V2 crypto accelerator driver
+ *
+ * Copyright (C) Texas Instruments 2025 - https://www.ti.com
+ * Author: T Pratham <t-pratham@ti.com>
+ */
+
+#include <crypto/algapi.h>
+#include <crypto/hash.h>
+#include <crypto/internal/hash.h>
+#include <crypto/md5.h>
+#include <crypto/sha2.h>
+
+#include "dthev2-common.h"
+
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/scatterlist.h>
+
+/* Registers */
+
+// Hashing Engine
+#define DTHE_P_HASH_BASE		0x5000
+#define DTHE_P_HASH512_IDIGEST_A	0x0240
+#define DTHE_P_HASH512_DIGEST_COUNT	0x0280
+#define DTHE_P_HASH512_MODE		0x0284
+#define DTHE_P_HASH512_LENGTH		0x0288
+#define DTHE_P_HASH512_DATA_IN_START	0x0080
+#define DTHE_P_HASH512_DATA_IN_END	0x00FC
+
+#define DTHE_P_HASH_SYSCONFIG		0x0110
+#define DTHE_P_HASH_IRQSTATUS		0x0118
+#define DTHE_P_HASH_IRQENABLE		0x011C
+
+/* Register write values and macros */
+#define DTHE_HASH_SYSCONFIG_INT_EN		BIT(2)
+#define DTHE_HASH_SYSCONFIG_DMA_EN		BIT(3)
+#define DTHE_HASH_IRQENABLE_EN_ALL		GENMASK(3, 0)
+#define DTHE_HASH_IRQSTATUS_OP_READY		BIT(0)
+#define DTHE_HASH_IRQSTATUS_IP_READY		BIT(1)
+#define DTHE_HASH_IRQSTATUS_PH_READY		BIT(2)
+#define DTHE_HASH_IRQSTATUS_CTX_READY		BIT(3)
+
+#define DTHE_HASH_MODE_USE_ALG_CONST		BIT(3)
+#define DTHE_HASH_MODE_CLOSE_HASH		BIT(4)
+
+/* Misc */
+#define MD5_BLOCK_SIZE				(MD5_BLOCK_WORDS * 4)
+
+enum dthe_hash_dma_callback_src {
+	DMA_CALLBACK_FROM_UPDATE = 0,
+	DMA_CALLBACK_FROM_FINAL,
+	DMA_CALLBACK_FROM_FINUP,
+};
+
+static int cnt;
+
+static struct scatterlist *dthe_set_src_sg(struct scatterlist *src, struct scatterlist *sg,
+					   int nents, int buflen)
+{
+	struct scatterlist *from_sg, *to_sg;
+	int sglen;
+
+	sg_init_table(src, nents);
+
+	for (to_sg = src, from_sg = sg; buflen && from_sg; buflen -= sglen) {
+		sglen = from_sg->length;
+		if (sglen > buflen)
+			sglen = buflen;
+		sg_set_buf(to_sg, sg_virt(from_sg), sglen);
+		from_sg = sg_next(from_sg);
+		to_sg = sg_next(to_sg);
+	}
+
+	return to_sg;
+}
+
+static void dthe_hash_write_zero_message(enum dthe_hash_alg_sel mode, void *dst)
+{
+	switch (mode) {
+	case DTHE_HASH_SHA512:
+		memcpy(dst, sha512_zero_message_hash, SHA512_DIGEST_SIZE);
+		break;
+	case DTHE_HASH_SHA384:
+		memcpy(dst, sha384_zero_message_hash, SHA384_DIGEST_SIZE);
+		break;
+	case DTHE_HASH_SHA256:
+		memcpy(dst, sha256_zero_message_hash, SHA256_DIGEST_SIZE);
+		break;
+	case DTHE_HASH_SHA224:
+		memcpy(dst, sha224_zero_message_hash, SHA224_DIGEST_SIZE);
+		break;
+	case DTHE_HASH_MD5:
+		memcpy(dst, md5_zero_message_hash, MD5_DIGEST_SIZE);
+		break;
+	default:
+		break;
+	}
+}
+
+static int dthe_sha512_cra_init(struct crypto_tfm *tfm)
+{
+	struct dthe_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+
+	if (!dev_data)
+		return -ENODEV;
+
+	ctx->ctx_info.hash_ctx = kzalloc(sizeof(*ctx->ctx_info.hash_ctx), GFP_KERNEL);
+	if (!ctx->ctx_info.hash_ctx)
+		return -ENOMEM;
+
+	ctx->ctx_info.hash_ctx->mode = DTHE_HASH_SHA512;
+	ctx->ctx_info.hash_ctx->block_size = SHA512_BLOCK_SIZE;
+	ctx->ctx_info.hash_ctx->digest_size = SHA512_DIGEST_SIZE;
+	ctx->ctx_info.hash_ctx->phash_size = SHA512_DIGEST_SIZE;
+	return 0;
+}
+
+static int dthe_sha384_cra_init(struct crypto_tfm *tfm)
+{
+	struct dthe_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+
+	if (!dev_data)
+		return -ENODEV;
+
+	ctx->ctx_info.hash_ctx = kzalloc(sizeof(*ctx->ctx_info.hash_ctx), GFP_KERNEL);
+	if (!ctx->ctx_info.hash_ctx)
+		return -ENOMEM;
+
+	ctx->ctx_info.hash_ctx->mode = DTHE_HASH_SHA384;
+	ctx->ctx_info.hash_ctx->block_size = SHA384_BLOCK_SIZE;
+	ctx->ctx_info.hash_ctx->digest_size = SHA384_DIGEST_SIZE;
+	ctx->ctx_info.hash_ctx->phash_size = SHA512_DIGEST_SIZE;
+	return 0;
+}
+
+static int dthe_sha256_cra_init(struct crypto_tfm *tfm)
+{
+	struct dthe_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+
+	if (!dev_data)
+		return -ENODEV;
+
+	ctx->ctx_info.hash_ctx = kzalloc(sizeof(*ctx->ctx_info.hash_ctx), GFP_KERNEL);
+	if (!ctx->ctx_info.hash_ctx)
+		return -ENOMEM;
+
+	ctx->ctx_info.hash_ctx->mode = DTHE_HASH_SHA256;
+	ctx->ctx_info.hash_ctx->block_size = SHA256_BLOCK_SIZE;
+	ctx->ctx_info.hash_ctx->digest_size = SHA256_DIGEST_SIZE;
+	ctx->ctx_info.hash_ctx->phash_size = SHA256_DIGEST_SIZE;
+	return 0;
+}
+
+static int dthe_sha224_cra_init(struct crypto_tfm *tfm)
+{
+	struct dthe_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+
+	if (!dev_data)
+		return -ENODEV;
+
+	ctx->ctx_info.hash_ctx = kzalloc(sizeof(*ctx->ctx_info.hash_ctx), GFP_KERNEL);
+	if (!ctx->ctx_info.hash_ctx)
+		return -ENOMEM;
+
+	ctx->ctx_info.hash_ctx->mode = DTHE_HASH_SHA224;
+	ctx->ctx_info.hash_ctx->block_size = SHA224_BLOCK_SIZE;
+	ctx->ctx_info.hash_ctx->digest_size = SHA224_DIGEST_SIZE;
+	ctx->ctx_info.hash_ctx->phash_size = SHA256_DIGEST_SIZE;
+	return 0;
+}
+
+static int dthe_md5_cra_init(struct crypto_tfm *tfm)
+{
+	struct dthe_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+
+	if (!dev_data)
+		return -ENODEV;
+
+	ctx->ctx_info.hash_ctx = kzalloc(sizeof(*ctx->ctx_info.hash_ctx), GFP_KERNEL);
+	if (!ctx->ctx_info.hash_ctx)
+		return -ENOMEM;
+
+	ctx->ctx_info.hash_ctx->mode = DTHE_HASH_MD5;
+	ctx->ctx_info.hash_ctx->block_size = MD5_BLOCK_SIZE;
+	ctx->ctx_info.hash_ctx->digest_size = MD5_DIGEST_SIZE;
+	ctx->ctx_info.hash_ctx->phash_size = MD5_DIGEST_SIZE;
+	return 0;
+}
+
+static void dthe_hash_cra_exit(struct crypto_tfm *tfm)
+{
+	struct dthe_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	kfree(ctx->ctx_info.hash_ctx);
+}
+
+static void dthe_hash_dma_in_callback(void *data)
+{
+	struct ahash_request *req = (struct ahash_request *)data;
+
+	struct dthe_tfm_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+	struct dthe_hash_ctx *sctx = ctx->ctx_info.hash_ctx;
+	u32 *data_out;
+	u32 out_len;
+
+	void __iomem *sha_base_reg = dev_data->regs + DTHE_P_HASH_BASE;
+
+	if (sctx->flags == DMA_CALLBACK_FROM_UPDATE) {
+		// If coming from update, we need to read the phash and store it for future
+		data_out = sctx->phash;
+		out_len = sctx->phash_size / sizeof(u32);
+	} else {
+		// If coming from finup or final, we need to read the final digest
+		data_out = (u32 *)req->result;
+		out_len = sctx->digest_size / sizeof(u32);
+	}
+
+	for (int i = 0; i < out_len; ++i)
+		data_out[i] = readl_relaxed(sha_base_reg +
+					    DTHE_P_HASH512_IDIGEST_A +
+					    (DTHE_REG_SIZE * i));
+
+	sctx->digestcnt = readl_relaxed(sha_base_reg + DTHE_P_HASH512_DIGEST_COUNT);
+	sctx->phash_available = 1;
+
+	complete(&sctx->hash_compl);
+}
+
+static int dthe_hash_dma_start(struct ahash_request *req, struct scatterlist *src, size_t len)
+{
+	struct dthe_tfm_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+	struct dthe_hash_ctx *sctx = ctx->ctx_info.hash_ctx;
+	struct dma_slave_config cfg;
+	struct device *tx_dev;
+	struct dma_async_tx_descriptor *desc_out;
+	int src_nents;
+	int mapped_nents;
+	enum dma_data_direction src_dir = DMA_TO_DEVICE;
+	int ret = 0;
+	void __iomem *sha_base_reg = dev_data->regs + DTHE_P_HASH_BASE;
+
+	// Config SHA DMA channel as per SHA mode
+	memzero_explicit(&cfg, sizeof(cfg));
+
+	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	cfg.dst_maxburst = sctx->block_size / 4;
+
+	// HACK: Delay to workaround DMA driver issue
+	cnt++;
+	if (cnt % 50 == 0) {
+		unsigned long delay = jiffies + usecs_to_jiffies(100);
+
+		while (time_before(jiffies, delay))
+			cond_resched();
+		cnt = 0;
+	}
+
+	ret = dmaengine_slave_config(dev_data->dma_sha_tx, &cfg);
+	if (ret) {
+		dev_err(dev_data->dev, "Can't configure OUT2 dmaengine slave: %d\n", ret);
+		goto hash_err;
+	}
+
+	tx_dev = dmaengine_get_dma_device(dev_data->dma_sha_tx);
+	if (!tx_dev) {
+		ret = -ENODEV;
+		goto hash_err;
+	}
+
+	src_nents = sg_nents_for_len(src, len);
+	mapped_nents = dma_map_sg(tx_dev, src, src_nents, src_dir);
+	if (mapped_nents == 0) {
+		ret = -EINVAL;
+		goto hash_err;
+	}
+
+	desc_out = dmaengine_prep_slave_sg(dev_data->dma_sha_tx, src, mapped_nents,
+					   DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc_out) {
+		dev_err(dev_data->dev, "OUT prep_slave_sg() failed\n");
+		ret = -EINVAL;
+		goto hash_prep_err;
+	}
+
+	desc_out->callback = dthe_hash_dma_in_callback;
+	desc_out->callback_param = req;
+
+	init_completion(&sctx->hash_compl);
+
+	dmaengine_submit(desc_out);
+
+	dma_async_issue_pending(dev_data->dma_sha_tx);
+
+	ret = wait_for_completion_timeout(&sctx->hash_compl,
+					  msecs_to_jiffies(DTHE_DMA_TIMEOUT_MS));
+	if (!ret) {
+		u32 *data_out;
+		u32 out_len;
+
+		ret = -ETIMEDOUT;
+
+		if (sctx->flags == DMA_CALLBACK_FROM_UPDATE) {
+			data_out = sctx->phash;
+			out_len = sctx->phash_size / sizeof(u32);
+		} else {
+			data_out = (u32 *)req->result;
+			out_len = sctx->digest_size / sizeof(u32);
+		}
+
+		for (int i = 0; i < out_len; ++i)
+			data_out[i] = readl_relaxed(sha_base_reg +
+						    DTHE_P_HASH512_IDIGEST_A +
+						    (DTHE_REG_SIZE * i));
+
+		sctx->digestcnt = readl_relaxed(sha_base_reg + DTHE_P_HASH512_DIGEST_COUNT);
+		sctx->phash_available = 1;
+	} else {
+		ret = 0;
+	}
+
+hash_prep_err:
+	dma_unmap_sg(tx_dev, src, src_nents, src_dir);
+hash_err:
+	mutex_unlock(&dev_data->hash_mutex);
+	ahash_request_complete(req, ret);
+
+	if (sctx->flags == DMA_CALLBACK_FROM_FINUP)
+		if ((req->nbytes + sctx->buflen) % sctx->block_size)
+			kfree(sg_virt(&src[src_nents - 1]));
+	kfree(src);
+	return ret;
+}
+
+static int dthe_hash_init(struct ahash_request *req)
+{
+	struct dthe_tfm_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+
+	void __iomem *sha_base_reg = dev_data->regs + DTHE_P_HASH_BASE;
+	u32 sha_sysconfig_val = DTHE_HASH_SYSCONFIG_INT_EN | DTHE_HASH_SYSCONFIG_DMA_EN;
+
+	ctx->ctx_info.hash_ctx->phash_available = 0;
+	ctx->ctx_info.hash_ctx->buflen = 0;
+	ctx->ctx_info.hash_ctx->digestcnt = 0;
+
+	writel_relaxed(sha_sysconfig_val, sha_base_reg + DTHE_P_HASH_SYSCONFIG);
+	writel_relaxed(DTHE_HASH_IRQENABLE_EN_ALL, sha_base_reg + DTHE_P_HASH_IRQENABLE);
+
+	return 0;
+}
+
+static int dthe_hash_update(struct ahash_request *req)
+{
+	struct dthe_tfm_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+	struct dthe_hash_ctx *sctx = ctx->ctx_info.hash_ctx;
+
+	struct scatterlist *src;
+	struct scatterlist *tmp;
+	int src_nents = 0;
+	int in_nents = sg_nents_for_len(req->src, req->nbytes);
+	unsigned int tot_len, cur_len;
+	unsigned int len_to_send, len_to_push;
+	u32 hash_mode_val;
+	int ret;
+
+	void __iomem *sha_base_reg = dev_data->regs + DTHE_P_HASH_BASE;
+
+	if (req->nbytes == 0) {
+		if (!sctx->phash_available && !sctx->buflen)
+			dthe_hash_write_zero_message(sctx->mode, sctx->phash);
+
+		return 0;
+	}
+
+	tot_len = sctx->buflen + req->nbytes;
+	len_to_send = tot_len - (tot_len % sctx->block_size);
+	len_to_push = ((len_to_send == 0) ? req->nbytes : (tot_len % sctx->block_size));
+	cur_len = 0;
+
+	if (tot_len % sctx->block_size == 0) {
+		len_to_send -= sctx->block_size;
+		if (tot_len == sctx->block_size)
+			len_to_push = req->nbytes;
+		else
+			len_to_push = sctx->block_size;
+	}
+
+	if (len_to_send == 0) {
+		sg_copy_to_buffer(req->src, in_nents, sctx->data_buf + sctx->buflen, len_to_push);
+		sctx->buflen += len_to_push;
+		return 0;
+	}
+
+	if (len_to_push < req->nbytes)
+		src_nents = sg_nents_for_len(req->src, req->nbytes - len_to_push);
+	if (sctx->buflen > 0)
+		src_nents++;
+
+	src = kcalloc(src_nents, sizeof(struct scatterlist), GFP_KERNEL);
+	if (!src)
+		return -ENOMEM;
+
+	tmp = src;
+
+	if (sctx->buflen > 0) {
+		sg_set_buf(tmp, sctx->data_buf, sctx->buflen);
+		tmp = sg_next(tmp);
+		cur_len += sctx->buflen;
+		src_nents--;
+	}
+	if (src_nents > 0)
+		dthe_set_src_sg(tmp, req->src, src_nents, len_to_send - cur_len);
+
+	mutex_lock(&dev_data->hash_mutex);
+
+	hash_mode_val = sctx->mode;
+	if (sctx->phash_available) {
+		for (int i = 0; i < sctx->phash_size / sizeof(u32); ++i)
+			writel_relaxed(sctx->phash[i],
+				       sha_base_reg +
+				       DTHE_P_HASH512_IDIGEST_A +
+				       (DTHE_REG_SIZE * i));
+
+		writel_relaxed(sctx->digestcnt, sha_base_reg + DTHE_P_HASH512_DIGEST_COUNT);
+	} else {
+		hash_mode_val |= DTHE_HASH_MODE_USE_ALG_CONST;
+	}
+
+	writel_relaxed(hash_mode_val, sha_base_reg + DTHE_P_HASH512_MODE);
+	writel_relaxed(len_to_send, sha_base_reg + DTHE_P_HASH512_LENGTH);
+
+	sctx->flags = DMA_CALLBACK_FROM_UPDATE;
+	ret = dthe_hash_dma_start(req, src, len_to_send);
+
+	sg_pcopy_to_buffer(req->src, in_nents, sctx->data_buf,
+			   len_to_push, req->nbytes - len_to_push);
+	sctx->buflen = len_to_push;
+
+	return ret;
+}
+
+static int dthe_hash_final(struct ahash_request *req)
+{
+	struct dthe_tfm_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+	struct dthe_hash_ctx *sctx = ctx->ctx_info.hash_ctx;
+	struct scatterlist *src;
+
+	void __iomem *sha_base_reg = dev_data->regs + DTHE_P_HASH_BASE;
+	u32 sha_mode_val = sctx->mode | DTHE_HASH_MODE_CLOSE_HASH;
+
+	if (sctx->buflen > 0) {
+		src = kzalloc(sizeof(struct scatterlist), GFP_KERNEL);
+		if (!src)
+			return -ENOMEM;
+
+		/* Certain DMA restrictions forced us to send data in multiples of BLOCK_SIZE
+		 * bytes. So, add a padding 0s at the end of src scatterlist if data is not a
+		 * multiple of block_size bytes. The extra data is ignored by the DTHE hardware.
+		 */
+		for (int i = sctx->buflen; i < sctx->block_size; ++i)
+			sctx->data_buf[i] = 0;
+
+		sg_set_buf(src, sctx->data_buf, sctx->block_size);
+
+		mutex_lock(&dev_data->hash_mutex);
+		if (sctx->phash_available) {
+			for (int i = 0; i < sctx->phash_size / sizeof(u32); ++i)
+				writel_relaxed(sctx->phash[i],
+					       sha_base_reg +
+					       DTHE_P_HASH512_IDIGEST_A +
+					       (DTHE_REG_SIZE * i));
+
+			writel_relaxed(sctx->digestcnt,
+				       sha_base_reg + DTHE_P_HASH512_DIGEST_COUNT);
+		} else {
+			sha_mode_val |= DTHE_HASH_MODE_USE_ALG_CONST;
+		}
+
+		writel_relaxed(sha_mode_val, sha_base_reg + DTHE_P_HASH512_MODE);
+		writel_relaxed(sctx->buflen, sha_base_reg + DTHE_P_HASH512_LENGTH);
+
+		sctx->flags = DMA_CALLBACK_FROM_FINAL;
+		return dthe_hash_dma_start(req, src, sctx->block_size);
+	} else if (!sctx->phash_available) {
+		dthe_hash_write_zero_message(sctx->mode, req->result);
+	}
+
+	memcpy(req->result, sctx->phash, sctx->digest_size);
+
+	ahash_request_complete(req, 0);
+	return 0;
+}
+
+static int dthe_hash_finup(struct ahash_request *req)
+{
+	struct dthe_tfm_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+	struct dthe_data *dev_data = dthe_get_dev(ctx);
+	struct dthe_hash_ctx *sctx = ctx->ctx_info.hash_ctx;
+
+	unsigned int tot_len = sctx->buflen + req->nbytes;
+	unsigned int cur_len = 0;
+	unsigned int pad_len = 0;
+	struct scatterlist *src;
+	struct scatterlist *tmp_sg;
+	int src_nents = 0;
+	u32 hash_mode_val;
+	u8 *pad_buf;
+
+	void __iomem *sha_base_reg = dev_data->regs + DTHE_P_HASH_BASE;
+
+	if (tot_len == 0) {
+		if (sctx->phash_available)
+			memcpy(req->result, sctx->phash, sctx->digest_size);
+		else
+			dthe_hash_write_zero_message(sctx->mode, req->result);
+
+		return 0;
+	}
+
+	if (tot_len % sctx->block_size)
+		pad_len = sctx->block_size - (tot_len % sctx->block_size);
+
+	if (req->nbytes > 0)
+		src_nents = sg_nents_for_len(req->src, req->nbytes);
+	if (sctx->buflen > 0)
+		src_nents++;
+	if (pad_len > 0)
+		src_nents++;
+
+	src = kcalloc(src_nents, sizeof(struct scatterlist), GFP_KERNEL);
+	if (!src)
+		return -ENOMEM;
+
+	tmp_sg = src;
+
+	if (sctx->buflen > 0) {
+		sg_set_buf(tmp_sg, sctx->data_buf, sctx->buflen);
+		tmp_sg = sg_next(tmp_sg);
+		cur_len += sctx->buflen;
+		src_nents--;
+	}
+	if (tot_len - cur_len > 0)
+		tmp_sg = dthe_set_src_sg(tmp_sg, req->src, src_nents, tot_len - cur_len);
+
+	/* Padding 0s in an additional nent at the end. See comment in dthe_hash_final function */
+	if (pad_len > 0) {
+		pad_buf = kcalloc(pad_len, sizeof(u8), GFP_KERNEL);
+		if (!pad_buf) {
+			kfree(src);
+			return -ENOMEM;
+		}
+		sg_set_buf(tmp_sg, pad_buf, pad_len);
+	}
+
+	mutex_lock(&dev_data->hash_mutex);
+
+	hash_mode_val = sctx->mode | DTHE_HASH_MODE_CLOSE_HASH;
+	if (!sctx->phash_available) {
+		hash_mode_val |= DTHE_HASH_MODE_USE_ALG_CONST;
+	} else {
+		for (int i = 0; i < sctx->phash_size / sizeof(u32); ++i)
+			writel_relaxed(sctx->phash[i],
+				       sha_base_reg +
+				       DTHE_P_HASH512_IDIGEST_A +
+				       (DTHE_REG_SIZE * i));
+
+		writel_relaxed(sctx->digestcnt,
+			       sha_base_reg + DTHE_P_HASH512_DIGEST_COUNT);
+	}
+
+	writel_relaxed(hash_mode_val, sha_base_reg + DTHE_P_HASH512_MODE);
+	writel_relaxed(tot_len, sha_base_reg + DTHE_P_HASH512_LENGTH);
+
+	sctx->flags = DMA_CALLBACK_FROM_FINUP;
+	return dthe_hash_dma_start(req, src, tot_len + pad_len);
+}
+
+static int dthe_hash_digest(struct ahash_request *req)
+{
+	dthe_hash_init(req);
+	return dthe_hash_finup(req);
+}
+
+static int dthe_hash_export(struct ahash_request *req, void *out)
+{
+	struct dthe_tfm_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+
+	memcpy(out, ctx->ctx_info.hash_ctx, sizeof(struct dthe_hash_ctx));
+	return 0;
+}
+
+static int dthe_hash_import(struct ahash_request *req, const void *in)
+{
+	struct dthe_tfm_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+
+	memcpy(ctx->ctx_info.hash_ctx, in, sizeof(struct dthe_hash_ctx));
+	return 0;
+}
+
+static struct ahash_alg hash_algs[] = {
+	{
+		.init	= dthe_hash_init,
+		.update	= dthe_hash_update,
+		.final	= dthe_hash_final,
+		.finup	= dthe_hash_finup,
+		.digest	= dthe_hash_digest,
+		.export = dthe_hash_export,
+		.import = dthe_hash_import,
+		.halg	= {
+			.digestsize = SHA512_DIGEST_SIZE,
+			.statesize = sizeof(struct dthe_hash_ctx),
+			.base = {
+				.cra_name	 = "sha512",
+				.cra_driver_name = "sha512-dthev2",
+				.cra_priority	 = 400,
+				.cra_flags	 = CRYPTO_ALG_TYPE_AHASH |
+						   CRYPTO_ALG_ASYNC |
+						   CRYPTO_ALG_OPTIONAL_KEY |
+						   CRYPTO_ALG_KERN_DRIVER_ONLY |
+						   CRYPTO_ALG_ALLOCATES_MEMORY,
+				.cra_blocksize	 = SHA512_BLOCK_SIZE,
+				.cra_ctxsize	 = sizeof(struct dthe_tfm_ctx),
+				.cra_module	 = THIS_MODULE,
+				.cra_init	 = dthe_sha512_cra_init,
+				.cra_exit	 = dthe_hash_cra_exit,
+			}
+		}
+	},
+	{
+		.init	= dthe_hash_init,
+		.update	= dthe_hash_update,
+		.final	= dthe_hash_final,
+		.finup	= dthe_hash_finup,
+		.digest	= dthe_hash_digest,
+		.export = dthe_hash_export,
+		.import = dthe_hash_import,
+		.halg	= {
+			.digestsize = SHA384_DIGEST_SIZE,
+			.statesize = sizeof(struct dthe_hash_ctx),
+			.base = {
+				.cra_name	 = "sha384",
+				.cra_driver_name = "sha384-dthev2",
+				.cra_priority	 = 400,
+				.cra_flags	 = CRYPTO_ALG_TYPE_AHASH |
+						   CRYPTO_ALG_ASYNC |
+						   CRYPTO_ALG_OPTIONAL_KEY |
+						   CRYPTO_ALG_KERN_DRIVER_ONLY |
+						   CRYPTO_ALG_ALLOCATES_MEMORY,
+				.cra_blocksize	 = SHA384_BLOCK_SIZE,
+				.cra_ctxsize	 = sizeof(struct dthe_tfm_ctx),
+				.cra_module	 = THIS_MODULE,
+				.cra_init	 = dthe_sha384_cra_init,
+				.cra_exit	 = dthe_hash_cra_exit,
+			}
+		}
+	},
+	{
+		.init	= dthe_hash_init,
+		.update	= dthe_hash_update,
+		.final	= dthe_hash_final,
+		.finup	= dthe_hash_finup,
+		.digest	= dthe_hash_digest,
+		.export = dthe_hash_export,
+		.import = dthe_hash_import,
+		.halg	= {
+			.digestsize = SHA256_DIGEST_SIZE,
+			.statesize = sizeof(struct dthe_hash_ctx),
+			.base = {
+				.cra_name	 = "sha256",
+				.cra_driver_name = "sha256-dthev2",
+				.cra_priority	 = 400,
+				.cra_flags	 = CRYPTO_ALG_TYPE_AHASH |
+						   CRYPTO_ALG_ASYNC |
+						   CRYPTO_ALG_OPTIONAL_KEY |
+						   CRYPTO_ALG_KERN_DRIVER_ONLY |
+						   CRYPTO_ALG_ALLOCATES_MEMORY,
+				.cra_blocksize	 = SHA256_BLOCK_SIZE,
+				.cra_ctxsize	 = sizeof(struct dthe_tfm_ctx),
+				.cra_module	 = THIS_MODULE,
+				.cra_init	 = dthe_sha256_cra_init,
+				.cra_exit	 = dthe_hash_cra_exit,
+			}
+		}
+	},
+	{
+		.init	= dthe_hash_init,
+		.update	= dthe_hash_update,
+		.final	= dthe_hash_final,
+		.finup	= dthe_hash_finup,
+		.digest	= dthe_hash_digest,
+		.export = dthe_hash_export,
+		.import = dthe_hash_import,
+		.halg	= {
+			.digestsize = SHA224_DIGEST_SIZE,
+			.statesize = sizeof(struct dthe_hash_ctx),
+			.base = {
+				.cra_name	 = "sha224",
+				.cra_driver_name = "sha224-dthev2",
+				.cra_priority	 = 400,
+				.cra_flags	 = CRYPTO_ALG_TYPE_AHASH |
+						   CRYPTO_ALG_ASYNC |
+						   CRYPTO_ALG_OPTIONAL_KEY |
+						   CRYPTO_ALG_KERN_DRIVER_ONLY |
+						   CRYPTO_ALG_ALLOCATES_MEMORY,
+				.cra_blocksize	 = SHA224_BLOCK_SIZE,
+				.cra_ctxsize	 = sizeof(struct dthe_tfm_ctx),
+				.cra_module	 = THIS_MODULE,
+				.cra_init	 = dthe_sha224_cra_init,
+				.cra_exit	 = dthe_hash_cra_exit,
+			}
+		}
+	},
+	{
+		.init	= dthe_hash_init,
+		.update	= dthe_hash_update,
+		.final	= dthe_hash_final,
+		.finup	= dthe_hash_finup,
+		.digest	= dthe_hash_digest,
+		.export = dthe_hash_export,
+		.import = dthe_hash_import,
+		.halg	= {
+			.digestsize = MD5_DIGEST_SIZE,
+			.statesize = sizeof(struct dthe_hash_ctx),
+			.base = {
+				.cra_name	 = "md5",
+				.cra_driver_name = "md5-dthev2",
+				.cra_priority	 = 400,
+				.cra_flags	 = CRYPTO_ALG_TYPE_AHASH |
+						   CRYPTO_ALG_ASYNC |
+						   CRYPTO_ALG_OPTIONAL_KEY |
+						   CRYPTO_ALG_KERN_DRIVER_ONLY |
+						   CRYPTO_ALG_ALLOCATES_MEMORY,
+				.cra_blocksize	 = MD5_BLOCK_SIZE,
+				.cra_ctxsize	 = sizeof(struct dthe_tfm_ctx),
+				.cra_module	 = THIS_MODULE,
+				.cra_init	 = dthe_md5_cra_init,
+				.cra_exit	 = dthe_hash_cra_exit,
+			}
+		}
+	},
+};
+
+int dthe_register_hash_algs(void)
+{
+	return crypto_register_ahashes(hash_algs, ARRAY_SIZE(hash_algs));
+}
+
+void dthe_unregister_hash_algs(void)
+{
+	crypto_unregister_ahashes(hash_algs, ARRAY_SIZE(hash_algs));
+}
diff -Naur --no-dereference a/drivers/crypto/ti/Kconfig b/drivers/crypto/ti/Kconfig
--- a/drivers/crypto/ti/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/crypto/ti/Kconfig	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config CRYPTO_DEV_TI_MCRC64
+	tristate "Texas Instruments MCRC64 engine support"
+	depends on ARCH_K3 || COMPILE_TEST
+	select CRYPTO_HASH
+	select CRYPTO_CRC64_ISO3309
+	help
+	  This enables support for the MCRC64 engine
+	  which can be found on all AM62* and J722S devices.
+	  MCRC64 engine calculates 64-bit cyclic redundancy checks (CRC)
+	  according to the ISO 3309 standard.
+
+config CRYPTO_DEV_TI_DTHEV2
+	tristate "Support for TI DTHE V2 crypto accelerators"
+	depends on CRYPTO && CRYPTO_HW && ARCH_K3
+	select CRYPTO_SKCIPHER
+	select CRYPTO_SHA256
+	select CRYPTO_SHA512
+	select CRYPTO_MD5
+	help
+	  This enables support for the TI DTHE V2 hw crypto accelerator
+	  which can be found on TI K3 SOCs. Selecting this enables use
+	  of hardware acceleration for cryptographic algorithms on
+	  these devices.
diff -Naur --no-dereference a/drivers/crypto/ti/Makefile b/drivers/crypto/ti/Makefile
--- a/drivers/crypto/ti/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/crypto/ti/Makefile	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_CRYPTO_DEV_TI_MCRC64) += mcrc64.o
+obj-$(CONFIG_CRYPTO_DEV_TI_DTHEV2) += dthev2.o
+dthev2-objs := dthev2-common.o dthev2-aes.o dthev2-hash.o
diff -Naur --no-dereference a/drivers/crypto/ti/mcrc64.c b/drivers/crypto/ti/mcrc64.c
--- a/drivers/crypto/ti/mcrc64.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/crypto/ti/mcrc64.c	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,435 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) Texas Instruments 2023 - http://www.ti.com
+ * Author: Kamlesh Gurudasani <kamlesh@ti.com>
+ */
+
+#include <linux/crc64.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include <crypto/internal/hash.h>
+
+#define DRIVER_NAME		"mcrc64"
+#define CHKSUM_DIGEST_SIZE	8
+#define CHKSUM_BLOCK_SIZE	1
+
+/* Registers */
+#define CRC_CTRL0 0x0000 /* CRC Global Control Register 0 */
+#define CH_PSA_SWRE(ch) BIT(((ch) - 1) << 3) /* PSA Software Reset  */
+
+#define CRC_CTRL1 0x0008 /* CRC Global Control Register 1 */
+#define PWDN BIT(0) /* Power Down  */
+
+#define CRC_CTRL2 0x0010 /* CRC Global Control Register 2 */
+#define CH_MODE(ch, m) ((m) << (((ch) - 1) << 3))
+
+#define PSA_SIGREGL(ch) ((0x6 + (4 * ((ch) - 1))) << 4) /* Signature register */
+
+#define MCRC64_ALG_MASK 0x8000000000000000
+#define MCRC64_CRC64_POLY 0x000000000000001b
+
+#define MCRC64_AUTOSUSPEND_DELAY 50
+
+enum mcrc64_mode {
+	MCRC64_MODE_DATA_CAPTURE = 0,
+	MCRC64_MODE_AUTO,
+	MCRC64_MODE_SEMI_CPU,
+	MCRC64_MODE_FULL_CPU,
+	MCRC64_MODE_INVALID,
+};
+
+enum mcrc64_channel {
+	MCRC64_CHANNEL_1 = 1,
+	MCRC64_CHANNEL_2,
+	MCRC64_CHANNEL_3,
+	MCRC64_CHANNEL_4,
+	MCRC64_CHANNEL_INVALID,
+};
+
+struct mcrc64_data {
+	struct list_head list;
+	struct device *dev;
+	void __iomem *regs;
+};
+
+struct mcrc64_list {
+	struct list_head dev_list;
+	spinlock_t lock; /* protect dev_list */
+};
+
+static struct mcrc64_list mcrc64_dev_list = {
+	.dev_list = LIST_HEAD_INIT(mcrc64_dev_list.dev_list),
+	.lock = __SPIN_LOCK_UNLOCKED(mcrc64_dev_list.lock),
+};
+
+struct mcrc64_tfm_ctx {
+	struct mcrc64_data *dev_data;
+	u64 key;
+};
+
+struct mcrc64_desc_ctx {
+	u64 signature;
+};
+
+static struct mcrc64_data *mcrc64_get_dev(struct mcrc64_tfm_ctx *tctx)
+{
+	struct mcrc64_data *dev_data;
+
+	if (tctx->dev_data)
+		return tctx->dev_data;
+
+	spin_lock_bh(&mcrc64_dev_list.lock);
+	dev_data = list_first_entry(&mcrc64_dev_list.dev_list, struct mcrc64_data, list);
+	if (dev_data)
+		list_move_tail(&dev_data->list, &mcrc64_dev_list.dev_list);
+	spin_unlock_bh(&mcrc64_dev_list.lock);
+
+	return dev_data;
+}
+
+static int mcrc64_set_mode(void __iomem *regs, u32 channel, u32 mode)
+{
+	u32 mode_set_val;
+	u32 crc_ctrl2_reg = 0;
+
+	if (mode < 0 || mode >= MCRC64_MODE_INVALID)
+		return -EINVAL;
+
+	if (channel <= 0 || channel >= MCRC64_CHANNEL_INVALID)
+		return -EINVAL;
+
+	mode_set_val = crc_ctrl2_reg | CH_MODE(channel, mode);
+
+	/* Write CRC_CTRL2, set mode */
+	writel_relaxed(mode_set_val, regs + CRC_CTRL2);
+
+	return 0;
+}
+
+static int mcrc64_reset_signature(void __iomem *regs, u32 channel)
+{
+	u32 crc_ctrl0_reg, reset_val, reset_undo_val;
+
+	if (channel <= 0 || channel >= MCRC64_CHANNEL_INVALID)
+		return -EINVAL;
+
+	/* reset PSA */
+	crc_ctrl0_reg = readl_relaxed(regs + CRC_CTRL0);
+
+	reset_val = crc_ctrl0_reg | CH_PSA_SWRE(channel);
+	reset_undo_val = crc_ctrl0_reg & ~CH_PSA_SWRE(channel);
+
+	/* Write CRC_CTRL0 register, reset PSA register */
+	writel_relaxed(reset_val, regs + CRC_CTRL0);
+	writel_relaxed(reset_undo_val, regs + CRC_CTRL0);
+
+	return 0;
+}
+
+/* This helper implements crc64 calculation using CPU */
+static u64 mcrc64_calculate_sw_crc(u64 crc, u8 byte)
+{
+	u64 bit = 0;
+	u8 j;
+
+	for (j = 0; j < 8; j++) {
+		bit = crc & MCRC64_ALG_MASK;
+		crc <<= 1;
+		if (byte & (0x80 >> j))
+			bit ^= MCRC64_ALG_MASK;
+		if (bit)
+			crc ^= MCRC64_CRC64_POLY;
+	}
+
+	return crc;
+}
+
+static int mcrc64_calculate_crc(void __iomem *regs, u32 channel,
+				const u8 *d8, size_t length, u64 *crc64)
+{
+	void __iomem *psa_reg;
+	u64 signature = 0;
+
+	if (channel <= 0 || channel >= MCRC64_CHANNEL_INVALID)
+		return -EINVAL;
+
+	psa_reg = regs + PSA_SIGREGL(channel);
+
+	for (; length >= sizeof(u64); d8 += sizeof(u64), length -= sizeof(u64))
+		writeq_relaxed(cpu_to_be64p((u64 *)d8), psa_reg);
+
+	signature = readq_relaxed(psa_reg);
+
+	if (length) {
+		while (length--)
+			signature = mcrc64_calculate_sw_crc(signature, *d8++);
+
+		/* set capture mode */
+		int ret = mcrc64_set_mode(regs, MCRC64_CHANNEL_1,
+					MCRC64_MODE_DATA_CAPTURE);
+		if (ret)
+			return ret;
+
+		ret = mcrc64_reset_signature(regs, MCRC64_CHANNEL_1);
+		if (ret)
+			return ret;
+
+		writeq_relaxed(signature, psa_reg);
+
+		ret = mcrc64_set_mode(regs, MCRC64_CHANNEL_1,
+				      MCRC64_MODE_FULL_CPU);
+		if (ret)
+			return ret;
+	}
+
+	*crc64 = signature;
+
+	return 0;
+}
+
+static int mcrc64_cra_init(struct crypto_tfm *tfm)
+{
+	struct mcrc64_tfm_ctx *tctx = crypto_tfm_ctx(tfm);
+	struct mcrc64_data *dev_data;
+
+	dev_data = mcrc64_get_dev(tctx);
+	if (!dev_data)
+		return -ENODEV;
+
+	pm_runtime_get_sync(dev_data->dev);
+
+	tctx->key = 0;
+
+	return 0;
+}
+
+static void mcrc64_cra_exit(struct crypto_tfm *tfm)
+{
+	struct mcrc64_tfm_ctx *tctx = crypto_tfm_ctx(tfm);
+	struct mcrc64_data *dev_data;
+
+	dev_data = mcrc64_get_dev(tctx);
+
+	pm_runtime_mark_last_busy(dev_data->dev);
+	pm_runtime_put_autosuspend(dev_data->dev);
+}
+
+static int mcrc64_setkey(struct crypto_shash *tfm, const u8 *key,
+			 unsigned int keylen)
+{
+	struct mcrc64_tfm_ctx *tctx = crypto_shash_ctx(tfm);
+
+	if (keylen != sizeof(u64))
+		return -EINVAL;
+
+	tctx->key = get_unaligned_le64(key);
+
+	return 0;
+}
+
+static int mcrc64_init(struct shash_desc *desc)
+{
+	struct mcrc64_desc_ctx *ctx = shash_desc_ctx(desc);
+	struct mcrc64_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+	struct mcrc64_data *dev_data;
+	void __iomem *psa_reg;
+
+	dev_data = mcrc64_get_dev(tctx);
+	if (!dev_data)
+		return -ENODEV;
+
+	pm_runtime_get_sync(dev_data->dev);
+
+	/* set capture mode */
+	int ret = mcrc64_set_mode(dev_data->regs, MCRC64_CHANNEL_1,
+				  MCRC64_MODE_DATA_CAPTURE);
+	if (ret)
+		return ret;
+
+	/* reset PSA */
+	psa_reg = dev_data->regs + PSA_SIGREGL(MCRC64_CHANNEL_1);
+	ret =  mcrc64_reset_signature(dev_data->regs, MCRC64_CHANNEL_1);
+	if (ret)
+		return ret;
+
+	/* write key  */
+	writeq_relaxed(tctx->key, psa_reg);
+
+	/* set full cpu mode */
+	ret = mcrc64_set_mode(dev_data->regs, MCRC64_CHANNEL_1,
+			      MCRC64_MODE_FULL_CPU);
+	if (ret)
+		return ret;
+
+	ctx->signature = readq_relaxed(psa_reg);
+
+	return 0;
+}
+
+static int mcrc64_update(struct shash_desc *desc, const u8 *d8,
+			 unsigned int length)
+{
+	struct mcrc64_desc_ctx *ctx = shash_desc_ctx(desc);
+	struct mcrc64_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+	struct mcrc64_data *dev_data;
+
+	dev_data = mcrc64_get_dev(tctx);
+	if (!dev_data)
+		return -ENODEV;
+
+	return mcrc64_calculate_crc(dev_data->regs, MCRC64_CHANNEL_1,
+				    d8, length, &ctx->signature);
+}
+
+static int mcrc64_final(struct shash_desc *desc, u8 *out)
+{
+	struct mcrc64_desc_ctx *ctx = shash_desc_ctx(desc);
+
+	/* Send computed CRC */
+	put_unaligned_le64(ctx->signature, out);
+	return 0;
+}
+
+static int mcrc64_finup(struct shash_desc *desc, const u8 *data,
+			unsigned int length, u8 *out)
+{
+	return mcrc64_update(desc, data, length) ?:
+		mcrc64_final(desc, out);
+}
+
+static int mcrc64_digest(struct shash_desc *desc, const u8 *data,
+			 unsigned int length, u8 *out)
+{
+	return mcrc64_init(desc) ?: mcrc64_finup(desc, data, length, out);
+}
+
+static unsigned int refcnt;
+static DEFINE_MUTEX(refcnt_lock);
+static struct shash_alg algs[] = {
+	/* CRC-64 */
+	{
+		.setkey		= mcrc64_setkey,
+		.init		= mcrc64_init,
+		.update		= mcrc64_update,
+		.final		= mcrc64_final,
+		.finup		= mcrc64_finup,
+		.digest		= mcrc64_digest,
+		.descsize	= sizeof(struct mcrc64_desc_ctx),
+		.digestsize	= CHKSUM_DIGEST_SIZE,
+		.base		= {
+			.cra_name		= CRC64_ISO3309_STRING,
+			.cra_driver_name	= "mcrc64",
+			.cra_priority		= 300,
+			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
+			.cra_blocksize		= CHKSUM_BLOCK_SIZE,
+			.cra_ctxsize		= sizeof(struct mcrc64_tfm_ctx),
+			.cra_module		= THIS_MODULE,
+			.cra_init		= mcrc64_cra_init,
+			.cra_exit		= mcrc64_cra_exit,
+		}
+	}
+};
+
+static int mcrc64_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mcrc64_data *dev_data;
+	int ret;
+
+	dev_data = devm_kzalloc(dev, sizeof(*dev_data), GFP_KERNEL);
+	if (!dev_data)
+		return -ENOMEM;
+
+	dev_data->dev = dev;
+	dev_data->regs = devm_platform_ioremap_resource(pdev, 0);
+
+	platform_set_drvdata(pdev, dev_data);
+
+	spin_lock(&mcrc64_dev_list.lock);
+	list_add(&dev_data->list, &mcrc64_dev_list.dev_list);
+	spin_unlock(&mcrc64_dev_list.lock);
+
+	mutex_lock(&refcnt_lock);
+	if (!refcnt) {
+		ret = crypto_register_shashes(algs, ARRAY_SIZE(algs));
+		if (ret) {
+			mutex_unlock(&refcnt_lock);
+			dev_err(dev, "Failed to register\n");
+			return ret;
+		}
+	}
+	refcnt++;
+	mutex_unlock(&refcnt_lock);
+
+	pm_runtime_set_autosuspend_delay(dev, MCRC64_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(dev);
+
+	pm_runtime_get_noresume(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+
+static void mcrc64_remove(struct platform_device *pdev)
+{
+	struct mcrc64_data *dev_data = platform_get_drvdata(pdev);
+
+	pm_runtime_resume_and_get(dev_data->dev);
+
+	spin_lock(&mcrc64_dev_list.lock);
+	list_del(&dev_data->list);
+	spin_unlock(&mcrc64_dev_list.lock);
+
+	mutex_lock(&refcnt_lock);
+	if (!--refcnt)
+		crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
+	mutex_unlock(&refcnt_lock);
+
+	pm_runtime_disable(dev_data->dev);
+	pm_runtime_put_noidle(dev_data->dev);
+}
+
+static int __maybe_unused mcrc64_suspend(struct device *dev)
+{
+	return	pm_runtime_force_suspend(dev);
+}
+
+static int __maybe_unused mcrc64_resume(struct device *dev)
+{
+	return pm_runtime_force_resume(dev);
+}
+
+static const struct dev_pm_ops mcrc64_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mcrc64_suspend,
+				mcrc64_resume)
+};
+
+static const struct of_device_id of_match[] = {
+	{ .compatible = "ti,am62-mcrc64", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, of_match);
+
+static struct platform_driver mcrc64_driver = {
+	.probe	= mcrc64_probe,
+	.remove = mcrc64_remove,
+	.driver = {
+		.name		= DRIVER_NAME,
+		.pm		= &mcrc64_pm_ops,
+		.of_match_table = of_match,
+	},
+};
+
+module_platform_driver(mcrc64_driver);
+
+MODULE_AUTHOR("Kamlesh Gurudasani <kamlesh@ti.com>");
+MODULE_DESCRIPTION("Texas Instruments MCRC64 driver");
+MODULE_LICENSE("GPL");
diff -Naur --no-dereference a/drivers/dma/ti/k3-psil-am62l.c b/drivers/dma/ti/k3-psil-am62l.c
--- a/drivers/dma/ti/k3-psil-am62l.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/dma/ti/k3-psil-am62l.c	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com
+ */
+
+#include <linux/kernel.h>
+
+#include "k3-psil-priv.h"
+
+#define PSIL_PDMA_XY_TR(x, ch)					\
+	{							\
+		.thread_id = x,					\
+		.ep_config = {					\
+			.ep_type = PSIL_EP_PDMA_XY,		\
+			.mapped_channel_id = ch,		\
+			.default_flow_id = -1,			\
+		},						\
+	}
+
+#define PSIL_PDMA_XY_PKT(x, ch)					\
+	{							\
+		.thread_id = x,					\
+		.ep_config = {					\
+			.ep_type = PSIL_EP_PDMA_XY,		\
+			.mapped_channel_id = ch,		\
+			.pkt_mode = 1,				\
+			.default_flow_id = -1			\
+		},						\
+	}
+
+#define PSIL_ETHERNET(x, ch, flow_base, flow_cnt)		\
+	{							\
+		.thread_id = x,					\
+		.ep_config = {					\
+			.ep_type = PSIL_EP_NATIVE,		\
+			.pkt_mode = 1,				\
+			.needs_epib = 1,			\
+			.psd_size = 16,				\
+			.mapped_channel_id = ch,		\
+			.flow_start = flow_base,		\
+			.flow_num = flow_cnt,			\
+			.default_flow_id = flow_base,		\
+		},						\
+	}
+
+#define PSIL_PDMA_MCASP(x, ch)				\
+	{						\
+		.thread_id = x,				\
+		.ep_config = {				\
+			.ep_type = PSIL_EP_PDMA_XY,	\
+			.pdma_acc32 = 1,		\
+			.pdma_burst = 1,		\
+			.mapped_channel_id = ch,	\
+		},					\
+	}
+
+/* PSI-L source thread IDs, used for RX (DMA_DEV_TO_MEM) */
+static struct psil_ep am62l_src_ep_map[] = {
+	/* PDMA_MAIN1 - UART0-6 */
+	PSIL_PDMA_XY_PKT(0x4400, 0),
+	PSIL_PDMA_XY_PKT(0x4401, 2),
+	PSIL_PDMA_XY_PKT(0x4402, 4),
+	PSIL_PDMA_XY_PKT(0x4403, 6),
+	PSIL_PDMA_XY_PKT(0x4404, 8),
+	PSIL_PDMA_XY_PKT(0x4405, 10),
+	PSIL_PDMA_XY_PKT(0x4406, 12),
+	/* PDMA_MAIN0 - SPI0 - CH0-3 */
+	PSIL_PDMA_XY_TR(0x4300, 16),
+	/* PDMA_MAIN0 - SPI1 - CH0-3 */
+	PSIL_PDMA_XY_TR(0x4301, 24),
+	/* PDMA_MAIN0 - SPI2 - CH0-3 */
+	PSIL_PDMA_XY_TR(0x4302, 32),
+	/* PDMA_MAIN0 - SPI3 - CH0-3 */
+	PSIL_PDMA_XY_TR(0x4303, 40),
+	/* PDMA_MAIN2 - MCASP0-2 */
+	PSIL_PDMA_MCASP(0x4500, 48),
+	PSIL_PDMA_MCASP(0x4501, 50),
+	PSIL_PDMA_MCASP(0x4502, 52),
+	/* PDMA_MAIN0 - AES */
+	PSIL_PDMA_XY_TR(0x4700, 65),
+	/* PDMA_MAIN0 - ADC */
+	PSIL_PDMA_XY_TR(0x4503, 80),
+	PSIL_PDMA_XY_TR(0x4504, 81),
+	PSIL_ETHERNET(0x4600, 96, 96, 16),
+};
+
+/* PSI-L destination thread IDs, used for TX (DMA_MEM_TO_DEV) */
+static struct psil_ep am62l_dst_ep_map[] = {
+	/* PDMA_MAIN1 - UART0-6 */
+	PSIL_PDMA_XY_PKT(0xC400, 1),
+	PSIL_PDMA_XY_PKT(0xC401, 3),
+	PSIL_PDMA_XY_PKT(0xC402, 5),
+	PSIL_PDMA_XY_PKT(0xC403, 7),
+	PSIL_PDMA_XY_PKT(0xC404, 9),
+	PSIL_PDMA_XY_PKT(0xC405, 11),
+	PSIL_PDMA_XY_PKT(0xC406, 13),
+	/* PDMA_MAIN0 - SPI0 - CH0-3 */
+	PSIL_PDMA_XY_TR(0xC300, 17),
+	/* PDMA_MAIN0 - SPI1 - CH0-3 */
+	PSIL_PDMA_XY_TR(0xC301, 25),
+	/* PDMA_MAIN0 - SPI2 - CH0-3 */
+	PSIL_PDMA_XY_TR(0xC302, 33),
+	/* PDMA_MAIN0 - SPI3 - CH0-3 */
+	PSIL_PDMA_XY_TR(0xC303, 41),
+	/* PDMA_MAIN2 - MCASP0-2 */
+	PSIL_PDMA_MCASP(0xC500, 49),
+	PSIL_PDMA_MCASP(0xC501, 51),
+	PSIL_PDMA_MCASP(0xC502, 53),
+	/* PDMA_MAIN0 - SHA */
+	PSIL_PDMA_XY_TR(0xC700, 64),
+	/* PDMA_MAIN0 - AES */
+	PSIL_PDMA_XY_TR(0xC701, 66),
+	/* PDMA_MAIN0 - CRC32 - CH0-1 */
+	PSIL_PDMA_XY_TR(0xC702, 67),
+	/* CPSW3G */
+	PSIL_ETHERNET(0xc600, 64, 64, 2),
+	PSIL_ETHERNET(0xc601, 66, 66, 2),
+	PSIL_ETHERNET(0xc602, 68, 68, 2),
+	PSIL_ETHERNET(0xc603, 70, 70, 2),
+	PSIL_ETHERNET(0xc604, 72, 72, 2),
+	PSIL_ETHERNET(0xc605, 74, 74, 2),
+	PSIL_ETHERNET(0xc606, 76, 76, 2),
+	PSIL_ETHERNET(0xc607, 78, 78, 2),
+};
+
+struct psil_ep_map am62l_ep_map = {
+	.name = "am62l",
+	.src = am62l_src_ep_map,
+	.src_count = ARRAY_SIZE(am62l_src_ep_map),
+	.dst = am62l_dst_ep_map,
+	.dst_count = ARRAY_SIZE(am62l_dst_ep_map),
+};
diff -Naur --no-dereference a/drivers/dma/ti/k3-psil.c b/drivers/dma/ti/k3-psil.c
--- a/drivers/dma/ti/k3-psil.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/dma/ti/k3-psil.c	2025-10-23 09:30:40.284462176 -0400
@@ -25,6 +25,7 @@
 	{ .family = "J721S2", .data = &j721s2_ep_map },
 	{ .family = "AM62X", .data = &am62_ep_map },
 	{ .family = "AM62AX", .data = &am62a_ep_map },
+	{ .family = "AM62LX", .data = &am62l_ep_map },
 	{ .family = "J784S4", .data = &j784s4_ep_map },
 	{ .family = "AM62PX", .data = &am62p_ep_map },
 	{ .family = "J722S", .data = &am62p_ep_map },
diff -Naur --no-dereference a/drivers/dma/ti/k3-psil-priv.h b/drivers/dma/ti/k3-psil-priv.h
--- a/drivers/dma/ti/k3-psil-priv.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/dma/ti/k3-psil-priv.h	2025-10-23 09:30:40.284462176 -0400
@@ -44,6 +44,7 @@
 extern struct psil_ep_map j721s2_ep_map;
 extern struct psil_ep_map am62_ep_map;
 extern struct psil_ep_map am62a_ep_map;
+extern struct psil_ep_map am62l_ep_map;
 extern struct psil_ep_map j784s4_ep_map;
 extern struct psil_ep_map am62p_ep_map;
 
diff -Naur --no-dereference a/drivers/dma/ti/k3-udma-am62l.c b/drivers/dma/ti/k3-udma-am62l.c
--- a/drivers/dma/ti/k3-udma-am62l.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/dma/ti/k3-udma-am62l.c	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,1509 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Derived from K3 UDMA driver (k3-udma.c)
+ *  Copyright (C) 2024-2025 Texas Instruments Incorporated - http://www.ti.com
+ *  Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *  Author: Sai Sree Kartheek Adivi <s-adivi@ti.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/sys_soc.h>
+#include <linux/of.h>
+#include <linux/of_dma.h>
+#include <linux/of_irq.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/iopoll.h>
+#include <linux/soc/ti/k3-ringacc.h>
+#include <linux/dma/k3-event-router.h>
+#include <linux/dma/ti-cppi5.h>
+
+#include "../virt-dma.h"
+#include "k3-udma.h"
+#include "k3-psil-priv.h"
+
+#define UDMA_CHAN_RT_STATIC_TR_XY_REG	0x800
+#define UDMA_CHAN_RT_STATIC_TR_Z_REG	0x804
+#define UDMA_CHAN_RT_PERIPH_BCNT_REG	0x810
+
+static const char * const am62l_mmr_names[] = {
+	[AM62L_MMR_GCFG] = "gcfg",
+	[AM62L_MMR_BCHANRT] = "bchanrt",
+	[AM62L_MMR_CHANRT] = "chanrt",
+};
+
+static int am62l_udma_check_chan_autopair_completion(struct udma_chan *uc)
+{
+	u32 val;
+
+	val = udma_chanrt_read(uc, UDMA_CHAN_RT_CTL_REG);
+	if (val & UDMA_CHAN_RT_CTL_PAIR_TIMEOUT)
+		return -ETIMEDOUT;
+	else if (val & UDMA_CHAN_RT_CTL_PAIR_COMPLETE)
+		return 1;
+
+	/* timeout didn't occur and also pairing didn't happen yet. */
+	return 0;
+}
+
+static bool am62l_udma_is_chan_paused(struct udma_chan *uc)
+{
+	u32 val, pause_mask;
+
+	if (uc->config.dir == DMA_MEM_TO_MEM) {
+		val = udma_chanrt_read(uc, UDMA_CHAN_RT_CTL_REG);
+		pause_mask = UDMA_CHAN_RT_CTL_PAUSE;
+	} else {
+		val = udma_chanrt_read(uc, UDMA_CHAN_RT_PDMA_STATE_REG);
+		pause_mask = UDMA_CHAN_RT_PDMA_STATE_PAUSE;
+	}
+
+	if (val & pause_mask)
+		return true;
+
+	return false;
+}
+
+static void am62l_udma_decrement_byte_counters(struct udma_chan *uc, u32 val)
+{
+	udma_chanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val);
+	udma_chanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val);
+	if (uc->config.ep_type != PSIL_EP_NATIVE)
+		udma_chanrt_write(uc, UDMA_CHAN_RT_PERIPH_BCNT_REG, val);
+}
+
+static void am62l_udma_reset_counters(struct udma_chan *uc)
+{
+	u32 val;
+
+	val = udma_chanrt_read(uc, UDMA_CHAN_RT_BCNT_REG);
+	udma_chanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val);
+
+	val = udma_chanrt_read(uc, UDMA_CHAN_RT_SBCNT_REG);
+	udma_chanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val);
+
+	val = udma_chanrt_read(uc, UDMA_CHAN_RT_PCNT_REG);
+	udma_chanrt_write(uc, UDMA_CHAN_RT_PCNT_REG, val);
+
+	if (!uc->bchan) {
+		val = udma_chanrt_read(uc, UDMA_CHAN_RT_PERIPH_BCNT_REG);
+		udma_chanrt_write(uc, UDMA_CHAN_RT_PERIPH_BCNT_REG, val);
+	}
+}
+
+static int am62l_udma_reset_chan(struct udma_chan *uc, bool hard)
+{
+	udma_chanrt_write(uc, UDMA_CHAN_RT_CTL_REG, 0);
+
+	/* Reset all counters */
+	am62l_udma_reset_counters(uc);
+
+	/* Hard reset: re-initialize the channel to reset */
+	if (hard) {
+		struct udma_chan_config ucc_backup;
+		int ret;
+
+		memcpy(&ucc_backup, &uc->config, sizeof(uc->config));
+		uc->ud->ddev.device_free_chan_resources(&uc->vc.chan);
+
+		/* restore the channel configuration */
+		memcpy(&uc->config, &ucc_backup, sizeof(uc->config));
+		ret = uc->ud->ddev.device_alloc_chan_resources(&uc->vc.chan);
+		if (ret)
+			return ret;
+
+		/*
+		 * Setting forced teardown after forced reset helps recovering
+		 * the rchan.
+		 */
+		if (uc->config.dir == DMA_DEV_TO_MEM)
+			udma_chanrt_update_bits(uc, UDMA_CHAN_RT_CTL_REG,
+					UDMA_CHAN_RT_CTL_EN | UDMA_CHAN_RT_CTL_TDOWN |
+					UDMA_CHAN_RT_CTL_FTDOWN,
+					UDMA_CHAN_RT_CTL_EN | UDMA_CHAN_RT_CTL_TDOWN |
+					UDMA_CHAN_RT_CTL_FTDOWN);
+	}
+	uc->state = UDMA_CHAN_IS_IDLE;
+
+	return 0;
+}
+
+static int am62l_udma_start(struct udma_chan *uc)
+{
+	struct virt_dma_desc *vd = vchan_next_desc(&uc->vc);
+	struct udma_dev *ud = uc->ud;
+	int status, ret;
+
+	if (!vd) {
+		uc->desc = NULL;
+		return -ENOENT;
+	}
+
+	list_del(&vd->node);
+
+	uc->desc = to_udma_desc(&vd->tx);
+
+	/* Channel is already running and does not need reconfiguration */
+	if (udma_is_chan_running(uc) && !udma_chan_needs_reconfiguration(uc)) {
+		udma_start_desc(uc);
+		goto out;
+	}
+
+	/* Make sure that we clear the teardown bit, if it is set */
+	ud->udma_reset_chan(uc, false);
+
+	/* Push descriptors before we start the channel */
+	udma_start_desc(uc);
+
+	switch (uc->desc->dir) {
+	case DMA_DEV_TO_MEM:
+		/* Config remote TR */
+		if (uc->config.ep_type == PSIL_EP_PDMA_XY) {
+			u32 val = PDMA_STATIC_TR_Y(uc->desc->static_tr.elcnt) |
+				  PDMA_STATIC_TR_X(uc->desc->static_tr.elsize);
+			const struct udma_match_data *match_data =
+							uc->ud->match_data;
+
+			if (uc->config.enable_acc32)
+				val |= PDMA_STATIC_TR_XY_ACC32;
+			if (uc->config.enable_burst)
+				val |= PDMA_STATIC_TR_XY_BURST;
+
+			udma_chanrt_write(uc,
+					   UDMA_CHAN_RT_STATIC_TR_XY_REG,
+					   val);
+
+			udma_chanrt_write(uc,
+				UDMA_CHAN_RT_STATIC_TR_Z_REG,
+				PDMA_STATIC_TR_Z(uc->desc->static_tr.bstcnt,
+						 match_data->statictr_z_mask));
+
+			/* save the current staticTR configuration */
+			memcpy(&uc->static_tr, &uc->desc->static_tr,
+			       sizeof(uc->static_tr));
+		}
+
+		udma_chanrt_write(uc, UDMA_CHAN_RT_CTL_REG,
+				UDMA_CHAN_RT_CTL_EN | UDMA_CHAN_RT_CTL_AUTOPAIR);
+
+		/* Poll for autopair completion */
+		ret = read_poll_timeout_atomic(am62l_udma_check_chan_autopair_completion,
+				status, status != 0, 100, 500, false, uc);
+
+		if (ret <= 0)
+			return -ETIMEDOUT;
+
+		break;
+	case DMA_MEM_TO_DEV:
+		/* Config remote TR */
+		if (uc->config.ep_type == PSIL_EP_PDMA_XY) {
+			u32 val = PDMA_STATIC_TR_Y(uc->desc->static_tr.elcnt) |
+				  PDMA_STATIC_TR_X(uc->desc->static_tr.elsize);
+
+			if (uc->config.enable_acc32)
+				val |= PDMA_STATIC_TR_XY_ACC32;
+			if (uc->config.enable_burst)
+				val |= PDMA_STATIC_TR_XY_BURST;
+
+			udma_chanrt_write(uc,
+					   UDMA_CHAN_RT_STATIC_TR_XY_REG,
+					   val);
+
+			/* save the current staticTR configuration */
+			memcpy(&uc->static_tr, &uc->desc->static_tr,
+			       sizeof(uc->static_tr));
+		}
+
+		udma_chanrt_write(uc, UDMA_CHAN_RT_CTL_REG,
+				UDMA_CHAN_RT_CTL_EN | UDMA_CHAN_RT_CTL_AUTOPAIR);
+
+		/* Poll for autopair completion */
+		ret = read_poll_timeout_atomic(am62l_udma_check_chan_autopair_completion,
+				status, status != 0, 100, 500, false, uc);
+
+		if (status <= 0)
+			return -ETIMEDOUT;
+
+		break;
+	case DMA_MEM_TO_MEM:
+		udma_bchanrt_write(uc, UDMA_CHAN_RT_CTL_REG,
+				   UDMA_CHAN_RT_CTL_EN);
+		udma_bchanrt_write(uc, UDMA_CHAN_RT_CTL_REG,
+				   UDMA_CHAN_RT_CTL_EN);
+
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	uc->state = UDMA_CHAN_IS_ACTIVE;
+out:
+
+	return 0;
+}
+
+static int am62l_udma_stop(struct udma_chan *uc)
+{
+	uc->state = UDMA_CHAN_IS_TERMINATING;
+	reinit_completion(&uc->teardown_completed);
+
+	if (uc->config.dir == DMA_DEV_TO_MEM) {
+		if (!uc->cyclic && !uc->desc)
+			udma_push_to_ring(uc, -1);
+	}
+
+	udma_chanrt_write(uc, UDMA_CHAN_RT_PEER_REG(8), UDMA_CHAN_RT_PEER_REG8_FLUSH);
+	udma_chanrt_update_bits(uc, UDMA_CHAN_RT_CTL_REG,
+		UDMA_CHAN_RT_CTL_EN | UDMA_CHAN_RT_CTL_TDOWN,
+		UDMA_CHAN_RT_CTL_EN | UDMA_CHAN_RT_CTL_TDOWN);
+
+	return 0;
+}
+
+static bool am62l_udma_is_desc_really_done(struct udma_chan *uc, struct udma_desc *d)
+{
+	u32 peer_bcnt, bcnt;
+
+	/*
+	 * Only TX towards PDMA is affected.
+	 * If DMA_PREP_INTERRUPT is not set by consumer then skip the transfer
+	 * completion calculation, consumer must ensure that there is no stale
+	 * data in DMA fabric in this case.
+	 */
+	if (uc->config.ep_type == PSIL_EP_NATIVE ||
+	    uc->config.dir != DMA_MEM_TO_DEV || !(uc->config.tx_flags & DMA_PREP_INTERRUPT))
+		return true;
+
+	peer_bcnt = udma_chanrt_read(uc, UDMA_CHAN_RT_PERIPH_BCNT_REG);
+	bcnt = udma_chanrt_read(uc, UDMA_CHAN_RT_BCNT_REG);
+
+	/* Transfer is incomplete, store current residue and time stamp */
+	if (peer_bcnt < bcnt) {
+		uc->tx_drain.residue = bcnt - peer_bcnt;
+		uc->tx_drain.tstamp = ktime_get();
+		return false;
+	}
+
+	return true;
+}
+
+static irqreturn_t am62l_udma_udma_irq_handler(int irq, void *data)
+{
+	struct udma_chan *uc = data;
+	struct udma_dev *ud = uc->ud;
+	struct udma_desc *d;
+
+	switch (uc->config.dir) {
+	case DMA_DEV_TO_MEM:
+		k3_ringacc_ring_clear_irq(uc->rflow->r_ring);
+		break;
+	case DMA_MEM_TO_DEV:
+	case DMA_MEM_TO_MEM:
+		k3_ringacc_ring_clear_irq(uc->tchan->tc_ring);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	spin_lock(&uc->vc.lock);
+	d = uc->desc;
+	if (d) {
+		d->tr_idx = (d->tr_idx + 1) % d->sglen;
+
+		if (uc->cyclic) {
+			vchan_cyclic_callback(&d->vd);
+		} else {
+			/* TODO: figure out the real amount of data */
+			ud->udma_decrement_byte_counters(uc, d->residue);
+			ud->udma_start(uc);
+			vchan_cookie_complete(&d->vd);
+		}
+	}
+
+	spin_unlock(&uc->vc.lock);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t am62l_udma_ring_irq_handler(int irq, void *data)
+{
+	struct udma_chan *uc = data;
+	struct udma_dev *ud = uc->ud;
+	struct udma_desc *d;
+	dma_addr_t paddr = 0;
+	u32 intr_status, reg;
+
+	switch (uc->config.dir) {
+	case DMA_DEV_TO_MEM:
+		intr_status =  k3_ringacc_ring_get_irq_status(uc->rflow->r_ring);
+		break;
+	case DMA_MEM_TO_DEV:
+	case DMA_MEM_TO_MEM:
+		intr_status =  k3_ringacc_ring_get_irq_status(uc->tchan->tc_ring);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	reg = udma_chanrt_read(uc, UDMA_CHAN_RT_CTL_REG);
+
+	if (intr_status & K3_RINGACC_RT_INT_STATUS_TR) {
+		/* check teardown status */
+		if ((reg & UDMA_CHAN_RT_CTL_TDOWN) && !(reg & UDMA_CHAN_RT_CTL_EN))
+			complete_all(&uc->teardown_completed);
+		return am62l_udma_udma_irq_handler(irq, data);
+	}
+
+	if (udma_pop_from_ring(uc, &paddr) || !paddr)
+		return IRQ_HANDLED;
+
+	spin_lock(&uc->vc.lock);
+
+	/* Teardown completion message */
+	if (cppi5_desc_is_tdcm(paddr)) {
+		complete_all(&uc->teardown_completed);
+
+		if (uc->terminated_desc) {
+			udma_desc_free(&uc->terminated_desc->vd);
+			uc->terminated_desc = NULL;
+		}
+
+		if (!uc->desc)
+			ud->udma_start(uc);
+
+		goto out;
+	}
+
+	d = udma_udma_desc_from_paddr(uc, paddr);
+
+	if (d) {
+		dma_addr_t desc_paddr = udma_curr_cppi5_desc_paddr(d,
+								   d->desc_idx);
+		if (desc_paddr != paddr) {
+			dev_err(uc->ud->dev, "not matching descriptors!\n");
+			goto out;
+		}
+
+		if (d == uc->desc) {
+			/* active descriptor */
+			if (uc->cyclic) {
+				udma_cyclic_packet_elapsed(uc);
+				vchan_cyclic_callback(&d->vd);
+			} else {
+				if (ud->udma_is_desc_really_done(uc, d)) {
+					ud->udma_decrement_byte_counters(uc, d->residue);
+					ud->udma_start(uc);
+					vchan_cookie_complete(&d->vd);
+				} else {
+					schedule_delayed_work(&uc->tx_drain.work,
+							      0);
+				}
+			}
+		} else {
+			/*
+			 * terminated descriptor, mark the descriptor as
+			 * completed to update the channel's cookie marker
+			 */
+			dma_cookie_complete(&d->vd.tx);
+		}
+	}
+out:
+	spin_unlock(&uc->vc.lock);
+
+	return IRQ_HANDLED;
+}
+
+static int am62l_bcdma_v2_get_bchan(struct udma_chan *uc)
+{
+	struct udma_dev *ud = uc->ud;
+	enum udma_tp_level tpl;
+	int ret;
+
+	if (uc->bchan) {
+		dev_dbg(ud->dev, "chan%d: already have bchan%d allocated\n",
+			uc->id, uc->bchan->id);
+		return 0;
+	}
+
+	/*
+	 * Use normal channels for peripherals, and highest TPL channel for
+	 * mem2mem
+	 */
+	if (uc->config.tr_trigger_type)
+		tpl = 0;
+	else
+		tpl = ud->bchan_tpl.levels - 1;
+
+	uc->bchan = __udma_reserve_bchan(ud, tpl, uc->id);
+	if (IS_ERR(uc->bchan)) {
+		ret = PTR_ERR(uc->bchan);
+		uc->bchan = NULL;
+		return ret;
+	}
+	uc->chan = uc->bchan;
+	uc->tchan = uc->bchan;
+
+	return 0;
+}
+
+static int am62l_bcdma_v2_alloc_bchan_resources(struct udma_chan *uc)
+{
+	struct k3_ring_cfg ring_cfg;
+	struct udma_dev *ud = uc->ud;
+	int ret;
+
+	ret = am62l_bcdma_v2_get_bchan(uc);
+	if (ret)
+		return ret;
+
+	ret = k3_ringacc_request_rings_pair(ud->ringacc, ud->match_data->chan_cnt + uc->id, -1,
+			&uc->bchan->t_ring,
+			&uc->bchan->tc_ring);
+	if (ret) {
+		ret = -EBUSY;
+		goto err_ring;
+	}
+
+	memset(&ring_cfg, 0, sizeof(ring_cfg));
+	ring_cfg.size = K3_UDMA_DEFAULT_RING_SIZE;
+	ring_cfg.elm_size = K3_RINGACC_RING_ELSIZE_8;
+	ring_cfg.mode = K3_RINGACC_RING_MODE_RING;
+
+	k3_configure_chan_coherency(&uc->vc.chan, ud->asel);
+	ring_cfg.asel = ud->asel;
+	ring_cfg.dma_dev = dmaengine_get_dma_device(&uc->vc.chan);
+
+	ret = k3_ringacc_ring_cfg(uc->bchan->t_ring, &ring_cfg);
+	if (ret)
+		goto err_ringcfg;
+
+	return 0;
+
+err_ringcfg:
+	k3_ringacc_ring_free(uc->bchan->tc_ring);
+	uc->bchan->tc_ring = NULL;
+	k3_ringacc_ring_free(uc->bchan->t_ring);
+	uc->bchan->t_ring = NULL;
+	k3_configure_chan_coherency(&uc->vc.chan, 0);
+err_ring:
+	bcdma_put_bchan(uc);
+
+	return ret;
+}
+
+static int am62l_udma_alloc_tx_resources(struct udma_chan *uc)
+{
+	struct k3_ring_cfg ring_cfg;
+	struct udma_dev *ud = uc->ud;
+	struct udma_tchan *tchan;
+	int ring_idx, ret;
+
+	ret = udma_get_tchan(uc);
+	if (ret)
+		return ret;
+
+	tchan = uc->tchan;
+	if (tchan->tflow_id >= 0)
+		ring_idx = tchan->tflow_id;
+	else
+		ring_idx = tchan->id;
+
+	ret = k3_ringacc_request_rings_pair(ud->ringacc, ring_idx, -1,
+					    &tchan->t_ring,
+					    &tchan->tc_ring);
+	if (ret) {
+		ret = -EBUSY;
+		goto err_ring;
+	}
+
+	memset(&ring_cfg, 0, sizeof(ring_cfg));
+	ring_cfg.size = K3_UDMA_DEFAULT_RING_SIZE;
+	ring_cfg.elm_size = K3_RINGACC_RING_ELSIZE_8;
+	ring_cfg.mode = K3_RINGACC_RING_MODE_RING;
+
+	k3_configure_chan_coherency(&uc->vc.chan, uc->config.asel);
+	ring_cfg.asel = uc->config.asel;
+	ring_cfg.dma_dev = dmaengine_get_dma_device(&uc->vc.chan);
+
+	ret = k3_ringacc_ring_cfg(tchan->t_ring, &ring_cfg);
+	ret |= k3_ringacc_ring_cfg(tchan->tc_ring, &ring_cfg);
+
+	if (ret)
+		goto err_ringcfg;
+
+	return 0;
+
+err_ringcfg:
+	k3_ringacc_ring_free(uc->tchan->tc_ring);
+	uc->tchan->tc_ring = NULL;
+	k3_ringacc_ring_free(uc->tchan->t_ring);
+	uc->tchan->t_ring = NULL;
+err_ring:
+	udma_put_tchan(uc);
+
+	return ret;
+}
+
+static int am62l_udma_alloc_rx_resources(struct udma_chan *uc)
+{
+	struct udma_dev *ud = uc->ud;
+	struct k3_ring_cfg ring_cfg;
+	struct udma_rflow *rflow;
+	int fd_ring_id;
+	int ret;
+
+	ret = udma_get_rchan(uc);
+	if (ret)
+		return ret;
+
+	/* For MEM_TO_MEM we don't need rflow or rings */
+	if (uc->config.dir == DMA_MEM_TO_MEM)
+		return 0;
+
+	if (uc->config.default_flow_id >= 0)
+		ret = udma_get_rflow(uc, uc->config.default_flow_id);
+	else
+		ret = udma_get_rflow(uc, uc->rchan->id);
+
+	if (ret) {
+		ret = -EBUSY;
+		goto err_rflow;
+	}
+
+	rflow = uc->rflow;
+	if (ud->tflow_cnt)
+		fd_ring_id = ud->tflow_cnt + rflow->id;
+	else
+		fd_ring_id = uc->rchan->id;
+	ret = k3_ringacc_request_rings_pair(ud->ringacc, fd_ring_id, -1,
+					    &rflow->fd_ring, &rflow->r_ring);
+	if (ret) {
+		ret = -EBUSY;
+		goto err_ring;
+	}
+
+	memset(&ring_cfg, 0, sizeof(ring_cfg));
+
+	ring_cfg.elm_size = K3_RINGACC_RING_ELSIZE_8;
+	ring_cfg.size = K3_UDMA_DEFAULT_RING_SIZE;
+	ring_cfg.mode = K3_RINGACC_RING_MODE_RING;
+
+	k3_configure_chan_coherency(&uc->vc.chan, uc->config.asel);
+	ring_cfg.asel = uc->config.asel;
+	ring_cfg.dma_dev = dmaengine_get_dma_device(&uc->vc.chan);
+
+	ret = k3_ringacc_ring_cfg(rflow->fd_ring, &ring_cfg);
+
+	ring_cfg.size = K3_UDMA_DEFAULT_RING_SIZE;
+	ret |= k3_ringacc_ring_cfg(rflow->r_ring, &ring_cfg);
+
+	if (ret)
+		goto err_ringcfg;
+
+	return 0;
+
+err_ringcfg:
+	k3_ringacc_ring_free(rflow->r_ring);
+	rflow->r_ring = NULL;
+	k3_ringacc_ring_free(rflow->fd_ring);
+	rflow->fd_ring = NULL;
+err_ring:
+	udma_put_rflow(uc);
+err_rflow:
+	udma_put_rchan(uc);
+
+	return ret;
+}
+
+static int am62l_bcdma_v2_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+	struct udma_dev *ud = to_udma_dev(chan->device);
+	u32 irq_ring_idx;
+	__be32 addr[2] = {0, 0};
+	struct of_phandle_args out_irq;
+	int ret;
+
+	/* Only TR mode is supported */
+	uc->config.pkt_mode = false;
+
+	/*
+	 * Make sure that the completion is in a known state:
+	 * No teardown, the channel is idle
+	 */
+	reinit_completion(&uc->teardown_completed);
+	complete_all(&uc->teardown_completed);
+	uc->state = UDMA_CHAN_IS_IDLE;
+
+	switch (uc->config.dir) {
+	case DMA_MEM_TO_MEM:
+		/* Non synchronized - mem to mem type of transfer */
+		dev_dbg(uc->ud->dev, "%s: chan%d as MEM-to-MEM\n", __func__,
+			uc->id);
+
+		ret = am62l_bcdma_v2_alloc_bchan_resources(uc);
+		if (ret)
+			return ret;
+
+		irq_ring_idx = ud->match_data->chan_cnt + uc->id;
+		break;
+	case DMA_MEM_TO_DEV:
+		/* Slave transfer synchronized - mem to dev (TX) trasnfer */
+		dev_dbg(uc->ud->dev, "%s: chan%d as MEM-to-DEV\n", __func__,
+			uc->id);
+
+		ret = am62l_udma_alloc_tx_resources(uc);
+		if (ret) {
+			uc->config.remote_thread_id = -1;
+			return ret;
+		}
+
+		uc->config.src_thread = ud->psil_base + uc->tchan->id;
+		uc->config.dst_thread = uc->config.remote_thread_id;
+		uc->config.dst_thread |= K3_PSIL_DST_THREAD_ID_OFFSET;
+
+		irq_ring_idx = uc->tchan->id;
+
+		break;
+	case DMA_DEV_TO_MEM:
+		/* Slave transfer synchronized - dev to mem (RX) trasnfer */
+		dev_dbg(uc->ud->dev, "%s: chan%d as DEV-to-MEM\n", __func__,
+			uc->id);
+
+		ret = am62l_udma_alloc_rx_resources(uc);
+		if (ret) {
+			uc->config.remote_thread_id = -1;
+			return ret;
+		}
+
+		uc->config.src_thread = uc->config.remote_thread_id;
+		uc->config.dst_thread = (ud->psil_base + uc->rchan->id) |
+					K3_PSIL_DST_THREAD_ID_OFFSET;
+
+		irq_ring_idx = uc->rchan->id;
+
+		break;
+	default:
+		/* Can not happen */
+		dev_err(uc->ud->dev, "%s: chan%d invalid direction (%u)\n",
+			__func__, uc->id, uc->config.dir);
+		return -EINVAL;
+	}
+
+	/* check if the channel configuration was successful */
+	if (ret)
+		goto err_res_free;
+
+	if (udma_is_chan_running(uc)) {
+		dev_warn(ud->dev, "chan%d: is running!\n", uc->id);
+		ud->udma_reset_chan(uc, false);
+		if (udma_is_chan_running(uc)) {
+			dev_err(ud->dev, "chan%d: won't stop!\n", uc->id);
+			ret = -EBUSY;
+			goto err_res_free;
+		}
+	}
+
+	uc->dma_dev = dmaengine_get_dma_device(chan);
+	if (uc->config.dir == DMA_MEM_TO_MEM  && !uc->config.tr_trigger_type) {
+		uc->config.hdesc_size = cppi5_trdesc_calc_size(
+					sizeof(struct cppi5_tr_type15_t), 2);
+
+		uc->hdesc_pool = dma_pool_create(uc->name, ud->ddev.dev,
+						 uc->config.hdesc_size,
+						 ud->desc_align,
+						 0);
+		if (!uc->hdesc_pool) {
+			dev_err(ud->ddev.dev,
+				"Descriptor pool allocation failed\n");
+			uc->use_dma_pool = false;
+			ret = -ENOMEM;
+			goto err_res_free;
+		}
+
+		uc->use_dma_pool = true;
+	} else if (uc->config.dir != DMA_MEM_TO_MEM) {
+		uc->psil_paired = true;
+	}
+
+	out_irq.np = dev_of_node(ud->dev);
+	out_irq.args_count = 1;
+	out_irq.args[0] = irq_ring_idx;
+	ret = of_irq_parse_raw(addr, &out_irq);
+	if (ret)
+		return ret;
+
+	uc->irq_num_ring = irq_create_of_mapping(&out_irq);
+
+	ret = devm_request_irq(ud->dev, uc->irq_num_ring, am62l_udma_ring_irq_handler,
+			IRQF_TRIGGER_HIGH, uc->name, uc);
+	if (ret) {
+		dev_err(ud->dev, "chan%d: ring irq request failed\n", uc->id);
+		goto err_irq_free;
+	}
+
+	udma_reset_rings(uc);
+
+	INIT_DELAYED_WORK_ONSTACK(&uc->tx_drain.work,
+				  udma_check_tx_completion);
+	return 0;
+
+err_irq_free:
+	uc->irq_num_ring = 0;
+	uc->irq_num_udma = 0;
+err_res_free:
+	bcdma_free_bchan_resources(uc);
+	udma_free_tx_resources(uc);
+	udma_free_rx_resources(uc);
+
+	udma_reset_uchan(uc);
+
+	if (uc->use_dma_pool) {
+		dma_pool_destroy(uc->hdesc_pool);
+		uc->use_dma_pool = false;
+	}
+
+	return ret;
+}
+
+static int am62l_pktdma_v2_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+	struct udma_dev *ud = to_udma_dev(chan->device);
+	u32 irq_ring_idx;
+	__be32 addr[2] = {0, 0};
+	struct of_phandle_args out_irq;
+	int ret;
+
+	/*
+	 * Make sure that the completion is in a known state:
+	 * No teardown, the channel is idle
+	 */
+	reinit_completion(&uc->teardown_completed);
+	complete_all(&uc->teardown_completed);
+	uc->state = UDMA_CHAN_IS_IDLE;
+
+	switch (uc->config.dir) {
+	case DMA_MEM_TO_DEV:
+		/* Slave transfer synchronized - mem to dev (TX) trasnfer */
+		dev_dbg(uc->ud->dev, "%s: chan%d as MEM-to-DEV\n", __func__,
+			uc->id);
+
+		ret = am62l_udma_alloc_tx_resources(uc);
+		if (ret) {
+			uc->config.remote_thread_id = -1;
+			return ret;
+		}
+
+		uc->config.src_thread = ud->psil_base + uc->tchan->id;
+		uc->config.dst_thread = uc->config.remote_thread_id;
+		uc->config.dst_thread |= K3_PSIL_DST_THREAD_ID_OFFSET;
+
+
+		irq_ring_idx = uc->config.mapped_channel_id;
+		break;
+	case DMA_DEV_TO_MEM:
+		/* Slave transfer synchronized - dev to mem (RX) trasnfer */
+		dev_dbg(uc->ud->dev, "%s: chan%d as DEV-to-MEM\n", __func__,
+			uc->id);
+
+		ret = am62l_udma_alloc_rx_resources(uc);
+		if (ret) {
+			uc->config.remote_thread_id = -1;
+			return ret;
+		}
+
+		uc->config.src_thread = uc->config.remote_thread_id;
+		uc->config.dst_thread = (ud->psil_base + uc->rchan->id) |
+					K3_PSIL_DST_THREAD_ID_OFFSET;
+
+		irq_ring_idx = uc->config.mapped_channel_id;
+		udma_write(uc->rflow->reg_rt, UDMA_RX_FLOWRT_RFA, BIT(28));
+		break;
+	default:
+		/* Can not happen */
+		dev_err(uc->ud->dev, "%s: chan%d invalid direction (%u)\n",
+			__func__, uc->id, uc->config.dir);
+		return -EINVAL;
+	}
+
+	/* check if the channel configuration was successful */
+	if (ret)
+		goto err_res_free;
+
+	if (udma_is_chan_running(uc)) {
+		dev_warn(ud->dev, "chan%d: is running!\n", uc->id);
+		ud->udma_reset_chan(uc, false);
+		if (udma_is_chan_running(uc)) {
+			dev_err(ud->dev, "chan%d: won't stop!\n", uc->id);
+			ret = -EBUSY;
+			goto err_res_free;
+		}
+	}
+
+	uc->dma_dev = dmaengine_get_dma_device(chan);
+	uc->hdesc_pool = dma_pool_create(uc->name, uc->dma_dev,
+					 uc->config.hdesc_size, ud->desc_align,
+					 0);
+	if (!uc->hdesc_pool) {
+		dev_err(ud->ddev.dev,
+			"Descriptor pool allocation failed\n");
+		uc->use_dma_pool = false;
+		ret = -ENOMEM;
+		goto err_res_free;
+	}
+
+	uc->use_dma_pool = true;
+
+	uc->psil_paired = true;
+
+	out_irq.np = dev_of_node(ud->dev);
+	out_irq.args_count = 1;
+	out_irq.args[0] = irq_ring_idx;
+	ret = of_irq_parse_raw(addr, &out_irq);
+	if (ret)
+		return ret;
+
+	uc->irq_num_ring = irq_create_of_mapping(&out_irq);
+
+	ret = devm_request_irq(ud->dev, uc->irq_num_ring, am62l_udma_ring_irq_handler,
+			IRQF_TRIGGER_HIGH, uc->name, uc);
+
+	if (ret) {
+		dev_err(ud->dev, "chan%d: ring irq request failed\n", uc->id);
+		goto err_irq_free;
+	}
+
+	uc->irq_num_udma = 0;
+
+	udma_reset_rings(uc);
+
+	INIT_DELAYED_WORK_ONSTACK(&uc->tx_drain.work,
+				  udma_check_tx_completion);
+
+	if (uc->tchan)
+		dev_dbg(ud->dev,
+			"chan%d: tchan%d, tflow%d, Remote thread: 0x%04x\n",
+			uc->id, uc->tchan->id, uc->tchan->tflow_id,
+			uc->config.remote_thread_id);
+	else if (uc->rchan)
+		dev_dbg(ud->dev,
+			"chan%d: rchan%d, rflow%d, Remote thread: 0x%04x\n",
+			uc->id, uc->rchan->id, uc->rflow->id,
+			uc->config.remote_thread_id);
+	return 0;
+
+err_irq_free:
+	uc->irq_num_ring = 0;
+err_res_free:
+	udma_free_tx_resources(uc);
+	udma_free_rx_resources(uc);
+
+	udma_reset_uchan(uc);
+
+	dma_pool_destroy(uc->hdesc_pool);
+	uc->use_dma_pool = false;
+
+	return ret;
+}
+
+static enum dma_status am62l_udma_tx_status(struct dma_chan *chan,
+				      dma_cookie_t cookie,
+				      struct dma_tx_state *txstate)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+	enum dma_status ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&uc->vc.lock, flags);
+
+	ret = dma_cookie_status(chan, cookie, txstate);
+
+	if (!udma_is_chan_running(uc))
+		ret = DMA_COMPLETE;
+
+	if (ret == DMA_IN_PROGRESS && am62l_udma_is_chan_paused(uc))
+		ret = DMA_PAUSED;
+
+	if (ret == DMA_COMPLETE || !txstate)
+		goto out;
+
+	if (uc->desc && uc->desc->vd.tx.cookie == cookie) {
+		u32 peer_bcnt = 0;
+		u32 bcnt = 0;
+		u32 residue = uc->desc->residue;
+		u32 delay = 0;
+
+		if (uc->desc->dir == DMA_MEM_TO_DEV) {
+			bcnt = udma_chanrt_read(uc, UDMA_CHAN_RT_SBCNT_REG);
+
+			if (uc->config.ep_type != PSIL_EP_NATIVE) {
+				peer_bcnt = udma_chanrt_read(uc, 0x810);
+
+				if (bcnt > peer_bcnt)
+					delay = bcnt - peer_bcnt;
+			}
+		} else if (uc->desc->dir == DMA_DEV_TO_MEM) {
+			bcnt = udma_chanrt_read(uc, UDMA_CHAN_RT_BCNT_REG);
+
+			if (uc->config.ep_type != PSIL_EP_NATIVE) {
+				peer_bcnt = udma_chanrt_read(uc, 0x810);
+
+				if (peer_bcnt > bcnt)
+					delay = peer_bcnt - bcnt;
+			}
+		} else {
+			bcnt = udma_chanrt_read(uc, UDMA_CHAN_RT_BCNT_REG);
+		}
+
+		if (bcnt && !(bcnt % uc->desc->residue))
+			residue = 0;
+		else
+			residue -= bcnt % uc->desc->residue;
+
+		if (!residue && (uc->config.dir == DMA_DEV_TO_MEM || !delay)) {
+			ret = DMA_COMPLETE;
+			delay = 0;
+		}
+
+		dma_set_residue(txstate, residue);
+		dma_set_in_flight_bytes(txstate, delay);
+
+	} else {
+		ret = DMA_COMPLETE;
+	}
+
+out:
+	spin_unlock_irqrestore(&uc->vc.lock, flags);
+	return ret;
+}
+
+static int am62l_udma_pause(struct dma_chan *chan)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+
+	/* pause the channel */
+	udma_chanrt_update_bits(uc, UDMA_CHAN_RT_CTL_REG,
+			UDMA_CHAN_RT_CTL_PAUSE, UDMA_CHAN_RT_CTL_PAUSE);
+
+	return 0;
+}
+
+static int am62l_udma_resume(struct dma_chan *chan)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+
+	/* resume the channel */
+	udma_chanrt_update_bits(uc, UDMA_CHAN_RT_CTL_REG,
+			UDMA_CHAN_RT_CTL_PAUSE, 0);
+
+	return 0;
+}
+
+static struct platform_driver am62l_bcdma_v2_driver;
+static struct platform_driver am62l_pktdma_v2_driver;
+
+static bool am62l_udma_dma_filter_fn(struct dma_chan *chan, void *param)
+{
+	struct udma_chan_config *ucc;
+	struct psil_endpoint_config *ep_config;
+	struct am62l_udma_filter_param *filter_param;
+	struct udma_chan *uc;
+	struct udma_dev *ud;
+
+	if (chan->device->dev->driver != &am62l_bcdma_v2_driver.driver &&
+		chan->device->dev->driver != &am62l_pktdma_v2_driver.driver)
+		return false;
+
+	uc = to_udma_chan(chan);
+	ucc = &uc->config;
+	ud = uc->ud;
+	filter_param = param;
+
+	if (filter_param->asel > 15) {
+		dev_err(ud->dev, "Invalid channel asel: %u\n",
+			filter_param->asel);
+		return false;
+	}
+
+	ucc->remote_thread_id = filter_param->remote_thread_id;
+	ucc->asel = filter_param->asel;
+	ucc->tr_trigger_type = filter_param->tr_trigger_type;
+
+	if (ucc->tr_trigger_type) {
+		ucc->dir = DMA_MEM_TO_MEM;
+		goto triggered_bchan;
+	} else if (ucc->remote_thread_id & K3_PSIL_DST_THREAD_ID_OFFSET) {
+		ucc->dir = DMA_MEM_TO_DEV;
+	} else {
+		ucc->dir = DMA_DEV_TO_MEM;
+	}
+
+	ep_config = psil_get_ep_config(ucc->remote_thread_id);
+	if (IS_ERR(ep_config)) {
+		dev_err(ud->dev, "No configuration for psi-l thread 0x%04x\n",
+			ucc->remote_thread_id);
+		ucc->dir = DMA_MEM_TO_MEM;
+		ucc->remote_thread_id = -1;
+		ucc->atype = 0;
+		ucc->asel = 0;
+		return false;
+	}
+
+	ucc->pkt_mode = ep_config->pkt_mode;
+	ucc->channel_tpl = ep_config->channel_tpl;
+	ucc->notdpkt = ep_config->notdpkt;
+	ucc->ep_type = ep_config->ep_type;
+
+	if ((ud->match_data->type >= DMA_TYPE_BCDMA_V2) &&
+		ep_config->mapped_channel_id >= 0) {
+		ucc->mapped_channel_id = ep_config->mapped_channel_id;
+		ucc->default_flow_id = ep_config->default_flow_id;
+	} else {
+		ucc->mapped_channel_id = -1;
+		ucc->default_flow_id = -1;
+	}
+
+	ucc->needs_epib = ep_config->needs_epib;
+	ucc->psd_size = ep_config->psd_size;
+	ucc->metadata_size =
+		(ucc->needs_epib ? CPPI5_INFO0_HDESC_EPIB_SIZE : 0) +
+		ucc->psd_size;
+
+	if (ucc->ep_type != PSIL_EP_NATIVE) {
+		const struct udma_match_data *match_data = ud->match_data;
+
+		if ((match_data->flags & UDMA_FLAG_PDMA_ACC32) && (ep_config->pdma_acc32))
+			ucc->enable_acc32 = true;
+		else
+			ucc->enable_acc32 = false;
+
+		if ((match_data->flags & UDMA_FLAG_PDMA_BURST) && (ep_config->pdma_burst))
+			ucc->enable_burst = true;
+		else
+			ucc->enable_burst = false;
+	}
+	if (ucc->pkt_mode)
+		ucc->hdesc_size = ALIGN(sizeof(struct cppi5_host_desc_t) +
+				 ucc->metadata_size, ud->desc_align);
+
+	dev_dbg(ud->dev, "chan%d: Remote thread: 0x%04x (%s)\n", uc->id,
+		ucc->remote_thread_id, dmaengine_get_direction_text(ucc->dir));
+
+	return true;
+
+triggered_bchan:
+	dev_dbg(ud->dev, "chan%d: triggered channel (type: %u)\n", uc->id,
+		ucc->tr_trigger_type);
+
+	return true;
+}
+
+static struct dma_chan *am62l_udma_of_xlate(struct of_phandle_args *dma_spec,
+				      struct of_dma *ofdma)
+{
+	struct udma_dev *ud = ofdma->of_dma_data;
+	dma_cap_mask_t mask = ud->ddev.cap_mask;
+	struct am62l_udma_filter_param filter_param;
+	struct dma_chan *chan;
+
+	if (ud->match_data->type == DMA_TYPE_BCDMA_V2) {
+		if (dma_spec->args_count != 4)
+			return NULL;
+
+		filter_param.tr_trigger_type = dma_spec->args[0];
+		filter_param.trigger_param = dma_spec->args[1];
+		filter_param.remote_thread_id = dma_spec->args[2];
+		filter_param.asel = dma_spec->args[3];
+	} else {
+		if (dma_spec->args_count != 1 && dma_spec->args_count != 2)
+			return NULL;
+
+		filter_param.remote_thread_id = dma_spec->args[0];
+		filter_param.tr_trigger_type = 0;
+		if (dma_spec->args_count == 2)
+			filter_param.asel = dma_spec->args[1];
+		else
+			filter_param.asel = 0;
+	}
+
+	chan = __dma_request_channel(&mask, am62l_udma_dma_filter_fn, &filter_param,
+				     ofdma->of_node);
+	if (!chan) {
+		dev_err(ud->dev, "get channel fail in %s.\n", __func__);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return chan;
+}
+
+static struct udma_match_data am62l_bcdma_v2_data = {
+	.type = DMA_TYPE_BCDMA_V2,
+	.psil_base = 0x2000, /* for tchan and rchan, not applicable to bchan */
+	.enable_memcpy_support = true, /* Supported via bchan */
+	.flags = UDMA_FLAGS_J7_CLASS,
+	.statictr_z_mask = GENMASK(23, 0),
+	.burst_size = {
+		TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* Normal Channels */
+		0, /* No H Channels */
+		0, /* No UH Channels */
+	},
+	.bchan_cnt = 16,
+	.chan_cnt = 128,
+	.tchan_cnt = 128,
+	.rchan_cnt = 128,
+};
+
+static struct udma_match_data am62l_pktdma_v2_data = {
+	.type = DMA_TYPE_PKTDMA_V2,
+	.psil_base = 0x1000,
+	.enable_memcpy_support = false, /* PKTDMA does not support MEM_TO_MEM */
+	.flags = UDMA_FLAGS_J7_CLASS,
+	.statictr_z_mask = GENMASK(23, 0),
+	.burst_size = {
+		TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* Normal Channels */
+		0, /* No H Channels */
+		0, /* No UH Channels */
+	},
+	.tchan_cnt = 97,
+	.rchan_cnt = 97,
+	.chan_cnt = 97,
+	.tflow_cnt = 112,
+	.rflow_cnt = 112,
+};
+
+static const struct of_device_id udma_of_match[] = {
+	{
+		.compatible = "ti,am62l-dmss-bcdma",
+		.data = &am62l_bcdma_v2_data,
+	},
+	{
+		.compatible = "ti,am62l-dmss-pktdma",
+		.data = &am62l_pktdma_v2_data,
+	},
+	{ /* Sentinel */ },
+};
+
+static const struct soc_device_attribute k3_soc_devices[] = {
+	{ .family = "AM62LX", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, udma_of_match);
+
+static int am62l_udma_get_mmrs(struct platform_device *pdev, struct udma_dev *ud)
+{
+	int i;
+
+	ud->mmrs[AM62L_MMR_GCFG] = devm_platform_ioremap_resource_byname(pdev,
+			am62l_mmr_names[AM62L_MMR_GCFG]);
+	if (IS_ERR(ud->mmrs[AM62L_MMR_GCFG]))
+		return PTR_ERR(ud->mmrs[AM62L_MMR_GCFG]);
+
+	/* There are no tchan and rchan in BCDMA_V2 and PKTDMA_V2.
+	 * Duplicate chan as tchan and rchan to keep the common code
+	 * in k3-udma-common.c functional.
+	 */
+	if (ud->match_data->type == DMA_TYPE_BCDMA_V2) {
+		ud->bchan_cnt = ud->match_data->bchan_cnt;
+		ud->chan_cnt = ud->match_data->chan_cnt;
+		ud->tchan_cnt = ud->match_data->chan_cnt;
+		ud->rchan_cnt = ud->match_data->chan_cnt;
+		ud->rflow_cnt = ud->chan_cnt;
+	} else if (ud->match_data->type == DMA_TYPE_PKTDMA_V2) {
+		ud->chan_cnt = ud->match_data->chan_cnt;
+		ud->tchan_cnt = ud->match_data->tchan_cnt;
+		ud->rchan_cnt = ud->match_data->rchan_cnt;
+		ud->rflow_cnt = ud->match_data->rflow_cnt;
+	}
+
+	for (i = 1; i < AM62L_MMR_LAST; i++) {
+		if (i == AM62L_MMR_BCHANRT && ud->bchan_cnt == 0)
+			continue;
+		if (i == AM62L_MMR_CHANRT && ud->chan_cnt == 0)
+			continue;
+
+		ud->mmrs[i] = devm_platform_ioremap_resource_byname(pdev, am62l_mmr_names[i]);
+		if (IS_ERR(ud->mmrs[i]))
+			return PTR_ERR(ud->mmrs[i]);
+	}
+
+	return 0;
+}
+
+static int am62l_udma_probe(struct platform_device *pdev)
+{
+	const struct soc_device_attribute *soc;
+	struct device *dev = &pdev->dev;
+	struct udma_dev *ud;
+	const struct of_device_id *match;
+	int i, ret;
+	int ch_count;
+
+	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(48));
+	if (ret)
+		dev_err(dev, "failed to set dma mask stuff\n");
+
+	ud = devm_kzalloc(dev, sizeof(*ud), GFP_KERNEL);
+	if (!ud)
+		return -ENOMEM;
+
+	match = of_match_node(udma_of_match, dev->of_node);
+	if (!match) {
+		dev_err(dev, "No compatible match found\n");
+		return -ENODEV;
+	}
+	ud->match_data = match->data;
+
+	ud->soc_data = ud->match_data->soc_data;
+	if (!ud->soc_data) {
+		soc = soc_device_match(k3_soc_devices);
+		if (!soc) {
+			dev_err(dev, "No compatible SoC found\n");
+			return -ENODEV;
+		}
+		ud->soc_data = soc->data;
+	}
+	// Setup function pointers
+	ud->udma_start = am62l_udma_start;
+	ud->udma_stop = am62l_udma_stop;
+	ud->udma_reset_chan = am62l_udma_reset_chan;
+	ud->udma_is_desc_really_done = am62l_udma_is_desc_really_done;
+	ud->udma_decrement_byte_counters = am62l_udma_decrement_byte_counters;
+
+	ret = am62l_udma_get_mmrs(pdev, ud);
+	if (ret)
+		return ret;
+
+	struct k3_ringacc_init_data ring_init_data = {0};
+
+	if (ud->match_data->type == DMA_TYPE_BCDMA_V2) {
+		ring_init_data.num_rings = ud->bchan_cnt + ud->chan_cnt;
+	} else if (ud->match_data->type == DMA_TYPE_PKTDMA_V2) {
+		ring_init_data.num_rings = ud->rflow_cnt;
+
+		ud->rflow_rt = devm_platform_ioremap_resource_byname(pdev, "ringrt");
+		ring_init_data.base_rt = ud->rflow_rt;
+	}
+
+	ud->ringacc = k3_ringacc_dmarings_init(pdev, &ring_init_data);
+
+	if (IS_ERR(ud->ringacc))
+		return PTR_ERR(ud->ringacc);
+
+	dma_cap_set(DMA_SLAVE, ud->ddev.cap_mask);
+
+	if (ud->match_data->type != DMA_TYPE_PKTDMA_V2) {
+		dma_cap_set(DMA_CYCLIC, ud->ddev.cap_mask);
+		ud->ddev.device_prep_dma_cyclic = udma_prep_dma_cyclic;
+	}
+
+	ud->ddev.device_config = udma_slave_config;
+	ud->ddev.device_prep_slave_sg = udma_prep_slave_sg;
+	ud->ddev.device_issue_pending = udma_issue_pending;
+	ud->ddev.device_tx_status = am62l_udma_tx_status;
+	ud->ddev.device_pause = am62l_udma_pause;
+	ud->ddev.device_resume = am62l_udma_resume;
+	ud->ddev.device_terminate_all = udma_terminate_all;
+	ud->ddev.device_synchronize = udma_synchronize;
+#ifdef CONFIG_DEBUG_FS
+	ud->ddev.dbg_summary_show = udma_dbg_summary_show;
+#endif
+
+	switch (ud->match_data->type) {
+	case DMA_TYPE_BCDMA_V2:
+		ud->ddev.device_alloc_chan_resources =
+			am62l_bcdma_v2_alloc_chan_resources;
+		break;
+	case DMA_TYPE_PKTDMA_V2:
+		ud->ddev.device_alloc_chan_resources =
+			am62l_pktdma_v2_alloc_chan_resources;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ud->ddev.device_free_chan_resources = udma_free_chan_resources;
+
+	ud->ddev.src_addr_widths = TI_UDMAC_BUSWIDTHS;
+	ud->ddev.dst_addr_widths = TI_UDMAC_BUSWIDTHS;
+	ud->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+	ud->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+	ud->ddev.desc_metadata_modes = DESC_METADATA_CLIENT |
+				       DESC_METADATA_ENGINE;
+	if (ud->match_data->enable_memcpy_support &&
+	    !(ud->match_data->type == DMA_TYPE_BCDMA && ud->bchan_cnt == 0)) {
+		dma_cap_set(DMA_MEMCPY, ud->ddev.cap_mask);
+		ud->ddev.device_prep_dma_memcpy = udma_prep_dma_memcpy;
+		ud->ddev.directions |= BIT(DMA_MEM_TO_MEM);
+	}
+
+	ud->ddev.dev = dev;
+	ud->dev = dev;
+	ud->psil_base = ud->match_data->psil_base;
+
+	INIT_LIST_HEAD(&ud->ddev.channels);
+	INIT_LIST_HEAD(&ud->desc_to_purge);
+
+	ch_count = setup_resources(ud);
+	if (ch_count <= 0)
+		return ch_count;
+
+	spin_lock_init(&ud->lock);
+	INIT_WORK(&ud->purge_work, udma_purge_desc_work);
+
+	ud->desc_align = 64;
+	if (ud->desc_align < dma_get_cache_alignment())
+		ud->desc_align = dma_get_cache_alignment();
+
+	ret = udma_setup_rx_flush(ud);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < ud->bchan_cnt; i++) {
+		struct udma_bchan *bchan = &ud->bchans[i];
+
+		bchan->id = i;
+		bchan->reg_rt = ud->mmrs[AM62L_MMR_BCHANRT] + i * 0x1000;
+	}
+
+	for (i = 0; i < ud->tchan_cnt; i++) {
+		struct udma_tchan *tchan = &ud->tchans[i];
+
+		tchan->id = i;
+		tchan->reg_rt = ud->mmrs[AM62L_MMR_CHANRT] + i * 0x1000;
+	}
+
+	for (i = 0; i < ud->rchan_cnt; i++) {
+		struct udma_rchan *rchan = &ud->rchans[i];
+
+		rchan->id = i;
+		rchan->reg_rt = ud->mmrs[AM62L_MMR_CHANRT] + i * 0x1000;
+	}
+
+	for (i = 0; i < ud->rflow_cnt; i++) {
+		struct udma_rflow *rflow = &ud->rflows[i];
+
+		rflow->id = i;
+		rflow->reg_rt = ud->rflow_rt + i * 0x2000;
+	}
+
+	for (i = 0; i < ch_count; i++) {
+		struct udma_chan *uc = &ud->channels[i];
+
+		uc->ud = ud;
+		uc->vc.desc_free = udma_desc_free;
+		uc->id = i;
+		uc->bchan = NULL;
+		uc->tchan = NULL;
+		uc->rchan = NULL;
+		uc->config.remote_thread_id = -1;
+		uc->config.mapped_channel_id = -1;
+		uc->config.default_flow_id = -1;
+		uc->config.dir = DMA_MEM_TO_MEM;
+		uc->name = devm_kasprintf(dev, GFP_KERNEL, "%s chan%d",
+					  dev_name(dev), i);
+
+		vchan_init(&uc->vc, &ud->ddev);
+		/* Use custom vchan completion handling */
+		tasklet_setup(&uc->vc.task, udma_vchan_complete);
+		init_completion(&uc->teardown_completed);
+		INIT_DELAYED_WORK(&uc->tx_drain.work, udma_check_tx_completion);
+	}
+
+	/* Configure the copy_align to the maximum burst size the device supports */
+	ud->ddev.copy_align = udma_get_copy_align(ud);
+
+	ret = dma_async_device_register(&ud->ddev);
+	if (ret) {
+		dev_err(dev, "failed to register slave DMA engine: %d\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, ud);
+
+	ret = of_dma_controller_register(dev->of_node, am62l_udma_of_xlate, ud);
+	if (ret) {
+		dev_err(dev, "failed to register of_dma controller\n");
+		dma_async_device_unregister(&ud->ddev);
+	}
+
+	return ret;
+}
+
+static int __maybe_unused am62l_udma_pm_suspend(struct device *dev)
+{
+	struct udma_dev *ud = dev_get_drvdata(dev);
+	struct dma_device *dma_dev = &ud->ddev;
+	struct dma_chan *chan;
+	struct udma_chan *uc;
+
+	list_for_each_entry(chan, &dma_dev->channels, device_node) {
+		if (chan->client_count) {
+			uc = to_udma_chan(chan);
+			/* backup the channel configuration */
+			memcpy(&uc->backup_config, &uc->config,
+			       sizeof(struct udma_chan_config));
+			dev_dbg(dev, "Suspending channel %s\n",
+				dma_chan_name(chan));
+			ud->ddev.device_free_chan_resources(chan);
+		}
+	}
+
+	return 0;
+}
+
+static int __maybe_unused am62l_udma_pm_resume(struct device *dev)
+{
+	struct udma_dev *ud = dev_get_drvdata(dev);
+	struct dma_device *dma_dev = &ud->ddev;
+	struct dma_chan *chan;
+	struct udma_chan *uc;
+	int ret;
+
+	list_for_each_entry(chan, &dma_dev->channels, device_node) {
+		if (chan->client_count) {
+			uc = to_udma_chan(chan);
+			/* restore the channel configuration */
+			memcpy(&uc->config, &uc->backup_config,
+			       sizeof(struct udma_chan_config));
+			dev_dbg(dev, "Resuming channel %s\n",
+				dma_chan_name(chan));
+			ret = ud->ddev.device_alloc_chan_resources(chan);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops udma_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(am62l_udma_pm_suspend, am62l_udma_pm_resume)
+};
+
+static struct platform_driver am62l_bcdma_v2_driver = {
+	.driver = {
+		.name	= "ti-udma-am62l",
+		.of_match_table = udma_of_match,
+		.suppress_bind_attrs = true,
+		.pm = &udma_pm_ops,
+	},
+	.probe		= am62l_udma_probe,
+};
+
+module_platform_driver(am62l_bcdma_v2_driver);
+MODULE_DESCRIPTION("Texas Instruments K3 AM62L UDMA support");
+MODULE_LICENSE("GPL");
+
diff -Naur --no-dereference a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
--- a/drivers/dma/ti/k3-udma.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/dma/ti/k3-udma.c	2025-10-23 09:30:40.284462176 -0400
@@ -33,43 +33,6 @@
 #include "k3-udma.h"
 #include "k3-psil-priv.h"
 
-struct udma_static_tr {
-	u8 elsize; /* RPSTR0 */
-	u16 elcnt; /* RPSTR0 */
-	u16 bstcnt; /* RPSTR1 */
-};
-
-#define K3_UDMA_MAX_RFLOWS		1024
-#define K3_UDMA_DEFAULT_RING_SIZE	16
-
-/* How SRC/DST tag should be updated by UDMA in the descriptor's Word 3 */
-#define UDMA_RFLOW_SRCTAG_NONE		0
-#define UDMA_RFLOW_SRCTAG_CFG_TAG	1
-#define UDMA_RFLOW_SRCTAG_FLOW_ID	2
-#define UDMA_RFLOW_SRCTAG_SRC_TAG	4
-
-#define UDMA_RFLOW_DSTTAG_NONE		0
-#define UDMA_RFLOW_DSTTAG_CFG_TAG	1
-#define UDMA_RFLOW_DSTTAG_FLOW_ID	2
-#define UDMA_RFLOW_DSTTAG_DST_TAG_LO	4
-#define UDMA_RFLOW_DSTTAG_DST_TAG_HI	5
-
-struct udma_chan;
-
-enum k3_dma_type {
-	DMA_TYPE_UDMA = 0,
-	DMA_TYPE_BCDMA,
-	DMA_TYPE_PKTDMA,
-};
-
-enum udma_mmr {
-	MMR_GCFG = 0,
-	MMR_BCHANRT,
-	MMR_RCHANRT,
-	MMR_TCHANRT,
-	MMR_LAST,
-};
-
 static const char * const mmr_names[] = {
 	[MMR_GCFG] = "gcfg",
 	[MMR_BCHANRT] = "bchanrt",
@@ -77,329 +40,7 @@
 	[MMR_TCHANRT] = "tchanrt",
 };
 
-struct udma_tchan {
-	void __iomem *reg_rt;
-
-	int id;
-	struct k3_ring *t_ring; /* Transmit ring */
-	struct k3_ring *tc_ring; /* Transmit Completion ring */
-	int tflow_id; /* applicable only for PKTDMA */
-
-};
-
-#define udma_bchan udma_tchan
-
-struct udma_rflow {
-	int id;
-	struct k3_ring *fd_ring; /* Free Descriptor ring */
-	struct k3_ring *r_ring; /* Receive ring */
-};
-
-struct udma_rchan {
-	void __iomem *reg_rt;
-
-	int id;
-};
-
-struct udma_oes_offsets {
-	/* K3 UDMA Output Event Offset */
-	u32 udma_rchan;
-
-	/* BCDMA Output Event Offsets */
-	u32 bcdma_bchan_data;
-	u32 bcdma_bchan_ring;
-	u32 bcdma_tchan_data;
-	u32 bcdma_tchan_ring;
-	u32 bcdma_rchan_data;
-	u32 bcdma_rchan_ring;
-
-	/* PKTDMA Output Event Offsets */
-	u32 pktdma_tchan_flow;
-	u32 pktdma_rchan_flow;
-};
-
-#define UDMA_FLAG_PDMA_ACC32		BIT(0)
-#define UDMA_FLAG_PDMA_BURST		BIT(1)
-#define UDMA_FLAG_TDTYPE		BIT(2)
-#define UDMA_FLAG_BURST_SIZE		BIT(3)
-#define UDMA_FLAGS_J7_CLASS		(UDMA_FLAG_PDMA_ACC32 | \
-					 UDMA_FLAG_PDMA_BURST | \
-					 UDMA_FLAG_TDTYPE | \
-					 UDMA_FLAG_BURST_SIZE)
-
-struct udma_match_data {
-	enum k3_dma_type type;
-	u32 psil_base;
-	bool enable_memcpy_support;
-	u32 flags;
-	u32 statictr_z_mask;
-	u8 burst_size[3];
-	struct udma_soc_data *soc_data;
-};
-
-struct udma_soc_data {
-	struct udma_oes_offsets oes;
-	u32 bcdma_trigger_event_offset;
-};
-
-struct udma_hwdesc {
-	size_t cppi5_desc_size;
-	void *cppi5_desc_vaddr;
-	dma_addr_t cppi5_desc_paddr;
-
-	/* TR descriptor internal pointers */
-	void *tr_req_base;
-	struct cppi5_tr_resp_t *tr_resp_base;
-};
-
-struct udma_rx_flush {
-	struct udma_hwdesc hwdescs[2];
-
-	size_t buffer_size;
-	void *buffer_vaddr;
-	dma_addr_t buffer_paddr;
-};
-
-struct udma_tpl {
-	u8 levels;
-	u32 start_idx[3];
-};
-
-struct udma_dev {
-	struct dma_device ddev;
-	struct device *dev;
-	void __iomem *mmrs[MMR_LAST];
-	const struct udma_match_data *match_data;
-	const struct udma_soc_data *soc_data;
-
-	struct udma_tpl bchan_tpl;
-	struct udma_tpl tchan_tpl;
-	struct udma_tpl rchan_tpl;
-
-	size_t desc_align; /* alignment to use for descriptors */
-
-	struct udma_tisci_rm tisci_rm;
-
-	struct k3_ringacc *ringacc;
-
-	struct work_struct purge_work;
-	struct list_head desc_to_purge;
-	spinlock_t lock;
-
-	struct udma_rx_flush rx_flush;
-
-	int bchan_cnt;
-	int tchan_cnt;
-	int echan_cnt;
-	int rchan_cnt;
-	int rflow_cnt;
-	int tflow_cnt;
-	unsigned long *bchan_map;
-	unsigned long *tchan_map;
-	unsigned long *rchan_map;
-	unsigned long *rflow_gp_map;
-	unsigned long *rflow_gp_map_allocated;
-	unsigned long *rflow_in_use;
-	unsigned long *tflow_map;
-
-	struct udma_bchan *bchans;
-	struct udma_tchan *tchans;
-	struct udma_rchan *rchans;
-	struct udma_rflow *rflows;
-
-	struct udma_chan *channels;
-	u32 psil_base;
-	u32 atype;
-	u32 asel;
-};
-
-struct udma_desc {
-	struct virt_dma_desc vd;
-
-	bool terminated;
-
-	enum dma_transfer_direction dir;
-
-	struct udma_static_tr static_tr;
-	u32 residue;
-
-	unsigned int sglen;
-	unsigned int desc_idx; /* Only used for cyclic in packet mode */
-	unsigned int tr_idx;
-
-	u32 metadata_size;
-	void *metadata; /* pointer to provided metadata buffer (EPIP, PSdata) */
-
-	unsigned int hwdesc_count;
-	struct udma_hwdesc hwdesc[];
-};
-
-enum udma_chan_state {
-	UDMA_CHAN_IS_IDLE = 0, /* not active, no teardown is in progress */
-	UDMA_CHAN_IS_ACTIVE, /* Normal operation */
-	UDMA_CHAN_IS_TERMINATING, /* channel is being terminated */
-};
-
-struct udma_tx_drain {
-	struct delayed_work work;
-	ktime_t tstamp;
-	u32 residue;
-};
-
-struct udma_chan_config {
-	bool pkt_mode; /* TR or packet */
-	bool needs_epib; /* EPIB is needed for the communication or not */
-	u32 psd_size; /* size of Protocol Specific Data */
-	u32 metadata_size; /* (needs_epib ? 16:0) + psd_size */
-	u32 hdesc_size; /* Size of a packet descriptor in packet mode */
-	bool notdpkt; /* Suppress sending TDC packet */
-	int remote_thread_id;
-	u32 atype;
-	u32 asel;
-	u32 src_thread;
-	u32 dst_thread;
-	enum psil_endpoint_type ep_type;
-	bool enable_acc32;
-	bool enable_burst;
-	enum udma_tp_level channel_tpl; /* Channel Throughput Level */
-
-	u32 tr_trigger_type;
-	unsigned long tx_flags;
-
-	/* PKDMA mapped channel */
-	int mapped_channel_id;
-	/* PKTDMA default tflow or rflow for mapped channel */
-	int default_flow_id;
-
-	enum dma_transfer_direction dir;
-};
-
-struct udma_chan {
-	struct virt_dma_chan vc;
-	struct dma_slave_config	cfg;
-	struct udma_dev *ud;
-	struct device *dma_dev;
-	struct udma_desc *desc;
-	struct udma_desc *terminated_desc;
-	struct udma_static_tr static_tr;
-	char *name;
-
-	struct udma_bchan *bchan;
-	struct udma_tchan *tchan;
-	struct udma_rchan *rchan;
-	struct udma_rflow *rflow;
-
-	bool psil_paired;
-
-	int irq_num_ring;
-	int irq_num_udma;
-
-	bool cyclic;
-	bool paused;
-
-	enum udma_chan_state state;
-	struct completion teardown_completed;
-
-	struct udma_tx_drain tx_drain;
-
-	/* Channel configuration parameters */
-	struct udma_chan_config config;
-	/* Channel configuration parameters (backup) */
-	struct udma_chan_config backup_config;
-
-	/* dmapool for packet mode descriptors */
-	bool use_dma_pool;
-	struct dma_pool *hdesc_pool;
-
-	u32 id;
-};
-
-static inline struct udma_dev *to_udma_dev(struct dma_device *d)
-{
-	return container_of(d, struct udma_dev, ddev);
-}
-
-static inline struct udma_chan *to_udma_chan(struct dma_chan *c)
-{
-	return container_of(c, struct udma_chan, vc.chan);
-}
-
-static inline struct udma_desc *to_udma_desc(struct dma_async_tx_descriptor *t)
-{
-	return container_of(t, struct udma_desc, vd.tx);
-}
-
-/* Generic register access functions */
-static inline u32 udma_read(void __iomem *base, int reg)
-{
-	return readl(base + reg);
-}
-
-static inline void udma_write(void __iomem *base, int reg, u32 val)
-{
-	writel(val, base + reg);
-}
-
-static inline void udma_update_bits(void __iomem *base, int reg,
-				    u32 mask, u32 val)
-{
-	u32 tmp, orig;
-
-	orig = readl(base + reg);
-	tmp = orig & ~mask;
-	tmp |= (val & mask);
-
-	if (tmp != orig)
-		writel(tmp, base + reg);
-}
-
-/* TCHANRT */
-static inline u32 udma_tchanrt_read(struct udma_chan *uc, int reg)
-{
-	if (!uc->tchan)
-		return 0;
-	return udma_read(uc->tchan->reg_rt, reg);
-}
-
-static inline void udma_tchanrt_write(struct udma_chan *uc, int reg, u32 val)
-{
-	if (!uc->tchan)
-		return;
-	udma_write(uc->tchan->reg_rt, reg, val);
-}
-
-static inline void udma_tchanrt_update_bits(struct udma_chan *uc, int reg,
-					    u32 mask, u32 val)
-{
-	if (!uc->tchan)
-		return;
-	udma_update_bits(uc->tchan->reg_rt, reg, mask, val);
-}
-
-/* RCHANRT */
-static inline u32 udma_rchanrt_read(struct udma_chan *uc, int reg)
-{
-	if (!uc->rchan)
-		return 0;
-	return udma_read(uc->rchan->reg_rt, reg);
-}
-
-static inline void udma_rchanrt_write(struct udma_chan *uc, int reg, u32 val)
-{
-	if (!uc->rchan)
-		return;
-	udma_write(uc->rchan->reg_rt, reg, val);
-}
-
-static inline void udma_rchanrt_update_bits(struct udma_chan *uc, int reg,
-					    u32 mask, u32 val)
-{
-	if (!uc->rchan)
-		return;
-	udma_update_bits(uc->rchan->reg_rt, reg, mask, val);
-}
-
-static int navss_psil_pair(struct udma_dev *ud, u32 src_thread, u32 dst_thread)
+int navss_psil_pair(struct udma_dev *ud, u32 src_thread, u32 dst_thread)
 {
 	struct udma_tisci_rm *tisci_rm = &ud->tisci_rm;
 
@@ -409,7 +50,7 @@
 					      src_thread, dst_thread);
 }
 
-static int navss_psil_unpair(struct udma_dev *ud, u32 src_thread,
+int navss_psil_unpair(struct udma_dev *ud, u32 src_thread,
 			     u32 dst_thread)
 {
 	struct udma_tisci_rm *tisci_rm = &ud->tisci_rm;
@@ -420,202 +61,6 @@
 						src_thread, dst_thread);
 }
 
-static void k3_configure_chan_coherency(struct dma_chan *chan, u32 asel)
-{
-	struct device *chan_dev = &chan->dev->device;
-
-	if (asel == 0) {
-		/* No special handling for the channel */
-		chan->dev->chan_dma_dev = false;
-
-		chan_dev->dma_coherent = false;
-		chan_dev->dma_parms = NULL;
-	} else if (asel == 14 || asel == 15) {
-		chan->dev->chan_dma_dev = true;
-
-		chan_dev->dma_coherent = true;
-		dma_coerce_mask_and_coherent(chan_dev, DMA_BIT_MASK(48));
-		chan_dev->dma_parms = chan_dev->parent->dma_parms;
-	} else {
-		dev_warn(chan->device->dev, "Invalid ASEL value: %u\n", asel);
-
-		chan_dev->dma_coherent = false;
-		chan_dev->dma_parms = NULL;
-	}
-}
-
-static u8 udma_get_chan_tpl_index(struct udma_tpl *tpl_map, int chan_id)
-{
-	int i;
-
-	for (i = 0; i < tpl_map->levels; i++) {
-		if (chan_id >= tpl_map->start_idx[i])
-			return i;
-	}
-
-	return 0;
-}
-
-static void udma_reset_uchan(struct udma_chan *uc)
-{
-	memset(&uc->config, 0, sizeof(uc->config));
-	uc->config.remote_thread_id = -1;
-	uc->config.mapped_channel_id = -1;
-	uc->config.default_flow_id = -1;
-	uc->state = UDMA_CHAN_IS_IDLE;
-}
-
-static void udma_dump_chan_stdata(struct udma_chan *uc)
-{
-	struct device *dev = uc->ud->dev;
-	u32 offset;
-	int i;
-
-	if (uc->config.dir == DMA_MEM_TO_DEV || uc->config.dir == DMA_MEM_TO_MEM) {
-		dev_dbg(dev, "TCHAN State data:\n");
-		for (i = 0; i < 32; i++) {
-			offset = UDMA_CHAN_RT_STDATA_REG + i * 4;
-			dev_dbg(dev, "TRT_STDATA[%02d]: 0x%08x\n", i,
-				udma_tchanrt_read(uc, offset));
-		}
-	}
-
-	if (uc->config.dir == DMA_DEV_TO_MEM || uc->config.dir == DMA_MEM_TO_MEM) {
-		dev_dbg(dev, "RCHAN State data:\n");
-		for (i = 0; i < 32; i++) {
-			offset = UDMA_CHAN_RT_STDATA_REG + i * 4;
-			dev_dbg(dev, "RRT_STDATA[%02d]: 0x%08x\n", i,
-				udma_rchanrt_read(uc, offset));
-		}
-	}
-}
-
-static inline dma_addr_t udma_curr_cppi5_desc_paddr(struct udma_desc *d,
-						    int idx)
-{
-	return d->hwdesc[idx].cppi5_desc_paddr;
-}
-
-static inline void *udma_curr_cppi5_desc_vaddr(struct udma_desc *d, int idx)
-{
-	return d->hwdesc[idx].cppi5_desc_vaddr;
-}
-
-static struct udma_desc *udma_udma_desc_from_paddr(struct udma_chan *uc,
-						   dma_addr_t paddr)
-{
-	struct udma_desc *d = uc->terminated_desc;
-
-	if (d) {
-		dma_addr_t desc_paddr = udma_curr_cppi5_desc_paddr(d,
-								   d->desc_idx);
-
-		if (desc_paddr != paddr)
-			d = NULL;
-	}
-
-	if (!d) {
-		d = uc->desc;
-		if (d) {
-			dma_addr_t desc_paddr = udma_curr_cppi5_desc_paddr(d,
-								d->desc_idx);
-
-			if (desc_paddr != paddr)
-				d = NULL;
-		}
-	}
-
-	return d;
-}
-
-static void udma_free_hwdesc(struct udma_chan *uc, struct udma_desc *d)
-{
-	if (uc->use_dma_pool) {
-		int i;
-
-		for (i = 0; i < d->hwdesc_count; i++) {
-			if (!d->hwdesc[i].cppi5_desc_vaddr)
-				continue;
-
-			dma_pool_free(uc->hdesc_pool,
-				      d->hwdesc[i].cppi5_desc_vaddr,
-				      d->hwdesc[i].cppi5_desc_paddr);
-
-			d->hwdesc[i].cppi5_desc_vaddr = NULL;
-		}
-	} else if (d->hwdesc[0].cppi5_desc_vaddr) {
-		dma_free_coherent(uc->dma_dev, d->hwdesc[0].cppi5_desc_size,
-				  d->hwdesc[0].cppi5_desc_vaddr,
-				  d->hwdesc[0].cppi5_desc_paddr);
-
-		d->hwdesc[0].cppi5_desc_vaddr = NULL;
-	}
-}
-
-static void udma_purge_desc_work(struct work_struct *work)
-{
-	struct udma_dev *ud = container_of(work, typeof(*ud), purge_work);
-	struct virt_dma_desc *vd, *_vd;
-	unsigned long flags;
-	LIST_HEAD(head);
-
-	spin_lock_irqsave(&ud->lock, flags);
-	list_splice_tail_init(&ud->desc_to_purge, &head);
-	spin_unlock_irqrestore(&ud->lock, flags);
-
-	list_for_each_entry_safe(vd, _vd, &head, node) {
-		struct udma_chan *uc = to_udma_chan(vd->tx.chan);
-		struct udma_desc *d = to_udma_desc(&vd->tx);
-
-		udma_free_hwdesc(uc, d);
-		list_del(&vd->node);
-		kfree(d);
-	}
-
-	/* If more to purge, schedule the work again */
-	if (!list_empty(&ud->desc_to_purge))
-		schedule_work(&ud->purge_work);
-}
-
-static void udma_desc_free(struct virt_dma_desc *vd)
-{
-	struct udma_dev *ud = to_udma_dev(vd->tx.chan->device);
-	struct udma_chan *uc = to_udma_chan(vd->tx.chan);
-	struct udma_desc *d = to_udma_desc(&vd->tx);
-	unsigned long flags;
-
-	if (uc->terminated_desc == d)
-		uc->terminated_desc = NULL;
-
-	if (uc->use_dma_pool) {
-		udma_free_hwdesc(uc, d);
-		kfree(d);
-		return;
-	}
-
-	spin_lock_irqsave(&ud->lock, flags);
-	list_add_tail(&vd->node, &ud->desc_to_purge);
-	spin_unlock_irqrestore(&ud->lock, flags);
-
-	schedule_work(&ud->purge_work);
-}
-
-static bool udma_is_chan_running(struct udma_chan *uc)
-{
-	u32 trt_ctl = 0;
-	u32 rrt_ctl = 0;
-
-	if (uc->tchan)
-		trt_ctl = udma_tchanrt_read(uc, UDMA_CHAN_RT_CTL_REG);
-	if (uc->rchan)
-		rrt_ctl = udma_rchanrt_read(uc, UDMA_CHAN_RT_CTL_REG);
-
-	if (trt_ctl & UDMA_CHAN_RT_CTL_EN || rrt_ctl & UDMA_CHAN_RT_CTL_EN)
-		return true;
-
-	return false;
-}
-
 static bool udma_is_chan_paused(struct udma_chan *uc)
 {
 	u32 val, pause_mask;
@@ -643,122 +88,6 @@
 	return false;
 }
 
-static inline dma_addr_t udma_get_rx_flush_hwdesc_paddr(struct udma_chan *uc)
-{
-	return uc->ud->rx_flush.hwdescs[uc->config.pkt_mode].cppi5_desc_paddr;
-}
-
-static int udma_push_to_ring(struct udma_chan *uc, int idx)
-{
-	struct udma_desc *d = uc->desc;
-	struct k3_ring *ring = NULL;
-	dma_addr_t paddr;
-
-	switch (uc->config.dir) {
-	case DMA_DEV_TO_MEM:
-		ring = uc->rflow->fd_ring;
-		break;
-	case DMA_MEM_TO_DEV:
-	case DMA_MEM_TO_MEM:
-		ring = uc->tchan->t_ring;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	/* RX flush packet: idx == -1 is only passed in case of DEV_TO_MEM */
-	if (idx == -1) {
-		paddr = udma_get_rx_flush_hwdesc_paddr(uc);
-	} else {
-		paddr = udma_curr_cppi5_desc_paddr(d, idx);
-
-		wmb(); /* Ensure that writes are not moved over this point */
-	}
-
-	return k3_ringacc_ring_push(ring, &paddr);
-}
-
-static bool udma_desc_is_rx_flush(struct udma_chan *uc, dma_addr_t addr)
-{
-	if (uc->config.dir != DMA_DEV_TO_MEM)
-		return false;
-
-	if (addr == udma_get_rx_flush_hwdesc_paddr(uc))
-		return true;
-
-	return false;
-}
-
-static int udma_pop_from_ring(struct udma_chan *uc, dma_addr_t *addr)
-{
-	struct k3_ring *ring = NULL;
-	int ret;
-
-	switch (uc->config.dir) {
-	case DMA_DEV_TO_MEM:
-		ring = uc->rflow->r_ring;
-		break;
-	case DMA_MEM_TO_DEV:
-	case DMA_MEM_TO_MEM:
-		ring = uc->tchan->tc_ring;
-		break;
-	default:
-		return -ENOENT;
-	}
-
-	ret = k3_ringacc_ring_pop(ring, addr);
-	if (ret)
-		return ret;
-
-	rmb(); /* Ensure that reads are not moved before this point */
-
-	/* Teardown completion */
-	if (cppi5_desc_is_tdcm(*addr))
-		return 0;
-
-	/* Check for flush descriptor */
-	if (udma_desc_is_rx_flush(uc, *addr))
-		return -ENOENT;
-
-	return 0;
-}
-
-static void udma_reset_rings(struct udma_chan *uc)
-{
-	struct k3_ring *ring1 = NULL;
-	struct k3_ring *ring2 = NULL;
-
-	switch (uc->config.dir) {
-	case DMA_DEV_TO_MEM:
-		if (uc->rchan) {
-			ring1 = uc->rflow->fd_ring;
-			ring2 = uc->rflow->r_ring;
-		}
-		break;
-	case DMA_MEM_TO_DEV:
-	case DMA_MEM_TO_MEM:
-		if (uc->tchan) {
-			ring1 = uc->tchan->t_ring;
-			ring2 = uc->tchan->tc_ring;
-		}
-		break;
-	default:
-		break;
-	}
-
-	if (ring1)
-		k3_ringacc_ring_reset_dma(ring1,
-					  k3_ringacc_ring_get_occ(ring1));
-	if (ring2)
-		k3_ringacc_ring_reset(ring2);
-
-	/* make sure we are not leaking memory by stalled descriptor */
-	if (uc->terminated_desc) {
-		udma_desc_free(&uc->terminated_desc->vd);
-		uc->terminated_desc = NULL;
-	}
-}
-
 static void udma_decrement_byte_counters(struct udma_chan *uc, u32 val)
 {
 	if (uc->desc->dir == DMA_DEV_TO_MEM) {
@@ -860,40 +189,6 @@
 	return 0;
 }
 
-static void udma_start_desc(struct udma_chan *uc)
-{
-	struct udma_chan_config *ucc = &uc->config;
-
-	if (uc->ud->match_data->type == DMA_TYPE_UDMA && ucc->pkt_mode &&
-	    (uc->cyclic || ucc->dir == DMA_DEV_TO_MEM)) {
-		int i;
-
-		/*
-		 * UDMA only: Push all descriptors to ring for packet mode
-		 * cyclic or RX
-		 * PKTDMA supports pre-linked descriptor and cyclic is not
-		 * supported
-		 */
-		for (i = 0; i < uc->desc->sglen; i++)
-			udma_push_to_ring(uc, i);
-	} else {
-		udma_push_to_ring(uc, 0);
-	}
-}
-
-static bool udma_chan_needs_reconfiguration(struct udma_chan *uc)
-{
-	/* Only PDMAs have staticTR */
-	if (uc->config.ep_type == PSIL_EP_NATIVE)
-		return false;
-
-	/* Check if the staticTR configuration has changed for TX */
-	if (memcmp(&uc->static_tr, &uc->desc->static_tr, sizeof(uc->static_tr)))
-		return true;
-
-	return false;
-}
-
 static int udma_start(struct udma_chan *uc)
 {
 	struct virt_dma_desc *vd = vchan_next_desc(&uc->vc);
@@ -1038,24 +333,6 @@
 	return 0;
 }
 
-static void udma_cyclic_packet_elapsed(struct udma_chan *uc)
-{
-	struct udma_desc *d = uc->desc;
-	struct cppi5_host_desc_t *h_desc;
-
-	h_desc = d->hwdesc[d->desc_idx].cppi5_desc_vaddr;
-	cppi5_hdesc_reset_to_original(h_desc);
-	udma_push_to_ring(uc, d->desc_idx);
-	d->desc_idx = (d->desc_idx + 1) % d->sglen;
-}
-
-static inline void udma_fetch_epib(struct udma_chan *uc, struct udma_desc *d)
-{
-	struct cppi5_host_desc_t *h_desc = d->hwdesc[0].cppi5_desc_vaddr;
-
-	memcpy(d->metadata, h_desc->epib, d->metadata_size);
-}
-
 static bool udma_is_desc_really_done(struct udma_chan *uc, struct udma_desc *d)
 {
 	u32 peer_bcnt, bcnt;
@@ -1083,75 +360,6 @@
 	return true;
 }
 
-static void udma_check_tx_completion(struct work_struct *work)
-{
-	struct udma_chan *uc = container_of(work, typeof(*uc),
-					    tx_drain.work.work);
-	bool desc_done = true;
-	u32 residue_diff;
-	ktime_t time_diff;
-	unsigned long delay;
-	unsigned long flags;
-
-	while (1) {
-		spin_lock_irqsave(&uc->vc.lock, flags);
-
-		if (uc->desc) {
-			/* Get previous residue and time stamp */
-			residue_diff = uc->tx_drain.residue;
-			time_diff = uc->tx_drain.tstamp;
-			/*
-			 * Get current residue and time stamp or see if
-			 * transfer is complete
-			 */
-			desc_done = udma_is_desc_really_done(uc, uc->desc);
-		}
-
-		if (!desc_done) {
-			/*
-			 * Find the time delta and residue delta w.r.t
-			 * previous poll
-			 */
-			time_diff = ktime_sub(uc->tx_drain.tstamp,
-					      time_diff) + 1;
-			residue_diff -= uc->tx_drain.residue;
-			if (residue_diff) {
-				/*
-				 * Try to guess when we should check
-				 * next time by calculating rate at
-				 * which data is being drained at the
-				 * peer device
-				 */
-				delay = (time_diff / residue_diff) *
-					uc->tx_drain.residue;
-			} else {
-				/* No progress, check again in 1 second  */
-				schedule_delayed_work(&uc->tx_drain.work, HZ);
-				break;
-			}
-
-			spin_unlock_irqrestore(&uc->vc.lock, flags);
-
-			usleep_range(ktime_to_us(delay),
-				     ktime_to_us(delay) + 10);
-			continue;
-		}
-
-		if (uc->desc) {
-			struct udma_desc *d = uc->desc;
-
-			udma_decrement_byte_counters(uc, d->residue);
-			udma_start(uc);
-			vchan_cookie_complete(&d->vd);
-			break;
-		}
-
-		break;
-	}
-
-	spin_unlock_irqrestore(&uc->vc.lock, flags);
-}
-
 static irqreturn_t udma_ring_irq_handler(int irq, void *data)
 {
 	struct udma_chan *uc = data;
@@ -1242,135 +450,6 @@
 	return IRQ_HANDLED;
 }
 
-/**
- * __udma_alloc_gp_rflow_range - alloc range of GP RX flows
- * @ud: UDMA device
- * @from: Start the search from this flow id number
- * @cnt: Number of consecutive flow ids to allocate
- *
- * Allocate range of RX flow ids for future use, those flows can be requested
- * only using explicit flow id number. if @from is set to -1 it will try to find
- * first free range. if @from is positive value it will force allocation only
- * of the specified range of flows.
- *
- * Returns -ENOMEM if can't find free range.
- * -EEXIST if requested range is busy.
- * -EINVAL if wrong input values passed.
- * Returns flow id on success.
- */
-static int __udma_alloc_gp_rflow_range(struct udma_dev *ud, int from, int cnt)
-{
-	int start, tmp_from;
-	DECLARE_BITMAP(tmp, K3_UDMA_MAX_RFLOWS);
-
-	tmp_from = from;
-	if (tmp_from < 0)
-		tmp_from = ud->rchan_cnt;
-	/* default flows can't be allocated and accessible only by id */
-	if (tmp_from < ud->rchan_cnt)
-		return -EINVAL;
-
-	if (tmp_from + cnt > ud->rflow_cnt)
-		return -EINVAL;
-
-	bitmap_or(tmp, ud->rflow_gp_map, ud->rflow_gp_map_allocated,
-		  ud->rflow_cnt);
-
-	start = bitmap_find_next_zero_area(tmp,
-					   ud->rflow_cnt,
-					   tmp_from, cnt, 0);
-	if (start >= ud->rflow_cnt)
-		return -ENOMEM;
-
-	if (from >= 0 && start != from)
-		return -EEXIST;
-
-	bitmap_set(ud->rflow_gp_map_allocated, start, cnt);
-	return start;
-}
-
-static int __udma_free_gp_rflow_range(struct udma_dev *ud, int from, int cnt)
-{
-	if (from < ud->rchan_cnt)
-		return -EINVAL;
-	if (from + cnt > ud->rflow_cnt)
-		return -EINVAL;
-
-	bitmap_clear(ud->rflow_gp_map_allocated, from, cnt);
-	return 0;
-}
-
-static struct udma_rflow *__udma_get_rflow(struct udma_dev *ud, int id)
-{
-	/*
-	 * Attempt to request rflow by ID can be made for any rflow
-	 * if not in use with assumption that caller knows what's doing.
-	 * TI-SCI FW will perform additional permission check ant way, it's
-	 * safe
-	 */
-
-	if (id < 0 || id >= ud->rflow_cnt)
-		return ERR_PTR(-ENOENT);
-
-	if (test_bit(id, ud->rflow_in_use))
-		return ERR_PTR(-ENOENT);
-
-	if (ud->rflow_gp_map) {
-		/* GP rflow has to be allocated first */
-		if (!test_bit(id, ud->rflow_gp_map) &&
-		    !test_bit(id, ud->rflow_gp_map_allocated))
-			return ERR_PTR(-EINVAL);
-	}
-
-	dev_dbg(ud->dev, "get rflow%d\n", id);
-	set_bit(id, ud->rflow_in_use);
-	return &ud->rflows[id];
-}
-
-static void __udma_put_rflow(struct udma_dev *ud, struct udma_rflow *rflow)
-{
-	if (!test_bit(rflow->id, ud->rflow_in_use)) {
-		dev_err(ud->dev, "attempt to put unused rflow%d\n", rflow->id);
-		return;
-	}
-
-	dev_dbg(ud->dev, "put rflow%d\n", rflow->id);
-	clear_bit(rflow->id, ud->rflow_in_use);
-}
-
-#define UDMA_RESERVE_RESOURCE(res)					\
-static struct udma_##res *__udma_reserve_##res(struct udma_dev *ud,	\
-					       enum udma_tp_level tpl,	\
-					       int id)			\
-{									\
-	if (id >= 0) {							\
-		if (test_bit(id, ud->res##_map)) {			\
-			dev_err(ud->dev, "res##%d is in use\n", id);	\
-			return ERR_PTR(-ENOENT);			\
-		}							\
-	} else {							\
-		int start;						\
-									\
-		if (tpl >= ud->res##_tpl.levels)			\
-			tpl = ud->res##_tpl.levels - 1;			\
-									\
-		start = ud->res##_tpl.start_idx[tpl];			\
-									\
-		id = find_next_zero_bit(ud->res##_map, ud->res##_cnt,	\
-					start);				\
-		if (id == ud->res##_cnt) {				\
-			return ERR_PTR(-ENOENT);			\
-		}							\
-	}								\
-									\
-	set_bit(id, ud->res##_map);					\
-	return &ud->res##s[id];						\
-}
-
-UDMA_RESERVE_RESOURCE(bchan);
-UDMA_RESERVE_RESOURCE(tchan);
-UDMA_RESERVE_RESOURCE(rchan);
-
 static int bcdma_get_bchan(struct udma_chan *uc)
 {
 	struct udma_dev *ud = uc->ud;
@@ -1404,223 +483,6 @@
 	return 0;
 }
 
-static int udma_get_tchan(struct udma_chan *uc)
-{
-	struct udma_dev *ud = uc->ud;
-	int ret;
-
-	if (uc->tchan) {
-		dev_dbg(ud->dev, "chan%d: already have tchan%d allocated\n",
-			uc->id, uc->tchan->id);
-		return 0;
-	}
-
-	/*
-	 * mapped_channel_id is -1 for UDMA, BCDMA and PKTDMA unmapped channels.
-	 * For PKTDMA mapped channels it is configured to a channel which must
-	 * be used to service the peripheral.
-	 */
-	uc->tchan = __udma_reserve_tchan(ud, uc->config.channel_tpl,
-					 uc->config.mapped_channel_id);
-	if (IS_ERR(uc->tchan)) {
-		ret = PTR_ERR(uc->tchan);
-		uc->tchan = NULL;
-		return ret;
-	}
-
-	if (ud->tflow_cnt) {
-		int tflow_id;
-
-		/* Only PKTDMA have support for tx flows */
-		if (uc->config.default_flow_id >= 0)
-			tflow_id = uc->config.default_flow_id;
-		else
-			tflow_id = uc->tchan->id;
-
-		if (test_bit(tflow_id, ud->tflow_map)) {
-			dev_err(ud->dev, "tflow%d is in use\n", tflow_id);
-			clear_bit(uc->tchan->id, ud->tchan_map);
-			uc->tchan = NULL;
-			return -ENOENT;
-		}
-
-		uc->tchan->tflow_id = tflow_id;
-		set_bit(tflow_id, ud->tflow_map);
-	} else {
-		uc->tchan->tflow_id = -1;
-	}
-
-	return 0;
-}
-
-static int udma_get_rchan(struct udma_chan *uc)
-{
-	struct udma_dev *ud = uc->ud;
-	int ret;
-
-	if (uc->rchan) {
-		dev_dbg(ud->dev, "chan%d: already have rchan%d allocated\n",
-			uc->id, uc->rchan->id);
-		return 0;
-	}
-
-	/*
-	 * mapped_channel_id is -1 for UDMA, BCDMA and PKTDMA unmapped channels.
-	 * For PKTDMA mapped channels it is configured to a channel which must
-	 * be used to service the peripheral.
-	 */
-	uc->rchan = __udma_reserve_rchan(ud, uc->config.channel_tpl,
-					 uc->config.mapped_channel_id);
-	if (IS_ERR(uc->rchan)) {
-		ret = PTR_ERR(uc->rchan);
-		uc->rchan = NULL;
-		return ret;
-	}
-
-	return 0;
-}
-
-static int udma_get_chan_pair(struct udma_chan *uc)
-{
-	struct udma_dev *ud = uc->ud;
-	int chan_id, end;
-
-	if ((uc->tchan && uc->rchan) && uc->tchan->id == uc->rchan->id) {
-		dev_info(ud->dev, "chan%d: already have %d pair allocated\n",
-			 uc->id, uc->tchan->id);
-		return 0;
-	}
-
-	if (uc->tchan) {
-		dev_err(ud->dev, "chan%d: already have tchan%d allocated\n",
-			uc->id, uc->tchan->id);
-		return -EBUSY;
-	} else if (uc->rchan) {
-		dev_err(ud->dev, "chan%d: already have rchan%d allocated\n",
-			uc->id, uc->rchan->id);
-		return -EBUSY;
-	}
-
-	/* Can be optimized, but let's have it like this for now */
-	end = min(ud->tchan_cnt, ud->rchan_cnt);
-	/*
-	 * Try to use the highest TPL channel pair for MEM_TO_MEM channels
-	 * Note: in UDMAP the channel TPL is symmetric between tchan and rchan
-	 */
-	chan_id = ud->tchan_tpl.start_idx[ud->tchan_tpl.levels - 1];
-	for (; chan_id < end; chan_id++) {
-		if (!test_bit(chan_id, ud->tchan_map) &&
-		    !test_bit(chan_id, ud->rchan_map))
-			break;
-	}
-
-	if (chan_id == end)
-		return -ENOENT;
-
-	set_bit(chan_id, ud->tchan_map);
-	set_bit(chan_id, ud->rchan_map);
-	uc->tchan = &ud->tchans[chan_id];
-	uc->rchan = &ud->rchans[chan_id];
-
-	/* UDMA does not use tx flows */
-	uc->tchan->tflow_id = -1;
-
-	return 0;
-}
-
-static int udma_get_rflow(struct udma_chan *uc, int flow_id)
-{
-	struct udma_dev *ud = uc->ud;
-	int ret;
-
-	if (!uc->rchan) {
-		dev_err(ud->dev, "chan%d: does not have rchan??\n", uc->id);
-		return -EINVAL;
-	}
-
-	if (uc->rflow) {
-		dev_dbg(ud->dev, "chan%d: already have rflow%d allocated\n",
-			uc->id, uc->rflow->id);
-		return 0;
-	}
-
-	uc->rflow = __udma_get_rflow(ud, flow_id);
-	if (IS_ERR(uc->rflow)) {
-		ret = PTR_ERR(uc->rflow);
-		uc->rflow = NULL;
-		return ret;
-	}
-
-	return 0;
-}
-
-static void bcdma_put_bchan(struct udma_chan *uc)
-{
-	struct udma_dev *ud = uc->ud;
-
-	if (uc->bchan) {
-		dev_dbg(ud->dev, "chan%d: put bchan%d\n", uc->id,
-			uc->bchan->id);
-		clear_bit(uc->bchan->id, ud->bchan_map);
-		uc->bchan = NULL;
-		uc->tchan = NULL;
-	}
-}
-
-static void udma_put_rchan(struct udma_chan *uc)
-{
-	struct udma_dev *ud = uc->ud;
-
-	if (uc->rchan) {
-		dev_dbg(ud->dev, "chan%d: put rchan%d\n", uc->id,
-			uc->rchan->id);
-		clear_bit(uc->rchan->id, ud->rchan_map);
-		uc->rchan = NULL;
-	}
-}
-
-static void udma_put_tchan(struct udma_chan *uc)
-{
-	struct udma_dev *ud = uc->ud;
-
-	if (uc->tchan) {
-		dev_dbg(ud->dev, "chan%d: put tchan%d\n", uc->id,
-			uc->tchan->id);
-		clear_bit(uc->tchan->id, ud->tchan_map);
-
-		if (uc->tchan->tflow_id >= 0)
-			clear_bit(uc->tchan->tflow_id, ud->tflow_map);
-
-		uc->tchan = NULL;
-	}
-}
-
-static void udma_put_rflow(struct udma_chan *uc)
-{
-	struct udma_dev *ud = uc->ud;
-
-	if (uc->rflow) {
-		dev_dbg(ud->dev, "chan%d: put rflow%d\n", uc->id,
-			uc->rflow->id);
-		__udma_put_rflow(ud, uc->rflow);
-		uc->rflow = NULL;
-	}
-}
-
-static void bcdma_free_bchan_resources(struct udma_chan *uc)
-{
-	if (!uc->bchan)
-		return;
-
-	k3_ringacc_ring_free(uc->bchan->tc_ring);
-	k3_ringacc_ring_free(uc->bchan->t_ring);
-	uc->bchan->tc_ring = NULL;
-	uc->bchan->t_ring = NULL;
-	k3_configure_chan_coherency(&uc->vc.chan, 0);
-
-	bcdma_put_bchan(uc);
-}
-
 static int bcdma_alloc_bchan_resources(struct udma_chan *uc)
 {
 	struct k3_ring_cfg ring_cfg;
@@ -1666,19 +528,6 @@
 	return ret;
 }
 
-static void udma_free_tx_resources(struct udma_chan *uc)
-{
-	if (!uc->tchan)
-		return;
-
-	k3_ringacc_ring_free(uc->tchan->t_ring);
-	k3_ringacc_ring_free(uc->tchan->tc_ring);
-	uc->tchan->t_ring = NULL;
-	uc->tchan->tc_ring = NULL;
-
-	udma_put_tchan(uc);
-}
-
 static int udma_alloc_tx_resources(struct udma_chan *uc)
 {
 	struct k3_ring_cfg ring_cfg;
@@ -1736,25 +585,6 @@
 	return ret;
 }
 
-static void udma_free_rx_resources(struct udma_chan *uc)
-{
-	if (!uc->rchan)
-		return;
-
-	if (uc->rflow) {
-		struct udma_rflow *rflow = uc->rflow;
-
-		k3_ringacc_ring_free(rflow->fd_ring);
-		k3_ringacc_ring_free(rflow->r_ring);
-		rflow->fd_ring = NULL;
-		rflow->r_ring = NULL;
-
-		udma_put_rflow(uc);
-	}
-
-	udma_put_rchan(uc);
-}
-
 static int udma_alloc_rx_resources(struct udma_chan *uc)
 {
 	struct udma_dev *ud = uc->ud;
@@ -2748,1079 +1578,6 @@
 	return ret;
 }
 
-static int udma_slave_config(struct dma_chan *chan,
-			     struct dma_slave_config *cfg)
-{
-	struct udma_chan *uc = to_udma_chan(chan);
-
-	memcpy(&uc->cfg, cfg, sizeof(uc->cfg));
-
-	return 0;
-}
-
-static struct udma_desc *udma_alloc_tr_desc(struct udma_chan *uc,
-					    size_t tr_size, int tr_count,
-					    enum dma_transfer_direction dir)
-{
-	struct udma_hwdesc *hwdesc;
-	struct cppi5_desc_hdr_t *tr_desc;
-	struct udma_desc *d;
-	u32 reload_count = 0;
-	u32 ring_id;
-
-	switch (tr_size) {
-	case 16:
-	case 32:
-	case 64:
-	case 128:
-		break;
-	default:
-		dev_err(uc->ud->dev, "Unsupported TR size of %zu\n", tr_size);
-		return NULL;
-	}
-
-	/* We have only one descriptor containing multiple TRs */
-	d = kzalloc(sizeof(*d) + sizeof(d->hwdesc[0]), GFP_NOWAIT);
-	if (!d)
-		return NULL;
-
-	d->sglen = tr_count;
-
-	d->hwdesc_count = 1;
-	hwdesc = &d->hwdesc[0];
-
-	/* Allocate memory for DMA ring descriptor */
-	if (uc->use_dma_pool) {
-		hwdesc->cppi5_desc_size = uc->config.hdesc_size;
-		hwdesc->cppi5_desc_vaddr = dma_pool_zalloc(uc->hdesc_pool,
-						GFP_NOWAIT,
-						&hwdesc->cppi5_desc_paddr);
-	} else {
-		hwdesc->cppi5_desc_size = cppi5_trdesc_calc_size(tr_size,
-								 tr_count);
-		hwdesc->cppi5_desc_size = ALIGN(hwdesc->cppi5_desc_size,
-						uc->ud->desc_align);
-		hwdesc->cppi5_desc_vaddr = dma_alloc_coherent(uc->ud->dev,
-						hwdesc->cppi5_desc_size,
-						&hwdesc->cppi5_desc_paddr,
-						GFP_NOWAIT);
-	}
-
-	if (!hwdesc->cppi5_desc_vaddr) {
-		kfree(d);
-		return NULL;
-	}
-
-	/* Start of the TR req records */
-	hwdesc->tr_req_base = hwdesc->cppi5_desc_vaddr + tr_size;
-	/* Start address of the TR response array */
-	hwdesc->tr_resp_base = hwdesc->tr_req_base + tr_size * tr_count;
-
-	tr_desc = hwdesc->cppi5_desc_vaddr;
-
-	if (uc->cyclic)
-		reload_count = CPPI5_INFO0_TRDESC_RLDCNT_INFINITE;
-
-	if (dir == DMA_DEV_TO_MEM)
-		ring_id = k3_ringacc_get_ring_id(uc->rflow->r_ring);
-	else
-		ring_id = k3_ringacc_get_ring_id(uc->tchan->tc_ring);
-
-	cppi5_trdesc_init(tr_desc, tr_count, tr_size, 0, reload_count);
-	cppi5_desc_set_pktids(tr_desc, uc->id,
-			      CPPI5_INFO1_DESC_FLOWID_DEFAULT);
-	cppi5_desc_set_retpolicy(tr_desc, 0, ring_id);
-
-	return d;
-}
-
-/**
- * udma_get_tr_counters - calculate TR counters for a given length
- * @len: Length of the trasnfer
- * @align_to: Preferred alignment
- * @tr0_cnt0: First TR icnt0
- * @tr0_cnt1: First TR icnt1
- * @tr1_cnt0: Second (if used) TR icnt0
- *
- * For len < SZ_64K only one TR is enough, tr1_cnt0 is not updated
- * For len >= SZ_64K two TRs are used in a simple way:
- * First TR: SZ_64K-alignment blocks (tr0_cnt0, tr0_cnt1)
- * Second TR: the remaining length (tr1_cnt0)
- *
- * Returns the number of TRs the length needs (1 or 2)
- * -EINVAL if the length can not be supported
- */
-static int udma_get_tr_counters(size_t len, unsigned long align_to,
-				u16 *tr0_cnt0, u16 *tr0_cnt1, u16 *tr1_cnt0)
-{
-	if (len < SZ_64K) {
-		*tr0_cnt0 = len;
-		*tr0_cnt1 = 1;
-
-		return 1;
-	}
-
-	if (align_to > 3)
-		align_to = 3;
-
-realign:
-	*tr0_cnt0 = SZ_64K - BIT(align_to);
-	if (len / *tr0_cnt0 >= SZ_64K) {
-		if (align_to) {
-			align_to--;
-			goto realign;
-		}
-		return -EINVAL;
-	}
-
-	*tr0_cnt1 = len / *tr0_cnt0;
-	*tr1_cnt0 = len % *tr0_cnt0;
-
-	return 2;
-}
-
-static struct udma_desc *
-udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl,
-		      unsigned int sglen, enum dma_transfer_direction dir,
-		      unsigned long tx_flags, void *context)
-{
-	struct scatterlist *sgent;
-	struct udma_desc *d;
-	struct cppi5_tr_type1_t *tr_req = NULL;
-	u16 tr0_cnt0, tr0_cnt1, tr1_cnt0;
-	unsigned int i;
-	size_t tr_size;
-	int num_tr = 0;
-	int tr_idx = 0;
-	u64 asel;
-
-	/* estimate the number of TRs we will need */
-	for_each_sg(sgl, sgent, sglen, i) {
-		if (sg_dma_len(sgent) < SZ_64K)
-			num_tr++;
-		else
-			num_tr += 2;
-	}
-
-	/* Now allocate and setup the descriptor. */
-	tr_size = sizeof(struct cppi5_tr_type1_t);
-	d = udma_alloc_tr_desc(uc, tr_size, num_tr, dir);
-	if (!d)
-		return NULL;
-
-	d->sglen = sglen;
-
-	if (uc->ud->match_data->type == DMA_TYPE_UDMA)
-		asel = 0;
-	else
-		asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT;
-
-	tr_req = d->hwdesc[0].tr_req_base;
-	for_each_sg(sgl, sgent, sglen, i) {
-		dma_addr_t sg_addr = sg_dma_address(sgent);
-
-		num_tr = udma_get_tr_counters(sg_dma_len(sgent), __ffs(sg_addr),
-					      &tr0_cnt0, &tr0_cnt1, &tr1_cnt0);
-		if (num_tr < 0) {
-			dev_err(uc->ud->dev, "size %u is not supported\n",
-				sg_dma_len(sgent));
-			udma_free_hwdesc(uc, d);
-			kfree(d);
-			return NULL;
-		}
-
-		cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE1, false,
-			      false, CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
-		cppi5_tr_csf_set(&tr_req[tr_idx].flags, CPPI5_TR_CSF_SUPR_EVT);
-
-		sg_addr |= asel;
-		tr_req[tr_idx].addr = sg_addr;
-		tr_req[tr_idx].icnt0 = tr0_cnt0;
-		tr_req[tr_idx].icnt1 = tr0_cnt1;
-		tr_req[tr_idx].dim1 = tr0_cnt0;
-		tr_idx++;
-
-		if (num_tr == 2) {
-			cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE1,
-				      false, false,
-				      CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
-			cppi5_tr_csf_set(&tr_req[tr_idx].flags,
-					 CPPI5_TR_CSF_SUPR_EVT);
-
-			tr_req[tr_idx].addr = sg_addr + tr0_cnt1 * tr0_cnt0;
-			tr_req[tr_idx].icnt0 = tr1_cnt0;
-			tr_req[tr_idx].icnt1 = 1;
-			tr_req[tr_idx].dim1 = tr1_cnt0;
-			tr_idx++;
-		}
-
-		d->residue += sg_dma_len(sgent);
-	}
-
-	cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags,
-			 CPPI5_TR_CSF_SUPR_EVT | CPPI5_TR_CSF_EOP);
-
-	return d;
-}
-
-static struct udma_desc *
-udma_prep_slave_sg_triggered_tr(struct udma_chan *uc, struct scatterlist *sgl,
-				unsigned int sglen,
-				enum dma_transfer_direction dir,
-				unsigned long tx_flags, void *context)
-{
-	struct scatterlist *sgent;
-	struct cppi5_tr_type15_t *tr_req = NULL;
-	enum dma_slave_buswidth dev_width;
-	u32 csf = CPPI5_TR_CSF_SUPR_EVT;
-	u16 tr_cnt0, tr_cnt1;
-	dma_addr_t dev_addr;
-	struct udma_desc *d;
-	unsigned int i;
-	size_t tr_size, sg_len;
-	int num_tr = 0;
-	int tr_idx = 0;
-	u32 burst, trigger_size, port_window;
-	u64 asel;
-
-	if (dir == DMA_DEV_TO_MEM) {
-		dev_addr = uc->cfg.src_addr;
-		dev_width = uc->cfg.src_addr_width;
-		burst = uc->cfg.src_maxburst;
-		port_window = uc->cfg.src_port_window_size;
-	} else if (dir == DMA_MEM_TO_DEV) {
-		dev_addr = uc->cfg.dst_addr;
-		dev_width = uc->cfg.dst_addr_width;
-		burst = uc->cfg.dst_maxburst;
-		port_window = uc->cfg.dst_port_window_size;
-	} else {
-		dev_err(uc->ud->dev, "%s: bad direction?\n", __func__);
-		return NULL;
-	}
-
-	if (!burst)
-		burst = 1;
-
-	if (port_window) {
-		if (port_window != burst) {
-			dev_err(uc->ud->dev,
-				"The burst must be equal to port_window\n");
-			return NULL;
-		}
-
-		tr_cnt0 = dev_width * port_window;
-		tr_cnt1 = 1;
-	} else {
-		tr_cnt0 = dev_width;
-		tr_cnt1 = burst;
-	}
-	trigger_size = tr_cnt0 * tr_cnt1;
-
-	/* estimate the number of TRs we will need */
-	for_each_sg(sgl, sgent, sglen, i) {
-		sg_len = sg_dma_len(sgent);
-
-		if (sg_len % trigger_size) {
-			dev_err(uc->ud->dev,
-				"Not aligned SG entry (%zu for %u)\n", sg_len,
-				trigger_size);
-			return NULL;
-		}
-
-		if (sg_len / trigger_size < SZ_64K)
-			num_tr++;
-		else
-			num_tr += 2;
-	}
-
-	/* Now allocate and setup the descriptor. */
-	tr_size = sizeof(struct cppi5_tr_type15_t);
-	d = udma_alloc_tr_desc(uc, tr_size, num_tr, dir);
-	if (!d)
-		return NULL;
-
-	d->sglen = sglen;
-
-	if (uc->ud->match_data->type == DMA_TYPE_UDMA) {
-		asel = 0;
-		csf |= CPPI5_TR_CSF_EOL_ICNT0;
-	} else {
-		asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT;
-		dev_addr |= asel;
-	}
-
-	tr_req = d->hwdesc[0].tr_req_base;
-	for_each_sg(sgl, sgent, sglen, i) {
-		u16 tr0_cnt2, tr0_cnt3, tr1_cnt2;
-		dma_addr_t sg_addr = sg_dma_address(sgent);
-
-		sg_len = sg_dma_len(sgent);
-		num_tr = udma_get_tr_counters(sg_len / trigger_size, 0,
-					      &tr0_cnt2, &tr0_cnt3, &tr1_cnt2);
-		if (num_tr < 0) {
-			dev_err(uc->ud->dev, "size %zu is not supported\n",
-				sg_len);
-			udma_free_hwdesc(uc, d);
-			kfree(d);
-			return NULL;
-		}
-
-		cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE15, false,
-			      true, CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
-		cppi5_tr_csf_set(&tr_req[tr_idx].flags, csf);
-		cppi5_tr_set_trigger(&tr_req[tr_idx].flags,
-				     uc->config.tr_trigger_type,
-				     CPPI5_TR_TRIGGER_TYPE_ICNT2_DEC, 0, 0);
-
-		sg_addr |= asel;
-		if (dir == DMA_DEV_TO_MEM) {
-			tr_req[tr_idx].addr = dev_addr;
-			tr_req[tr_idx].icnt0 = tr_cnt0;
-			tr_req[tr_idx].icnt1 = tr_cnt1;
-			tr_req[tr_idx].icnt2 = tr0_cnt2;
-			tr_req[tr_idx].icnt3 = tr0_cnt3;
-			tr_req[tr_idx].dim1 = (-1) * tr_cnt0;
-
-			tr_req[tr_idx].daddr = sg_addr;
-			tr_req[tr_idx].dicnt0 = tr_cnt0;
-			tr_req[tr_idx].dicnt1 = tr_cnt1;
-			tr_req[tr_idx].dicnt2 = tr0_cnt2;
-			tr_req[tr_idx].dicnt3 = tr0_cnt3;
-			tr_req[tr_idx].ddim1 = tr_cnt0;
-			tr_req[tr_idx].ddim2 = trigger_size;
-			tr_req[tr_idx].ddim3 = trigger_size * tr0_cnt2;
-		} else {
-			tr_req[tr_idx].addr = sg_addr;
-			tr_req[tr_idx].icnt0 = tr_cnt0;
-			tr_req[tr_idx].icnt1 = tr_cnt1;
-			tr_req[tr_idx].icnt2 = tr0_cnt2;
-			tr_req[tr_idx].icnt3 = tr0_cnt3;
-			tr_req[tr_idx].dim1 = tr_cnt0;
-			tr_req[tr_idx].dim2 = trigger_size;
-			tr_req[tr_idx].dim3 = trigger_size * tr0_cnt2;
-
-			tr_req[tr_idx].daddr = dev_addr;
-			tr_req[tr_idx].dicnt0 = tr_cnt0;
-			tr_req[tr_idx].dicnt1 = tr_cnt1;
-			tr_req[tr_idx].dicnt2 = tr0_cnt2;
-			tr_req[tr_idx].dicnt3 = tr0_cnt3;
-			tr_req[tr_idx].ddim1 = (-1) * tr_cnt0;
-		}
-
-		tr_idx++;
-
-		if (num_tr == 2) {
-			cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE15,
-				      false, true,
-				      CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
-			cppi5_tr_csf_set(&tr_req[tr_idx].flags, csf);
-			cppi5_tr_set_trigger(&tr_req[tr_idx].flags,
-					     uc->config.tr_trigger_type,
-					     CPPI5_TR_TRIGGER_TYPE_ICNT2_DEC,
-					     0, 0);
-
-			sg_addr += trigger_size * tr0_cnt2 * tr0_cnt3;
-			if (dir == DMA_DEV_TO_MEM) {
-				tr_req[tr_idx].addr = dev_addr;
-				tr_req[tr_idx].icnt0 = tr_cnt0;
-				tr_req[tr_idx].icnt1 = tr_cnt1;
-				tr_req[tr_idx].icnt2 = tr1_cnt2;
-				tr_req[tr_idx].icnt3 = 1;
-				tr_req[tr_idx].dim1 = (-1) * tr_cnt0;
-
-				tr_req[tr_idx].daddr = sg_addr;
-				tr_req[tr_idx].dicnt0 = tr_cnt0;
-				tr_req[tr_idx].dicnt1 = tr_cnt1;
-				tr_req[tr_idx].dicnt2 = tr1_cnt2;
-				tr_req[tr_idx].dicnt3 = 1;
-				tr_req[tr_idx].ddim1 = tr_cnt0;
-				tr_req[tr_idx].ddim2 = trigger_size;
-			} else {
-				tr_req[tr_idx].addr = sg_addr;
-				tr_req[tr_idx].icnt0 = tr_cnt0;
-				tr_req[tr_idx].icnt1 = tr_cnt1;
-				tr_req[tr_idx].icnt2 = tr1_cnt2;
-				tr_req[tr_idx].icnt3 = 1;
-				tr_req[tr_idx].dim1 = tr_cnt0;
-				tr_req[tr_idx].dim2 = trigger_size;
-
-				tr_req[tr_idx].daddr = dev_addr;
-				tr_req[tr_idx].dicnt0 = tr_cnt0;
-				tr_req[tr_idx].dicnt1 = tr_cnt1;
-				tr_req[tr_idx].dicnt2 = tr1_cnt2;
-				tr_req[tr_idx].dicnt3 = 1;
-				tr_req[tr_idx].ddim1 = (-1) * tr_cnt0;
-			}
-			tr_idx++;
-		}
-
-		d->residue += sg_len;
-	}
-
-	cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags, csf | CPPI5_TR_CSF_EOP);
-
-	return d;
-}
-
-static int udma_configure_statictr(struct udma_chan *uc, struct udma_desc *d,
-				   enum dma_slave_buswidth dev_width,
-				   u16 elcnt)
-{
-	if (uc->config.ep_type != PSIL_EP_PDMA_XY)
-		return 0;
-
-	/* Bus width translates to the element size (ES) */
-	switch (dev_width) {
-	case DMA_SLAVE_BUSWIDTH_1_BYTE:
-		d->static_tr.elsize = 0;
-		break;
-	case DMA_SLAVE_BUSWIDTH_2_BYTES:
-		d->static_tr.elsize = 1;
-		break;
-	case DMA_SLAVE_BUSWIDTH_3_BYTES:
-		d->static_tr.elsize = 2;
-		break;
-	case DMA_SLAVE_BUSWIDTH_4_BYTES:
-		d->static_tr.elsize = 3;
-		break;
-	case DMA_SLAVE_BUSWIDTH_8_BYTES:
-		d->static_tr.elsize = 4;
-		break;
-	default: /* not reached */
-		return -EINVAL;
-	}
-
-	d->static_tr.elcnt = elcnt;
-
-	if (uc->config.pkt_mode || !uc->cyclic) {
-		/*
-		 * PDMA must close the packet when the channel is in packet mode.
-		 * For TR mode when the channel is not cyclic we also need PDMA
-		 * to close the packet otherwise the transfer will stall because
-		 * PDMA holds on the data it has received from the peripheral.
-		 */
-		unsigned int div = dev_width * elcnt;
-
-		if (uc->cyclic)
-			d->static_tr.bstcnt = d->residue / d->sglen / div;
-		else
-			d->static_tr.bstcnt = d->residue / div;
-	} else if (uc->ud->match_data->type == DMA_TYPE_BCDMA &&
-		   uc->config.dir == DMA_DEV_TO_MEM &&
-		   uc->cyclic) {
-		/*
-		 * For cyclic mode with BCDMA we have to set EOP in each TR to
-		 * prevent short packet errors seen on channel teardown. So the
-		 * PDMA must close the packet after every TR transfer by setting
-		 * burst count equal to the number of bytes transferred.
-		 */
-		struct cppi5_tr_type1_t *tr_req = d->hwdesc[0].tr_req_base;
-
-		d->static_tr.bstcnt =
-			(tr_req->icnt0 * tr_req->icnt1) / dev_width;
-	} else {
-		d->static_tr.bstcnt = 0;
-	}
-
-	if (uc->config.dir == DMA_DEV_TO_MEM &&
-	    d->static_tr.bstcnt > uc->ud->match_data->statictr_z_mask)
-		return -EINVAL;
-
-	return 0;
-}
-
-static struct udma_desc *
-udma_prep_slave_sg_pkt(struct udma_chan *uc, struct scatterlist *sgl,
-		       unsigned int sglen, enum dma_transfer_direction dir,
-		       unsigned long tx_flags, void *context)
-{
-	struct scatterlist *sgent;
-	struct cppi5_host_desc_t *h_desc = NULL;
-	struct udma_desc *d;
-	u32 ring_id;
-	unsigned int i;
-	u64 asel;
-
-	d = kzalloc(struct_size(d, hwdesc, sglen), GFP_NOWAIT);
-	if (!d)
-		return NULL;
-
-	d->sglen = sglen;
-	d->hwdesc_count = sglen;
-
-	if (dir == DMA_DEV_TO_MEM)
-		ring_id = k3_ringacc_get_ring_id(uc->rflow->r_ring);
-	else
-		ring_id = k3_ringacc_get_ring_id(uc->tchan->tc_ring);
-
-	if (uc->ud->match_data->type == DMA_TYPE_UDMA)
-		asel = 0;
-	else
-		asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT;
-
-	for_each_sg(sgl, sgent, sglen, i) {
-		struct udma_hwdesc *hwdesc = &d->hwdesc[i];
-		dma_addr_t sg_addr = sg_dma_address(sgent);
-		struct cppi5_host_desc_t *desc;
-		size_t sg_len = sg_dma_len(sgent);
-
-		hwdesc->cppi5_desc_vaddr = dma_pool_zalloc(uc->hdesc_pool,
-						GFP_NOWAIT,
-						&hwdesc->cppi5_desc_paddr);
-		if (!hwdesc->cppi5_desc_vaddr) {
-			dev_err(uc->ud->dev,
-				"descriptor%d allocation failed\n", i);
-
-			udma_free_hwdesc(uc, d);
-			kfree(d);
-			return NULL;
-		}
-
-		d->residue += sg_len;
-		hwdesc->cppi5_desc_size = uc->config.hdesc_size;
-		desc = hwdesc->cppi5_desc_vaddr;
-
-		if (i == 0) {
-			cppi5_hdesc_init(desc, 0, 0);
-			/* Flow and Packed ID */
-			cppi5_desc_set_pktids(&desc->hdr, uc->id,
-					      CPPI5_INFO1_DESC_FLOWID_DEFAULT);
-			cppi5_desc_set_retpolicy(&desc->hdr, 0, ring_id);
-		} else {
-			cppi5_hdesc_reset_hbdesc(desc);
-			cppi5_desc_set_retpolicy(&desc->hdr, 0, 0xffff);
-		}
-
-		/* attach the sg buffer to the descriptor */
-		sg_addr |= asel;
-		cppi5_hdesc_attach_buf(desc, sg_addr, sg_len, sg_addr, sg_len);
-
-		/* Attach link as host buffer descriptor */
-		if (h_desc)
-			cppi5_hdesc_link_hbdesc(h_desc,
-						hwdesc->cppi5_desc_paddr | asel);
-
-		if (uc->ud->match_data->type == DMA_TYPE_PKTDMA ||
-		    dir == DMA_MEM_TO_DEV)
-			h_desc = desc;
-	}
-
-	if (d->residue >= SZ_4M) {
-		dev_err(uc->ud->dev,
-			"%s: Transfer size %u is over the supported 4M range\n",
-			__func__, d->residue);
-		udma_free_hwdesc(uc, d);
-		kfree(d);
-		return NULL;
-	}
-
-	h_desc = d->hwdesc[0].cppi5_desc_vaddr;
-	cppi5_hdesc_set_pktlen(h_desc, d->residue);
-
-	return d;
-}
-
-static int udma_attach_metadata(struct dma_async_tx_descriptor *desc,
-				void *data, size_t len)
-{
-	struct udma_desc *d = to_udma_desc(desc);
-	struct udma_chan *uc = to_udma_chan(desc->chan);
-	struct cppi5_host_desc_t *h_desc;
-	u32 psd_size = len;
-	u32 flags = 0;
-
-	if (!uc->config.pkt_mode || !uc->config.metadata_size)
-		return -ENOTSUPP;
-
-	if (!data || len > uc->config.metadata_size)
-		return -EINVAL;
-
-	if (uc->config.needs_epib && len < CPPI5_INFO0_HDESC_EPIB_SIZE)
-		return -EINVAL;
-
-	h_desc = d->hwdesc[0].cppi5_desc_vaddr;
-	if (d->dir == DMA_MEM_TO_DEV)
-		memcpy(h_desc->epib, data, len);
-
-	if (uc->config.needs_epib)
-		psd_size -= CPPI5_INFO0_HDESC_EPIB_SIZE;
-
-	d->metadata = data;
-	d->metadata_size = len;
-	if (uc->config.needs_epib)
-		flags |= CPPI5_INFO0_HDESC_EPIB_PRESENT;
-
-	cppi5_hdesc_update_flags(h_desc, flags);
-	cppi5_hdesc_update_psdata_size(h_desc, psd_size);
-
-	return 0;
-}
-
-static void *udma_get_metadata_ptr(struct dma_async_tx_descriptor *desc,
-				   size_t *payload_len, size_t *max_len)
-{
-	struct udma_desc *d = to_udma_desc(desc);
-	struct udma_chan *uc = to_udma_chan(desc->chan);
-	struct cppi5_host_desc_t *h_desc;
-
-	if (!uc->config.pkt_mode || !uc->config.metadata_size)
-		return ERR_PTR(-ENOTSUPP);
-
-	h_desc = d->hwdesc[0].cppi5_desc_vaddr;
-
-	*max_len = uc->config.metadata_size;
-
-	*payload_len = cppi5_hdesc_epib_present(&h_desc->hdr) ?
-		       CPPI5_INFO0_HDESC_EPIB_SIZE : 0;
-	*payload_len += cppi5_hdesc_get_psdata_size(h_desc);
-
-	return h_desc->epib;
-}
-
-static int udma_set_metadata_len(struct dma_async_tx_descriptor *desc,
-				 size_t payload_len)
-{
-	struct udma_desc *d = to_udma_desc(desc);
-	struct udma_chan *uc = to_udma_chan(desc->chan);
-	struct cppi5_host_desc_t *h_desc;
-	u32 psd_size = payload_len;
-	u32 flags = 0;
-
-	if (!uc->config.pkt_mode || !uc->config.metadata_size)
-		return -ENOTSUPP;
-
-	if (payload_len > uc->config.metadata_size)
-		return -EINVAL;
-
-	if (uc->config.needs_epib && payload_len < CPPI5_INFO0_HDESC_EPIB_SIZE)
-		return -EINVAL;
-
-	h_desc = d->hwdesc[0].cppi5_desc_vaddr;
-
-	if (uc->config.needs_epib) {
-		psd_size -= CPPI5_INFO0_HDESC_EPIB_SIZE;
-		flags |= CPPI5_INFO0_HDESC_EPIB_PRESENT;
-	}
-
-	cppi5_hdesc_update_flags(h_desc, flags);
-	cppi5_hdesc_update_psdata_size(h_desc, psd_size);
-
-	return 0;
-}
-
-static struct dma_descriptor_metadata_ops metadata_ops = {
-	.attach = udma_attach_metadata,
-	.get_ptr = udma_get_metadata_ptr,
-	.set_len = udma_set_metadata_len,
-};
-
-static struct dma_async_tx_descriptor *
-udma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
-		   unsigned int sglen, enum dma_transfer_direction dir,
-		   unsigned long tx_flags, void *context)
-{
-	struct udma_chan *uc = to_udma_chan(chan);
-	enum dma_slave_buswidth dev_width;
-	struct udma_desc *d;
-	u32 burst;
-
-	if (dir != uc->config.dir &&
-	    (uc->config.dir == DMA_MEM_TO_MEM && !uc->config.tr_trigger_type)) {
-		dev_err(chan->device->dev,
-			"%s: chan%d is for %s, not supporting %s\n",
-			__func__, uc->id,
-			dmaengine_get_direction_text(uc->config.dir),
-			dmaengine_get_direction_text(dir));
-		return NULL;
-	}
-
-	if (dir == DMA_DEV_TO_MEM) {
-		dev_width = uc->cfg.src_addr_width;
-		burst = uc->cfg.src_maxburst;
-	} else if (dir == DMA_MEM_TO_DEV) {
-		dev_width = uc->cfg.dst_addr_width;
-		burst = uc->cfg.dst_maxburst;
-	} else {
-		dev_err(chan->device->dev, "%s: bad direction?\n", __func__);
-		return NULL;
-	}
-
-	if (!burst)
-		burst = 1;
-
-	uc->config.tx_flags = tx_flags;
-
-	if (uc->config.pkt_mode)
-		d = udma_prep_slave_sg_pkt(uc, sgl, sglen, dir, tx_flags,
-					   context);
-	else if (is_slave_direction(uc->config.dir))
-		d = udma_prep_slave_sg_tr(uc, sgl, sglen, dir, tx_flags,
-					  context);
-	else
-		d = udma_prep_slave_sg_triggered_tr(uc, sgl, sglen, dir,
-						    tx_flags, context);
-
-	if (!d)
-		return NULL;
-
-	d->dir = dir;
-	d->desc_idx = 0;
-	d->tr_idx = 0;
-
-	/* static TR for remote PDMA */
-	if (udma_configure_statictr(uc, d, dev_width, burst)) {
-		dev_err(uc->ud->dev,
-			"%s: StaticTR Z is limited to maximum %u (%u)\n",
-			__func__, uc->ud->match_data->statictr_z_mask,
-			d->static_tr.bstcnt);
-
-		udma_free_hwdesc(uc, d);
-		kfree(d);
-		return NULL;
-	}
-
-	if (uc->config.metadata_size)
-		d->vd.tx.metadata_ops = &metadata_ops;
-
-	return vchan_tx_prep(&uc->vc, &d->vd, tx_flags);
-}
-
-static struct udma_desc *
-udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr,
-			size_t buf_len, size_t period_len,
-			enum dma_transfer_direction dir, unsigned long flags)
-{
-	struct udma_desc *d;
-	size_t tr_size, period_addr;
-	struct cppi5_tr_type1_t *tr_req;
-	unsigned int periods = buf_len / period_len;
-	u16 tr0_cnt0, tr0_cnt1, tr1_cnt0;
-	unsigned int i;
-	int num_tr;
-	u32 period_csf = 0;
-
-	num_tr = udma_get_tr_counters(period_len, __ffs(buf_addr), &tr0_cnt0,
-				      &tr0_cnt1, &tr1_cnt0);
-	if (num_tr < 0) {
-		dev_err(uc->ud->dev, "size %zu is not supported\n",
-			period_len);
-		return NULL;
-	}
-
-	/* Now allocate and setup the descriptor. */
-	tr_size = sizeof(struct cppi5_tr_type1_t);
-	d = udma_alloc_tr_desc(uc, tr_size, periods * num_tr, dir);
-	if (!d)
-		return NULL;
-
-	tr_req = d->hwdesc[0].tr_req_base;
-	if (uc->ud->match_data->type == DMA_TYPE_UDMA)
-		period_addr = buf_addr;
-	else
-		period_addr = buf_addr |
-			((u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT);
-
-	/*
-	 * For BCDMA <-> PDMA transfers, the EOP flag needs to be set on the
-	 * last TR of a descriptor, to mark the packet as complete.
-	 * This is required for getting the teardown completion message in case
-	 * of TX, and to avoid short-packet error in case of RX.
-	 *
-	 * As we are in cyclic mode, we do not know which period might be the
-	 * last one, so set the flag for each period.
-	 */
-	if (uc->config.ep_type == PSIL_EP_PDMA_XY &&
-	    uc->ud->match_data->type == DMA_TYPE_BCDMA) {
-		period_csf = CPPI5_TR_CSF_EOP;
-	}
-
-	for (i = 0; i < periods; i++) {
-		int tr_idx = i * num_tr;
-
-		cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE1, false,
-			      false, CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
-
-		tr_req[tr_idx].addr = period_addr;
-		tr_req[tr_idx].icnt0 = tr0_cnt0;
-		tr_req[tr_idx].icnt1 = tr0_cnt1;
-		tr_req[tr_idx].dim1 = tr0_cnt0;
-
-		if (num_tr == 2) {
-			cppi5_tr_csf_set(&tr_req[tr_idx].flags,
-					 CPPI5_TR_CSF_SUPR_EVT);
-			tr_idx++;
-
-			cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE1,
-				      false, false,
-				      CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
-
-			tr_req[tr_idx].addr = period_addr + tr0_cnt1 * tr0_cnt0;
-			tr_req[tr_idx].icnt0 = tr1_cnt0;
-			tr_req[tr_idx].icnt1 = 1;
-			tr_req[tr_idx].dim1 = tr1_cnt0;
-		}
-
-		if (!(flags & DMA_PREP_INTERRUPT))
-			period_csf |= CPPI5_TR_CSF_SUPR_EVT;
-
-		if (period_csf)
-			cppi5_tr_csf_set(&tr_req[tr_idx].flags, period_csf);
-
-		period_addr += period_len;
-	}
-
-	return d;
-}
-
-static struct udma_desc *
-udma_prep_dma_cyclic_pkt(struct udma_chan *uc, dma_addr_t buf_addr,
-			 size_t buf_len, size_t period_len,
-			 enum dma_transfer_direction dir, unsigned long flags)
-{
-	struct udma_desc *d;
-	u32 ring_id;
-	int i;
-	int periods = buf_len / period_len;
-
-	if (periods > (K3_UDMA_DEFAULT_RING_SIZE - 1))
-		return NULL;
-
-	if (period_len >= SZ_4M)
-		return NULL;
-
-	d = kzalloc(struct_size(d, hwdesc, periods), GFP_NOWAIT);
-	if (!d)
-		return NULL;
-
-	d->hwdesc_count = periods;
-
-	/* TODO: re-check this... */
-	if (dir == DMA_DEV_TO_MEM)
-		ring_id = k3_ringacc_get_ring_id(uc->rflow->r_ring);
-	else
-		ring_id = k3_ringacc_get_ring_id(uc->tchan->tc_ring);
-
-	if (uc->ud->match_data->type != DMA_TYPE_UDMA)
-		buf_addr |= (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT;
-
-	for (i = 0; i < periods; i++) {
-		struct udma_hwdesc *hwdesc = &d->hwdesc[i];
-		dma_addr_t period_addr = buf_addr + (period_len * i);
-		struct cppi5_host_desc_t *h_desc;
-
-		hwdesc->cppi5_desc_vaddr = dma_pool_zalloc(uc->hdesc_pool,
-						GFP_NOWAIT,
-						&hwdesc->cppi5_desc_paddr);
-		if (!hwdesc->cppi5_desc_vaddr) {
-			dev_err(uc->ud->dev,
-				"descriptor%d allocation failed\n", i);
-
-			udma_free_hwdesc(uc, d);
-			kfree(d);
-			return NULL;
-		}
-
-		hwdesc->cppi5_desc_size = uc->config.hdesc_size;
-		h_desc = hwdesc->cppi5_desc_vaddr;
-
-		cppi5_hdesc_init(h_desc, 0, 0);
-		cppi5_hdesc_set_pktlen(h_desc, period_len);
-
-		/* Flow and Packed ID */
-		cppi5_desc_set_pktids(&h_desc->hdr, uc->id,
-				      CPPI5_INFO1_DESC_FLOWID_DEFAULT);
-		cppi5_desc_set_retpolicy(&h_desc->hdr, 0, ring_id);
-
-		/* attach each period to a new descriptor */
-		cppi5_hdesc_attach_buf(h_desc,
-				       period_addr, period_len,
-				       period_addr, period_len);
-	}
-
-	return d;
-}
-
-static struct dma_async_tx_descriptor *
-udma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
-		     size_t period_len, enum dma_transfer_direction dir,
-		     unsigned long flags)
-{
-	struct udma_chan *uc = to_udma_chan(chan);
-	enum dma_slave_buswidth dev_width;
-	struct udma_desc *d;
-	u32 burst;
-
-	if (dir != uc->config.dir) {
-		dev_err(chan->device->dev,
-			"%s: chan%d is for %s, not supporting %s\n",
-			__func__, uc->id,
-			dmaengine_get_direction_text(uc->config.dir),
-			dmaengine_get_direction_text(dir));
-		return NULL;
-	}
-
-	uc->cyclic = true;
-
-	if (dir == DMA_DEV_TO_MEM) {
-		dev_width = uc->cfg.src_addr_width;
-		burst = uc->cfg.src_maxburst;
-	} else if (dir == DMA_MEM_TO_DEV) {
-		dev_width = uc->cfg.dst_addr_width;
-		burst = uc->cfg.dst_maxburst;
-	} else {
-		dev_err(uc->ud->dev, "%s: bad direction?\n", __func__);
-		return NULL;
-	}
-
-	if (!burst)
-		burst = 1;
-
-	if (uc->config.pkt_mode)
-		d = udma_prep_dma_cyclic_pkt(uc, buf_addr, buf_len, period_len,
-					     dir, flags);
-	else
-		d = udma_prep_dma_cyclic_tr(uc, buf_addr, buf_len, period_len,
-					    dir, flags);
-
-	if (!d)
-		return NULL;
-
-	d->sglen = buf_len / period_len;
-
-	d->dir = dir;
-	d->residue = buf_len;
-
-	/* static TR for remote PDMA */
-	if (udma_configure_statictr(uc, d, dev_width, burst)) {
-		dev_err(uc->ud->dev,
-			"%s: StaticTR Z is limited to maximum %u (%u)\n",
-			__func__, uc->ud->match_data->statictr_z_mask,
-			d->static_tr.bstcnt);
-
-		udma_free_hwdesc(uc, d);
-		kfree(d);
-		return NULL;
-	}
-
-	if (uc->config.metadata_size)
-		d->vd.tx.metadata_ops = &metadata_ops;
-
-	return vchan_tx_prep(&uc->vc, &d->vd, flags);
-}
-
-static struct dma_async_tx_descriptor *
-udma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
-		     size_t len, unsigned long tx_flags)
-{
-	struct udma_chan *uc = to_udma_chan(chan);
-	struct udma_desc *d;
-	struct cppi5_tr_type15_t *tr_req;
-	int num_tr;
-	size_t tr_size = sizeof(struct cppi5_tr_type15_t);
-	u16 tr0_cnt0, tr0_cnt1, tr1_cnt0;
-	u32 csf = CPPI5_TR_CSF_SUPR_EVT;
-
-	if (uc->config.dir != DMA_MEM_TO_MEM) {
-		dev_err(chan->device->dev,
-			"%s: chan%d is for %s, not supporting %s\n",
-			__func__, uc->id,
-			dmaengine_get_direction_text(uc->config.dir),
-			dmaengine_get_direction_text(DMA_MEM_TO_MEM));
-		return NULL;
-	}
-
-	num_tr = udma_get_tr_counters(len, __ffs(src | dest), &tr0_cnt0,
-				      &tr0_cnt1, &tr1_cnt0);
-	if (num_tr < 0) {
-		dev_err(uc->ud->dev, "size %zu is not supported\n",
-			len);
-		return NULL;
-	}
-
-	d = udma_alloc_tr_desc(uc, tr_size, num_tr, DMA_MEM_TO_MEM);
-	if (!d)
-		return NULL;
-
-	d->dir = DMA_MEM_TO_MEM;
-	d->desc_idx = 0;
-	d->tr_idx = 0;
-	d->residue = len;
-
-	if (uc->ud->match_data->type != DMA_TYPE_UDMA) {
-		src |= (u64)uc->ud->asel << K3_ADDRESS_ASEL_SHIFT;
-		dest |= (u64)uc->ud->asel << K3_ADDRESS_ASEL_SHIFT;
-	} else {
-		csf |= CPPI5_TR_CSF_EOL_ICNT0;
-	}
-
-	tr_req = d->hwdesc[0].tr_req_base;
-
-	cppi5_tr_init(&tr_req[0].flags, CPPI5_TR_TYPE15, false, true,
-		      CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
-	cppi5_tr_csf_set(&tr_req[0].flags, csf);
-
-	tr_req[0].addr = src;
-	tr_req[0].icnt0 = tr0_cnt0;
-	tr_req[0].icnt1 = tr0_cnt1;
-	tr_req[0].icnt2 = 1;
-	tr_req[0].icnt3 = 1;
-	tr_req[0].dim1 = tr0_cnt0;
-
-	tr_req[0].daddr = dest;
-	tr_req[0].dicnt0 = tr0_cnt0;
-	tr_req[0].dicnt1 = tr0_cnt1;
-	tr_req[0].dicnt2 = 1;
-	tr_req[0].dicnt3 = 1;
-	tr_req[0].ddim1 = tr0_cnt0;
-
-	if (num_tr == 2) {
-		cppi5_tr_init(&tr_req[1].flags, CPPI5_TR_TYPE15, false, true,
-			      CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
-		cppi5_tr_csf_set(&tr_req[1].flags, csf);
-
-		tr_req[1].addr = src + tr0_cnt1 * tr0_cnt0;
-		tr_req[1].icnt0 = tr1_cnt0;
-		tr_req[1].icnt1 = 1;
-		tr_req[1].icnt2 = 1;
-		tr_req[1].icnt3 = 1;
-
-		tr_req[1].daddr = dest + tr0_cnt1 * tr0_cnt0;
-		tr_req[1].dicnt0 = tr1_cnt0;
-		tr_req[1].dicnt1 = 1;
-		tr_req[1].dicnt2 = 1;
-		tr_req[1].dicnt3 = 1;
-	}
-
-	cppi5_tr_csf_set(&tr_req[num_tr - 1].flags, csf | CPPI5_TR_CSF_EOP);
-
-	if (uc->config.metadata_size)
-		d->vd.tx.metadata_ops = &metadata_ops;
-
-	return vchan_tx_prep(&uc->vc, &d->vd, tx_flags);
-}
-
-static void udma_issue_pending(struct dma_chan *chan)
-{
-	struct udma_chan *uc = to_udma_chan(chan);
-	unsigned long flags;
-
-	spin_lock_irqsave(&uc->vc.lock, flags);
-
-	/* If we have something pending and no active descriptor, then */
-	if (vchan_issue_pending(&uc->vc) && !uc->desc) {
-		/*
-		 * start a descriptor if the channel is NOT [marked as
-		 * terminating _and_ it is still running (teardown has not
-		 * completed yet)].
-		 */
-		if (!(uc->state == UDMA_CHAN_IS_TERMINATING &&
-		      udma_is_chan_running(uc)))
-			udma_start(uc);
-	}
-
-	spin_unlock_irqrestore(&uc->vc.lock, flags);
-}
-
 static enum dma_status udma_tx_status(struct dma_chan *chan,
 				      dma_cookie_t cookie,
 				      struct dma_tx_state *txstate)
@@ -3948,194 +1705,10 @@
 	return 0;
 }
 
-static int udma_terminate_all(struct dma_chan *chan)
-{
-	struct udma_chan *uc = to_udma_chan(chan);
-	unsigned long flags;
-	LIST_HEAD(head);
-
-	spin_lock_irqsave(&uc->vc.lock, flags);
-
-	if (udma_is_chan_running(uc))
-		udma_stop(uc);
-
-	if (uc->desc) {
-		uc->terminated_desc = uc->desc;
-		uc->desc = NULL;
-		uc->terminated_desc->terminated = true;
-		cancel_delayed_work(&uc->tx_drain.work);
-	}
-
-	uc->paused = false;
-
-	vchan_get_all_descriptors(&uc->vc, &head);
-	spin_unlock_irqrestore(&uc->vc.lock, flags);
-	vchan_dma_desc_free_list(&uc->vc, &head);
-
-	return 0;
-}
-
-static void udma_synchronize(struct dma_chan *chan)
-{
-	struct udma_chan *uc = to_udma_chan(chan);
-	unsigned long timeout = msecs_to_jiffies(1000);
-
-	vchan_synchronize(&uc->vc);
-
-	if (uc->state == UDMA_CHAN_IS_TERMINATING) {
-		timeout = wait_for_completion_timeout(&uc->teardown_completed,
-						      timeout);
-		if (!timeout) {
-			dev_warn(uc->ud->dev, "chan%d teardown timeout!\n",
-				 uc->id);
-			udma_dump_chan_stdata(uc);
-			udma_reset_chan(uc, true);
-		}
-	}
-
-	udma_reset_chan(uc, false);
-	if (udma_is_chan_running(uc))
-		dev_warn(uc->ud->dev, "chan%d refused to stop!\n", uc->id);
-
-	cancel_delayed_work_sync(&uc->tx_drain.work);
-	udma_reset_rings(uc);
-}
-
-static void udma_desc_pre_callback(struct virt_dma_chan *vc,
-				   struct virt_dma_desc *vd,
-				   struct dmaengine_result *result)
-{
-	struct udma_chan *uc = to_udma_chan(&vc->chan);
-	struct udma_desc *d;
-	u8 status;
-
-	if (!vd)
-		return;
-
-	d = to_udma_desc(&vd->tx);
-
-	if (d->metadata_size)
-		udma_fetch_epib(uc, d);
-
-	if (result) {
-		void *desc_vaddr = udma_curr_cppi5_desc_vaddr(d, d->desc_idx);
-
-		if (cppi5_desc_get_type(desc_vaddr) ==
-		    CPPI5_INFO0_DESC_TYPE_VAL_HOST) {
-			/* Provide residue information for the client */
-			result->residue = d->residue -
-					  cppi5_hdesc_get_pktlen(desc_vaddr);
-			if (result->residue)
-				result->result = DMA_TRANS_ABORTED;
-			else
-				result->result = DMA_TRANS_NOERROR;
-		} else {
-			result->residue = 0;
-			/* Propagate TR Response errors to the client */
-			status = d->hwdesc[0].tr_resp_base->status;
-			if (status)
-				result->result = DMA_TRANS_ABORTED;
-			else
-				result->result = DMA_TRANS_NOERROR;
-		}
-	}
-}
-
-/*
- * This tasklet handles the completion of a DMA descriptor by
- * calling its callback and freeing it.
- */
-static void udma_vchan_complete(struct tasklet_struct *t)
-{
-	struct virt_dma_chan *vc = from_tasklet(vc, t, task);
-	struct virt_dma_desc *vd, *_vd;
-	struct dmaengine_desc_callback cb;
-	LIST_HEAD(head);
-
-	spin_lock_irq(&vc->lock);
-	list_splice_tail_init(&vc->desc_completed, &head);
-	vd = vc->cyclic;
-	if (vd) {
-		vc->cyclic = NULL;
-		dmaengine_desc_get_callback(&vd->tx, &cb);
-	} else {
-		memset(&cb, 0, sizeof(cb));
-	}
-	spin_unlock_irq(&vc->lock);
-
-	udma_desc_pre_callback(vc, vd, NULL);
-	dmaengine_desc_callback_invoke(&cb, NULL);
-
-	list_for_each_entry_safe(vd, _vd, &head, node) {
-		struct dmaengine_result result;
-
-		dmaengine_desc_get_callback(&vd->tx, &cb);
-
-		list_del(&vd->node);
-
-		udma_desc_pre_callback(vc, vd, &result);
-		dmaengine_desc_callback_invoke(&cb, &result);
-
-		vchan_vdesc_fini(vd);
-	}
-}
-
-static void udma_free_chan_resources(struct dma_chan *chan)
-{
-	struct udma_chan *uc = to_udma_chan(chan);
-	struct udma_dev *ud = to_udma_dev(chan->device);
-
-	udma_terminate_all(chan);
-	if (uc->terminated_desc) {
-		udma_reset_chan(uc, false);
-		udma_reset_rings(uc);
-	}
-
-	cancel_delayed_work_sync(&uc->tx_drain.work);
-
-	if (uc->irq_num_ring > 0) {
-		free_irq(uc->irq_num_ring, uc);
-
-		uc->irq_num_ring = 0;
-	}
-	if (uc->irq_num_udma > 0) {
-		free_irq(uc->irq_num_udma, uc);
-
-		uc->irq_num_udma = 0;
-	}
-
-	/* Release PSI-L pairing */
-	if (uc->psil_paired) {
-		navss_psil_unpair(ud, uc->config.src_thread,
-				  uc->config.dst_thread);
-		uc->psil_paired = false;
-	}
-
-	vchan_free_chan_resources(&uc->vc);
-	tasklet_kill(&uc->vc.task);
-
-	bcdma_free_bchan_resources(uc);
-	udma_free_tx_resources(uc);
-	udma_free_rx_resources(uc);
-	udma_reset_uchan(uc);
-
-	if (uc->use_dma_pool) {
-		dma_pool_destroy(uc->hdesc_pool);
-		uc->use_dma_pool = false;
-	}
-}
-
 static struct platform_driver udma_driver;
 static struct platform_driver bcdma_driver;
 static struct platform_driver pktdma_driver;
 
-struct udma_filter_param {
-	int remote_thread_id;
-	u32 atype;
-	u32 asel;
-	u32 tr_trigger_type;
-};
-
 static bool udma_dma_filter_fn(struct dma_chan *chan, void *param)
 {
 	struct udma_chan_config *ucc;
@@ -4410,6 +1983,18 @@
 	.soc_data = &j721s2_bcdma_csi_soc_data,
 };
 
+static struct udma_match_data j722s_bcdma_csi_data = {
+	.type = DMA_TYPE_BCDMA,
+	.psil_base = 0x3100,
+	.enable_memcpy_support = false,
+	.burst_size = {
+		TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* Normal Channels */
+		0, /* No H Channels */
+		0, /* No UH Channels */
+	},
+	.soc_data = &j721s2_bcdma_csi_soc_data,
+};
+
 static const struct of_device_id udma_of_match[] = {
 	{
 		.compatible = "ti,am654-navss-main-udmap",
@@ -4441,6 +2026,10 @@
 		.compatible = "ti,j721s2-dmss-bcdma-csi",
 		.data = &j721s2_bcdma_csi_data,
 	},
+	{
+		.compatible = "ti,j722s-dmss-bcdma-csi",
+		.data = &j722s_bcdma_csi_data,
+	},
 	{ /* Sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, udma_of_match);
@@ -4545,813 +2134,6 @@
 	return 0;
 }
 
-static void udma_mark_resource_ranges(struct udma_dev *ud, unsigned long *map,
-				      struct ti_sci_resource_desc *rm_desc,
-				      char *name)
-{
-	bitmap_clear(map, rm_desc->start, rm_desc->num);
-	bitmap_clear(map, rm_desc->start_sec, rm_desc->num_sec);
-	dev_dbg(ud->dev, "ti_sci resource range for %s: %d:%d | %d:%d\n", name,
-		rm_desc->start, rm_desc->num, rm_desc->start_sec,
-		rm_desc->num_sec);
-}
-
-static const char * const range_names[] = {
-	[RM_RANGE_BCHAN] = "ti,sci-rm-range-bchan",
-	[RM_RANGE_TCHAN] = "ti,sci-rm-range-tchan",
-	[RM_RANGE_RCHAN] = "ti,sci-rm-range-rchan",
-	[RM_RANGE_RFLOW] = "ti,sci-rm-range-rflow",
-	[RM_RANGE_TFLOW] = "ti,sci-rm-range-tflow",
-};
-
-static int udma_setup_resources(struct udma_dev *ud)
-{
-	int ret, i, j;
-	struct device *dev = ud->dev;
-	struct ti_sci_resource *rm_res, irq_res;
-	struct udma_tisci_rm *tisci_rm = &ud->tisci_rm;
-	u32 cap3;
-
-	/* Set up the throughput level start indexes */
-	cap3 = udma_read(ud->mmrs[MMR_GCFG], 0x2c);
-	if (of_device_is_compatible(dev->of_node,
-				    "ti,am654-navss-main-udmap")) {
-		ud->tchan_tpl.levels = 2;
-		ud->tchan_tpl.start_idx[0] = 8;
-	} else if (of_device_is_compatible(dev->of_node,
-					   "ti,am654-navss-mcu-udmap")) {
-		ud->tchan_tpl.levels = 2;
-		ud->tchan_tpl.start_idx[0] = 2;
-	} else if (UDMA_CAP3_UCHAN_CNT(cap3)) {
-		ud->tchan_tpl.levels = 3;
-		ud->tchan_tpl.start_idx[1] = UDMA_CAP3_UCHAN_CNT(cap3);
-		ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3);
-	} else if (UDMA_CAP3_HCHAN_CNT(cap3)) {
-		ud->tchan_tpl.levels = 2;
-		ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3);
-	} else {
-		ud->tchan_tpl.levels = 1;
-	}
-
-	ud->rchan_tpl.levels = ud->tchan_tpl.levels;
-	ud->rchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0];
-	ud->rchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1];
-
-	ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt),
-					   sizeof(unsigned long), GFP_KERNEL);
-	ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans),
-				  GFP_KERNEL);
-	ud->rchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rchan_cnt),
-					   sizeof(unsigned long), GFP_KERNEL);
-	ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans),
-				  GFP_KERNEL);
-	ud->rflow_gp_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rflow_cnt),
-					      sizeof(unsigned long),
-					      GFP_KERNEL);
-	ud->rflow_gp_map_allocated = devm_kcalloc(dev,
-						  BITS_TO_LONGS(ud->rflow_cnt),
-						  sizeof(unsigned long),
-						  GFP_KERNEL);
-	ud->rflow_in_use = devm_kcalloc(dev, BITS_TO_LONGS(ud->rflow_cnt),
-					sizeof(unsigned long),
-					GFP_KERNEL);
-	ud->rflows = devm_kcalloc(dev, ud->rflow_cnt, sizeof(*ud->rflows),
-				  GFP_KERNEL);
-
-	if (!ud->tchan_map || !ud->rchan_map || !ud->rflow_gp_map ||
-	    !ud->rflow_gp_map_allocated || !ud->tchans || !ud->rchans ||
-	    !ud->rflows || !ud->rflow_in_use)
-		return -ENOMEM;
-
-	/*
-	 * RX flows with the same Ids as RX channels are reserved to be used
-	 * as default flows if remote HW can't generate flow_ids. Those
-	 * RX flows can be requested only explicitly by id.
-	 */
-	bitmap_set(ud->rflow_gp_map_allocated, 0, ud->rchan_cnt);
-
-	/* by default no GP rflows are assigned to Linux */
-	bitmap_set(ud->rflow_gp_map, 0, ud->rflow_cnt);
-
-	/* Get resource ranges from tisci */
-	for (i = 0; i < RM_RANGE_LAST; i++) {
-		if (i == RM_RANGE_BCHAN || i == RM_RANGE_TFLOW)
-			continue;
-
-		tisci_rm->rm_ranges[i] =
-			devm_ti_sci_get_of_resource(tisci_rm->tisci, dev,
-						    tisci_rm->tisci_dev_id,
-						    (char *)range_names[i]);
-	}
-
-	/* tchan ranges */
-	rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
-	if (IS_ERR(rm_res)) {
-		bitmap_zero(ud->tchan_map, ud->tchan_cnt);
-		irq_res.sets = 1;
-	} else {
-		bitmap_fill(ud->tchan_map, ud->tchan_cnt);
-		for (i = 0; i < rm_res->sets; i++)
-			udma_mark_resource_ranges(ud, ud->tchan_map,
-						  &rm_res->desc[i], "tchan");
-		irq_res.sets = rm_res->sets;
-	}
-
-	/* rchan and matching default flow ranges */
-	rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
-	if (IS_ERR(rm_res)) {
-		bitmap_zero(ud->rchan_map, ud->rchan_cnt);
-		irq_res.sets++;
-	} else {
-		bitmap_fill(ud->rchan_map, ud->rchan_cnt);
-		for (i = 0; i < rm_res->sets; i++)
-			udma_mark_resource_ranges(ud, ud->rchan_map,
-						  &rm_res->desc[i], "rchan");
-		irq_res.sets += rm_res->sets;
-	}
-
-	irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL);
-	if (!irq_res.desc)
-		return -ENOMEM;
-	rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
-	if (IS_ERR(rm_res)) {
-		irq_res.desc[0].start = 0;
-		irq_res.desc[0].num = ud->tchan_cnt;
-		i = 1;
-	} else {
-		for (i = 0; i < rm_res->sets; i++) {
-			irq_res.desc[i].start = rm_res->desc[i].start;
-			irq_res.desc[i].num = rm_res->desc[i].num;
-			irq_res.desc[i].start_sec = rm_res->desc[i].start_sec;
-			irq_res.desc[i].num_sec = rm_res->desc[i].num_sec;
-		}
-	}
-	rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
-	if (IS_ERR(rm_res)) {
-		irq_res.desc[i].start = 0;
-		irq_res.desc[i].num = ud->rchan_cnt;
-	} else {
-		for (j = 0; j < rm_res->sets; j++, i++) {
-			if (rm_res->desc[j].num) {
-				irq_res.desc[i].start = rm_res->desc[j].start +
-						ud->soc_data->oes.udma_rchan;
-				irq_res.desc[i].num = rm_res->desc[j].num;
-			}
-			if (rm_res->desc[j].num_sec) {
-				irq_res.desc[i].start_sec = rm_res->desc[j].start_sec +
-						ud->soc_data->oes.udma_rchan;
-				irq_res.desc[i].num_sec = rm_res->desc[j].num_sec;
-			}
-		}
-	}
-	ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res);
-	kfree(irq_res.desc);
-	if (ret) {
-		dev_err(ud->dev, "Failed to allocate MSI interrupts\n");
-		return ret;
-	}
-
-	/* GP rflow ranges */
-	rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW];
-	if (IS_ERR(rm_res)) {
-		/* all gp flows are assigned exclusively to Linux */
-		bitmap_clear(ud->rflow_gp_map, ud->rchan_cnt,
-			     ud->rflow_cnt - ud->rchan_cnt);
-	} else {
-		for (i = 0; i < rm_res->sets; i++)
-			udma_mark_resource_ranges(ud, ud->rflow_gp_map,
-						  &rm_res->desc[i], "gp-rflow");
-	}
-
-	return 0;
-}
-
-static int bcdma_setup_resources(struct udma_dev *ud)
-{
-	int ret, i, j;
-	struct device *dev = ud->dev;
-	struct ti_sci_resource *rm_res, irq_res;
-	struct udma_tisci_rm *tisci_rm = &ud->tisci_rm;
-	const struct udma_oes_offsets *oes = &ud->soc_data->oes;
-	u32 cap;
-
-	/* Set up the throughput level start indexes */
-	cap = udma_read(ud->mmrs[MMR_GCFG], 0x2c);
-	if (BCDMA_CAP3_UBCHAN_CNT(cap)) {
-		ud->bchan_tpl.levels = 3;
-		ud->bchan_tpl.start_idx[1] = BCDMA_CAP3_UBCHAN_CNT(cap);
-		ud->bchan_tpl.start_idx[0] = BCDMA_CAP3_HBCHAN_CNT(cap);
-	} else if (BCDMA_CAP3_HBCHAN_CNT(cap)) {
-		ud->bchan_tpl.levels = 2;
-		ud->bchan_tpl.start_idx[0] = BCDMA_CAP3_HBCHAN_CNT(cap);
-	} else {
-		ud->bchan_tpl.levels = 1;
-	}
-
-	cap = udma_read(ud->mmrs[MMR_GCFG], 0x30);
-	if (BCDMA_CAP4_URCHAN_CNT(cap)) {
-		ud->rchan_tpl.levels = 3;
-		ud->rchan_tpl.start_idx[1] = BCDMA_CAP4_URCHAN_CNT(cap);
-		ud->rchan_tpl.start_idx[0] = BCDMA_CAP4_HRCHAN_CNT(cap);
-	} else if (BCDMA_CAP4_HRCHAN_CNT(cap)) {
-		ud->rchan_tpl.levels = 2;
-		ud->rchan_tpl.start_idx[0] = BCDMA_CAP4_HRCHAN_CNT(cap);
-	} else {
-		ud->rchan_tpl.levels = 1;
-	}
-
-	if (BCDMA_CAP4_UTCHAN_CNT(cap)) {
-		ud->tchan_tpl.levels = 3;
-		ud->tchan_tpl.start_idx[1] = BCDMA_CAP4_UTCHAN_CNT(cap);
-		ud->tchan_tpl.start_idx[0] = BCDMA_CAP4_HTCHAN_CNT(cap);
-	} else if (BCDMA_CAP4_HTCHAN_CNT(cap)) {
-		ud->tchan_tpl.levels = 2;
-		ud->tchan_tpl.start_idx[0] = BCDMA_CAP4_HTCHAN_CNT(cap);
-	} else {
-		ud->tchan_tpl.levels = 1;
-	}
-
-	ud->bchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->bchan_cnt),
-					   sizeof(unsigned long), GFP_KERNEL);
-	ud->bchans = devm_kcalloc(dev, ud->bchan_cnt, sizeof(*ud->bchans),
-				  GFP_KERNEL);
-	ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt),
-					   sizeof(unsigned long), GFP_KERNEL);
-	ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans),
-				  GFP_KERNEL);
-	ud->rchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rchan_cnt),
-					   sizeof(unsigned long), GFP_KERNEL);
-	ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans),
-				  GFP_KERNEL);
-	/* BCDMA do not really have flows, but the driver expect it */
-	ud->rflow_in_use = devm_kcalloc(dev, BITS_TO_LONGS(ud->rchan_cnt),
-					sizeof(unsigned long),
-					GFP_KERNEL);
-	ud->rflows = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rflows),
-				  GFP_KERNEL);
-
-	if (!ud->bchan_map || !ud->tchan_map || !ud->rchan_map ||
-	    !ud->rflow_in_use || !ud->bchans || !ud->tchans || !ud->rchans ||
-	    !ud->rflows)
-		return -ENOMEM;
-
-	/* Get resource ranges from tisci */
-	for (i = 0; i < RM_RANGE_LAST; i++) {
-		if (i == RM_RANGE_RFLOW || i == RM_RANGE_TFLOW)
-			continue;
-		if (i == RM_RANGE_BCHAN && ud->bchan_cnt == 0)
-			continue;
-		if (i == RM_RANGE_TCHAN && ud->tchan_cnt == 0)
-			continue;
-		if (i == RM_RANGE_RCHAN && ud->rchan_cnt == 0)
-			continue;
-
-		tisci_rm->rm_ranges[i] =
-			devm_ti_sci_get_of_resource(tisci_rm->tisci, dev,
-						    tisci_rm->tisci_dev_id,
-						    (char *)range_names[i]);
-	}
-
-	irq_res.sets = 0;
-
-	/* bchan ranges */
-	if (ud->bchan_cnt) {
-		rm_res = tisci_rm->rm_ranges[RM_RANGE_BCHAN];
-		if (IS_ERR(rm_res)) {
-			bitmap_zero(ud->bchan_map, ud->bchan_cnt);
-			irq_res.sets++;
-		} else {
-			bitmap_fill(ud->bchan_map, ud->bchan_cnt);
-			for (i = 0; i < rm_res->sets; i++)
-				udma_mark_resource_ranges(ud, ud->bchan_map,
-							  &rm_res->desc[i],
-							  "bchan");
-			irq_res.sets += rm_res->sets;
-		}
-	}
-
-	/* tchan ranges */
-	if (ud->tchan_cnt) {
-		rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
-		if (IS_ERR(rm_res)) {
-			bitmap_zero(ud->tchan_map, ud->tchan_cnt);
-			irq_res.sets += 2;
-		} else {
-			bitmap_fill(ud->tchan_map, ud->tchan_cnt);
-			for (i = 0; i < rm_res->sets; i++)
-				udma_mark_resource_ranges(ud, ud->tchan_map,
-							  &rm_res->desc[i],
-							  "tchan");
-			irq_res.sets += rm_res->sets * 2;
-		}
-	}
-
-	/* rchan ranges */
-	if (ud->rchan_cnt) {
-		rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
-		if (IS_ERR(rm_res)) {
-			bitmap_zero(ud->rchan_map, ud->rchan_cnt);
-			irq_res.sets += 2;
-		} else {
-			bitmap_fill(ud->rchan_map, ud->rchan_cnt);
-			for (i = 0; i < rm_res->sets; i++)
-				udma_mark_resource_ranges(ud, ud->rchan_map,
-							  &rm_res->desc[i],
-							  "rchan");
-			irq_res.sets += rm_res->sets * 2;
-		}
-	}
-
-	irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL);
-	if (!irq_res.desc)
-		return -ENOMEM;
-	if (ud->bchan_cnt) {
-		rm_res = tisci_rm->rm_ranges[RM_RANGE_BCHAN];
-		if (IS_ERR(rm_res)) {
-			irq_res.desc[0].start = oes->bcdma_bchan_ring;
-			irq_res.desc[0].num = ud->bchan_cnt;
-			i = 1;
-		} else {
-			for (i = 0; i < rm_res->sets; i++) {
-				irq_res.desc[i].start = rm_res->desc[i].start +
-							oes->bcdma_bchan_ring;
-				irq_res.desc[i].num = rm_res->desc[i].num;
-			}
-		}
-	} else {
-		i = 0;
-	}
-
-	if (ud->tchan_cnt) {
-		rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
-		if (IS_ERR(rm_res)) {
-			irq_res.desc[i].start = oes->bcdma_tchan_data;
-			irq_res.desc[i].num = ud->tchan_cnt;
-			irq_res.desc[i + 1].start = oes->bcdma_tchan_ring;
-			irq_res.desc[i + 1].num = ud->tchan_cnt;
-			i += 2;
-		} else {
-			for (j = 0; j < rm_res->sets; j++, i += 2) {
-				irq_res.desc[i].start = rm_res->desc[j].start +
-							oes->bcdma_tchan_data;
-				irq_res.desc[i].num = rm_res->desc[j].num;
-
-				irq_res.desc[i + 1].start = rm_res->desc[j].start +
-							oes->bcdma_tchan_ring;
-				irq_res.desc[i + 1].num = rm_res->desc[j].num;
-			}
-		}
-	}
-	if (ud->rchan_cnt) {
-		rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
-		if (IS_ERR(rm_res)) {
-			irq_res.desc[i].start = oes->bcdma_rchan_data;
-			irq_res.desc[i].num = ud->rchan_cnt;
-			irq_res.desc[i + 1].start = oes->bcdma_rchan_ring;
-			irq_res.desc[i + 1].num = ud->rchan_cnt;
-			i += 2;
-		} else {
-			for (j = 0; j < rm_res->sets; j++, i += 2) {
-				irq_res.desc[i].start = rm_res->desc[j].start +
-							oes->bcdma_rchan_data;
-				irq_res.desc[i].num = rm_res->desc[j].num;
-
-				irq_res.desc[i + 1].start = rm_res->desc[j].start +
-							oes->bcdma_rchan_ring;
-				irq_res.desc[i + 1].num = rm_res->desc[j].num;
-			}
-		}
-	}
-
-	ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res);
-	kfree(irq_res.desc);
-	if (ret) {
-		dev_err(ud->dev, "Failed to allocate MSI interrupts\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static int pktdma_setup_resources(struct udma_dev *ud)
-{
-	int ret, i, j;
-	struct device *dev = ud->dev;
-	struct ti_sci_resource *rm_res, irq_res;
-	struct udma_tisci_rm *tisci_rm = &ud->tisci_rm;
-	const struct udma_oes_offsets *oes = &ud->soc_data->oes;
-	u32 cap3;
-
-	/* Set up the throughput level start indexes */
-	cap3 = udma_read(ud->mmrs[MMR_GCFG], 0x2c);
-	if (UDMA_CAP3_UCHAN_CNT(cap3)) {
-		ud->tchan_tpl.levels = 3;
-		ud->tchan_tpl.start_idx[1] = UDMA_CAP3_UCHAN_CNT(cap3);
-		ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3);
-	} else if (UDMA_CAP3_HCHAN_CNT(cap3)) {
-		ud->tchan_tpl.levels = 2;
-		ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3);
-	} else {
-		ud->tchan_tpl.levels = 1;
-	}
-
-	ud->rchan_tpl.levels = ud->tchan_tpl.levels;
-	ud->rchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0];
-	ud->rchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1];
-
-	ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt),
-					   sizeof(unsigned long), GFP_KERNEL);
-	ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans),
-				  GFP_KERNEL);
-	ud->rchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rchan_cnt),
-					   sizeof(unsigned long), GFP_KERNEL);
-	ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans),
-				  GFP_KERNEL);
-	ud->rflow_in_use = devm_kcalloc(dev, BITS_TO_LONGS(ud->rflow_cnt),
-					sizeof(unsigned long),
-					GFP_KERNEL);
-	ud->rflows = devm_kcalloc(dev, ud->rflow_cnt, sizeof(*ud->rflows),
-				  GFP_KERNEL);
-	ud->tflow_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tflow_cnt),
-					   sizeof(unsigned long), GFP_KERNEL);
-
-	if (!ud->tchan_map || !ud->rchan_map || !ud->tflow_map || !ud->tchans ||
-	    !ud->rchans || !ud->rflows || !ud->rflow_in_use)
-		return -ENOMEM;
-
-	/* Get resource ranges from tisci */
-	for (i = 0; i < RM_RANGE_LAST; i++) {
-		if (i == RM_RANGE_BCHAN)
-			continue;
-
-		tisci_rm->rm_ranges[i] =
-			devm_ti_sci_get_of_resource(tisci_rm->tisci, dev,
-						    tisci_rm->tisci_dev_id,
-						    (char *)range_names[i]);
-	}
-
-	/* tchan ranges */
-	rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
-	if (IS_ERR(rm_res)) {
-		bitmap_zero(ud->tchan_map, ud->tchan_cnt);
-	} else {
-		bitmap_fill(ud->tchan_map, ud->tchan_cnt);
-		for (i = 0; i < rm_res->sets; i++)
-			udma_mark_resource_ranges(ud, ud->tchan_map,
-						  &rm_res->desc[i], "tchan");
-	}
-
-	/* rchan ranges */
-	rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
-	if (IS_ERR(rm_res)) {
-		bitmap_zero(ud->rchan_map, ud->rchan_cnt);
-	} else {
-		bitmap_fill(ud->rchan_map, ud->rchan_cnt);
-		for (i = 0; i < rm_res->sets; i++)
-			udma_mark_resource_ranges(ud, ud->rchan_map,
-						  &rm_res->desc[i], "rchan");
-	}
-
-	/* rflow ranges */
-	rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW];
-	if (IS_ERR(rm_res)) {
-		/* all rflows are assigned exclusively to Linux */
-		bitmap_zero(ud->rflow_in_use, ud->rflow_cnt);
-		irq_res.sets = 1;
-	} else {
-		bitmap_fill(ud->rflow_in_use, ud->rflow_cnt);
-		for (i = 0; i < rm_res->sets; i++)
-			udma_mark_resource_ranges(ud, ud->rflow_in_use,
-						  &rm_res->desc[i], "rflow");
-		irq_res.sets = rm_res->sets;
-	}
-
-	/* tflow ranges */
-	rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW];
-	if (IS_ERR(rm_res)) {
-		/* all tflows are assigned exclusively to Linux */
-		bitmap_zero(ud->tflow_map, ud->tflow_cnt);
-		irq_res.sets++;
-	} else {
-		bitmap_fill(ud->tflow_map, ud->tflow_cnt);
-		for (i = 0; i < rm_res->sets; i++)
-			udma_mark_resource_ranges(ud, ud->tflow_map,
-						  &rm_res->desc[i], "tflow");
-		irq_res.sets += rm_res->sets;
-	}
-
-	irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL);
-	if (!irq_res.desc)
-		return -ENOMEM;
-	rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW];
-	if (IS_ERR(rm_res)) {
-		irq_res.desc[0].start = oes->pktdma_tchan_flow;
-		irq_res.desc[0].num = ud->tflow_cnt;
-		i = 1;
-	} else {
-		for (i = 0; i < rm_res->sets; i++) {
-			irq_res.desc[i].start = rm_res->desc[i].start +
-						oes->pktdma_tchan_flow;
-			irq_res.desc[i].num = rm_res->desc[i].num;
-		}
-	}
-	rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW];
-	if (IS_ERR(rm_res)) {
-		irq_res.desc[i].start = oes->pktdma_rchan_flow;
-		irq_res.desc[i].num = ud->rflow_cnt;
-	} else {
-		for (j = 0; j < rm_res->sets; j++, i++) {
-			irq_res.desc[i].start = rm_res->desc[j].start +
-						oes->pktdma_rchan_flow;
-			irq_res.desc[i].num = rm_res->desc[j].num;
-		}
-	}
-	ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res);
-	kfree(irq_res.desc);
-	if (ret) {
-		dev_err(ud->dev, "Failed to allocate MSI interrupts\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static int setup_resources(struct udma_dev *ud)
-{
-	struct device *dev = ud->dev;
-	int ch_count, ret;
-
-	switch (ud->match_data->type) {
-	case DMA_TYPE_UDMA:
-		ret = udma_setup_resources(ud);
-		break;
-	case DMA_TYPE_BCDMA:
-		ret = bcdma_setup_resources(ud);
-		break;
-	case DMA_TYPE_PKTDMA:
-		ret = pktdma_setup_resources(ud);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	if (ret)
-		return ret;
-
-	ch_count  = ud->bchan_cnt + ud->tchan_cnt + ud->rchan_cnt;
-	if (ud->bchan_cnt)
-		ch_count -= bitmap_weight(ud->bchan_map, ud->bchan_cnt);
-	ch_count -= bitmap_weight(ud->tchan_map, ud->tchan_cnt);
-	ch_count -= bitmap_weight(ud->rchan_map, ud->rchan_cnt);
-	if (!ch_count)
-		return -ENODEV;
-
-	ud->channels = devm_kcalloc(dev, ch_count, sizeof(*ud->channels),
-				    GFP_KERNEL);
-	if (!ud->channels)
-		return -ENOMEM;
-
-	switch (ud->match_data->type) {
-	case DMA_TYPE_UDMA:
-		dev_info(dev,
-			 "Channels: %d (tchan: %u, rchan: %u, gp-rflow: %u)\n",
-			 ch_count,
-			 ud->tchan_cnt - bitmap_weight(ud->tchan_map,
-						       ud->tchan_cnt),
-			 ud->rchan_cnt - bitmap_weight(ud->rchan_map,
-						       ud->rchan_cnt),
-			 ud->rflow_cnt - bitmap_weight(ud->rflow_gp_map,
-						       ud->rflow_cnt));
-		break;
-	case DMA_TYPE_BCDMA:
-		dev_info(dev,
-			 "Channels: %d (bchan: %u, tchan: %u, rchan: %u)\n",
-			 ch_count,
-			 ud->bchan_cnt - bitmap_weight(ud->bchan_map,
-						       ud->bchan_cnt),
-			 ud->tchan_cnt - bitmap_weight(ud->tchan_map,
-						       ud->tchan_cnt),
-			 ud->rchan_cnt - bitmap_weight(ud->rchan_map,
-						       ud->rchan_cnt));
-		break;
-	case DMA_TYPE_PKTDMA:
-		dev_info(dev,
-			 "Channels: %d (tchan: %u, rchan: %u)\n",
-			 ch_count,
-			 ud->tchan_cnt - bitmap_weight(ud->tchan_map,
-						       ud->tchan_cnt),
-			 ud->rchan_cnt - bitmap_weight(ud->rchan_map,
-						       ud->rchan_cnt));
-		break;
-	default:
-		break;
-	}
-
-	return ch_count;
-}
-
-static int udma_setup_rx_flush(struct udma_dev *ud)
-{
-	struct udma_rx_flush *rx_flush = &ud->rx_flush;
-	struct cppi5_desc_hdr_t *tr_desc;
-	struct cppi5_tr_type1_t *tr_req;
-	struct cppi5_host_desc_t *desc;
-	struct device *dev = ud->dev;
-	struct udma_hwdesc *hwdesc;
-	size_t tr_size;
-
-	/* Allocate 1K buffer for discarded data on RX channel teardown */
-	rx_flush->buffer_size = SZ_1K;
-	rx_flush->buffer_vaddr = devm_kzalloc(dev, rx_flush->buffer_size,
-					      GFP_KERNEL);
-	if (!rx_flush->buffer_vaddr)
-		return -ENOMEM;
-
-	rx_flush->buffer_paddr = dma_map_single(dev, rx_flush->buffer_vaddr,
-						rx_flush->buffer_size,
-						DMA_TO_DEVICE);
-	if (dma_mapping_error(dev, rx_flush->buffer_paddr))
-		return -ENOMEM;
-
-	/* Set up descriptor to be used for TR mode */
-	hwdesc = &rx_flush->hwdescs[0];
-	tr_size = sizeof(struct cppi5_tr_type1_t);
-	hwdesc->cppi5_desc_size = cppi5_trdesc_calc_size(tr_size, 1);
-	hwdesc->cppi5_desc_size = ALIGN(hwdesc->cppi5_desc_size,
-					ud->desc_align);
-
-	hwdesc->cppi5_desc_vaddr = devm_kzalloc(dev, hwdesc->cppi5_desc_size,
-						GFP_KERNEL);
-	if (!hwdesc->cppi5_desc_vaddr)
-		return -ENOMEM;
-
-	hwdesc->cppi5_desc_paddr = dma_map_single(dev, hwdesc->cppi5_desc_vaddr,
-						  hwdesc->cppi5_desc_size,
-						  DMA_TO_DEVICE);
-	if (dma_mapping_error(dev, hwdesc->cppi5_desc_paddr))
-		return -ENOMEM;
-
-	/* Start of the TR req records */
-	hwdesc->tr_req_base = hwdesc->cppi5_desc_vaddr + tr_size;
-	/* Start address of the TR response array */
-	hwdesc->tr_resp_base = hwdesc->tr_req_base + tr_size;
-
-	tr_desc = hwdesc->cppi5_desc_vaddr;
-	cppi5_trdesc_init(tr_desc, 1, tr_size, 0, 0);
-	cppi5_desc_set_pktids(tr_desc, 0, CPPI5_INFO1_DESC_FLOWID_DEFAULT);
-	cppi5_desc_set_retpolicy(tr_desc, 0, 0);
-
-	tr_req = hwdesc->tr_req_base;
-	cppi5_tr_init(&tr_req->flags, CPPI5_TR_TYPE1, false, false,
-		      CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
-	cppi5_tr_csf_set(&tr_req->flags, CPPI5_TR_CSF_SUPR_EVT);
-
-	tr_req->addr = rx_flush->buffer_paddr;
-	tr_req->icnt0 = rx_flush->buffer_size;
-	tr_req->icnt1 = 1;
-
-	dma_sync_single_for_device(dev, hwdesc->cppi5_desc_paddr,
-				   hwdesc->cppi5_desc_size, DMA_TO_DEVICE);
-
-	/* Set up descriptor to be used for packet mode */
-	hwdesc = &rx_flush->hwdescs[1];
-	hwdesc->cppi5_desc_size = ALIGN(sizeof(struct cppi5_host_desc_t) +
-					CPPI5_INFO0_HDESC_EPIB_SIZE +
-					CPPI5_INFO0_HDESC_PSDATA_MAX_SIZE,
-					ud->desc_align);
-
-	hwdesc->cppi5_desc_vaddr = devm_kzalloc(dev, hwdesc->cppi5_desc_size,
-						GFP_KERNEL);
-	if (!hwdesc->cppi5_desc_vaddr)
-		return -ENOMEM;
-
-	hwdesc->cppi5_desc_paddr = dma_map_single(dev, hwdesc->cppi5_desc_vaddr,
-						  hwdesc->cppi5_desc_size,
-						  DMA_TO_DEVICE);
-	if (dma_mapping_error(dev, hwdesc->cppi5_desc_paddr))
-		return -ENOMEM;
-
-	desc = hwdesc->cppi5_desc_vaddr;
-	cppi5_hdesc_init(desc, 0, 0);
-	cppi5_desc_set_pktids(&desc->hdr, 0, CPPI5_INFO1_DESC_FLOWID_DEFAULT);
-	cppi5_desc_set_retpolicy(&desc->hdr, 0, 0);
-
-	cppi5_hdesc_attach_buf(desc,
-			       rx_flush->buffer_paddr, rx_flush->buffer_size,
-			       rx_flush->buffer_paddr, rx_flush->buffer_size);
-
-	dma_sync_single_for_device(dev, hwdesc->cppi5_desc_paddr,
-				   hwdesc->cppi5_desc_size, DMA_TO_DEVICE);
-	return 0;
-}
-
-#ifdef CONFIG_DEBUG_FS
-static void udma_dbg_summary_show_chan(struct seq_file *s,
-				       struct dma_chan *chan)
-{
-	struct udma_chan *uc = to_udma_chan(chan);
-	struct udma_chan_config *ucc = &uc->config;
-
-	seq_printf(s, " %-13s| %s", dma_chan_name(chan),
-		   chan->dbg_client_name ?: "in-use");
-	if (ucc->tr_trigger_type)
-		seq_puts(s, " (triggered, ");
-	else
-		seq_printf(s, " (%s, ",
-			   dmaengine_get_direction_text(uc->config.dir));
-
-	switch (uc->config.dir) {
-	case DMA_MEM_TO_MEM:
-		if (uc->ud->match_data->type == DMA_TYPE_BCDMA) {
-			seq_printf(s, "bchan%d)\n", uc->bchan->id);
-			return;
-		}
-
-		seq_printf(s, "chan%d pair [0x%04x -> 0x%04x], ", uc->tchan->id,
-			   ucc->src_thread, ucc->dst_thread);
-		break;
-	case DMA_DEV_TO_MEM:
-		seq_printf(s, "rchan%d [0x%04x -> 0x%04x], ", uc->rchan->id,
-			   ucc->src_thread, ucc->dst_thread);
-		if (uc->ud->match_data->type == DMA_TYPE_PKTDMA)
-			seq_printf(s, "rflow%d, ", uc->rflow->id);
-		break;
-	case DMA_MEM_TO_DEV:
-		seq_printf(s, "tchan%d [0x%04x -> 0x%04x], ", uc->tchan->id,
-			   ucc->src_thread, ucc->dst_thread);
-		if (uc->ud->match_data->type == DMA_TYPE_PKTDMA)
-			seq_printf(s, "tflow%d, ", uc->tchan->tflow_id);
-		break;
-	default:
-		seq_printf(s, ")\n");
-		return;
-	}
-
-	if (ucc->ep_type == PSIL_EP_NATIVE) {
-		seq_printf(s, "PSI-L Native");
-		if (ucc->metadata_size) {
-			seq_printf(s, "[%s", ucc->needs_epib ? " EPIB" : "");
-			if (ucc->psd_size)
-				seq_printf(s, " PSDsize:%u", ucc->psd_size);
-			seq_printf(s, " ]");
-		}
-	} else {
-		seq_printf(s, "PDMA");
-		if (ucc->enable_acc32 || ucc->enable_burst)
-			seq_printf(s, "[%s%s ]",
-				   ucc->enable_acc32 ? " ACC32" : "",
-				   ucc->enable_burst ? " BURST" : "");
-	}
-
-	seq_printf(s, ", %s)\n", ucc->pkt_mode ? "Packet mode" : "TR mode");
-}
-
-static void udma_dbg_summary_show(struct seq_file *s,
-				  struct dma_device *dma_dev)
-{
-	struct dma_chan *chan;
-
-	list_for_each_entry(chan, &dma_dev->channels, device_node) {
-		if (chan->client_count)
-			udma_dbg_summary_show_chan(s, chan);
-	}
-}
-#endif /* CONFIG_DEBUG_FS */
-
-static enum dmaengine_alignment udma_get_copy_align(struct udma_dev *ud)
-{
-	const struct udma_match_data *match_data = ud->match_data;
-	u8 tpl;
-
-	if (!match_data->enable_memcpy_support)
-		return DMAENGINE_ALIGN_8_BYTES;
-
-	/* Get the highest TPL level the device supports for memcpy */
-	if (ud->bchan_cnt)
-		tpl = udma_get_chan_tpl_index(&ud->bchan_tpl, 0);
-	else if (ud->tchan_cnt)
-		tpl = udma_get_chan_tpl_index(&ud->tchan_tpl, 0);
-	else
-		return DMAENGINE_ALIGN_8_BYTES;
-
-	switch (match_data->burst_size[tpl]) {
-	case TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_256_BYTES:
-		return DMAENGINE_ALIGN_256_BYTES;
-	case TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_128_BYTES:
-		return DMAENGINE_ALIGN_128_BYTES;
-	case TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES:
-	fallthrough;
-	default:
-		return DMAENGINE_ALIGN_64_BYTES;
-	}
-}
-
-#define TI_UDMAC_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
-				 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
-				 BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
-				 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
-				 BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
-
 static int udma_probe(struct platform_device *pdev)
 {
 	struct device_node *navss_node = pdev->dev.parent->of_node;
@@ -5387,6 +2169,13 @@
 		ud->soc_data = soc->data;
 	}
 
+	// Setup function pointers
+	ud->udma_start = udma_start;
+	ud->udma_stop = udma_stop;
+	ud->udma_reset_chan = udma_reset_chan;
+	ud->udma_is_desc_really_done = udma_is_desc_really_done;
+	ud->udma_decrement_byte_counters = udma_decrement_byte_counters;
+
 	ret = udma_get_mmrs(pdev, ud);
 	if (ret)
 		return ret;
@@ -5432,7 +2221,7 @@
 	if (ud->match_data->type == DMA_TYPE_UDMA) {
 		ud->ringacc = of_k3_ringacc_get_by_phandle(dev->of_node, "ti,ringacc");
 	} else {
-		struct k3_ringacc_init_data ring_init_data;
+		struct k3_ringacc_init_data ring_init_data = { 0 };
 
 		ring_init_data.tisci = ud->tisci_rm.tisci;
 		ring_init_data.tisci_dev_id = ud->tisci_rm.tisci_dev_id;
@@ -5665,6 +2454,3 @@
 module_platform_driver(udma_driver);
 MODULE_DESCRIPTION("Texas Instruments UDMA support");
 MODULE_LICENSE("GPL v2");
-
-/* Private interfaces to UDMA */
-#include "k3-udma-private.c"
diff -Naur --no-dereference a/drivers/dma/ti/k3-udma-common.c b/drivers/dma/ti/k3-udma-common.c
--- a/drivers/dma/ti/k3-udma-common.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/dma/ti/k3-udma-common.c	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,2979 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Copyright (C) 2025 Texas Instruments Incorporated - http://www.ti.com
+ *  Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/sys_soc.h>
+#include <linux/of.h>
+#include <linux/of_dma.h>
+#include <linux/of_irq.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/soc/ti/k3-ringacc.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+#include <linux/soc/ti/ti_sci_inta_msi.h>
+#include <linux/dma/k3-event-router.h>
+#include <linux/dma/ti-cppi5.h>
+
+#include "../virt-dma.h"
+#include "k3-udma.h"
+#include "k3-psil-priv.h"
+
+static const char * const range_names[] = {
+	[RM_RANGE_BCHAN] = "ti,sci-rm-range-bchan",
+	[RM_RANGE_TCHAN] = "ti,sci-rm-range-tchan",
+	[RM_RANGE_RCHAN] = "ti,sci-rm-range-rchan",
+	[RM_RANGE_RFLOW] = "ti,sci-rm-range-rflow",
+	[RM_RANGE_TFLOW] = "ti,sci-rm-range-tflow",
+};
+
+void k3_configure_chan_coherency(struct dma_chan *chan, u32 asel)
+{
+	struct device *chan_dev = &chan->dev->device;
+
+	if (asel == 0) {
+		/* No special handling for the channel */
+		chan->dev->chan_dma_dev = false;
+
+		chan_dev->dma_coherent = false;
+		chan_dev->dma_parms = NULL;
+	} else if (asel == 14 || asel == 15) {
+		chan->dev->chan_dma_dev = true;
+
+		chan_dev->dma_coherent = true;
+		dma_coerce_mask_and_coherent(chan_dev, DMA_BIT_MASK(48));
+		chan_dev->dma_parms = chan_dev->parent->dma_parms;
+	} else {
+		dev_warn(chan->device->dev, "Invalid ASEL value: %u\n", asel);
+
+		chan_dev->dma_coherent = false;
+		chan_dev->dma_parms = NULL;
+	}
+}
+
+u8 udma_get_chan_tpl_index(struct udma_tpl *tpl_map, int chan_id)
+{
+	int i;
+
+	for (i = 0; i < tpl_map->levels; i++) {
+		if (chan_id >= tpl_map->start_idx[i])
+			return i;
+	}
+
+	return 0;
+}
+
+void udma_reset_uchan(struct udma_chan *uc)
+{
+	memset(&uc->config, 0, sizeof(uc->config));
+	uc->config.remote_thread_id = -1;
+	uc->config.mapped_channel_id = -1;
+	uc->config.default_flow_id = -1;
+	uc->state = UDMA_CHAN_IS_IDLE;
+}
+
+void udma_dump_chan_stdata(struct udma_chan *uc)
+{
+	struct device *dev = uc->ud->dev;
+	u32 offset;
+	int i;
+
+	if (uc->config.dir == DMA_MEM_TO_DEV || uc->config.dir == DMA_MEM_TO_MEM) {
+		dev_dbg(dev, "TCHAN State data:\n");
+		for (i = 0; i < 32; i++) {
+			offset = UDMA_CHAN_RT_STDATA_REG + i * 4;
+			dev_dbg(dev, "TRT_STDATA[%02d]: 0x%08x\n", i,
+				udma_tchanrt_read(uc, offset));
+		}
+	}
+
+	if (uc->config.dir == DMA_DEV_TO_MEM || uc->config.dir == DMA_MEM_TO_MEM) {
+		dev_dbg(dev, "RCHAN State data:\n");
+		for (i = 0; i < 32; i++) {
+			offset = UDMA_CHAN_RT_STDATA_REG + i * 4;
+			dev_dbg(dev, "RRT_STDATA[%02d]: 0x%08x\n", i,
+				udma_rchanrt_read(uc, offset));
+		}
+	}
+}
+
+struct udma_desc *udma_udma_desc_from_paddr(struct udma_chan *uc,
+						   dma_addr_t paddr)
+{
+	struct udma_desc *d = uc->terminated_desc;
+
+	if (d) {
+		dma_addr_t desc_paddr = udma_curr_cppi5_desc_paddr(d,
+								   d->desc_idx);
+
+		if (desc_paddr != paddr)
+			d = NULL;
+	}
+
+	if (!d) {
+		d = uc->desc;
+		if (d) {
+			dma_addr_t desc_paddr = udma_curr_cppi5_desc_paddr(d,
+								d->desc_idx);
+
+			if (desc_paddr != paddr)
+				d = NULL;
+		}
+	}
+
+	return d;
+}
+
+void udma_free_hwdesc(struct udma_chan *uc, struct udma_desc *d)
+{
+	if (uc->use_dma_pool) {
+		int i;
+
+		for (i = 0; i < d->hwdesc_count; i++) {
+			if (!d->hwdesc[i].cppi5_desc_vaddr)
+				continue;
+
+			dma_pool_free(uc->hdesc_pool,
+				      d->hwdesc[i].cppi5_desc_vaddr,
+				      d->hwdesc[i].cppi5_desc_paddr);
+
+			d->hwdesc[i].cppi5_desc_vaddr = NULL;
+		}
+	} else if (d->hwdesc[0].cppi5_desc_vaddr) {
+		dma_free_coherent(uc->dma_dev, d->hwdesc[0].cppi5_desc_size,
+				  d->hwdesc[0].cppi5_desc_vaddr,
+				  d->hwdesc[0].cppi5_desc_paddr);
+
+		d->hwdesc[0].cppi5_desc_vaddr = NULL;
+	}
+}
+
+void udma_purge_desc_work(struct work_struct *work)
+{
+	struct udma_dev *ud = container_of(work, typeof(*ud), purge_work);
+	struct virt_dma_desc *vd, *_vd;
+	unsigned long flags;
+	LIST_HEAD(head);
+
+	spin_lock_irqsave(&ud->lock, flags);
+	list_splice_tail_init(&ud->desc_to_purge, &head);
+	spin_unlock_irqrestore(&ud->lock, flags);
+
+	list_for_each_entry_safe(vd, _vd, &head, node) {
+		struct udma_chan *uc = to_udma_chan(vd->tx.chan);
+		struct udma_desc *d = to_udma_desc(&vd->tx);
+
+		udma_free_hwdesc(uc, d);
+		list_del(&vd->node);
+		kfree(d);
+	}
+
+	/* If more to purge, schedule the work again */
+	if (!list_empty(&ud->desc_to_purge))
+		schedule_work(&ud->purge_work);
+}
+
+void udma_desc_free(struct virt_dma_desc *vd)
+{
+	struct udma_dev *ud = to_udma_dev(vd->tx.chan->device);
+	struct udma_chan *uc = to_udma_chan(vd->tx.chan);
+	struct udma_desc *d = to_udma_desc(&vd->tx);
+	unsigned long flags;
+
+	if (uc->terminated_desc == d)
+		uc->terminated_desc = NULL;
+
+	if (uc->use_dma_pool) {
+		udma_free_hwdesc(uc, d);
+		kfree(d);
+		return;
+	}
+
+	spin_lock_irqsave(&ud->lock, flags);
+	list_add_tail(&vd->node, &ud->desc_to_purge);
+	spin_unlock_irqrestore(&ud->lock, flags);
+
+	schedule_work(&ud->purge_work);
+}
+
+bool udma_is_chan_running(struct udma_chan *uc)
+{
+	u32 trt_ctl = 0;
+	u32 rrt_ctl = 0;
+
+	if (uc->tchan)
+		trt_ctl = udma_tchanrt_read(uc, UDMA_CHAN_RT_CTL_REG);
+	if (uc->rchan)
+		rrt_ctl = udma_rchanrt_read(uc, UDMA_CHAN_RT_CTL_REG);
+
+	if (trt_ctl & UDMA_CHAN_RT_CTL_EN || rrt_ctl & UDMA_CHAN_RT_CTL_EN)
+		return true;
+
+	return false;
+}
+
+void udma_reset_rings(struct udma_chan *uc)
+{
+	struct k3_ring *ring1 = NULL;
+	struct k3_ring *ring2 = NULL;
+
+	switch (uc->config.dir) {
+		case DMA_DEV_TO_MEM:
+			if (uc->rchan) {
+				ring1 = uc->rflow->fd_ring;
+				ring2 = uc->rflow->r_ring;
+			}
+			break;
+		case DMA_MEM_TO_DEV:
+		case DMA_MEM_TO_MEM:
+			if (uc->tchan) {
+				ring1 = uc->tchan->t_ring;
+				ring2 = uc->tchan->tc_ring;
+			}
+			break;
+		default:
+			break;
+	}
+
+	if (ring1)
+		k3_ringacc_ring_reset_dma(ring1,
+				k3_ringacc_ring_get_occ(ring1));
+	if (ring2)
+		k3_ringacc_ring_reset(ring2);
+
+	/* make sure we are not leaking memory by stalled descriptor */
+	if (uc->terminated_desc) {
+		udma_desc_free(&uc->terminated_desc->vd);
+		uc->terminated_desc = NULL;
+	}
+}
+
+int udma_push_to_ring(struct udma_chan *uc, int idx)
+{
+	struct udma_desc *d = uc->desc;
+	struct k3_ring *ring = NULL;
+	dma_addr_t paddr;
+
+	switch (uc->config.dir) {
+	case DMA_DEV_TO_MEM:
+		ring = uc->rflow->fd_ring;
+		break;
+	case DMA_MEM_TO_DEV:
+	case DMA_MEM_TO_MEM:
+		ring = uc->tchan->t_ring;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* RX flush packet: idx == -1 is only passed in case of DEV_TO_MEM */
+	if (idx == -1) {
+		paddr = udma_get_rx_flush_hwdesc_paddr(uc);
+	} else {
+		paddr = udma_curr_cppi5_desc_paddr(d, idx);
+
+		wmb(); /* Ensure that writes are not moved over this point */
+	}
+
+	return k3_ringacc_ring_push(ring, &paddr);
+}
+
+bool udma_desc_is_rx_flush(struct udma_chan *uc, dma_addr_t addr)
+{
+	if (uc->config.dir != DMA_DEV_TO_MEM)
+		return false;
+
+	if (addr == udma_get_rx_flush_hwdesc_paddr(uc))
+		return true;
+
+	return false;
+}
+
+int udma_pop_from_ring(struct udma_chan *uc, dma_addr_t *addr)
+{
+	struct k3_ring *ring = NULL;
+	int ret;
+
+	switch (uc->config.dir) {
+	case DMA_DEV_TO_MEM:
+		ring = uc->rflow->r_ring;
+		break;
+	case DMA_MEM_TO_DEV:
+	case DMA_MEM_TO_MEM:
+		ring = uc->tchan->tc_ring;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	ret = k3_ringacc_ring_pop(ring, addr);
+	if (ret)
+		return ret;
+
+	rmb(); /* Ensure that reads are not moved before this point */
+
+	/* Teardown completion */
+	if (cppi5_desc_is_tdcm(*addr))
+		return 0;
+
+	/* Check for flush descriptor */
+	if (udma_desc_is_rx_flush(uc, *addr))
+		return -ENOENT;
+
+	return 0;
+}
+
+void udma_start_desc(struct udma_chan *uc)
+{
+	struct udma_chan_config *ucc = &uc->config;
+
+	if (uc->ud->match_data->type == DMA_TYPE_UDMA && ucc->pkt_mode &&
+	    (uc->cyclic || ucc->dir == DMA_DEV_TO_MEM)) {
+		int i;
+
+		/*
+		 * UDMA only: Push all descriptors to ring for packet mode
+		 * cyclic or RX
+		 * PKTDMA supports pre-linked descriptor and cyclic is not
+		 * supported
+		 */
+		for (i = 0; i < uc->desc->sglen; i++)
+			udma_push_to_ring(uc, i);
+	} else {
+		udma_push_to_ring(uc, 0);
+	}
+}
+
+bool udma_chan_needs_reconfiguration(struct udma_chan *uc)
+{
+	/* Only PDMAs have staticTR */
+	if (uc->config.ep_type == PSIL_EP_NATIVE)
+		return false;
+
+	/* Check if the staticTR configuration has changed for TX */
+	if (memcmp(&uc->static_tr, &uc->desc->static_tr, sizeof(uc->static_tr)))
+		return true;
+
+	return false;
+}
+
+void udma_cyclic_packet_elapsed(struct udma_chan *uc)
+{
+	struct udma_desc *d = uc->desc;
+	struct cppi5_host_desc_t *h_desc;
+
+	h_desc = d->hwdesc[d->desc_idx].cppi5_desc_vaddr;
+	cppi5_hdesc_reset_to_original(h_desc);
+	udma_push_to_ring(uc, d->desc_idx);
+	d->desc_idx = (d->desc_idx + 1) % d->sglen;
+}
+
+void udma_check_tx_completion(struct work_struct *work)
+{
+	struct udma_chan *uc = container_of(work, typeof(*uc),
+					    tx_drain.work.work);
+	struct udma_dev *ud = uc->ud;
+	bool desc_done = true;
+	u32 residue_diff;
+	ktime_t time_diff;
+	unsigned long delay;
+	unsigned long flags;
+
+	while (1) {
+		spin_lock_irqsave(&uc->vc.lock, flags);
+
+		if (uc->desc) {
+			/* Get previous residue and time stamp */
+			residue_diff = uc->tx_drain.residue;
+			time_diff = uc->tx_drain.tstamp;
+			/*
+			 * Get current residue and time stamp or see if
+			 * transfer is complete
+			 */
+			desc_done = ud->udma_is_desc_really_done(uc, uc->desc);
+		}
+
+		if (!desc_done) {
+			/*
+			 * Find the time delta and residue delta w.r.t
+			 * previous poll
+			 */
+			time_diff = ktime_sub(uc->tx_drain.tstamp,
+					      time_diff) + 1;
+			residue_diff -= uc->tx_drain.residue;
+			if (residue_diff) {
+				/*
+				 * Try to guess when we should check
+				 * next time by calculating rate at
+				 * which data is being drained at the
+				 * peer device
+				 */
+				delay = (time_diff / residue_diff) *
+					uc->tx_drain.residue;
+			} else {
+				/* No progress, check again in 1 second  */
+				schedule_delayed_work(&uc->tx_drain.work, HZ);
+				break;
+			}
+
+			spin_unlock_irqrestore(&uc->vc.lock, flags);
+
+			usleep_range(ktime_to_us(delay),
+				     ktime_to_us(delay) + 10);
+			continue;
+		}
+
+		if (uc->desc) {
+			struct udma_desc *d = uc->desc;
+
+			ud->udma_decrement_byte_counters(uc, d->residue);
+			ud->udma_start(uc);
+			vchan_cookie_complete(&d->vd);
+			break;
+		}
+
+		break;
+	}
+
+	spin_unlock_irqrestore(&uc->vc.lock, flags);
+}
+
+/**
+ * __udma_alloc_gp_rflow_range - alloc range of GP RX flows
+ * @ud: UDMA device
+ * @from: Start the search from this flow id number
+ * @cnt: Number of consecutive flow ids to allocate
+ *
+ * Allocate range of RX flow ids for future use, those flows can be requested
+ * only using explicit flow id number. if @from is set to -1 it will try to find
+ * first free range. if @from is positive value it will force allocation only
+ * of the specified range of flows.
+ *
+ * Returns -ENOMEM if can't find free range.
+ * -EEXIST if requested range is busy.
+ * -EINVAL if wrong input values passed.
+ * Returns flow id on success.
+ */
+int __udma_alloc_gp_rflow_range(struct udma_dev *ud, int from, int cnt)
+{
+	int start, tmp_from;
+	DECLARE_BITMAP(tmp, K3_UDMA_MAX_RFLOWS);
+
+	tmp_from = from;
+	if (tmp_from < 0)
+		tmp_from = ud->rchan_cnt;
+	/* default flows can't be allocated and accessible only by id */
+	if (tmp_from < ud->rchan_cnt)
+		return -EINVAL;
+
+	if (tmp_from + cnt > ud->rflow_cnt)
+		return -EINVAL;
+
+	bitmap_or(tmp, ud->rflow_gp_map, ud->rflow_gp_map_allocated,
+		  ud->rflow_cnt);
+
+	start = bitmap_find_next_zero_area(tmp,
+					   ud->rflow_cnt,
+					   tmp_from, cnt, 0);
+	if (start >= ud->rflow_cnt)
+		return -ENOMEM;
+
+	if (from >= 0 && start != from)
+		return -EEXIST;
+
+	bitmap_set(ud->rflow_gp_map_allocated, start, cnt);
+	return start;
+}
+
+int __udma_free_gp_rflow_range(struct udma_dev *ud, int from, int cnt)
+{
+	if (from < ud->rchan_cnt)
+		return -EINVAL;
+	if (from + cnt > ud->rflow_cnt)
+		return -EINVAL;
+
+	bitmap_clear(ud->rflow_gp_map_allocated, from, cnt);
+	return 0;
+}
+
+struct udma_rflow *__udma_get_rflow(struct udma_dev *ud, int id)
+{
+	/*
+	 * Attempt to request rflow by ID can be made for any rflow
+	 * if not in use with assumption that caller knows what's doing.
+	 * TI-SCI FW will perform additional permission check ant way, it's
+	 * safe
+	 */
+
+	if (id < 0 || id >= ud->rflow_cnt)
+		return ERR_PTR(-ENOENT);
+
+	if (test_bit(id, ud->rflow_in_use))
+		return ERR_PTR(-ENOENT);
+
+	if (ud->rflow_gp_map) {
+		/* GP rflow has to be allocated first */
+		if (!test_bit(id, ud->rflow_gp_map) &&
+		    !test_bit(id, ud->rflow_gp_map_allocated))
+			return ERR_PTR(-EINVAL);
+	}
+
+	dev_dbg(ud->dev, "get rflow%d\n", id);
+	set_bit(id, ud->rflow_in_use);
+	return &ud->rflows[id];
+}
+
+void __udma_put_rflow(struct udma_dev *ud, struct udma_rflow *rflow)
+{
+	if (!test_bit(rflow->id, ud->rflow_in_use)) {
+		dev_err(ud->dev, "attempt to put unused rflow%d\n", rflow->id);
+		return;
+	}
+
+	dev_dbg(ud->dev, "put rflow%d\n", rflow->id);
+	clear_bit(rflow->id, ud->rflow_in_use);
+}
+
+#define UDMA_RESERVE_RESOURCE(res)					\
+struct udma_##res *__udma_reserve_##res(struct udma_dev *ud,	\
+					       enum udma_tp_level tpl,	\
+					       int id)			\
+{									\
+	if (id >= 0) {							\
+		if (test_bit(id, ud->res##_map)) {			\
+			dev_err(ud->dev, "res##%d is in use\n", id);	\
+			return ERR_PTR(-ENOENT);			\
+		}							\
+	} else {							\
+		int start;						\
+									\
+		if (tpl >= ud->res##_tpl.levels)			\
+			tpl = ud->res##_tpl.levels - 1;			\
+									\
+		start = ud->res##_tpl.start_idx[tpl];			\
+									\
+		id = find_next_zero_bit(ud->res##_map, ud->res##_cnt,	\
+					start);				\
+		if (id == ud->res##_cnt) {				\
+			return ERR_PTR(-ENOENT);			\
+		}							\
+	}								\
+									\
+	set_bit(id, ud->res##_map);					\
+	return &ud->res##s[id];						\
+}
+
+UDMA_RESERVE_RESOURCE(bchan);
+UDMA_RESERVE_RESOURCE(tchan);
+UDMA_RESERVE_RESOURCE(rchan);
+
+int udma_get_tchan(struct udma_chan *uc)
+{
+	struct udma_dev *ud = uc->ud;
+	int ret;
+
+	if (uc->tchan) {
+		dev_dbg(ud->dev, "chan%d: already have tchan%d allocated\n",
+			uc->id, uc->tchan->id);
+		return 0;
+	}
+
+	/*
+	 * mapped_channel_id is -1 for UDMA, BCDMA and PKTDMA unmapped channels.
+	 * For PKTDMA mapped channels it is configured to a channel which must
+	 * be used to service the peripheral.
+	 */
+	uc->tchan = __udma_reserve_tchan(ud, uc->config.channel_tpl,
+					 uc->config.mapped_channel_id);
+	if (IS_ERR(uc->tchan)) {
+		ret = PTR_ERR(uc->tchan);
+		uc->tchan = NULL;
+		return ret;
+	}
+	if (ud->match_data->type == DMA_TYPE_BCDMA_V2)
+		uc->chan = uc->tchan;
+
+	if (ud->tflow_cnt) {
+		int tflow_id;
+
+		/* Only PKTDMA have support for tx flows */
+		if (uc->config.default_flow_id >= 0)
+			tflow_id = uc->config.default_flow_id;
+		else
+			tflow_id = uc->tchan->id;
+
+		if (test_bit(tflow_id, ud->tflow_map)) {
+			dev_err(ud->dev, "tflow%d is in use\n", tflow_id);
+			clear_bit(uc->tchan->id, ud->tchan_map);
+			uc->tchan = NULL;
+			return -ENOENT;
+		}
+
+		uc->tchan->tflow_id = tflow_id;
+		set_bit(tflow_id, ud->tflow_map);
+	} else {
+		uc->tchan->tflow_id = -1;
+	}
+
+	return 0;
+}
+
+int udma_get_rchan(struct udma_chan *uc)
+{
+	struct udma_dev *ud = uc->ud;
+	int ret;
+
+	if (uc->rchan) {
+		dev_dbg(ud->dev, "chan%d: already have rchan%d allocated\n",
+			uc->id, uc->rchan->id);
+		return 0;
+	}
+
+	/*
+	 * mapped_channel_id is -1 for UDMA, BCDMA and PKTDMA unmapped channels.
+	 * For PKTDMA mapped channels it is configured to a channel which must
+	 * be used to service the peripheral.
+	 */
+	uc->rchan = __udma_reserve_rchan(ud, uc->config.channel_tpl,
+					 uc->config.mapped_channel_id);
+	if (IS_ERR(uc->rchan)) {
+		ret = PTR_ERR(uc->rchan);
+		uc->rchan = NULL;
+		return ret;
+	}
+	if (ud->match_data->type == DMA_TYPE_BCDMA_V2)
+		uc->chan = uc->rchan;
+
+	return 0;
+}
+
+int udma_get_chan_pair(struct udma_chan *uc)
+{
+	struct udma_dev *ud = uc->ud;
+	int chan_id, end;
+
+	if ((uc->tchan && uc->rchan) && uc->tchan->id == uc->rchan->id) {
+		dev_info(ud->dev, "chan%d: already have %d pair allocated\n",
+			 uc->id, uc->tchan->id);
+		return 0;
+	}
+
+	if (uc->tchan) {
+		dev_err(ud->dev, "chan%d: already have tchan%d allocated\n",
+			uc->id, uc->tchan->id);
+		return -EBUSY;
+	} else if (uc->rchan) {
+		dev_err(ud->dev, "chan%d: already have rchan%d allocated\n",
+			uc->id, uc->rchan->id);
+		return -EBUSY;
+	}
+
+	/* Can be optimized, but let's have it like this for now */
+	end = min(ud->tchan_cnt, ud->rchan_cnt);
+	/*
+	 * Try to use the highest TPL channel pair for MEM_TO_MEM channels
+	 * Note: in UDMAP the channel TPL is symmetric between tchan and rchan
+	 */
+	chan_id = ud->tchan_tpl.start_idx[ud->tchan_tpl.levels - 1];
+	for (; chan_id < end; chan_id++) {
+		if (!test_bit(chan_id, ud->tchan_map) &&
+		    !test_bit(chan_id, ud->rchan_map))
+			break;
+	}
+
+	if (chan_id == end)
+		return -ENOENT;
+
+	set_bit(chan_id, ud->tchan_map);
+	set_bit(chan_id, ud->rchan_map);
+	uc->tchan = &ud->tchans[chan_id];
+	uc->rchan = &ud->rchans[chan_id];
+
+	/* UDMA does not use tx flows */
+	uc->tchan->tflow_id = -1;
+
+	return 0;
+}
+
+int udma_get_rflow(struct udma_chan *uc, int flow_id)
+{
+	struct udma_dev *ud = uc->ud;
+	int ret;
+
+	if (!uc->rchan) {
+		dev_err(ud->dev, "chan%d: does not have rchan??\n", uc->id);
+		return -EINVAL;
+	}
+
+	if (uc->rflow) {
+		dev_dbg(ud->dev, "chan%d: already have rflow%d allocated\n",
+			uc->id, uc->rflow->id);
+		return 0;
+	}
+
+	uc->rflow = __udma_get_rflow(ud, flow_id);
+	if (IS_ERR(uc->rflow)) {
+		ret = PTR_ERR(uc->rflow);
+		uc->rflow = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+
+void bcdma_put_bchan(struct udma_chan *uc)
+{
+	struct udma_dev *ud = uc->ud;
+
+	if (uc->bchan) {
+		dev_dbg(ud->dev, "chan%d: put bchan%d\n", uc->id,
+			uc->bchan->id);
+		clear_bit(uc->bchan->id, ud->bchan_map);
+		uc->bchan = NULL;
+		uc->tchan = NULL;
+	}
+}
+
+void udma_put_rchan(struct udma_chan *uc)
+{
+	struct udma_dev *ud = uc->ud;
+
+	if (uc->rchan) {
+		dev_dbg(ud->dev, "chan%d: put rchan%d\n", uc->id,
+			uc->rchan->id);
+		clear_bit(uc->rchan->id, ud->rchan_map);
+		uc->rchan = NULL;
+	}
+}
+
+void udma_put_tchan(struct udma_chan *uc)
+{
+	struct udma_dev *ud = uc->ud;
+
+	if (uc->tchan) {
+		dev_dbg(ud->dev, "chan%d: put tchan%d\n", uc->id,
+			uc->tchan->id);
+		clear_bit(uc->tchan->id, ud->tchan_map);
+
+		if (uc->tchan->tflow_id >= 0)
+			clear_bit(uc->tchan->tflow_id, ud->tflow_map);
+
+		uc->tchan = NULL;
+	}
+}
+
+void udma_put_rflow(struct udma_chan *uc)
+{
+	struct udma_dev *ud = uc->ud;
+
+	if (uc->rflow) {
+		dev_dbg(ud->dev, "chan%d: put rflow%d\n", uc->id,
+			uc->rflow->id);
+		__udma_put_rflow(ud, uc->rflow);
+		uc->rflow = NULL;
+	}
+}
+
+void bcdma_free_bchan_resources(struct udma_chan *uc)
+{
+	if (!uc->bchan)
+		return;
+
+	k3_ringacc_ring_free(uc->bchan->tc_ring);
+	k3_ringacc_ring_free(uc->bchan->t_ring);
+	uc->bchan->tc_ring = NULL;
+	uc->bchan->t_ring = NULL;
+	k3_configure_chan_coherency(&uc->vc.chan, 0);
+
+	bcdma_put_bchan(uc);
+}
+
+void udma_free_tx_resources(struct udma_chan *uc)
+{
+	if (!uc->tchan)
+		return;
+
+	k3_ringacc_ring_free(uc->tchan->t_ring);
+	k3_ringacc_ring_free(uc->tchan->tc_ring);
+	uc->tchan->t_ring = NULL;
+	uc->tchan->tc_ring = NULL;
+
+	udma_put_tchan(uc);
+}
+
+void udma_free_rx_resources(struct udma_chan *uc)
+{
+	if (!uc->rchan)
+		return;
+
+	if (uc->rflow) {
+		struct udma_rflow *rflow = uc->rflow;
+
+		k3_ringacc_ring_free(rflow->fd_ring);
+		k3_ringacc_ring_free(rflow->r_ring);
+		rflow->fd_ring = NULL;
+		rflow->r_ring = NULL;
+
+		udma_put_rflow(uc);
+	}
+
+	udma_put_rchan(uc);
+}
+
+int udma_slave_config(struct dma_chan *chan,
+			     struct dma_slave_config *cfg)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+
+	memcpy(&uc->cfg, cfg, sizeof(uc->cfg));
+
+	return 0;
+}
+
+struct udma_desc *udma_alloc_tr_desc(struct udma_chan *uc,
+					    size_t tr_size, int tr_count,
+					    enum dma_transfer_direction dir)
+{
+	struct udma_hwdesc *hwdesc;
+	struct cppi5_desc_hdr_t *tr_desc;
+	struct udma_desc *d;
+	u32 reload_count = 0;
+	u32 ring_id;
+
+	switch (tr_size) {
+	case 16:
+	case 32:
+	case 64:
+	case 128:
+		break;
+	default:
+		dev_err(uc->ud->dev, "Unsupported TR size of %zu\n", tr_size);
+		return NULL;
+	}
+
+	/* We have only one descriptor containing multiple TRs */
+	d = kzalloc(sizeof(*d) + sizeof(d->hwdesc[0]), GFP_NOWAIT);
+	if (!d)
+		return NULL;
+
+	d->sglen = tr_count;
+
+	d->hwdesc_count = 1;
+	hwdesc = &d->hwdesc[0];
+
+	/* Allocate memory for DMA ring descriptor */
+	if (uc->use_dma_pool) {
+		hwdesc->cppi5_desc_size = uc->config.hdesc_size;
+		hwdesc->cppi5_desc_vaddr = dma_pool_zalloc(uc->hdesc_pool,
+						GFP_NOWAIT,
+						&hwdesc->cppi5_desc_paddr);
+	} else {
+		hwdesc->cppi5_desc_size = cppi5_trdesc_calc_size(tr_size,
+								 tr_count);
+		hwdesc->cppi5_desc_size = ALIGN(hwdesc->cppi5_desc_size,
+						uc->ud->desc_align);
+		hwdesc->cppi5_desc_vaddr = dma_alloc_coherent(uc->ud->dev,
+						hwdesc->cppi5_desc_size,
+						&hwdesc->cppi5_desc_paddr,
+						GFP_NOWAIT);
+	}
+
+	if (!hwdesc->cppi5_desc_vaddr) {
+		kfree(d);
+		return NULL;
+	}
+
+	/* Start of the TR req records */
+	hwdesc->tr_req_base = hwdesc->cppi5_desc_vaddr + tr_size;
+	/* Start address of the TR response array */
+	hwdesc->tr_resp_base = hwdesc->tr_req_base + tr_size * tr_count;
+
+	tr_desc = hwdesc->cppi5_desc_vaddr;
+
+	if (uc->cyclic)
+		reload_count = CPPI5_INFO0_TRDESC_RLDCNT_INFINITE;
+
+	if (dir == DMA_DEV_TO_MEM)
+		ring_id = k3_ringacc_get_ring_id(uc->rflow->r_ring);
+	else
+		ring_id = k3_ringacc_get_ring_id(uc->tchan->tc_ring);
+
+	cppi5_trdesc_init(tr_desc, tr_count, tr_size, 0, reload_count);
+	cppi5_desc_set_pktids(tr_desc, uc->id,
+			      CPPI5_INFO1_DESC_FLOWID_DEFAULT);
+	cppi5_desc_set_retpolicy(tr_desc, 0, ring_id);
+
+	return d;
+}
+
+/**
+ * udma_get_tr_counters - calculate TR counters for a given length
+ * @len: Length of the trasnfer
+ * @align_to: Preferred alignment
+ * @tr0_cnt0: First TR icnt0
+ * @tr0_cnt1: First TR icnt1
+ * @tr1_cnt0: Second (if used) TR icnt0
+ *
+ * For len < SZ_64K only one TR is enough, tr1_cnt0 is not updated
+ * For len >= SZ_64K two TRs are used in a simple way:
+ * First TR: SZ_64K-alignment blocks (tr0_cnt0, tr0_cnt1)
+ * Second TR: the remaining length (tr1_cnt0)
+ *
+ * Returns the number of TRs the length needs (1 or 2)
+ * -EINVAL if the length can not be supported
+ */
+int udma_get_tr_counters(size_t len, unsigned long align_to,
+				u16 *tr0_cnt0, u16 *tr0_cnt1, u16 *tr1_cnt0)
+{
+	if (len < SZ_64K) {
+		*tr0_cnt0 = len;
+		*tr0_cnt1 = 1;
+
+		return 1;
+	}
+
+	if (align_to > 3)
+		align_to = 3;
+
+realign:
+	*tr0_cnt0 = SZ_64K - BIT(align_to);
+	if (len / *tr0_cnt0 >= SZ_64K) {
+		if (align_to) {
+			align_to--;
+			goto realign;
+		}
+		return -EINVAL;
+	}
+
+	*tr0_cnt1 = len / *tr0_cnt0;
+	*tr1_cnt0 = len % *tr0_cnt0;
+
+	return 2;
+}
+
+struct udma_desc *
+udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl,
+		      unsigned int sglen, enum dma_transfer_direction dir,
+		      unsigned long tx_flags, void *context)
+{
+	struct scatterlist *sgent;
+	struct udma_desc *d;
+	struct cppi5_tr_type1_t *tr_req = NULL;
+	u16 tr0_cnt0, tr0_cnt1, tr1_cnt0;
+	unsigned int i;
+	size_t tr_size;
+	int num_tr = 0;
+	int tr_idx = 0;
+	u32 extra_flags = 0;
+	u64 asel;
+
+	/* estimate the number of TRs we will need */
+	for_each_sg(sgl, sgent, sglen, i) {
+		if (sg_dma_len(sgent) < SZ_64K)
+			num_tr++;
+		else
+			num_tr += 2;
+	}
+
+	/* Now allocate and setup the descriptor. */
+	tr_size = sizeof(struct cppi5_tr_type1_t);
+	d = udma_alloc_tr_desc(uc, tr_size, num_tr, dir);
+	if (!d)
+		return NULL;
+
+	d->sglen = sglen;
+
+	if (uc->ud->match_data->type == DMA_TYPE_UDMA)
+		asel = 0;
+	else
+		asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT;
+
+	if (dir == DMA_MEM_TO_DEV && uc->ud->match_data->type == DMA_TYPE_BCDMA_V2)
+		extra_flags = CPPI5_TR_CSF_EOP;
+
+	tr_req = d->hwdesc[0].tr_req_base;
+	for_each_sg(sgl, sgent, sglen, i) {
+		dma_addr_t sg_addr = sg_dma_address(sgent);
+
+		num_tr = udma_get_tr_counters(sg_dma_len(sgent), __ffs(sg_addr),
+					      &tr0_cnt0, &tr0_cnt1, &tr1_cnt0);
+		if (num_tr < 0) {
+			dev_err(uc->ud->dev, "size %u is not supported\n",
+				sg_dma_len(sgent));
+			udma_free_hwdesc(uc, d);
+			kfree(d);
+			return NULL;
+		}
+
+		cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE1, false,
+			      false, CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
+		cppi5_tr_csf_set(&tr_req[tr_idx].flags, CPPI5_TR_CSF_SUPR_EVT | extra_flags);
+
+		sg_addr |= asel;
+		tr_req[tr_idx].addr = sg_addr;
+		tr_req[tr_idx].icnt0 = tr0_cnt0;
+		tr_req[tr_idx].icnt1 = tr0_cnt1;
+		tr_req[tr_idx].dim1 = tr0_cnt0;
+		tr_idx++;
+
+		if (num_tr == 2) {
+			cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE1,
+				      false, false,
+				      CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
+			cppi5_tr_csf_set(&tr_req[tr_idx].flags,
+					 CPPI5_TR_CSF_SUPR_EVT | extra_flags);
+
+			tr_req[tr_idx].addr = sg_addr + tr0_cnt1 * tr0_cnt0;
+			tr_req[tr_idx].icnt0 = tr1_cnt0;
+			tr_req[tr_idx].icnt1 = 1;
+			tr_req[tr_idx].dim1 = tr1_cnt0;
+			tr_idx++;
+		}
+
+		d->residue += sg_dma_len(sgent);
+	}
+
+	cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags,
+			 CPPI5_TR_CSF_SUPR_EVT | CPPI5_TR_CSF_EOP);
+
+	return d;
+}
+
+struct udma_desc *
+udma_prep_slave_sg_triggered_tr(struct udma_chan *uc, struct scatterlist *sgl,
+				unsigned int sglen,
+				enum dma_transfer_direction dir,
+				unsigned long tx_flags, void *context)
+{
+	struct scatterlist *sgent;
+	struct cppi5_tr_type15_t *tr_req = NULL;
+	enum dma_slave_buswidth dev_width;
+	u32 csf = CPPI5_TR_CSF_SUPR_EVT;
+	u16 tr_cnt0, tr_cnt1;
+	dma_addr_t dev_addr;
+	struct udma_desc *d;
+	unsigned int i;
+	size_t tr_size, sg_len;
+	int num_tr = 0;
+	int tr_idx = 0;
+	u32 burst, trigger_size, port_window;
+	u64 asel;
+
+	if (dir == DMA_DEV_TO_MEM) {
+		dev_addr = uc->cfg.src_addr;
+		dev_width = uc->cfg.src_addr_width;
+		burst = uc->cfg.src_maxburst;
+		port_window = uc->cfg.src_port_window_size;
+	} else if (dir == DMA_MEM_TO_DEV) {
+		dev_addr = uc->cfg.dst_addr;
+		dev_width = uc->cfg.dst_addr_width;
+		burst = uc->cfg.dst_maxburst;
+		port_window = uc->cfg.dst_port_window_size;
+	} else {
+		dev_err(uc->ud->dev, "%s: bad direction?\n", __func__);
+		return NULL;
+	}
+
+	if (!burst)
+		burst = 1;
+
+	if (port_window) {
+		if (port_window != burst) {
+			dev_err(uc->ud->dev,
+				"The burst must be equal to port_window\n");
+			return NULL;
+		}
+
+		tr_cnt0 = dev_width * port_window;
+		tr_cnt1 = 1;
+	} else {
+		tr_cnt0 = dev_width;
+		tr_cnt1 = burst;
+	}
+	trigger_size = tr_cnt0 * tr_cnt1;
+
+	/* estimate the number of TRs we will need */
+	for_each_sg(sgl, sgent, sglen, i) {
+		sg_len = sg_dma_len(sgent);
+
+		if (sg_len % trigger_size) {
+			dev_err(uc->ud->dev,
+				"Not aligned SG entry (%zu for %u)\n", sg_len,
+				trigger_size);
+			return NULL;
+		}
+
+		if (sg_len / trigger_size < SZ_64K)
+			num_tr++;
+		else
+			num_tr += 2;
+	}
+
+	/* Now allocate and setup the descriptor. */
+	tr_size = sizeof(struct cppi5_tr_type15_t);
+	d = udma_alloc_tr_desc(uc, tr_size, num_tr, dir);
+	if (!d)
+		return NULL;
+
+	d->sglen = sglen;
+
+	if (uc->ud->match_data->type == DMA_TYPE_UDMA) {
+		asel = 0;
+		csf |= CPPI5_TR_CSF_EOL_ICNT0;
+	} else {
+		asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT;
+		dev_addr |= asel;
+	}
+
+	tr_req = d->hwdesc[0].tr_req_base;
+	for_each_sg(sgl, sgent, sglen, i) {
+		u16 tr0_cnt2, tr0_cnt3, tr1_cnt2;
+		dma_addr_t sg_addr = sg_dma_address(sgent);
+
+		sg_len = sg_dma_len(sgent);
+		num_tr = udma_get_tr_counters(sg_len / trigger_size, 0,
+					      &tr0_cnt2, &tr0_cnt3, &tr1_cnt2);
+		if (num_tr < 0) {
+			dev_err(uc->ud->dev, "size %zu is not supported\n",
+				sg_len);
+			udma_free_hwdesc(uc, d);
+			kfree(d);
+			return NULL;
+		}
+
+		cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE15, false,
+			      true, CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
+		cppi5_tr_csf_set(&tr_req[tr_idx].flags, csf);
+		cppi5_tr_set_trigger(&tr_req[tr_idx].flags,
+				     uc->config.tr_trigger_type,
+				     CPPI5_TR_TRIGGER_TYPE_ICNT2_DEC, 0, 0);
+
+		sg_addr |= asel;
+		if (dir == DMA_DEV_TO_MEM) {
+			tr_req[tr_idx].addr = dev_addr;
+			tr_req[tr_idx].icnt0 = tr_cnt0;
+			tr_req[tr_idx].icnt1 = tr_cnt1;
+			tr_req[tr_idx].icnt2 = tr0_cnt2;
+			tr_req[tr_idx].icnt3 = tr0_cnt3;
+			tr_req[tr_idx].dim1 = (-1) * tr_cnt0;
+
+			tr_req[tr_idx].daddr = sg_addr;
+			tr_req[tr_idx].dicnt0 = tr_cnt0;
+			tr_req[tr_idx].dicnt1 = tr_cnt1;
+			tr_req[tr_idx].dicnt2 = tr0_cnt2;
+			tr_req[tr_idx].dicnt3 = tr0_cnt3;
+			tr_req[tr_idx].ddim1 = tr_cnt0;
+			tr_req[tr_idx].ddim2 = trigger_size;
+			tr_req[tr_idx].ddim3 = trigger_size * tr0_cnt2;
+		} else {
+			tr_req[tr_idx].addr = sg_addr;
+			tr_req[tr_idx].icnt0 = tr_cnt0;
+			tr_req[tr_idx].icnt1 = tr_cnt1;
+			tr_req[tr_idx].icnt2 = tr0_cnt2;
+			tr_req[tr_idx].icnt3 = tr0_cnt3;
+			tr_req[tr_idx].dim1 = tr_cnt0;
+			tr_req[tr_idx].dim2 = trigger_size;
+			tr_req[tr_idx].dim3 = trigger_size * tr0_cnt2;
+
+			tr_req[tr_idx].daddr = dev_addr;
+			tr_req[tr_idx].dicnt0 = tr_cnt0;
+			tr_req[tr_idx].dicnt1 = tr_cnt1;
+			tr_req[tr_idx].dicnt2 = tr0_cnt2;
+			tr_req[tr_idx].dicnt3 = tr0_cnt3;
+			tr_req[tr_idx].ddim1 = (-1) * tr_cnt0;
+		}
+
+		tr_idx++;
+
+		if (num_tr == 2) {
+			cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE15,
+				      false, true,
+				      CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
+			cppi5_tr_csf_set(&tr_req[tr_idx].flags, csf);
+			cppi5_tr_set_trigger(&tr_req[tr_idx].flags,
+					     uc->config.tr_trigger_type,
+					     CPPI5_TR_TRIGGER_TYPE_ICNT2_DEC,
+					     0, 0);
+
+			sg_addr += trigger_size * tr0_cnt2 * tr0_cnt3;
+			if (dir == DMA_DEV_TO_MEM) {
+				tr_req[tr_idx].addr = dev_addr;
+				tr_req[tr_idx].icnt0 = tr_cnt0;
+				tr_req[tr_idx].icnt1 = tr_cnt1;
+				tr_req[tr_idx].icnt2 = tr1_cnt2;
+				tr_req[tr_idx].icnt3 = 1;
+				tr_req[tr_idx].dim1 = (-1) * tr_cnt0;
+
+				tr_req[tr_idx].daddr = sg_addr;
+				tr_req[tr_idx].dicnt0 = tr_cnt0;
+				tr_req[tr_idx].dicnt1 = tr_cnt1;
+				tr_req[tr_idx].dicnt2 = tr1_cnt2;
+				tr_req[tr_idx].dicnt3 = 1;
+				tr_req[tr_idx].ddim1 = tr_cnt0;
+				tr_req[tr_idx].ddim2 = trigger_size;
+			} else {
+				tr_req[tr_idx].addr = sg_addr;
+				tr_req[tr_idx].icnt0 = tr_cnt0;
+				tr_req[tr_idx].icnt1 = tr_cnt1;
+				tr_req[tr_idx].icnt2 = tr1_cnt2;
+				tr_req[tr_idx].icnt3 = 1;
+				tr_req[tr_idx].dim1 = tr_cnt0;
+				tr_req[tr_idx].dim2 = trigger_size;
+
+				tr_req[tr_idx].daddr = dev_addr;
+				tr_req[tr_idx].dicnt0 = tr_cnt0;
+				tr_req[tr_idx].dicnt1 = tr_cnt1;
+				tr_req[tr_idx].dicnt2 = tr1_cnt2;
+				tr_req[tr_idx].dicnt3 = 1;
+				tr_req[tr_idx].ddim1 = (-1) * tr_cnt0;
+			}
+			tr_idx++;
+		}
+
+		d->residue += sg_len;
+	}
+
+	cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags, csf | CPPI5_TR_CSF_EOP);
+
+	return d;
+}
+
+int udma_configure_statictr(struct udma_chan *uc, struct udma_desc *d,
+				   enum dma_slave_buswidth dev_width,
+				   u16 elcnt)
+{
+	if (uc->config.ep_type != PSIL_EP_PDMA_XY)
+		return 0;
+
+	/* Bus width translates to the element size (ES) */
+	switch (dev_width) {
+	case DMA_SLAVE_BUSWIDTH_1_BYTE:
+		d->static_tr.elsize = 0;
+		break;
+	case DMA_SLAVE_BUSWIDTH_2_BYTES:
+		d->static_tr.elsize = 1;
+		break;
+	case DMA_SLAVE_BUSWIDTH_3_BYTES:
+		d->static_tr.elsize = 2;
+		break;
+	case DMA_SLAVE_BUSWIDTH_4_BYTES:
+		d->static_tr.elsize = 3;
+		break;
+	case DMA_SLAVE_BUSWIDTH_8_BYTES:
+		d->static_tr.elsize = 4;
+		break;
+	default: /* not reached */
+		return -EINVAL;
+	}
+
+	d->static_tr.elcnt = elcnt;
+
+	if (uc->config.pkt_mode || !uc->cyclic) {
+		/*
+		 * PDMA must close the packet when the channel is in packet mode.
+		 * For TR mode when the channel is not cyclic we also need PDMA
+		 * to close the packet otherwise the transfer will stall because
+		 * PDMA holds on the data it has received from the peripheral.
+		 */
+		unsigned int div = dev_width * elcnt;
+
+		if (uc->cyclic)
+			d->static_tr.bstcnt = d->residue / d->sglen / div;
+		else
+			d->static_tr.bstcnt = d->residue / div;
+	} else if ((uc->ud->match_data->type == DMA_TYPE_BCDMA ||
+				uc->ud->match_data->type == DMA_TYPE_BCDMA_V2) &&
+		   uc->config.dir == DMA_DEV_TO_MEM &&
+		   uc->cyclic) {
+		/*
+		 * For cyclic mode with BCDMA we have to set EOP in each TR to
+		 * prevent short packet errors seen on channel teardown. So the
+		 * PDMA must close the packet after every TR transfer by setting
+		 * burst count equal to the number of bytes transferred.
+		 */
+		struct cppi5_tr_type1_t *tr_req = d->hwdesc[0].tr_req_base;
+
+		d->static_tr.bstcnt =
+			(tr_req->icnt0 * tr_req->icnt1) / dev_width;
+	} else {
+		d->static_tr.bstcnt = 0;
+	}
+
+	if (uc->config.dir == DMA_DEV_TO_MEM &&
+	    d->static_tr.bstcnt > uc->ud->match_data->statictr_z_mask)
+		return -EINVAL;
+
+	return 0;
+}
+
+struct udma_desc *
+udma_prep_slave_sg_pkt(struct udma_chan *uc, struct scatterlist *sgl,
+		       unsigned int sglen, enum dma_transfer_direction dir,
+		       unsigned long tx_flags, void *context)
+{
+	struct scatterlist *sgent;
+	struct cppi5_host_desc_t *h_desc = NULL;
+	struct udma_desc *d;
+	u32 ring_id;
+	unsigned int i;
+	u64 asel;
+
+	d = kzalloc(struct_size(d, hwdesc, sglen), GFP_NOWAIT);
+	if (!d)
+		return NULL;
+
+	d->sglen = sglen;
+	d->hwdesc_count = sglen;
+
+	if (dir == DMA_DEV_TO_MEM)
+		ring_id = k3_ringacc_get_ring_id(uc->rflow->r_ring);
+	else
+		ring_id = k3_ringacc_get_ring_id(uc->tchan->tc_ring);
+
+	if (uc->ud->match_data->type == DMA_TYPE_UDMA)
+		asel = 0;
+	else
+		asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT;
+
+	for_each_sg(sgl, sgent, sglen, i) {
+		struct udma_hwdesc *hwdesc = &d->hwdesc[i];
+		dma_addr_t sg_addr = sg_dma_address(sgent);
+		struct cppi5_host_desc_t *desc;
+		size_t sg_len = sg_dma_len(sgent);
+
+		hwdesc->cppi5_desc_vaddr = dma_pool_zalloc(uc->hdesc_pool,
+						GFP_NOWAIT,
+						&hwdesc->cppi5_desc_paddr);
+		if (!hwdesc->cppi5_desc_vaddr) {
+			dev_err(uc->ud->dev,
+				"descriptor%d allocation failed\n", i);
+
+			udma_free_hwdesc(uc, d);
+			kfree(d);
+			return NULL;
+		}
+
+		d->residue += sg_len;
+		hwdesc->cppi5_desc_size = uc->config.hdesc_size;
+		desc = hwdesc->cppi5_desc_vaddr;
+
+		if (i == 0) {
+			cppi5_hdesc_init(desc, 0, 0);
+			/* Flow and Packed ID */
+			cppi5_desc_set_pktids(&desc->hdr, uc->id,
+					      CPPI5_INFO1_DESC_FLOWID_DEFAULT);
+			cppi5_desc_set_retpolicy(&desc->hdr, 0, ring_id);
+		} else {
+			cppi5_hdesc_reset_hbdesc(desc);
+			cppi5_desc_set_retpolicy(&desc->hdr, 0, 0xffff);
+		}
+
+		/* attach the sg buffer to the descriptor */
+		sg_addr |= asel;
+		cppi5_hdesc_attach_buf(desc, sg_addr, sg_len, sg_addr, sg_len);
+
+		/* Attach link as host buffer descriptor */
+		if (h_desc)
+			cppi5_hdesc_link_hbdesc(h_desc,
+						hwdesc->cppi5_desc_paddr | asel);
+
+		if (uc->ud->match_data->type == DMA_TYPE_PKTDMA ||
+		    dir == DMA_MEM_TO_DEV)
+			h_desc = desc;
+	}
+
+	if (d->residue >= SZ_4M) {
+		dev_err(uc->ud->dev,
+			"%s: Transfer size %u is over the supported 4M range\n",
+			__func__, d->residue);
+		udma_free_hwdesc(uc, d);
+		kfree(d);
+		return NULL;
+	}
+
+	h_desc = d->hwdesc[0].cppi5_desc_vaddr;
+	cppi5_hdesc_set_pktlen(h_desc, d->residue);
+
+	return d;
+}
+
+int udma_attach_metadata(struct dma_async_tx_descriptor *desc,
+				void *data, size_t len)
+{
+	struct udma_desc *d = to_udma_desc(desc);
+	struct udma_chan *uc = to_udma_chan(desc->chan);
+	struct cppi5_host_desc_t *h_desc;
+	u32 psd_size = len;
+	u32 flags = 0;
+
+	if (!uc->config.pkt_mode || !uc->config.metadata_size)
+		return -EOPNOTSUPP;
+
+	if (!data || len > uc->config.metadata_size)
+		return -EINVAL;
+
+	if (uc->config.needs_epib && len < CPPI5_INFO0_HDESC_EPIB_SIZE)
+		return -EINVAL;
+
+	h_desc = d->hwdesc[0].cppi5_desc_vaddr;
+	if (d->dir == DMA_MEM_TO_DEV)
+		memcpy(h_desc->epib, data, len);
+
+	if (uc->config.needs_epib)
+		psd_size -= CPPI5_INFO0_HDESC_EPIB_SIZE;
+
+	d->metadata = data;
+	d->metadata_size = len;
+	if (uc->config.needs_epib)
+		flags |= CPPI5_INFO0_HDESC_EPIB_PRESENT;
+
+	cppi5_hdesc_update_flags(h_desc, flags);
+	cppi5_hdesc_update_psdata_size(h_desc, psd_size);
+
+	return 0;
+}
+
+void *udma_get_metadata_ptr(struct dma_async_tx_descriptor *desc,
+				   size_t *payload_len, size_t *max_len)
+{
+	struct udma_desc *d = to_udma_desc(desc);
+	struct udma_chan *uc = to_udma_chan(desc->chan);
+	struct cppi5_host_desc_t *h_desc;
+
+	if (!uc->config.pkt_mode || !uc->config.metadata_size)
+		return ERR_PTR(-EOPNOTSUPP);
+
+	h_desc = d->hwdesc[0].cppi5_desc_vaddr;
+
+	*max_len = uc->config.metadata_size;
+
+	*payload_len = cppi5_hdesc_epib_present(&h_desc->hdr) ?
+		       CPPI5_INFO0_HDESC_EPIB_SIZE : 0;
+	*payload_len += cppi5_hdesc_get_psdata_size(h_desc);
+
+	return h_desc->epib;
+}
+
+int udma_set_metadata_len(struct dma_async_tx_descriptor *desc,
+				 size_t payload_len)
+{
+	struct udma_desc *d = to_udma_desc(desc);
+	struct udma_chan *uc = to_udma_chan(desc->chan);
+	struct cppi5_host_desc_t *h_desc;
+	u32 psd_size = payload_len;
+	u32 flags = 0;
+
+	if (!uc->config.pkt_mode || !uc->config.metadata_size)
+		return -EOPNOTSUPP;
+
+	if (payload_len > uc->config.metadata_size)
+		return -EINVAL;
+
+	if (uc->config.needs_epib && payload_len < CPPI5_INFO0_HDESC_EPIB_SIZE)
+		return -EINVAL;
+
+	h_desc = d->hwdesc[0].cppi5_desc_vaddr;
+
+	if (uc->config.needs_epib) {
+		psd_size -= CPPI5_INFO0_HDESC_EPIB_SIZE;
+		flags |= CPPI5_INFO0_HDESC_EPIB_PRESENT;
+	}
+
+	cppi5_hdesc_update_flags(h_desc, flags);
+	cppi5_hdesc_update_psdata_size(h_desc, psd_size);
+
+	return 0;
+}
+
+struct dma_descriptor_metadata_ops metadata_ops = {
+	.attach = udma_attach_metadata,
+	.get_ptr = udma_get_metadata_ptr,
+	.set_len = udma_set_metadata_len,
+};
+
+struct dma_async_tx_descriptor *
+udma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+		   unsigned int sglen, enum dma_transfer_direction dir,
+		   unsigned long tx_flags, void *context)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+	enum dma_slave_buswidth dev_width;
+	struct udma_desc *d;
+	u32 burst;
+
+	if (dir != uc->config.dir &&
+	    (uc->config.dir == DMA_MEM_TO_MEM && !uc->config.tr_trigger_type)) {
+		dev_err(chan->device->dev,
+			"%s: chan%d is for %s, not supporting %s\n",
+			__func__, uc->id,
+			dmaengine_get_direction_text(uc->config.dir),
+			dmaengine_get_direction_text(dir));
+		return NULL;
+	}
+
+	if (dir == DMA_DEV_TO_MEM) {
+		dev_width = uc->cfg.src_addr_width;
+		burst = uc->cfg.src_maxburst;
+	} else if (dir == DMA_MEM_TO_DEV) {
+		dev_width = uc->cfg.dst_addr_width;
+		burst = uc->cfg.dst_maxburst;
+	} else {
+		dev_err(chan->device->dev, "%s: bad direction?\n", __func__);
+		return NULL;
+	}
+
+	if (!burst)
+		burst = 1;
+
+	uc->config.tx_flags = tx_flags;
+
+	if (uc->config.pkt_mode)
+		d = udma_prep_slave_sg_pkt(uc, sgl, sglen, dir, tx_flags,
+					   context);
+	else if (is_slave_direction(uc->config.dir))
+		d = udma_prep_slave_sg_tr(uc, sgl, sglen, dir, tx_flags,
+					  context);
+	else
+		d = udma_prep_slave_sg_triggered_tr(uc, sgl, sglen, dir,
+						    tx_flags, context);
+
+	if (!d)
+		return NULL;
+
+	d->dir = dir;
+	d->desc_idx = 0;
+	d->tr_idx = 0;
+
+	/* static TR for remote PDMA */
+	if (udma_configure_statictr(uc, d, dev_width, burst)) {
+		dev_err(uc->ud->dev,
+			"%s: StaticTR Z is limited to maximum %u (%u)\n",
+			__func__, uc->ud->match_data->statictr_z_mask,
+			d->static_tr.bstcnt);
+
+		udma_free_hwdesc(uc, d);
+		kfree(d);
+		return NULL;
+	}
+
+	if (uc->config.metadata_size)
+		d->vd.tx.metadata_ops = &metadata_ops;
+
+	return vchan_tx_prep(&uc->vc, &d->vd, tx_flags);
+}
+
+struct udma_desc *
+udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr,
+			size_t buf_len, size_t period_len,
+			enum dma_transfer_direction dir, unsigned long flags)
+{
+	struct udma_desc *d;
+	size_t tr_size, period_addr;
+	struct cppi5_tr_type1_t *tr_req;
+	unsigned int periods = buf_len / period_len;
+	u16 tr0_cnt0, tr0_cnt1, tr1_cnt0;
+	unsigned int i;
+	int num_tr;
+	u32 period_csf = 0;
+
+	num_tr = udma_get_tr_counters(period_len, __ffs(buf_addr), &tr0_cnt0,
+				      &tr0_cnt1, &tr1_cnt0);
+	if (num_tr < 0) {
+		dev_err(uc->ud->dev, "size %zu is not supported\n",
+			period_len);
+		return NULL;
+	}
+
+	/* Now allocate and setup the descriptor. */
+	tr_size = sizeof(struct cppi5_tr_type1_t);
+	d = udma_alloc_tr_desc(uc, tr_size, periods * num_tr, dir);
+	if (!d)
+		return NULL;
+
+	tr_req = d->hwdesc[0].tr_req_base;
+	if (uc->ud->match_data->type == DMA_TYPE_UDMA)
+		period_addr = buf_addr;
+	else
+		period_addr = buf_addr |
+			((u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT);
+
+	/*
+	 * For BCDMA <-> PDMA transfers, the EOP flag needs to be set on the
+	 * last TR of a descriptor, to mark the packet as complete.
+	 * This is required for getting the teardown completion message in case
+	 * of TX, and to avoid short-packet error in case of RX.
+	 *
+	 * As we are in cyclic mode, we do not know which period might be the
+	 * last one, so set the flag for each period.
+	 */
+	if (uc->config.ep_type == PSIL_EP_PDMA_XY &&
+	    (uc->ud->match_data->type == DMA_TYPE_BCDMA ||
+		 uc->ud->match_data->type == DMA_TYPE_BCDMA_V2)) {
+		period_csf = CPPI5_TR_CSF_EOP;
+	}
+
+	for (i = 0; i < periods; i++) {
+		int tr_idx = i * num_tr;
+
+		cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE1, false,
+			      false, CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
+
+		tr_req[tr_idx].addr = period_addr;
+		tr_req[tr_idx].icnt0 = tr0_cnt0;
+		tr_req[tr_idx].icnt1 = tr0_cnt1;
+		tr_req[tr_idx].dim1 = tr0_cnt0;
+
+		if (num_tr == 2) {
+			cppi5_tr_csf_set(&tr_req[tr_idx].flags,
+					 CPPI5_TR_CSF_SUPR_EVT);
+			tr_idx++;
+
+			cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE1,
+				      false, false,
+				      CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
+
+			tr_req[tr_idx].addr = period_addr + tr0_cnt1 * tr0_cnt0;
+			tr_req[tr_idx].icnt0 = tr1_cnt0;
+			tr_req[tr_idx].icnt1 = 1;
+			tr_req[tr_idx].dim1 = tr1_cnt0;
+		}
+
+		if (!(flags & DMA_PREP_INTERRUPT))
+			period_csf |= CPPI5_TR_CSF_SUPR_EVT;
+
+		if (period_csf)
+			cppi5_tr_csf_set(&tr_req[tr_idx].flags, period_csf);
+
+		period_addr += period_len;
+	}
+
+	return d;
+}
+
+struct udma_desc *
+udma_prep_dma_cyclic_pkt(struct udma_chan *uc, dma_addr_t buf_addr,
+			 size_t buf_len, size_t period_len,
+			 enum dma_transfer_direction dir, unsigned long flags)
+{
+	struct udma_desc *d;
+	u32 ring_id;
+	int i;
+	int periods = buf_len / period_len;
+
+	if (periods > (K3_UDMA_DEFAULT_RING_SIZE - 1))
+		return NULL;
+
+	if (period_len >= SZ_4M)
+		return NULL;
+
+	d = kzalloc(struct_size(d, hwdesc, periods), GFP_NOWAIT);
+	if (!d)
+		return NULL;
+
+	d->hwdesc_count = periods;
+
+	/* TODO: re-check this... */
+	if (dir == DMA_DEV_TO_MEM)
+		ring_id = k3_ringacc_get_ring_id(uc->rflow->r_ring);
+	else
+		ring_id = k3_ringacc_get_ring_id(uc->tchan->tc_ring);
+
+	if (uc->ud->match_data->type != DMA_TYPE_UDMA)
+		buf_addr |= (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT;
+
+	for (i = 0; i < periods; i++) {
+		struct udma_hwdesc *hwdesc = &d->hwdesc[i];
+		dma_addr_t period_addr = buf_addr + (period_len * i);
+		struct cppi5_host_desc_t *h_desc;
+
+		hwdesc->cppi5_desc_vaddr = dma_pool_zalloc(uc->hdesc_pool,
+						GFP_NOWAIT,
+						&hwdesc->cppi5_desc_paddr);
+		if (!hwdesc->cppi5_desc_vaddr) {
+			dev_err(uc->ud->dev,
+				"descriptor%d allocation failed\n", i);
+
+			udma_free_hwdesc(uc, d);
+			kfree(d);
+			return NULL;
+		}
+
+		hwdesc->cppi5_desc_size = uc->config.hdesc_size;
+		h_desc = hwdesc->cppi5_desc_vaddr;
+
+		cppi5_hdesc_init(h_desc, 0, 0);
+		cppi5_hdesc_set_pktlen(h_desc, period_len);
+
+		/* Flow and Packed ID */
+		cppi5_desc_set_pktids(&h_desc->hdr, uc->id,
+				      CPPI5_INFO1_DESC_FLOWID_DEFAULT);
+		cppi5_desc_set_retpolicy(&h_desc->hdr, 0, ring_id);
+
+		/* attach each period to a new descriptor */
+		cppi5_hdesc_attach_buf(h_desc,
+				       period_addr, period_len,
+				       period_addr, period_len);
+	}
+
+	return d;
+}
+
+struct dma_async_tx_descriptor *
+udma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
+		     size_t period_len, enum dma_transfer_direction dir,
+		     unsigned long flags)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+	enum dma_slave_buswidth dev_width;
+	struct udma_desc *d;
+	u32 burst;
+
+	if (dir != uc->config.dir) {
+		dev_err(chan->device->dev,
+			"%s: chan%d is for %s, not supporting %s\n",
+			__func__, uc->id,
+			dmaengine_get_direction_text(uc->config.dir),
+			dmaengine_get_direction_text(dir));
+		return NULL;
+	}
+
+	uc->cyclic = true;
+
+	if (dir == DMA_DEV_TO_MEM) {
+		dev_width = uc->cfg.src_addr_width;
+		burst = uc->cfg.src_maxburst;
+	} else if (dir == DMA_MEM_TO_DEV) {
+		dev_width = uc->cfg.dst_addr_width;
+		burst = uc->cfg.dst_maxburst;
+	} else {
+		dev_err(uc->ud->dev, "%s: bad direction?\n", __func__);
+		return NULL;
+	}
+
+	if (!burst)
+		burst = 1;
+
+	if (uc->config.pkt_mode)
+		d = udma_prep_dma_cyclic_pkt(uc, buf_addr, buf_len, period_len,
+					     dir, flags);
+	else
+		d = udma_prep_dma_cyclic_tr(uc, buf_addr, buf_len, period_len,
+					    dir, flags);
+
+	if (!d)
+		return NULL;
+
+	d->sglen = buf_len / period_len;
+
+	d->dir = dir;
+	d->residue = buf_len;
+
+	/* static TR for remote PDMA */
+	if (udma_configure_statictr(uc, d, dev_width, burst)) {
+		dev_err(uc->ud->dev,
+			"%s: StaticTR Z is limited to maximum %u (%u)\n",
+			__func__, uc->ud->match_data->statictr_z_mask,
+			d->static_tr.bstcnt);
+
+		udma_free_hwdesc(uc, d);
+		kfree(d);
+		return NULL;
+	}
+
+	if (uc->config.metadata_size)
+		d->vd.tx.metadata_ops = &metadata_ops;
+
+	return vchan_tx_prep(&uc->vc, &d->vd, flags);
+}
+
+struct dma_async_tx_descriptor *
+udma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+		     size_t len, unsigned long tx_flags)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+	struct udma_desc *d;
+	struct cppi5_tr_type15_t *tr_req;
+	int num_tr;
+	size_t tr_size = sizeof(struct cppi5_tr_type15_t);
+	u16 tr0_cnt0, tr0_cnt1, tr1_cnt0;
+	u32 csf = CPPI5_TR_CSF_SUPR_EVT;
+
+	if (uc->config.dir != DMA_MEM_TO_MEM) {
+		dev_err(chan->device->dev,
+			"%s: chan%d is for %s, not supporting %s\n",
+			__func__, uc->id,
+			dmaengine_get_direction_text(uc->config.dir),
+			dmaengine_get_direction_text(DMA_MEM_TO_MEM));
+		return NULL;
+	}
+
+	num_tr = udma_get_tr_counters(len, __ffs(src | dest), &tr0_cnt0,
+				      &tr0_cnt1, &tr1_cnt0);
+	if (num_tr < 0) {
+		dev_err(uc->ud->dev, "size %zu is not supported\n",
+			len);
+		return NULL;
+	}
+
+	d = udma_alloc_tr_desc(uc, tr_size, num_tr, DMA_MEM_TO_MEM);
+	if (!d)
+		return NULL;
+
+	d->dir = DMA_MEM_TO_MEM;
+	d->desc_idx = 0;
+	d->tr_idx = 0;
+	d->residue = len;
+
+	if (uc->ud->match_data->type != DMA_TYPE_UDMA) {
+		src |= (u64)uc->ud->asel << K3_ADDRESS_ASEL_SHIFT;
+		dest |= (u64)uc->ud->asel << K3_ADDRESS_ASEL_SHIFT;
+	} else {
+		csf |= CPPI5_TR_CSF_EOL_ICNT0;
+	}
+
+	tr_req = d->hwdesc[0].tr_req_base;
+
+	cppi5_tr_init(&tr_req[0].flags, CPPI5_TR_TYPE15, false, true,
+		      CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
+	cppi5_tr_csf_set(&tr_req[0].flags, csf);
+
+	tr_req[0].addr = src;
+	tr_req[0].icnt0 = tr0_cnt0;
+	tr_req[0].icnt1 = tr0_cnt1;
+	tr_req[0].icnt2 = 1;
+	tr_req[0].icnt3 = 1;
+	tr_req[0].dim1 = tr0_cnt0;
+
+	tr_req[0].daddr = dest;
+	tr_req[0].dicnt0 = tr0_cnt0;
+	tr_req[0].dicnt1 = tr0_cnt1;
+	tr_req[0].dicnt2 = 1;
+	tr_req[0].dicnt3 = 1;
+	tr_req[0].ddim1 = tr0_cnt0;
+
+	if (num_tr == 2) {
+		cppi5_tr_init(&tr_req[1].flags, CPPI5_TR_TYPE15, false, true,
+			      CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
+		cppi5_tr_csf_set(&tr_req[1].flags, csf);
+
+		tr_req[1].addr = src + tr0_cnt1 * tr0_cnt0;
+		tr_req[1].icnt0 = tr1_cnt0;
+		tr_req[1].icnt1 = 1;
+		tr_req[1].icnt2 = 1;
+		tr_req[1].icnt3 = 1;
+
+		tr_req[1].daddr = dest + tr0_cnt1 * tr0_cnt0;
+		tr_req[1].dicnt0 = tr1_cnt0;
+		tr_req[1].dicnt1 = 1;
+		tr_req[1].dicnt2 = 1;
+		tr_req[1].dicnt3 = 1;
+	}
+
+	cppi5_tr_csf_set(&tr_req[num_tr - 1].flags, csf | CPPI5_TR_CSF_EOP);
+
+	if (uc->config.metadata_size)
+		d->vd.tx.metadata_ops = &metadata_ops;
+
+	return vchan_tx_prep(&uc->vc, &d->vd, tx_flags);
+}
+
+void udma_issue_pending(struct dma_chan *chan)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+	struct udma_dev *ud = to_udma_dev(chan->device);
+	unsigned long flags;
+
+	spin_lock_irqsave(&uc->vc.lock, flags);
+
+	/* If we have something pending and no active descriptor, then */
+	if (vchan_issue_pending(&uc->vc) && !uc->desc) {
+		/*
+		 * start a descriptor if the channel is NOT [marked as
+		 * terminating _and_ it is still running (teardown has not
+		 * completed yet)].
+		 */
+		if (!(uc->state == UDMA_CHAN_IS_TERMINATING &&
+		      udma_is_chan_running(uc)))
+			ud->udma_start(uc);
+	}
+
+	spin_unlock_irqrestore(&uc->vc.lock, flags);
+}
+
+int udma_terminate_all(struct dma_chan *chan)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+	struct udma_dev *ud = to_udma_dev(chan->device);
+	unsigned long flags;
+	LIST_HEAD(head);
+
+	spin_lock_irqsave(&uc->vc.lock, flags);
+
+	if (udma_is_chan_running(uc))
+		ud->udma_stop(uc);
+
+	if (uc->desc) {
+		uc->terminated_desc = uc->desc;
+		uc->desc = NULL;
+		uc->terminated_desc->terminated = true;
+		cancel_delayed_work(&uc->tx_drain.work);
+	}
+
+	uc->paused = false;
+
+	vchan_get_all_descriptors(&uc->vc, &head);
+	spin_unlock_irqrestore(&uc->vc.lock, flags);
+	vchan_dma_desc_free_list(&uc->vc, &head);
+
+	return 0;
+}
+
+void udma_synchronize(struct dma_chan *chan)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+	struct udma_dev *ud = to_udma_dev(chan->device);
+	unsigned long timeout = msecs_to_jiffies(1000);
+
+	vchan_synchronize(&uc->vc);
+
+	if (uc->state == UDMA_CHAN_IS_TERMINATING) {
+		timeout = wait_for_completion_timeout(&uc->teardown_completed,
+						      timeout);
+		if (!timeout) {
+			dev_warn(uc->ud->dev, "chan%d teardown timeout!\n",
+				 uc->id);
+			udma_dump_chan_stdata(uc);
+			ud->udma_reset_chan(uc, true);
+		}
+	}
+
+	ud->udma_reset_chan(uc, false);
+	if (udma_is_chan_running(uc))
+		dev_warn(uc->ud->dev, "chan%d refused to stop!\n", uc->id);
+
+	cancel_delayed_work_sync(&uc->tx_drain.work);
+	udma_reset_rings(uc);
+}
+
+void udma_desc_pre_callback(struct virt_dma_chan *vc,
+				   struct virt_dma_desc *vd,
+				   struct dmaengine_result *result)
+{
+	struct udma_chan *uc = to_udma_chan(&vc->chan);
+	struct udma_desc *d;
+	u8 status;
+
+	if (!vd)
+		return;
+
+	d = to_udma_desc(&vd->tx);
+
+	if (d->metadata_size)
+		udma_fetch_epib(uc, d);
+
+	if (result) {
+		void *desc_vaddr = udma_curr_cppi5_desc_vaddr(d, d->desc_idx);
+
+		if (cppi5_desc_get_type(desc_vaddr) ==
+		    CPPI5_INFO0_DESC_TYPE_VAL_HOST) {
+			/* Provide residue information for the client */
+			result->residue = d->residue -
+					  cppi5_hdesc_get_pktlen(desc_vaddr);
+			if (result->residue)
+				result->result = DMA_TRANS_ABORTED;
+			else
+				result->result = DMA_TRANS_NOERROR;
+		} else {
+			result->residue = 0;
+			/* Propagate TR Response errors to the client */
+			status = d->hwdesc[0].tr_resp_base->status;
+			if (status)
+				result->result = DMA_TRANS_ABORTED;
+			else
+				result->result = DMA_TRANS_NOERROR;
+		}
+	}
+}
+
+/*
+ * This tasklet handles the completion of a DMA descriptor by
+ * calling its callback and freeing it.
+ */
+void udma_vchan_complete(struct tasklet_struct *t)
+{
+	struct virt_dma_chan *vc = from_tasklet(vc, t, task);
+	struct virt_dma_desc *vd, *_vd;
+	struct dmaengine_desc_callback cb;
+	LIST_HEAD(head);
+
+	spin_lock_irq(&vc->lock);
+	list_splice_tail_init(&vc->desc_completed, &head);
+	vd = vc->cyclic;
+	if (vd) {
+		vc->cyclic = NULL;
+		dmaengine_desc_get_callback(&vd->tx, &cb);
+	} else {
+		memset(&cb, 0, sizeof(cb));
+	}
+	spin_unlock_irq(&vc->lock);
+
+	udma_desc_pre_callback(vc, vd, NULL);
+	dmaengine_desc_callback_invoke(&cb, NULL);
+
+	list_for_each_entry_safe(vd, _vd, &head, node) {
+		struct dmaengine_result result;
+
+		dmaengine_desc_get_callback(&vd->tx, &cb);
+
+		list_del(&vd->node);
+
+		udma_desc_pre_callback(vc, vd, &result);
+		dmaengine_desc_callback_invoke(&cb, &result);
+
+		vchan_vdesc_fini(vd);
+	}
+}
+
+void udma_free_chan_resources(struct dma_chan *chan)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+	struct udma_dev *ud = to_udma_dev(chan->device);
+
+	udma_terminate_all(chan);
+	if (uc->terminated_desc) {
+		ud->udma_reset_chan(uc, false);
+		udma_reset_rings(uc);
+	}
+
+	cancel_delayed_work_sync(&uc->tx_drain.work);
+
+	if (uc->irq_num_ring > 0) {
+		free_irq(uc->irq_num_ring, uc);
+
+		uc->irq_num_ring = 0;
+	}
+	if (uc->irq_num_udma > 0) {
+		free_irq(uc->irq_num_udma, uc);
+
+		uc->irq_num_udma = 0;
+	}
+
+	/* Release PSI-L pairing */
+	if (uc->psil_paired) {
+		if (ud->match_data->type < DMA_TYPE_BCDMA_V2 && IS_ENABLED(CONFIG_TI_K3_UDMA))
+			navss_psil_unpair(ud, uc->config.src_thread,
+					uc->config.dst_thread);
+		uc->psil_paired = false;
+	}
+
+	vchan_free_chan_resources(&uc->vc);
+	tasklet_kill(&uc->vc.task);
+
+	bcdma_free_bchan_resources(uc);
+	udma_free_tx_resources(uc);
+	udma_free_rx_resources(uc);
+	udma_reset_uchan(uc);
+
+	if (uc->use_dma_pool) {
+		dma_pool_destroy(uc->hdesc_pool);
+		uc->use_dma_pool = false;
+	}
+}
+
+int setup_resources(struct udma_dev *ud)
+{
+	struct device *dev = ud->dev;
+	int ch_count, ret;
+
+	switch (ud->match_data->type) {
+	case DMA_TYPE_UDMA:
+		ret = udma_setup_resources(ud);
+		break;
+	case DMA_TYPE_BCDMA:
+	case DMA_TYPE_BCDMA_V2:
+		ret = bcdma_setup_resources(ud);
+		break;
+	case DMA_TYPE_PKTDMA:
+	case DMA_TYPE_PKTDMA_V2:
+		ret = pktdma_setup_resources(ud);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (ret)
+		return ret;
+
+	if (ud->match_data->type >= DMA_TYPE_BCDMA_V2) {
+		ch_count = ud->bchan_cnt + ud->tchan_cnt;
+		if (ud->bchan_cnt)
+			ch_count -= bitmap_weight(ud->bchan_map, ud->bchan_cnt);
+		ch_count -= bitmap_weight(ud->tchan_map, ud->tchan_cnt);
+	} else {
+		ch_count  = ud->bchan_cnt + ud->tchan_cnt + ud->rchan_cnt;
+		if (ud->bchan_cnt)
+			ch_count -= bitmap_weight(ud->bchan_map, ud->bchan_cnt);
+		ch_count -= bitmap_weight(ud->tchan_map, ud->tchan_cnt);
+		ch_count -= bitmap_weight(ud->rchan_map, ud->rchan_cnt);
+	}
+	if (!ch_count)
+		return -ENODEV;
+
+	ud->channels = devm_kcalloc(dev, ch_count, sizeof(*ud->channels),
+				    GFP_KERNEL);
+	if (!ud->channels)
+		return -ENOMEM;
+
+	switch (ud->match_data->type) {
+	case DMA_TYPE_UDMA:
+		dev_info(dev,
+			 "Channels: %d (tchan: %u, rchan: %u, gp-rflow: %u)\n",
+			 ch_count,
+			 ud->tchan_cnt - bitmap_weight(ud->tchan_map,
+						       ud->tchan_cnt),
+			 ud->rchan_cnt - bitmap_weight(ud->rchan_map,
+						       ud->rchan_cnt),
+			 ud->rflow_cnt - bitmap_weight(ud->rflow_gp_map,
+						       ud->rflow_cnt));
+		break;
+	case DMA_TYPE_BCDMA:
+		dev_info(dev,
+			 "Channels: %d (bchan: %u, tchan: %u, rchan: %u)\n",
+			 ch_count,
+			 ud->bchan_cnt - bitmap_weight(ud->bchan_map,
+						       ud->bchan_cnt),
+			 ud->tchan_cnt - bitmap_weight(ud->tchan_map,
+						       ud->tchan_cnt),
+			 ud->rchan_cnt - bitmap_weight(ud->rchan_map,
+						       ud->rchan_cnt));
+		break;
+	case DMA_TYPE_BCDMA_V2:
+		dev_info(dev,
+			 "Channels: %d (bchan: %u, tchan + rchan: %u)\n",
+			 ch_count,
+			 ud->bchan_cnt - bitmap_weight(ud->bchan_map,
+						       ud->bchan_cnt),
+			 ud->chan_cnt - bitmap_weight(ud->chan_map,
+						       ud->chan_cnt));
+		break;
+	case DMA_TYPE_PKTDMA:
+		dev_info(dev,
+			 "Channels: %d (tchan: %u, rchan: %u)\n",
+			 ch_count,
+			 ud->tchan_cnt - bitmap_weight(ud->tchan_map,
+						       ud->tchan_cnt),
+			 ud->rchan_cnt - bitmap_weight(ud->rchan_map,
+						       ud->rchan_cnt));
+		break;
+	case DMA_TYPE_PKTDMA_V2:
+		dev_info(dev,
+			 "Channels: %d (tchan + rchan: %u)\n",
+			 ch_count,
+			 ud->chan_cnt - bitmap_weight(ud->chan_map,
+						       ud->chan_cnt));
+		break;
+	default:
+		break;
+	}
+
+	return ch_count;
+}
+
+void udma_mark_resource_ranges(struct udma_dev *ud, unsigned long *map,
+				      struct ti_sci_resource_desc *rm_desc,
+				      char *name)
+{
+	bitmap_clear(map, rm_desc->start, rm_desc->num);
+	bitmap_clear(map, rm_desc->start_sec, rm_desc->num_sec);
+	dev_dbg(ud->dev, "ti_sci resource range for %s: %d:%d | %d:%d\n", name,
+		rm_desc->start, rm_desc->num, rm_desc->start_sec,
+		rm_desc->num_sec);
+}
+
+int udma_setup_resources(struct udma_dev *ud)
+{
+	int ret, i, j;
+	struct device *dev = ud->dev;
+	struct ti_sci_resource *rm_res, irq_res;
+	struct udma_tisci_rm *tisci_rm = &ud->tisci_rm;
+	u32 cap3;
+
+	/* Set up the throughput level start indexes */
+	cap3 = udma_read(ud->mmrs[MMR_GCFG], 0x2c);
+	if (of_device_is_compatible(dev->of_node,
+				    "ti,am654-navss-main-udmap")) {
+		ud->tchan_tpl.levels = 2;
+		ud->tchan_tpl.start_idx[0] = 8;
+	} else if (of_device_is_compatible(dev->of_node,
+					   "ti,am654-navss-mcu-udmap")) {
+		ud->tchan_tpl.levels = 2;
+		ud->tchan_tpl.start_idx[0] = 2;
+	} else if (UDMA_CAP3_UCHAN_CNT(cap3)) {
+		ud->tchan_tpl.levels = 3;
+		ud->tchan_tpl.start_idx[1] = UDMA_CAP3_UCHAN_CNT(cap3);
+		ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3);
+	} else if (UDMA_CAP3_HCHAN_CNT(cap3)) {
+		ud->tchan_tpl.levels = 2;
+		ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3);
+	} else {
+		ud->tchan_tpl.levels = 1;
+	}
+
+	ud->rchan_tpl.levels = ud->tchan_tpl.levels;
+	ud->rchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0];
+	ud->rchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1];
+
+	ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt),
+					   sizeof(unsigned long), GFP_KERNEL);
+	ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans),
+				  GFP_KERNEL);
+	ud->rchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rchan_cnt),
+					   sizeof(unsigned long), GFP_KERNEL);
+	ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans),
+				  GFP_KERNEL);
+	ud->rflow_gp_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rflow_cnt),
+					      sizeof(unsigned long),
+					      GFP_KERNEL);
+	ud->rflow_gp_map_allocated = devm_kcalloc(dev,
+						  BITS_TO_LONGS(ud->rflow_cnt),
+						  sizeof(unsigned long),
+						  GFP_KERNEL);
+	ud->rflow_in_use = devm_kcalloc(dev, BITS_TO_LONGS(ud->rflow_cnt),
+					sizeof(unsigned long),
+					GFP_KERNEL);
+	ud->rflows = devm_kcalloc(dev, ud->rflow_cnt, sizeof(*ud->rflows),
+				  GFP_KERNEL);
+
+	if (!ud->tchan_map || !ud->rchan_map || !ud->rflow_gp_map ||
+	    !ud->rflow_gp_map_allocated || !ud->tchans || !ud->rchans ||
+	    !ud->rflows || !ud->rflow_in_use)
+		return -ENOMEM;
+
+	/*
+	 * RX flows with the same Ids as RX channels are reserved to be used
+	 * as default flows if remote HW can't generate flow_ids. Those
+	 * RX flows can be requested only explicitly by id.
+	 */
+	bitmap_set(ud->rflow_gp_map_allocated, 0, ud->rchan_cnt);
+
+	/* by default no GP rflows are assigned to Linux */
+	bitmap_set(ud->rflow_gp_map, 0, ud->rflow_cnt);
+
+	/* Get resource ranges from tisci */
+	for (i = 0; i < RM_RANGE_LAST; i++) {
+		if (i == RM_RANGE_BCHAN || i == RM_RANGE_TFLOW)
+			continue;
+
+		tisci_rm->rm_ranges[i] =
+			devm_ti_sci_get_of_resource(tisci_rm->tisci, dev,
+						    tisci_rm->tisci_dev_id,
+						    (char *)range_names[i]);
+	}
+
+	/* tchan ranges */
+	rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
+	if (IS_ERR(rm_res)) {
+		bitmap_zero(ud->tchan_map, ud->tchan_cnt);
+		irq_res.sets = 1;
+	} else {
+		bitmap_fill(ud->tchan_map, ud->tchan_cnt);
+		for (i = 0; i < rm_res->sets; i++)
+			udma_mark_resource_ranges(ud, ud->tchan_map,
+						  &rm_res->desc[i], "tchan");
+		irq_res.sets = rm_res->sets;
+	}
+
+	/* rchan and matching default flow ranges */
+	rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
+	if (IS_ERR(rm_res)) {
+		bitmap_zero(ud->rchan_map, ud->rchan_cnt);
+		irq_res.sets++;
+	} else {
+		bitmap_fill(ud->rchan_map, ud->rchan_cnt);
+		for (i = 0; i < rm_res->sets; i++)
+			udma_mark_resource_ranges(ud, ud->rchan_map,
+						  &rm_res->desc[i], "rchan");
+		irq_res.sets += rm_res->sets;
+	}
+
+	irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL);
+	if (!irq_res.desc)
+		return -ENOMEM;
+	rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
+	if (IS_ERR(rm_res)) {
+		irq_res.desc[0].start = 0;
+		irq_res.desc[0].num = ud->tchan_cnt;
+		i = 1;
+	} else {
+		for (i = 0; i < rm_res->sets; i++) {
+			irq_res.desc[i].start = rm_res->desc[i].start;
+			irq_res.desc[i].num = rm_res->desc[i].num;
+			irq_res.desc[i].start_sec = rm_res->desc[i].start_sec;
+			irq_res.desc[i].num_sec = rm_res->desc[i].num_sec;
+		}
+	}
+	rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
+	if (IS_ERR(rm_res)) {
+		irq_res.desc[i].start = 0;
+		irq_res.desc[i].num = ud->rchan_cnt;
+	} else {
+		for (j = 0; j < rm_res->sets; j++, i++) {
+			if (rm_res->desc[j].num) {
+				irq_res.desc[i].start = rm_res->desc[j].start +
+						ud->soc_data->oes.udma_rchan;
+				irq_res.desc[i].num = rm_res->desc[j].num;
+			}
+			if (rm_res->desc[j].num_sec) {
+				irq_res.desc[i].start_sec = rm_res->desc[j].start_sec +
+						ud->soc_data->oes.udma_rchan;
+				irq_res.desc[i].num_sec = rm_res->desc[j].num_sec;
+			}
+		}
+	}
+	ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res);
+	kfree(irq_res.desc);
+	if (ret) {
+		dev_err(ud->dev, "Failed to allocate MSI interrupts\n");
+		return ret;
+	}
+
+	/* GP rflow ranges */
+	rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW];
+	if (IS_ERR(rm_res)) {
+		/* all gp flows are assigned exclusively to Linux */
+		bitmap_clear(ud->rflow_gp_map, ud->rchan_cnt,
+			     ud->rflow_cnt - ud->rchan_cnt);
+	} else {
+		for (i = 0; i < rm_res->sets; i++)
+			udma_mark_resource_ranges(ud, ud->rflow_gp_map,
+						  &rm_res->desc[i], "gp-rflow");
+	}
+
+	return 0;
+}
+
+int bcdma_setup_resources(struct udma_dev *ud)
+{
+	int ret, i, j;
+	struct device *dev = ud->dev;
+	struct ti_sci_resource *rm_res, irq_res;
+	struct udma_tisci_rm *tisci_rm = &ud->tisci_rm;
+	const struct udma_oes_offsets *oes = &ud->soc_data->oes;
+	u32 cap;
+
+	/* Set up the throughput level start indexes */
+	cap = udma_read(ud->mmrs[MMR_GCFG], 0x2c);
+	if (BCDMA_CAP3_UBCHAN_CNT(cap)) {
+		ud->bchan_tpl.levels = 3;
+		ud->bchan_tpl.start_idx[1] = BCDMA_CAP3_UBCHAN_CNT(cap);
+		ud->bchan_tpl.start_idx[0] = BCDMA_CAP3_HBCHAN_CNT(cap);
+	} else if (BCDMA_CAP3_HBCHAN_CNT(cap)) {
+		ud->bchan_tpl.levels = 2;
+		ud->bchan_tpl.start_idx[0] = BCDMA_CAP3_HBCHAN_CNT(cap);
+	} else {
+		ud->bchan_tpl.levels = 1;
+	}
+
+	cap = udma_read(ud->mmrs[MMR_GCFG], 0x30);
+	if (BCDMA_CAP4_URCHAN_CNT(cap)) {
+		ud->rchan_tpl.levels = 3;
+		ud->rchan_tpl.start_idx[1] = BCDMA_CAP4_URCHAN_CNT(cap);
+		ud->rchan_tpl.start_idx[0] = BCDMA_CAP4_HRCHAN_CNT(cap);
+	} else if (BCDMA_CAP4_HRCHAN_CNT(cap)) {
+		ud->rchan_tpl.levels = 2;
+		ud->rchan_tpl.start_idx[0] = BCDMA_CAP4_HRCHAN_CNT(cap);
+	} else {
+		ud->rchan_tpl.levels = 1;
+	}
+
+	if (BCDMA_CAP4_UTCHAN_CNT(cap)) {
+		ud->tchan_tpl.levels = 3;
+		ud->tchan_tpl.start_idx[1] = BCDMA_CAP4_UTCHAN_CNT(cap);
+		ud->tchan_tpl.start_idx[0] = BCDMA_CAP4_HTCHAN_CNT(cap);
+	} else if (BCDMA_CAP4_HTCHAN_CNT(cap)) {
+		ud->tchan_tpl.levels = 2;
+		ud->tchan_tpl.start_idx[0] = BCDMA_CAP4_HTCHAN_CNT(cap);
+	} else {
+		ud->tchan_tpl.levels = 1;
+	}
+
+	ud->bchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->bchan_cnt),
+					   sizeof(unsigned long), GFP_KERNEL);
+	bitmap_zero(ud->bchan_map, ud->bchan_cnt);
+	ud->bchans = devm_kcalloc(dev, ud->bchan_cnt, sizeof(*ud->bchans),
+				  GFP_KERNEL);
+	ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt),
+					   sizeof(unsigned long), GFP_KERNEL);
+	bitmap_zero(ud->tchan_map, ud->tchan_cnt);
+	ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans),
+				  GFP_KERNEL);
+	if (ud->match_data->type == DMA_TYPE_BCDMA_V2) {
+		ud->rchan_map = ud->tchan_map;
+		ud->rchans = ud->tchans;
+		ud->chan_map = ud->tchan_map;
+		ud->chans = ud->tchans;
+	} else {
+		ud->rchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rchan_cnt),
+				sizeof(unsigned long), GFP_KERNEL);
+		bitmap_zero(ud->rchan_map, ud->rchan_cnt);
+		ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans),
+				GFP_KERNEL);
+	}
+	/* BCDMA do not really have flows, but the driver expect it */
+	ud->rflow_in_use = devm_kcalloc(dev, BITS_TO_LONGS(ud->rchan_cnt),
+					sizeof(unsigned long),
+					GFP_KERNEL);
+	ud->rflows = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rflows),
+				  GFP_KERNEL);
+
+	if (!ud->bchan_map || !ud->tchan_map || !ud->rchan_map ||
+	    !ud->rflow_in_use || !ud->bchans || !ud->tchans || !ud->rchans ||
+	    !ud->rflows)
+		return -ENOMEM;
+
+	if (ud->match_data->type == DMA_TYPE_BCDMA_V2)
+		return 0;
+
+	/* Get resource ranges from tisci */
+	for (i = 0; i < RM_RANGE_LAST; i++) {
+		if (i == RM_RANGE_RFLOW || i == RM_RANGE_TFLOW)
+			continue;
+		if (i == RM_RANGE_BCHAN && ud->bchan_cnt == 0)
+			continue;
+		if (i == RM_RANGE_TCHAN && ud->tchan_cnt == 0)
+			continue;
+		if (i == RM_RANGE_RCHAN && ud->rchan_cnt == 0)
+			continue;
+
+		tisci_rm->rm_ranges[i] =
+			devm_ti_sci_get_of_resource(tisci_rm->tisci, dev,
+						    tisci_rm->tisci_dev_id,
+						    (char *)range_names[i]);
+	}
+
+	irq_res.sets = 0;
+
+	/* bchan ranges */
+	if (ud->bchan_cnt) {
+		rm_res = tisci_rm->rm_ranges[RM_RANGE_BCHAN];
+		if (IS_ERR(rm_res)) {
+			bitmap_zero(ud->bchan_map, ud->bchan_cnt);
+			irq_res.sets++;
+		} else {
+			bitmap_fill(ud->bchan_map, ud->bchan_cnt);
+			for (i = 0; i < rm_res->sets; i++)
+				udma_mark_resource_ranges(ud, ud->bchan_map,
+							  &rm_res->desc[i],
+							  "bchan");
+			irq_res.sets += rm_res->sets;
+		}
+	}
+
+	/* tchan ranges */
+	if (ud->tchan_cnt) {
+		rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
+		if (IS_ERR(rm_res)) {
+			bitmap_zero(ud->tchan_map, ud->tchan_cnt);
+			irq_res.sets += 2;
+		} else {
+			bitmap_fill(ud->tchan_map, ud->tchan_cnt);
+			for (i = 0; i < rm_res->sets; i++)
+				udma_mark_resource_ranges(ud, ud->tchan_map,
+							  &rm_res->desc[i],
+							  "tchan");
+			irq_res.sets += rm_res->sets * 2;
+		}
+	}
+
+	/* rchan ranges */
+	if (ud->rchan_cnt) {
+		rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
+		if (IS_ERR(rm_res)) {
+			bitmap_zero(ud->rchan_map, ud->rchan_cnt);
+			irq_res.sets += 2;
+		} else {
+			bitmap_fill(ud->rchan_map, ud->rchan_cnt);
+			for (i = 0; i < rm_res->sets; i++)
+				udma_mark_resource_ranges(ud, ud->rchan_map,
+							  &rm_res->desc[i],
+							  "rchan");
+			irq_res.sets += rm_res->sets * 2;
+		}
+	}
+
+	irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL);
+	if (!irq_res.desc)
+		return -ENOMEM;
+	if (ud->bchan_cnt) {
+		rm_res = tisci_rm->rm_ranges[RM_RANGE_BCHAN];
+		if (IS_ERR(rm_res)) {
+			irq_res.desc[0].start = oes->bcdma_bchan_ring;
+			irq_res.desc[0].num = ud->bchan_cnt;
+			i = 1;
+		} else {
+			for (i = 0; i < rm_res->sets; i++) {
+				irq_res.desc[i].start = rm_res->desc[i].start +
+							oes->bcdma_bchan_ring;
+				irq_res.desc[i].num = rm_res->desc[i].num;
+
+				if (rm_res->desc[i].num_sec) {
+					irq_res.desc[i].start_sec = rm_res->desc[i].start_sec +
+									oes->bcdma_bchan_ring;
+					irq_res.desc[i].num_sec = rm_res->desc[i].num_sec;
+				}
+			}
+		}
+	} else {
+		i = 0;
+	}
+
+	if (ud->tchan_cnt) {
+		rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
+		if (IS_ERR(rm_res)) {
+			irq_res.desc[i].start = oes->bcdma_tchan_data;
+			irq_res.desc[i].num = ud->tchan_cnt;
+			irq_res.desc[i + 1].start = oes->bcdma_tchan_ring;
+			irq_res.desc[i + 1].num = ud->tchan_cnt;
+			i += 2;
+		} else {
+			for (j = 0; j < rm_res->sets; j++, i += 2) {
+				irq_res.desc[i].start = rm_res->desc[j].start +
+							oes->bcdma_tchan_data;
+				irq_res.desc[i].num = rm_res->desc[j].num;
+
+				irq_res.desc[i + 1].start = rm_res->desc[j].start +
+							oes->bcdma_tchan_ring;
+				irq_res.desc[i + 1].num = rm_res->desc[j].num;
+
+				if (rm_res->desc[j].num_sec) {
+					irq_res.desc[i].start_sec = rm_res->desc[j].start_sec +
+									oes->bcdma_tchan_data;
+					irq_res.desc[i].num_sec = rm_res->desc[j].num_sec;
+					irq_res.desc[i + 1].start_sec = rm_res->desc[j].start_sec +
+									oes->bcdma_tchan_ring;
+					irq_res.desc[i + 1].num_sec = rm_res->desc[j].num_sec;
+				}
+			}
+		}
+	}
+	if (ud->rchan_cnt) {
+		rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
+		if (IS_ERR(rm_res)) {
+			irq_res.desc[i].start = oes->bcdma_rchan_data;
+			irq_res.desc[i].num = ud->rchan_cnt;
+			irq_res.desc[i + 1].start = oes->bcdma_rchan_ring;
+			irq_res.desc[i + 1].num = ud->rchan_cnt;
+			i += 2;
+		} else {
+			for (j = 0; j < rm_res->sets; j++, i += 2) {
+				irq_res.desc[i].start = rm_res->desc[j].start +
+							oes->bcdma_rchan_data;
+				irq_res.desc[i].num = rm_res->desc[j].num;
+
+				irq_res.desc[i + 1].start = rm_res->desc[j].start +
+							oes->bcdma_rchan_ring;
+				irq_res.desc[i + 1].num = rm_res->desc[j].num;
+
+				if (rm_res->desc[j].num_sec) {
+					irq_res.desc[i].start_sec = rm_res->desc[j].start_sec +
+									oes->bcdma_rchan_data;
+					irq_res.desc[i].num_sec = rm_res->desc[j].num_sec;
+					irq_res.desc[i + 1].start_sec = rm_res->desc[j].start_sec +
+									oes->bcdma_rchan_ring;
+					irq_res.desc[i + 1].num_sec = rm_res->desc[j].num_sec;
+				}
+			}
+		}
+	}
+
+	ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res);
+	kfree(irq_res.desc);
+	if (ret) {
+		dev_err(ud->dev, "Failed to allocate MSI interrupts\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+int pktdma_setup_resources(struct udma_dev *ud)
+{
+	int ret, i, j;
+	struct device *dev = ud->dev;
+	struct ti_sci_resource *rm_res, irq_res;
+	struct udma_tisci_rm *tisci_rm = &ud->tisci_rm;
+	const struct udma_oes_offsets *oes = &ud->soc_data->oes;
+	u32 cap3;
+
+	/* Set up the throughput level start indexes */
+	cap3 = udma_read(ud->mmrs[MMR_GCFG], 0x2c);
+	if (UDMA_CAP3_UCHAN_CNT(cap3)) {
+		ud->tchan_tpl.levels = 3;
+		ud->tchan_tpl.start_idx[1] = UDMA_CAP3_UCHAN_CNT(cap3);
+		ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3);
+	} else if (UDMA_CAP3_HCHAN_CNT(cap3)) {
+		ud->tchan_tpl.levels = 2;
+		ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3);
+	} else {
+		ud->tchan_tpl.levels = 1;
+	}
+
+	ud->rchan_tpl.levels = ud->tchan_tpl.levels;
+	ud->rchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0];
+	ud->rchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1];
+
+	ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt),
+					   sizeof(unsigned long), GFP_KERNEL);
+	bitmap_zero(ud->tchan_map, ud->tchan_cnt);
+	ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans),
+				  GFP_KERNEL);
+	if (ud->match_data->type == DMA_TYPE_PKTDMA_V2) {
+		ud->rchan_map = ud->tchan_map;
+		ud->rchans = ud->tchans;
+		ud->chan_map = ud->tchan_map;
+		ud->chans = ud->tchans;
+	} else {
+		ud->rchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rchan_cnt),
+				sizeof(unsigned long), GFP_KERNEL);
+		bitmap_zero(ud->rchan_map, ud->rchan_cnt);
+		ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans),
+				GFP_KERNEL);
+	}
+	ud->rflow_in_use = devm_kcalloc(dev, BITS_TO_LONGS(ud->rflow_cnt),
+					sizeof(unsigned long),
+					GFP_KERNEL);
+	ud->rflows = devm_kcalloc(dev, ud->rflow_cnt, sizeof(*ud->rflows),
+				  GFP_KERNEL);
+	ud->tflow_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tflow_cnt),
+					   sizeof(unsigned long), GFP_KERNEL);
+	bitmap_zero(ud->tflow_map, ud->tflow_cnt);
+
+	if (!ud->tchan_map || !ud->rchan_map || !ud->tflow_map || !ud->tchans ||
+	    !ud->rchans || !ud->rflows || !ud->rflow_in_use)
+		return -ENOMEM;
+
+	if (ud->match_data->type == DMA_TYPE_PKTDMA_V2)
+		return 0;
+
+	/* Get resource ranges from tisci */
+	for (i = 0; i < RM_RANGE_LAST; i++) {
+		if (i == RM_RANGE_BCHAN)
+			continue;
+
+		tisci_rm->rm_ranges[i] =
+			devm_ti_sci_get_of_resource(tisci_rm->tisci, dev,
+						    tisci_rm->tisci_dev_id,
+						    (char *)range_names[i]);
+	}
+
+	/* tchan ranges */
+	rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN];
+	if (IS_ERR(rm_res)) {
+		bitmap_zero(ud->tchan_map, ud->tchan_cnt);
+	} else {
+		bitmap_fill(ud->tchan_map, ud->tchan_cnt);
+		for (i = 0; i < rm_res->sets; i++)
+			udma_mark_resource_ranges(ud, ud->tchan_map,
+						  &rm_res->desc[i], "tchan");
+	}
+
+	/* rchan ranges */
+	rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN];
+	if (IS_ERR(rm_res)) {
+		bitmap_zero(ud->rchan_map, ud->rchan_cnt);
+	} else {
+		bitmap_fill(ud->rchan_map, ud->rchan_cnt);
+		for (i = 0; i < rm_res->sets; i++)
+			udma_mark_resource_ranges(ud, ud->rchan_map,
+						  &rm_res->desc[i], "rchan");
+	}
+
+	/* rflow ranges */
+	rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW];
+	if (IS_ERR(rm_res)) {
+		/* all rflows are assigned exclusively to Linux */
+		bitmap_zero(ud->rflow_in_use, ud->rflow_cnt);
+		irq_res.sets = 1;
+	} else {
+		bitmap_fill(ud->rflow_in_use, ud->rflow_cnt);
+		for (i = 0; i < rm_res->sets; i++)
+			udma_mark_resource_ranges(ud, ud->rflow_in_use,
+						  &rm_res->desc[i], "rflow");
+		irq_res.sets = rm_res->sets;
+	}
+
+	/* tflow ranges */
+	rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW];
+	if (IS_ERR(rm_res)) {
+		/* all tflows are assigned exclusively to Linux */
+		bitmap_zero(ud->tflow_map, ud->tflow_cnt);
+		irq_res.sets++;
+	} else {
+		bitmap_fill(ud->tflow_map, ud->tflow_cnt);
+		for (i = 0; i < rm_res->sets; i++)
+			udma_mark_resource_ranges(ud, ud->tflow_map,
+						  &rm_res->desc[i], "tflow");
+		irq_res.sets += rm_res->sets;
+	}
+
+	irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL);
+	if (!irq_res.desc)
+		return -ENOMEM;
+	rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW];
+	if (IS_ERR(rm_res)) {
+		irq_res.desc[0].start = oes->pktdma_tchan_flow;
+		irq_res.desc[0].num = ud->tflow_cnt;
+		i = 1;
+	} else {
+		for (i = 0; i < rm_res->sets; i++) {
+			irq_res.desc[i].start = rm_res->desc[i].start +
+						oes->pktdma_tchan_flow;
+			irq_res.desc[i].num = rm_res->desc[i].num;
+
+			if (rm_res->desc[i].num_sec) {
+				irq_res.desc[i].start_sec = rm_res->desc[i].start_sec +
+								oes->pktdma_tchan_flow;
+				irq_res.desc[i].num_sec = rm_res->desc[i].num_sec;
+			}
+		}
+	}
+	rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW];
+	if (IS_ERR(rm_res)) {
+		irq_res.desc[i].start = oes->pktdma_rchan_flow;
+		irq_res.desc[i].num = ud->rflow_cnt;
+	} else {
+		for (j = 0; j < rm_res->sets; j++, i++) {
+			irq_res.desc[i].start = rm_res->desc[j].start +
+						oes->pktdma_rchan_flow;
+			irq_res.desc[i].num = rm_res->desc[j].num;
+
+			if (rm_res->desc[j].num_sec) {
+				irq_res.desc[i].start_sec = rm_res->desc[j].start_sec +
+								oes->pktdma_rchan_flow;
+				irq_res.desc[i].num_sec = rm_res->desc[j].num_sec;
+			}
+		}
+	}
+	ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res);
+	kfree(irq_res.desc);
+	if (ret) {
+		dev_err(ud->dev, "Failed to allocate MSI interrupts\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+int udma_setup_rx_flush(struct udma_dev *ud)
+{
+	struct udma_rx_flush *rx_flush = &ud->rx_flush;
+	struct cppi5_desc_hdr_t *tr_desc;
+	struct cppi5_tr_type1_t *tr_req;
+	struct cppi5_host_desc_t *desc;
+	struct device *dev = ud->dev;
+	struct udma_hwdesc *hwdesc;
+	size_t tr_size;
+
+	/* Allocate 1K buffer for discarded data on RX channel teardown */
+	rx_flush->buffer_size = SZ_1K;
+	rx_flush->buffer_vaddr = devm_kzalloc(dev, rx_flush->buffer_size,
+					      GFP_KERNEL);
+	if (!rx_flush->buffer_vaddr)
+		return -ENOMEM;
+
+	rx_flush->buffer_paddr = dma_map_single(dev, rx_flush->buffer_vaddr,
+						rx_flush->buffer_size,
+						DMA_TO_DEVICE);
+	if (dma_mapping_error(dev, rx_flush->buffer_paddr))
+		return -ENOMEM;
+
+	/* Set up descriptor to be used for TR mode */
+	hwdesc = &rx_flush->hwdescs[0];
+	tr_size = sizeof(struct cppi5_tr_type1_t);
+	hwdesc->cppi5_desc_size = cppi5_trdesc_calc_size(tr_size, 1);
+	hwdesc->cppi5_desc_size = ALIGN(hwdesc->cppi5_desc_size,
+					ud->desc_align);
+
+	hwdesc->cppi5_desc_vaddr = devm_kzalloc(dev, hwdesc->cppi5_desc_size,
+						GFP_KERNEL);
+	if (!hwdesc->cppi5_desc_vaddr)
+		return -ENOMEM;
+
+	hwdesc->cppi5_desc_paddr = dma_map_single(dev, hwdesc->cppi5_desc_vaddr,
+						  hwdesc->cppi5_desc_size,
+						  DMA_TO_DEVICE);
+	if (dma_mapping_error(dev, hwdesc->cppi5_desc_paddr))
+		return -ENOMEM;
+
+	/* Start of the TR req records */
+	hwdesc->tr_req_base = hwdesc->cppi5_desc_vaddr + tr_size;
+	/* Start address of the TR response array */
+	hwdesc->tr_resp_base = hwdesc->tr_req_base + tr_size;
+
+	tr_desc = hwdesc->cppi5_desc_vaddr;
+	cppi5_trdesc_init(tr_desc, 1, tr_size, 0, 0);
+	cppi5_desc_set_pktids(tr_desc, 0, CPPI5_INFO1_DESC_FLOWID_DEFAULT);
+	cppi5_desc_set_retpolicy(tr_desc, 0, 0);
+
+	tr_req = hwdesc->tr_req_base;
+	cppi5_tr_init(&tr_req->flags, CPPI5_TR_TYPE1, false, false,
+		      CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
+	cppi5_tr_csf_set(&tr_req->flags, CPPI5_TR_CSF_SUPR_EVT);
+
+	tr_req->addr = rx_flush->buffer_paddr;
+	tr_req->icnt0 = rx_flush->buffer_size;
+	tr_req->icnt1 = 1;
+
+	dma_sync_single_for_device(dev, hwdesc->cppi5_desc_paddr,
+				   hwdesc->cppi5_desc_size, DMA_TO_DEVICE);
+
+	/* Set up descriptor to be used for packet mode */
+	hwdesc = &rx_flush->hwdescs[1];
+	hwdesc->cppi5_desc_size = ALIGN(sizeof(struct cppi5_host_desc_t) +
+					CPPI5_INFO0_HDESC_EPIB_SIZE +
+					CPPI5_INFO0_HDESC_PSDATA_MAX_SIZE,
+					ud->desc_align);
+
+	hwdesc->cppi5_desc_vaddr = devm_kzalloc(dev, hwdesc->cppi5_desc_size,
+						GFP_KERNEL);
+	if (!hwdesc->cppi5_desc_vaddr)
+		return -ENOMEM;
+
+	hwdesc->cppi5_desc_paddr = dma_map_single(dev, hwdesc->cppi5_desc_vaddr,
+						  hwdesc->cppi5_desc_size,
+						  DMA_TO_DEVICE);
+	if (dma_mapping_error(dev, hwdesc->cppi5_desc_paddr))
+		return -ENOMEM;
+
+	desc = hwdesc->cppi5_desc_vaddr;
+	cppi5_hdesc_init(desc, 0, 0);
+	cppi5_desc_set_pktids(&desc->hdr, 0, CPPI5_INFO1_DESC_FLOWID_DEFAULT);
+	cppi5_desc_set_retpolicy(&desc->hdr, 0, 0);
+
+	cppi5_hdesc_attach_buf(desc,
+			       rx_flush->buffer_paddr, rx_flush->buffer_size,
+			       rx_flush->buffer_paddr, rx_flush->buffer_size);
+
+	dma_sync_single_for_device(dev, hwdesc->cppi5_desc_paddr,
+				   hwdesc->cppi5_desc_size, DMA_TO_DEVICE);
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+void udma_dbg_summary_show_chan(struct seq_file *s,
+				       struct dma_chan *chan)
+{
+	struct udma_chan *uc = to_udma_chan(chan);
+	struct udma_chan_config *ucc = &uc->config;
+
+	seq_printf(s, " %-13s| %s", dma_chan_name(chan),
+		   chan->dbg_client_name ?: "in-use");
+	if (ucc->tr_trigger_type)
+		seq_puts(s, " (triggered, ");
+	else
+		seq_printf(s, " (%s, ",
+			   dmaengine_get_direction_text(uc->config.dir));
+
+	switch (uc->config.dir) {
+	case DMA_MEM_TO_MEM:
+		if (uc->ud->match_data->type == DMA_TYPE_BCDMA ||
+			uc->ud->match_data->type == DMA_TYPE_BCDMA_V2) {
+			seq_printf(s, "bchan%d)\n", uc->bchan->id);
+			return;
+		}
+
+		seq_printf(s, "chan%d pair [0x%04x -> 0x%04x], ", uc->tchan->id,
+			   ucc->src_thread, ucc->dst_thread);
+		break;
+	case DMA_DEV_TO_MEM:
+		seq_printf(s, "rchan%d [0x%04x -> 0x%04x], ", uc->rchan->id,
+			   ucc->src_thread, ucc->dst_thread);
+		if (uc->ud->match_data->type == DMA_TYPE_PKTDMA)
+			seq_printf(s, "rflow%d, ", uc->rflow->id);
+		break;
+	case DMA_MEM_TO_DEV:
+		seq_printf(s, "tchan%d [0x%04x -> 0x%04x], ", uc->tchan->id,
+			   ucc->src_thread, ucc->dst_thread);
+		if (uc->ud->match_data->type == DMA_TYPE_PKTDMA)
+			seq_printf(s, "tflow%d, ", uc->tchan->tflow_id);
+		break;
+	default:
+		seq_puts(s, ")\n");
+		return;
+	}
+
+	if (ucc->ep_type == PSIL_EP_NATIVE) {
+		seq_puts(s, "PSI-L Native");
+		if (ucc->metadata_size) {
+			seq_printf(s, "[%s", ucc->needs_epib ? " EPIB" : "");
+			if (ucc->psd_size)
+				seq_printf(s, " PSDsize:%u", ucc->psd_size);
+			seq_puts(s, " ]");
+		}
+	} else {
+		seq_puts(s, "PDMA");
+		if (ucc->enable_acc32 || ucc->enable_burst)
+			seq_printf(s, "[%s%s ]",
+				   ucc->enable_acc32 ? " ACC32" : "",
+				   ucc->enable_burst ? " BURST" : "");
+	}
+
+	seq_printf(s, ", %s)\n", ucc->pkt_mode ? "Packet mode" : "TR mode");
+}
+
+void udma_dbg_summary_show(struct seq_file *s,
+				  struct dma_device *dma_dev)
+{
+	struct dma_chan *chan;
+
+	list_for_each_entry(chan, &dma_dev->channels, device_node) {
+		if (chan->client_count)
+			udma_dbg_summary_show_chan(s, chan);
+	}
+}
+#endif /* CONFIG_DEBUG_FS */
+
+enum dmaengine_alignment udma_get_copy_align(struct udma_dev *ud)
+{
+	const struct udma_match_data *match_data = ud->match_data;
+	u8 tpl;
+
+	if (!match_data->enable_memcpy_support)
+		return DMAENGINE_ALIGN_8_BYTES;
+
+	/* Get the highest TPL level the device supports for memcpy */
+	if (ud->bchan_cnt)
+		tpl = udma_get_chan_tpl_index(&ud->bchan_tpl, 0);
+	else if (ud->tchan_cnt)
+		tpl = udma_get_chan_tpl_index(&ud->tchan_tpl, 0);
+	else
+		return DMAENGINE_ALIGN_8_BYTES;
+
+	switch (match_data->burst_size[tpl]) {
+	case TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_256_BYTES:
+		return DMAENGINE_ALIGN_256_BYTES;
+	case TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_128_BYTES:
+		return DMAENGINE_ALIGN_128_BYTES;
+	case TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES:
+	fallthrough;
+	default:
+		return DMAENGINE_ALIGN_64_BYTES;
+	}
+}
+
+/* Private interfaces to UDMA */
+#include "k3-udma-private.c"
diff -Naur --no-dereference a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c
--- a/drivers/dma/ti/k3-udma-glue.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/dma/ti/k3-udma-glue.c	2025-10-23 09:30:40.284462176 -0400
@@ -243,6 +243,9 @@
 	const struct udma_tisci_rm *tisci_rm = tx_chn->common.tisci_rm;
 	struct ti_sci_msg_rm_udmap_tx_ch_cfg req;
 
+	if (!tisci_rm->tisci)
+		return 0;
+
 	memset(&req, 0, sizeof(req));
 
 	req.valid_params = TI_SCI_MSG_VALUE_RM_UDMAP_CH_PAUSE_ON_ERR_VALID |
@@ -501,21 +504,26 @@
 {
 	int ret;
 
-	ret = xudma_navss_psil_pair(tx_chn->common.udmax,
-				    tx_chn->common.src_thread,
-				    tx_chn->common.dst_thread);
-	if (ret) {
-		dev_err(tx_chn->common.dev, "PSI-L request err %d\n", ret);
-		return ret;
-	}
+	if (tx_chn->common.udmax->match_data->type == DMA_TYPE_PKTDMA_V2) {
+		xudma_tchanrt_write(tx_chn->udma_tchanx, UDMA_CHAN_RT_CTL_REG,
+				UDMA_CHAN_RT_CTL_AUTOPAIR | UDMA_CHAN_RT_CTL_EN);
+	} else {
+		ret = xudma_navss_psil_pair(tx_chn->common.udmax,
+					    tx_chn->common.src_thread,
+					    tx_chn->common.dst_thread);
+		if (ret) {
+			dev_err(tx_chn->common.dev, "PSI-L request err %d\n", ret);
+			return ret;
+		}
 
-	tx_chn->psil_paired = true;
+		tx_chn->psil_paired = true;
 
-	xudma_tchanrt_write(tx_chn->udma_tchanx, UDMA_CHAN_RT_PEER_RT_EN_REG,
-			    UDMA_PEER_RT_EN_ENABLE);
+		xudma_tchanrt_write(tx_chn->udma_tchanx, UDMA_CHAN_RT_PEER_RT_EN_REG,
+				UDMA_PEER_RT_EN_ENABLE);
 
-	xudma_tchanrt_write(tx_chn->udma_tchanx, UDMA_CHAN_RT_CTL_REG,
-			    UDMA_CHAN_RT_CTL_EN);
+		xudma_tchanrt_write(tx_chn->udma_tchanx, UDMA_CHAN_RT_CTL_REG,
+				UDMA_CHAN_RT_CTL_EN);
+	}
 
 	k3_udma_glue_dump_tx_rt_chn(tx_chn, "txchn en");
 	return 0;
@@ -681,7 +689,6 @@
 			   TI_SCI_MSG_VALUE_RM_UDMAP_CH_CHAN_TYPE_VALID |
 			   TI_SCI_MSG_VALUE_RM_UDMAP_CH_ATYPE_VALID;
 
-	req.nav_id = tisci_rm->tisci_dev_id;
 	req.index = rx_chn->udma_rchan_id;
 	req.rx_fetch_size = rx_chn->common.hdesc_size >> 2;
 	/*
@@ -701,11 +708,18 @@
 	req.rx_chan_type = TI_SCI_RM_UDMAP_CHAN_TYPE_PKT_PBRR;
 	req.rx_atype = rx_chn->common.atype_asel;
 
+	if (!tisci_rm->tisci) {
+		// TODO: look at the chan settings
+		xudma_rchanrt_write(rx_chn->udma_rchanx, UDMA_CHAN_RT_CFG_REG,
+				    UDMA_CHAN_RT_CTL_TDOWN | UDMA_CHAN_RT_CTL_PAUSE);
+		return 0;
+	}
+
+	req.nav_id = tisci_rm->tisci_dev_id;
 	ret = tisci_rm->tisci_udmap_ops->rx_ch_cfg(tisci_rm->tisci, &req);
 	if (ret)
 		dev_err(rx_chn->common.dev, "rchan%d cfg failed %d\n",
-			rx_chn->udma_rchan_id, ret);
-
+				rx_chn->udma_rchan_id, ret);
 	return ret;
 }
 
@@ -754,8 +768,11 @@
 	}
 
 	if (xudma_is_pktdma(rx_chn->common.udmax)) {
-		rx_ringfdq_id = flow->udma_rflow_id +
+		if (tisci_rm->tisci)
+			rx_ringfdq_id = flow->udma_rflow_id +
 				xudma_get_rflow_ring_offset(rx_chn->common.udmax);
+		else
+			rx_ringfdq_id = flow->udma_rflow_id;
 		rx_ring_id = 0;
 	} else {
 		rx_ring_id = flow_cfg->ring_rxq_id;
@@ -802,6 +819,13 @@
 		rx_ringfdq_id = k3_ringacc_get_ring_id(flow->ringrxfdq);
 	}
 
+	if (!tisci_rm->tisci) {
+		xudma_rflowrt_write(flow->udma_rflow, UDMA_RX_FLOWRT_RFA,
+				UDMA_CHAN_RT_CTL_TDOWN | UDMA_CHAN_RT_CTL_PAUSE);
+		rx_chn->flows_ready++;
+		return 0;
+	}
+
 	memset(&req, 0, sizeof(req));
 
 	req.valid_params =
@@ -1300,6 +1324,9 @@
 	if (!rx_chn->remote)
 		return -EINVAL;
 
+	if (!tisci_rm->tisci)
+		return 0;
+
 	rx_ring_id = k3_ringacc_get_ring_id(flow->ringrx);
 	rx_ringfdq_id = k3_ringacc_get_ring_id(flow->ringrxfdq);
 
@@ -1341,6 +1368,9 @@
 	if (!rx_chn->remote)
 		return -EINVAL;
 
+	if (!tisci_rm->tisci)
+		return 0;
+
 	memset(&req, 0, sizeof(req));
 	req.valid_params =
 			TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DEST_QNUM_VALID |
@@ -1376,21 +1406,26 @@
 	if (rx_chn->flows_ready < rx_chn->flow_num)
 		return -EINVAL;
 
-	ret = xudma_navss_psil_pair(rx_chn->common.udmax,
-				    rx_chn->common.src_thread,
-				    rx_chn->common.dst_thread);
-	if (ret) {
-		dev_err(rx_chn->common.dev, "PSI-L request err %d\n", ret);
-		return ret;
-	}
+	if (rx_chn->common.udmax->match_data->type == DMA_TYPE_PKTDMA_V2) {
+		xudma_rchanrt_write(rx_chn->udma_rchanx, UDMA_CHAN_RT_CTL_REG,
+				UDMA_CHAN_RT_CTL_AUTOPAIR |  UDMA_CHAN_RT_CTL_EN);
+	} else {
+		ret = xudma_navss_psil_pair(rx_chn->common.udmax,
+					    rx_chn->common.src_thread,
+					    rx_chn->common.dst_thread);
+		if (ret) {
+			dev_err(rx_chn->common.dev, "PSI-L request err %d\n", ret);
+			return ret;
+		}
 
-	rx_chn->psil_paired = true;
+		rx_chn->psil_paired = true;
 
-	xudma_rchanrt_write(rx_chn->udma_rchanx, UDMA_CHAN_RT_CTL_REG,
-			    UDMA_CHAN_RT_CTL_EN);
+		xudma_rchanrt_write(rx_chn->udma_rchanx, UDMA_CHAN_RT_CTL_REG,
+				UDMA_CHAN_RT_CTL_EN);
 
-	xudma_rchanrt_write(rx_chn->udma_rchanx, UDMA_CHAN_RT_PEER_RT_EN_REG,
-			    UDMA_PEER_RT_EN_ENABLE);
+		xudma_rchanrt_write(rx_chn->udma_rchanx, UDMA_CHAN_RT_PEER_RT_EN_REG,
+				UDMA_PEER_RT_EN_ENABLE);
+	}
 
 	k3_udma_glue_dump_rx_rt_chn(rx_chn, "rxrt en");
 	return 0;
diff -Naur --no-dereference a/drivers/dma/ti/k3-udma.h b/drivers/dma/ti/k3-udma.h
--- a/drivers/dma/ti/k3-udma.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/dma/ti/k3-udma.h	2025-10-23 09:30:40.284462176 -0400
@@ -6,7 +6,33 @@
 #ifndef K3_UDMA_H_
 #define K3_UDMA_H_
 
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/sys_soc.h>
+#include <linux/of.h>
+#include <linux/of_dma.h>
+#include <linux/of_irq.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/soc/ti/k3-ringacc.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
+#include <linux/soc/ti/ti_sci_inta_msi.h>
+#include <linux/dma/k3-event-router.h>
+#include <linux/dma/ti-cppi5.h>
+
+#include "../virt-dma.h"
+#include "k3-psil-priv.h"
 
 /* Global registers */
 #define UDMA_REV_REG			0x0
@@ -18,11 +44,16 @@
 #define UDMA_RX_FLOW_ID_FW_OES_REG	0x80
 #define UDMA_RX_FLOW_ID_FW_STATUS_REG	0x88
 
+#define UDMA_RX_FLOWRT_RFA             0x8
+
 /* BCHANRT/TCHANRT/RCHANRT registers */
 #define UDMA_CHAN_RT_CTL_REG		0x0
+#define UDMA_CHAN_RT_CFG_REG		0x4
 #define UDMA_CHAN_RT_SWTRIG_REG		0x8
 #define UDMA_CHAN_RT_STDATA_REG		0x80
 
+#define UDMA_CHAN_RT_PDMA_STATE_REG		0x80c
+
 #define UDMA_CHAN_RT_PEER_REG(i)	(0x200 + ((i) * 0x4))
 #define UDMA_CHAN_RT_PEER_STATIC_TR_XY_REG	\
 	UDMA_CHAN_RT_PEER_REG(0)	/* PSI-L: 0x400 */
@@ -62,8 +93,16 @@
 #define UDMA_CHAN_RT_CTL_TDOWN		BIT(30)
 #define UDMA_CHAN_RT_CTL_PAUSE		BIT(29)
 #define UDMA_CHAN_RT_CTL_FTDOWN		BIT(28)
+#define UDMA_CHAN_RT_CTL_AUTOPAIR      BIT(23)
+#define UDMA_CHAN_RT_CTL_PAIR_TIMEOUT  BIT(17)
+#define UDMA_CHAN_RT_CTL_PAIR_COMPLETE BIT(16)
 #define UDMA_CHAN_RT_CTL_ERROR		BIT(0)
 
+/* UDMA_CHAN_RT_PDMA_STATE_REG */
+#define UDMA_CHAN_RT_PDMA_STATE_IN_EVT		BIT(31)
+#define UDMA_CHAN_RT_PDMA_STATE_TDOWN		BIT(30)
+#define UDMA_CHAN_RT_PDMA_STATE_PAUSE		BIT(29)
+
 /* UDMA_CHAN_RT_PEER_RT_EN_REG */
 #define UDMA_PEER_RT_EN_ENABLE		BIT(31)
 #define UDMA_PEER_RT_EN_TEARDOWN	BIT(30)
@@ -94,13 +133,68 @@
  */
 #define PDMA_STATIC_TR_Z(x, mask)	((x) & (mask))
 
+/* UDMA_CHAN_RT_PEER_REG(8) */
+#define UDMA_CHAN_RT_PEER_REG8_FLUSH	0x09000000
+
 /* Address Space Select */
 #define K3_ADDRESS_ASEL_SHIFT		48
 
+#define K3_UDMA_MAX_RFLOWS		1024
+#define K3_UDMA_DEFAULT_RING_SIZE	16
+
+/* How SRC/DST tag should be updated by UDMA in the descriptor's Word 3 */
+#define UDMA_RFLOW_SRCTAG_NONE		0
+#define UDMA_RFLOW_SRCTAG_CFG_TAG	1
+#define UDMA_RFLOW_SRCTAG_FLOW_ID	2
+#define UDMA_RFLOW_SRCTAG_SRC_TAG	4
+
+#define UDMA_RFLOW_DSTTAG_NONE		0
+#define UDMA_RFLOW_DSTTAG_CFG_TAG	1
+#define UDMA_RFLOW_DSTTAG_FLOW_ID	2
+#define UDMA_RFLOW_DSTTAG_DST_TAG_LO	4
+#define UDMA_RFLOW_DSTTAG_DST_TAG_HI	5
+
+/* Device capability flags */
+#define UDMA_FLAG_PDMA_ACC32		BIT(0)
+#define UDMA_FLAG_PDMA_BURST		BIT(1)
+#define UDMA_FLAG_TDTYPE		BIT(2)
+#define UDMA_FLAG_BURST_SIZE		BIT(3)
+#define UDMA_FLAGS_J7_CLASS		(UDMA_FLAG_PDMA_ACC32 | \
+					 UDMA_FLAG_PDMA_BURST | \
+					 UDMA_FLAG_TDTYPE | \
+					 UDMA_FLAG_BURST_SIZE)
+
+#define TI_UDMAC_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
+
+struct udma_chan;
 struct udma_dev;
-struct udma_tchan;
-struct udma_rchan;
-struct udma_rflow;
+
+enum k3_dma_type {
+	DMA_TYPE_UDMA = 0,
+	DMA_TYPE_BCDMA,
+	DMA_TYPE_PKTDMA,
+	DMA_TYPE_BCDMA_V2,
+	DMA_TYPE_PKTDMA_V2,
+};
+
+enum udma_mmr {
+	MMR_GCFG = 0,
+	MMR_BCHANRT,
+	MMR_RCHANRT,
+	MMR_TCHANRT,
+	MMR_LAST,
+};
+
+enum am62l_udma_mmr {
+	AM62L_MMR_GCFG = 0,
+	AM62L_MMR_BCHANRT,
+	AM62L_MMR_CHANRT,
+	AM62L_MMR_LAST,
+};
 
 enum udma_rm_range {
 	RM_RANGE_BCHAN = 0,
@@ -111,6 +205,69 @@
 	RM_RANGE_LAST,
 };
 
+enum udma_chan_state {
+	UDMA_CHAN_IS_IDLE = 0, /* not active, no teardown is in progress */
+	UDMA_CHAN_IS_ACTIVE, /* Normal operation */
+	UDMA_CHAN_IS_TERMINATING, /* channel is being terminated */
+};
+
+struct udma_filter_param {
+	int remote_thread_id;
+	u32 atype;
+	u32 asel;
+	u32 tr_trigger_type;
+};
+
+struct am62l_udma_filter_param {
+	u32 tr_trigger_type;
+	u32 trigger_param;
+	int remote_thread_id;
+	u32 asel;
+};
+
+struct udma_static_tr {
+	u8 elsize; /* RPSTR0 */
+	u16 elcnt; /* RPSTR0 */
+	u16 bstcnt; /* RPSTR1 */
+};
+
+struct udma_tchan {
+	void __iomem *reg_rt;
+
+	int id;
+	struct k3_ring *t_ring; /* Transmit ring */
+	struct k3_ring *tc_ring; /* Transmit Completion ring */
+	int tflow_id; /* applicable only for PKTDMA */
+};
+
+#define udma_bchan udma_tchan
+#define udma_rchan udma_tchan
+
+struct udma_rflow {
+	int id;
+	struct k3_ring *fd_ring; /* Free Descriptor ring */
+	struct k3_ring *r_ring; /* Receive ring */
+	void __iomem *reg_rt;
+};
+
+struct udma_oes_offsets {
+	/* K3 UDMA Output Event Offset */
+	u32 udma_rchan;
+
+	/* BCDMA Output Event Offsets */
+	u32 bcdma_bchan_data;
+	u32 bcdma_bchan_ring;
+	u32 bcdma_tchan_data;
+	u32 bcdma_tchan_ring;
+	u32 bcdma_rchan_data;
+	u32 bcdma_rchan_ring;
+
+	/* PKTDMA Output Event Offsets */
+	u32 pktdma_tchan_flow;
+	u32 pktdma_rchan_flow;
+};
+
+
 struct udma_tisci_rm {
 	const struct ti_sci_handle *tisci;
 	const struct ti_sci_rm_udmap_ops *tisci_udmap_ops;
@@ -123,6 +280,414 @@
 	struct ti_sci_resource *rm_ranges[RM_RANGE_LAST];
 };
 
+
+struct udma_match_data {
+	enum k3_dma_type type;
+	u32 psil_base;
+	bool enable_memcpy_support;
+	u32 flags;
+	u32 statictr_z_mask;
+	u8 burst_size[3];
+	struct udma_soc_data *soc_data;
+	u32 bchan_cnt;
+	u32 chan_cnt;
+	u32 tchan_cnt;
+	u32 rchan_cnt;
+	u32 tflow_cnt;
+	u32 rflow_cnt;
+};
+
+struct udma_soc_data {
+	struct udma_oes_offsets oes;
+	u32 bcdma_trigger_event_offset;
+};
+
+struct udma_hwdesc {
+	size_t cppi5_desc_size;
+	void *cppi5_desc_vaddr;
+	dma_addr_t cppi5_desc_paddr;
+
+	/* TR descriptor internal pointers */
+	void *tr_req_base;
+	struct cppi5_tr_resp_t *tr_resp_base;
+};
+
+struct udma_rx_flush {
+	struct udma_hwdesc hwdescs[2];
+
+	size_t buffer_size;
+	void *buffer_vaddr;
+	dma_addr_t buffer_paddr;
+};
+
+struct udma_tpl {
+	u8 levels;
+	u32 start_idx[3];
+};
+
+struct udma_desc {
+	struct virt_dma_desc vd;
+
+	bool terminated;
+
+	enum dma_transfer_direction dir;
+
+	struct udma_static_tr static_tr;
+	u32 residue;
+
+	unsigned int sglen;
+	unsigned int desc_idx; /* Only used for cyclic in packet mode */
+	unsigned int tr_idx;
+
+	u32 metadata_size;
+	void *metadata; /* pointer to provided metadata buffer (EPIP, PSdata) */
+
+	unsigned int hwdesc_count;
+	struct udma_hwdesc hwdesc[];
+};
+
+struct udma_tx_drain {
+	struct delayed_work work;
+	ktime_t tstamp;
+	u32 residue;
+};
+
+struct udma_chan_config {
+	bool pkt_mode; /* TR or packet */
+	bool needs_epib; /* EPIB is needed for the communication or not */
+	u32 psd_size; /* size of Protocol Specific Data */
+	u32 metadata_size; /* (needs_epib ? 16:0) + psd_size */
+	u32 hdesc_size; /* Size of a packet descriptor in packet mode */
+	bool notdpkt; /* Suppress sending TDC packet */
+	int remote_thread_id;
+	u32 atype;
+	u32 asel;
+	u32 src_thread;
+	u32 dst_thread;
+	enum psil_endpoint_type ep_type;
+	bool enable_acc32;
+	bool enable_burst;
+	enum udma_tp_level channel_tpl; /* Channel Throughput Level */
+
+	u32 tr_trigger_type;
+	unsigned long tx_flags;
+
+	/* PKDMA mapped channel */
+	int mapped_channel_id;
+	/* PKTDMA default tflow or rflow for mapped channel */
+	int default_flow_id;
+
+	enum dma_transfer_direction dir;
+};
+
+struct udma_dev {
+	struct dma_device ddev;
+	struct device *dev;
+	void __iomem *mmrs[MMR_LAST];
+	void __iomem *rflow_rt;
+	const struct udma_match_data *match_data;
+	const struct udma_soc_data *soc_data;
+
+	struct udma_tpl bchan_tpl;
+	struct udma_tpl tchan_tpl;
+	struct udma_tpl rchan_tpl;
+
+	size_t desc_align; /* alignment to use for descriptors */
+
+	struct udma_tisci_rm tisci_rm;
+
+	struct k3_ringacc *ringacc;
+
+	struct work_struct purge_work;
+	struct list_head desc_to_purge;
+	spinlock_t lock;
+
+	struct udma_rx_flush rx_flush;
+
+	int bchan_cnt;
+	int chan_cnt;
+	int tchan_cnt;
+	int echan_cnt;
+	int rchan_cnt;
+	int rflow_cnt;
+	int tflow_cnt;
+	unsigned long *bchan_map;
+	unsigned long *chan_map;
+	unsigned long *tchan_map;
+	unsigned long *rchan_map;
+	unsigned long *rflow_gp_map;
+	unsigned long *rflow_gp_map_allocated;
+	unsigned long *rflow_in_use;
+	unsigned long *tflow_map;
+
+	struct udma_bchan *bchans;
+	struct udma_tchan *chans;
+	struct udma_tchan *tchans;
+	struct udma_rchan *rchans;
+	struct udma_rflow *rflows;
+
+	struct udma_chan *channels;
+	u32 psil_base;
+	u32 atype;
+	u32 asel;
+
+	int (*udma_start)(struct udma_chan *uc);
+	int (*udma_stop)(struct udma_chan *uc);
+	int (*udma_reset_chan)(struct udma_chan *uc, bool hard);
+	bool (*udma_is_desc_really_done)(struct udma_chan *uc, struct udma_desc *d);
+	void (*udma_decrement_byte_counters)(struct udma_chan *uc, u32 val);
+};
+
+struct udma_chan {
+	struct virt_dma_chan vc;
+	struct dma_slave_config	cfg;
+	struct udma_dev *ud;
+	struct device *dma_dev;
+	struct udma_desc *desc;
+	struct udma_desc *terminated_desc;
+	struct udma_static_tr static_tr;
+	char *name;
+
+	struct udma_bchan *bchan;
+	struct udma_tchan *chan;
+	struct udma_tchan *tchan;
+	struct udma_rchan *rchan;
+	struct udma_rflow *rflow;
+
+	bool psil_paired;
+
+	int irq_num_ring;
+	int irq_num_udma;
+
+	bool cyclic;
+	bool paused;
+
+	enum udma_chan_state state;
+	struct completion teardown_completed;
+
+	struct udma_tx_drain tx_drain;
+
+	/* Channel configuration parameters */
+	struct udma_chan_config config;
+	/* Channel configuration parameters (backup) */
+	struct udma_chan_config backup_config;
+
+	/* dmapool for packet mode descriptors */
+	bool use_dma_pool;
+	struct dma_pool *hdesc_pool;
+
+	u32 id;
+};
+
+/* K3 UDMA helper functions */
+static inline struct udma_dev *to_udma_dev(struct dma_device *d)
+{
+	return container_of(d, struct udma_dev, ddev);
+}
+
+static inline struct udma_chan *to_udma_chan(struct dma_chan *c)
+{
+	return container_of(c, struct udma_chan, vc.chan);
+}
+
+static inline struct udma_desc *to_udma_desc(struct dma_async_tx_descriptor *t)
+{
+	return container_of(t, struct udma_desc, vd.tx);
+}
+
+/* Generic register access functions */
+static inline u32 udma_read(void __iomem *base, int reg)
+{
+	return readl(base + reg);
+}
+
+static inline void udma_write(void __iomem *base, int reg, u32 val)
+{
+	writel(val, base + reg);
+}
+
+static inline void udma_update_bits(void __iomem *base, int reg,
+				    u32 mask, u32 val)
+{
+	u32 tmp, orig;
+
+	orig = readl(base + reg);
+	tmp = orig & ~mask;
+	tmp |= (val & mask);
+
+	if (tmp != orig)
+		writel(tmp, base + reg);
+}
+
+#define _UDMA_REG_ACCESS(channel)					\
+static inline u32 udma_##channel##rt_read(struct udma_chan *uc, int reg) \
+{ \
+	if (!uc->channel) \
+		return 0; \
+	return udma_read(uc->channel->reg_rt, reg); \
+} \
+\
+static inline void udma_##channel##rt_write(struct udma_chan *uc, int reg, u32 val) \
+{ \
+	if (!uc->channel) \
+		return; \
+	udma_write(uc->channel->reg_rt, reg, val); \
+} \
+\
+static inline void udma_##channel##rt_update_bits(struct udma_chan *uc, int reg, \
+						u32 mask, u32 val) \
+{ \
+	if (!uc->channel) \
+		return; \
+	udma_update_bits(uc->channel->reg_rt, reg, mask, val); \
+}
+
+_UDMA_REG_ACCESS(chan);
+_UDMA_REG_ACCESS(bchan);
+_UDMA_REG_ACCESS(tchan);
+_UDMA_REG_ACCESS(rchan);
+
+static inline dma_addr_t udma_curr_cppi5_desc_paddr(struct udma_desc *d,
+						    int idx)
+{
+	return d->hwdesc[idx].cppi5_desc_paddr;
+}
+
+static inline void *udma_curr_cppi5_desc_vaddr(struct udma_desc *d, int idx)
+{
+	return d->hwdesc[idx].cppi5_desc_vaddr;
+}
+
+static inline dma_addr_t udma_get_rx_flush_hwdesc_paddr(struct udma_chan *uc)
+{
+	return uc->ud->rx_flush.hwdescs[uc->config.pkt_mode].cppi5_desc_paddr;
+}
+
+static inline void udma_fetch_epib(struct udma_chan *uc, struct udma_desc *d)
+{
+	struct cppi5_host_desc_t *h_desc = d->hwdesc[0].cppi5_desc_vaddr;
+
+	memcpy(d->metadata, h_desc->epib, d->metadata_size);
+}
+
+void udma_start_desc(struct udma_chan *uc);
+bool udma_chan_needs_reconfiguration(struct udma_chan *uc);
+void udma_cyclic_packet_elapsed(struct udma_chan *uc);
+void udma_check_tx_completion(struct work_struct *work);
+void udma_issue_pending(struct dma_chan *chan);
+void udma_free_chan_resources(struct dma_chan *chan);
+int setup_resources(struct udma_dev *ud);
+void udma_mark_resource_ranges(struct udma_dev *ud, unsigned long *map,
+			    struct ti_sci_resource_desc *rm_desc,
+			    char *name);
+int udma_setup_resources(struct udma_dev *ud);
+int bcdma_setup_resources(struct udma_dev *ud);
+int pktdma_setup_resources(struct udma_dev *ud);
+
+void k3_configure_chan_coherency(struct dma_chan *chan, u32 asel);
+u8 udma_get_chan_tpl_index(struct udma_tpl *tpl_map, int chan_id);
+void udma_reset_uchan(struct udma_chan *uc);
+void udma_dump_chan_stdata(struct udma_chan *uc);
+struct udma_desc *udma_udma_desc_from_paddr(struct udma_chan *uc,
+				   dma_addr_t paddr);
+void udma_free_hwdesc(struct udma_chan *uc, struct udma_desc *d);
+void udma_purge_desc_work(struct work_struct *work);
+void udma_desc_free(struct virt_dma_desc *vd);
+bool udma_is_chan_running(struct udma_chan *uc);
+void udma_reset_rings(struct udma_chan *uc);
+int udma_push_to_ring(struct udma_chan *uc, int idx);
+bool udma_desc_is_rx_flush(struct udma_chan *uc, dma_addr_t addr);
+int udma_pop_from_ring(struct udma_chan *uc, dma_addr_t *addr);
+
+int __udma_alloc_gp_rflow_range(struct udma_dev *ud, int from, int cnt);
+int __udma_free_gp_rflow_range(struct udma_dev *ud, int from, int cnt);
+struct udma_rflow *__udma_get_rflow(struct udma_dev *ud, int id);
+void __udma_put_rflow(struct udma_dev *ud, struct udma_rflow *rflow);
+
+struct udma_bchan *__udma_reserve_bchan(struct udma_dev *ud, enum udma_tp_level tpl, int id);
+struct udma_tchan *__udma_reserve_tchan(struct udma_dev *ud, enum udma_tp_level tpl, int id);
+struct udma_rchan *__udma_reserve_rchan(struct udma_dev *ud, enum udma_tp_level tpl, int id);
+
+int udma_get_tchan(struct udma_chan *uc);
+int udma_get_rchan(struct udma_chan *uc);
+int udma_get_chan_pair(struct udma_chan *uc);
+int udma_get_rflow(struct udma_chan *uc, int flow_id);
+void bcdma_put_bchan(struct udma_chan *uc);
+void udma_put_rchan(struct udma_chan *uc);
+void udma_put_tchan(struct udma_chan *uc);
+void udma_put_rflow(struct udma_chan *uc);
+void bcdma_free_bchan_resources(struct udma_chan *uc);
+void udma_free_tx_resources(struct udma_chan *uc);
+void udma_free_rx_resources(struct udma_chan *uc);
+int udma_slave_config(struct dma_chan *chan,
+	     struct dma_slave_config *cfg);
+struct udma_desc *udma_alloc_tr_desc(struct udma_chan *uc,
+			    size_t tr_size, int tr_count,
+			    enum dma_transfer_direction dir);
+int udma_get_tr_counters(size_t len, unsigned long align_to,
+		u16 *tr0_cnt0, u16 *tr0_cnt1, u16 *tr1_cnt0);
+struct udma_desc *
+udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl,
+		      unsigned int sglen, enum dma_transfer_direction dir,
+		      unsigned long tx_flags, void *context);
+struct udma_desc *
+udma_prep_slave_sg_triggered_tr(struct udma_chan *uc, struct scatterlist *sgl,
+				unsigned int sglen,
+				enum dma_transfer_direction dir,
+				unsigned long tx_flags, void *context);
+int udma_configure_statictr(struct udma_chan *uc, struct udma_desc *d,
+				   enum dma_slave_buswidth dev_width,
+				   u16 elcnt);
+struct udma_desc *
+udma_prep_slave_sg_pkt(struct udma_chan *uc, struct scatterlist *sgl,
+		       unsigned int sglen, enum dma_transfer_direction dir,
+		       unsigned long tx_flags, void *context);
+int udma_attach_metadata(struct dma_async_tx_descriptor *desc,
+				void *data, size_t len);
+void *udma_get_metadata_ptr(struct dma_async_tx_descriptor *desc,
+				   size_t *payload_len, size_t *max_len);
+int udma_set_metadata_len(struct dma_async_tx_descriptor *desc,
+				 size_t payload_len);
+struct dma_async_tx_descriptor *
+udma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+		   unsigned int sglen, enum dma_transfer_direction dir,
+		   unsigned long tx_flags, void *context);
+struct udma_desc *
+udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr,
+			size_t buf_len, size_t period_len,
+			enum dma_transfer_direction dir, unsigned long flags);
+struct udma_desc *
+udma_prep_dma_cyclic_pkt(struct udma_chan *uc, dma_addr_t buf_addr,
+			 size_t buf_len, size_t period_len,
+			 enum dma_transfer_direction dir, unsigned long flags);
+struct dma_async_tx_descriptor *
+udma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
+		     size_t period_len, enum dma_transfer_direction dir,
+		     unsigned long flags);
+struct dma_async_tx_descriptor *
+udma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+		     size_t len, unsigned long tx_flags);
+int udma_terminate_all(struct dma_chan *chan);
+void udma_synchronize(struct dma_chan *chan);
+void udma_desc_pre_callback(struct virt_dma_chan *vc,
+		   struct virt_dma_desc *vd,
+		   struct dmaengine_result *result);
+
+void udma_vchan_complete(struct tasklet_struct *t);
+int udma_setup_rx_flush(struct udma_dev *ud);
+
+#ifdef CONFIG_DEBUG_FS
+void udma_dbg_summary_show_chan(struct seq_file *s,
+				       struct dma_chan *chan);
+void udma_dbg_summary_show(struct seq_file *s,
+				  struct dma_device *dma_dev);
+#endif /* CONFIG_DEBUG_FS */
+
+enum dmaengine_alignment udma_get_copy_align(struct udma_dev *ud);
+int navss_psil_pair(struct udma_dev *ud, u32 src_thread, u32 dst_thread);
+int navss_psil_unpair(struct udma_dev *ud, u32 src_thread,
+	     u32 dst_thread);
+
 /* Direct access to UDMA low lever resources for the glue layer */
 int xudma_navss_psil_pair(struct udma_dev *ud, u32 src_thread, u32 dst_thread);
 int xudma_navss_psil_unpair(struct udma_dev *ud, u32 src_thread,
@@ -155,6 +720,8 @@
 void xudma_rchanrt_write(struct udma_rchan *rchan, int reg, u32 val);
 bool xudma_rflow_is_gp(struct udma_dev *ud, int id);
 int xudma_get_rflow_ring_offset(struct udma_dev *ud);
+u32 xudma_rflowrt_read(struct udma_rflow *rflow, int reg);
+void xudma_rflowrt_write(struct udma_rflow *rflow, int reg, u32 val);
 
 int xudma_is_pktdma(struct udma_dev *ud);
 
diff -Naur --no-dereference a/drivers/dma/ti/k3-udma-private.c b/drivers/dma/ti/k3-udma-private.c
--- a/drivers/dma/ti/k3-udma-private.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/dma/ti/k3-udma-private.c	2025-10-23 09:30:40.284462176 -0400
@@ -3,18 +3,28 @@
  *  Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com
  *  Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
  */
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/interrupt.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 
 int xudma_navss_psil_pair(struct udma_dev *ud, u32 src_thread, u32 dst_thread)
 {
-	return navss_psil_pair(ud, src_thread, dst_thread);
+	if (IS_ENABLED(CONFIG_TI_K3_UDMA))
+		return navss_psil_pair(ud, src_thread, dst_thread);
+
+	return 0;
 }
 EXPORT_SYMBOL(xudma_navss_psil_pair);
 
 int xudma_navss_psil_unpair(struct udma_dev *ud, u32 src_thread, u32 dst_thread)
 {
-	return navss_psil_unpair(ud, src_thread, dst_thread);
+	if (IS_ENABLED(CONFIG_TI_K3_UDMA))
+		return navss_psil_unpair(ud, src_thread, dst_thread);
+
+	return 0;
 }
 EXPORT_SYMBOL(xudma_navss_psil_unpair);
 
@@ -159,15 +169,32 @@
 EXPORT_SYMBOL(xudma_##res##rt_write)
 XUDMA_RT_IO_FUNCTIONS(tchan);
 XUDMA_RT_IO_FUNCTIONS(rchan);
+XUDMA_RT_IO_FUNCTIONS(rflow);
 
 int xudma_is_pktdma(struct udma_dev *ud)
 {
-	return ud->match_data->type == DMA_TYPE_PKTDMA;
+	return (ud->match_data->type == DMA_TYPE_PKTDMA ||
+			ud->match_data->type == DMA_TYPE_PKTDMA_V2);
 }
 EXPORT_SYMBOL(xudma_is_pktdma);
 
 int xudma_pktdma_tflow_get_irq(struct udma_dev *ud, int udma_tflow_id)
 {
+	if (ud->match_data->type == DMA_TYPE_PKTDMA_V2) {
+		__be32 addr[2] = {0, 0};
+		struct of_phandle_args out_irq;
+		int ret;
+
+		out_irq.np = dev_of_node(ud->dev);
+		out_irq.args_count = 1;
+		out_irq.args[0] = udma_tflow_id;
+		ret = of_irq_parse_raw(addr, &out_irq);
+		if (ret)
+			return ret;
+
+		return irq_create_of_mapping(&out_irq);
+	}
+
 	const struct udma_oes_offsets *oes = &ud->soc_data->oes;
 
 	return msi_get_virq(ud->dev, udma_tflow_id + oes->pktdma_tchan_flow);
@@ -176,6 +203,21 @@
 
 int xudma_pktdma_rflow_get_irq(struct udma_dev *ud, int udma_rflow_id)
 {
+	if (ud->match_data->type == DMA_TYPE_PKTDMA_V2) {
+		__be32 addr[2] = {0, 0};
+		struct of_phandle_args out_irq;
+		int ret;
+
+		out_irq.np = dev_of_node(ud->dev);
+		out_irq.args_count = 1;
+		out_irq.args[0] = udma_rflow_id;
+		ret = of_irq_parse_raw(addr, &out_irq);
+		if (ret)
+			return ret;
+
+		return irq_create_of_mapping(&out_irq);
+	}
+
 	const struct udma_oes_offsets *oes = &ud->soc_data->oes;
 
 	return msi_get_virq(ud->dev, udma_rflow_id + oes->pktdma_rchan_flow);
diff -Naur --no-dereference a/drivers/dma/ti/Kconfig b/drivers/dma/ti/Kconfig
--- a/drivers/dma/ti/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/dma/ti/Kconfig	2025-10-23 09:30:40.284462176 -0400
@@ -47,17 +47,27 @@
 	  Enable support for the TI UDMA (Unified DMA) controller. This
 	  DMA engine is used in AM65x and j721e.
 
+config TI_K3_UDMA_AM62L
+	tristate "Texas Instruments AM62L UDMA support"
+	depends on ARCH_K3
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+	select TI_K3_RINGACC
+	select TI_K3_PSIL
+        help
+	  Enable support for the TI AM62L UDMA (Unified DMA) controller.
+
 config TI_K3_UDMA_GLUE_LAYER
 	tristate "Texas Instruments UDMA Glue layer for non DMAengine users"
 	depends on ARCH_K3
-	depends on TI_K3_UDMA
+	depends on TI_K3_UDMA || TI_K3_UDMA_AM62L
 	help
 	  Say y here to support the K3 NAVSS DMA glue interface
 	  If unsure, say N.
 
 config TI_K3_PSIL
        tristate
-       default TI_K3_UDMA
+       default TI_K3_UDMA || TI_K3_UDMA_AM62L
 
 config TI_DMA_CROSSBAR
 	bool
diff -Naur --no-dereference a/drivers/dma/ti/Makefile b/drivers/dma/ti/Makefile
--- a/drivers/dma/ti/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/dma/ti/Makefile	2025-10-23 09:30:40.284462176 -0400
@@ -2,7 +2,8 @@
 obj-$(CONFIG_TI_CPPI41) += cppi41.o
 obj-$(CONFIG_TI_EDMA) += edma.o
 obj-$(CONFIG_DMA_OMAP) += omap-dma.o
-obj-$(CONFIG_TI_K3_UDMA) += k3-udma.o
+obj-$(CONFIG_TI_K3_UDMA) += k3-udma.o k3-udma-common.o
+obj-$(CONFIG_TI_K3_UDMA_AM62L) += k3-udma-am62l.o k3-udma-common.o
 obj-$(CONFIG_TI_K3_UDMA_GLUE_LAYER) += k3-udma-glue.o
 k3-psil-lib-objs := k3-psil.o \
 		    k3-psil-am654.o \
@@ -12,6 +13,7 @@
 		    k3-psil-j721s2.o \
 		    k3-psil-am62.o \
 		    k3-psil-am62a.o \
+		    k3-psil-am62l.o \
 		    k3-psil-j784s4.o \
 		    k3-psil-am62p.o
 obj-$(CONFIG_TI_K3_PSIL) += k3-psil-lib.o
diff -Naur --no-dereference a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
--- a/drivers/dma-buf/dma-heap.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/dma-buf/dma-heap.c	2025-10-23 09:30:40.284462176 -0400
@@ -326,4 +326,4 @@
 
 	return 0;
 }
-subsys_initcall(dma_heap_init);
+core_initcall(dma_heap_init);
diff -Naur --no-dereference a/drivers/dma-buf/heaps/carveout-heap.c b/drivers/dma-buf/heaps/carveout-heap.c
--- a/drivers/dma-buf/heaps/carveout-heap.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/dma-buf/heaps/carveout-heap.c	2025-10-23 09:30:40.284462176 -0400
@@ -0,0 +1,411 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Carveout DMA-Heap userspace exporter
+ *
+ * Copyright (C) 2019-2022 Texas Instruments Incorporated - https://www.ti.com/
+ *	Andrew Davis <afd@ti.com>
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/genalloc.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/dma-buf.h>
+#include <linux/dma-heap.h>
+
+struct carveout_dma_heap {
+	struct dma_heap *heap;
+	struct gen_pool *pool;
+	bool cached;
+};
+
+struct carveout_dma_heap_buffer {
+	struct gen_pool *pool;
+	struct list_head attachments;
+	struct mutex attachments_lock;
+	struct mutex vmap_lock;
+	int vmap_cnt;
+	unsigned long len;
+	void *vaddr;
+	phys_addr_t paddr;
+	bool cached;
+};
+
+struct dma_heap_attachment {
+	struct device *dev;
+	struct sg_table *table;
+	struct list_head list;
+};
+
+static int dma_heap_attach(struct dma_buf *dmabuf,
+			   struct dma_buf_attachment *attachment)
+{
+	struct carveout_dma_heap_buffer *buffer = dmabuf->priv;
+	struct dma_heap_attachment *a;
+	struct sg_table *table;
+
+	a = kzalloc(sizeof(*a), GFP_KERNEL);
+	if (!a)
+		return -ENOMEM;
+
+	table = kmalloc(sizeof(*table), GFP_KERNEL);
+	if (!table) {
+		kfree(a);
+		return -ENOMEM;
+	}
+	if (sg_alloc_table(table, 1, GFP_KERNEL)) {
+		kfree(a);
+		return -ENOMEM;
+	}
+	sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(buffer->paddr)), buffer->len, 0);
+
+	a->table = table;
+	a->dev = attachment->dev;
+	INIT_LIST_HEAD(&a->list);
+
+	attachment->priv = a;
+
+	mutex_lock(&buffer->attachments_lock);
+	list_add(&a->list, &buffer->attachments);
+	mutex_unlock(&buffer->attachments_lock);
+
+	return 0;
+}
+
+static void dma_heap_detatch(struct dma_buf *dmabuf,
+			     struct dma_buf_attachment *attachment)
+{
+	struct carveout_dma_heap_buffer *buffer = dmabuf->priv;
+	struct dma_heap_attachment *a = attachment->priv;
+
+	mutex_lock(&buffer->attachments_lock);
+	list_del(&a->list);
+	mutex_unlock(&buffer->attachments_lock);
+
+	sg_free_table(a->table);
+	kfree(a->table);
+	kfree(a);
+}
+
+static struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment *attachment,
+					     enum dma_data_direction direction)
+{
+	struct carveout_dma_heap_buffer *buffer = attachment->dmabuf->priv;
+	struct dma_heap_attachment *a = attachment->priv;
+	struct sg_table *table = a->table;
+
+	unsigned long attrs = buffer->cached ? 0 : DMA_ATTR_SKIP_CPU_SYNC;
+
+	if (!dma_map_sg_attrs(attachment->dev, table->sgl, table->nents,
+			      direction, attrs))
+		return ERR_PTR(-ENOMEM);
+
+	return table;
+}
+
+static void dma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
+				   struct sg_table *table,
+				   enum dma_data_direction direction)
+{
+	struct carveout_dma_heap_buffer *buffer = attachment->dmabuf->priv;
+	unsigned long attrs = buffer->cached ? 0 : DMA_ATTR_SKIP_CPU_SYNC;
+
+	dma_unmap_sg_attrs(attachment->dev, table->sgl, table->nents,
+			   direction, attrs);
+}
+
+static void dma_heap_dma_buf_release(struct dma_buf *dmabuf)
+{
+	struct carveout_dma_heap_buffer *buffer = dmabuf->priv;
+
+	if (buffer->vmap_cnt > 0) {
+		WARN(1, "%s: buffer still mapped in the kernel\n", __func__);
+		memunmap(buffer->vaddr);
+	}
+
+	gen_pool_free(buffer->pool, buffer->paddr, buffer->len);
+	kfree(buffer);
+}
+
+static int dma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
+					     enum dma_data_direction direction)
+{
+	struct carveout_dma_heap_buffer *buffer = dmabuf->priv;
+	struct dma_heap_attachment *a;
+
+	if (!buffer->cached)
+		return 0;
+
+	mutex_lock(&buffer->vmap_lock);
+	if (buffer->vmap_cnt)
+		invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
+	mutex_unlock(&buffer->vmap_lock);
+
+	mutex_lock(&buffer->attachments_lock);
+	list_for_each_entry(a, &buffer->attachments, list) {
+		dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents,
+				    direction);
+	}
+	mutex_unlock(&buffer->attachments_lock);
+
+	return 0;
+}
+
+static int dma_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
+					   enum dma_data_direction direction)
+{
+	struct carveout_dma_heap_buffer *buffer = dmabuf->priv;
+	struct dma_heap_attachment *a;
+
+	if (!buffer->cached)
+		return 0;
+
+	mutex_lock(&buffer->vmap_lock);
+	if (buffer->vmap_cnt)
+		flush_kernel_vmap_range(buffer->vaddr, buffer->len);
+	mutex_unlock(&buffer->vmap_lock);
+
+	mutex_lock(&buffer->attachments_lock);
+	list_for_each_entry(a, &buffer->attachments, list) {
+		dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents,
+				       direction);
+	}
+	mutex_unlock(&buffer->attachments_lock);
+
+	return 0;
+}
+
+static int dma_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
+{
+	struct carveout_dma_heap_buffer *buffer = dmabuf->priv;
+	int ret;
+
+	if (!buffer->cached)
+		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+	ret = vm_iomap_memory(vma, buffer->paddr, buffer->len);
+	if (ret)
+		pr_err("Could not map buffer to userspace\n");
+
+	return ret;
+}
+
+static int dma_heap_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
+{
+	struct carveout_dma_heap_buffer *buffer = dmabuf->priv;
+	void *vaddr;
+	int ret = 0;
+
+	mutex_lock(&buffer->vmap_lock);
+
+	if (buffer->vmap_cnt) {
+		buffer->vmap_cnt++;
+		iosys_map_set_vaddr(map, buffer->vaddr);
+		goto exit;
+	}
+	if (buffer->cached)
+		vaddr = memremap(buffer->paddr, buffer->len, MEMREMAP_WB);
+	else
+		vaddr = memremap(buffer->paddr, buffer->len, MEMREMAP_WC);
+	if (!vaddr) {
+		pr_err("Could not memremap buffer\n");
+		ret = -ENOMEM;
+		goto exit;
+	}
+	if (IS_ERR(vaddr)) {
+		ret = PTR_ERR(vaddr);
+		goto exit;
+	}
+
+	buffer->vaddr = vaddr;
+	buffer->vmap_cnt++;
+	iosys_map_set_vaddr(map, buffer->vaddr);
+exit:
+	mutex_unlock(&buffer->vmap_lock);
+
+	return ret;
+}
+
+static void dma_heap_vunmap(struct dma_buf *dmabuf, struct iosys_map *map)
+{
+	struct carveout_dma_heap_buffer *buffer = dmabuf->priv;
+
+	mutex_lock(&buffer->vmap_lock);
+	if (!--buffer->vmap_cnt) {
+		memunmap(buffer->vaddr);
+		buffer->vaddr = NULL;
+	}
+	mutex_unlock(&buffer->vmap_lock);
+}
+
+static const struct dma_buf_ops carveout_dma_heap_buf_ops = {
+	.attach = dma_heap_attach,
+	.detach = dma_heap_detatch,
+	.map_dma_buf = dma_heap_map_dma_buf,
+	.unmap_dma_buf = dma_heap_unmap_dma_buf,
+	.release = dma_heap_dma_buf_release,
+	.begin_cpu_access = dma_heap_dma_buf_begin_cpu_access,
+	.end_cpu_access = dma_heap_dma_buf_end_cpu_access,
+	.mmap = dma_heap_mmap,
+	.vmap = dma_heap_vmap,
+	.vunmap = dma_heap_vunmap,
+};
+
+static struct dma_buf *carveout_dma_heap_allocate(struct dma_heap *heap,
+						  unsigned long len,
+						  u32 fd_flags,
+						  u64 heap_flags)
+{
+	struct carveout_dma_heap *carveout_dma_heap = dma_heap_get_drvdata(heap);
+	struct carveout_dma_heap_buffer *buffer;
+
+	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+	struct dma_buf *dmabuf;
+	int ret = 0;
+
+	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
+	if (!buffer)
+		return ERR_PTR(-ENOMEM);
+	buffer->pool = carveout_dma_heap->pool;
+	buffer->cached = carveout_dma_heap->cached;
+	INIT_LIST_HEAD(&buffer->attachments);
+	mutex_init(&buffer->attachments_lock);
+	mutex_init(&buffer->vmap_lock);
+	buffer->len = len;
+
+	buffer->paddr = gen_pool_alloc(buffer->pool, buffer->len);
+	if (!buffer->paddr) {
+		ret = -ENOMEM;
+		goto free_buffer;
+	}
+
+	/* create the dmabuf */
+	exp_info.exp_name = dma_heap_get_name(heap);
+	exp_info.ops = &carveout_dma_heap_buf_ops;
+	exp_info.size = buffer->len;
+	exp_info.flags = fd_flags;
+	exp_info.priv = buffer;
+	dmabuf = dma_buf_export(&exp_info);
+	if (IS_ERR(dmabuf)) {
+		ret = PTR_ERR(dmabuf);
+		goto free_pool;
+	}
+
+	return dmabuf;
+
+free_pool:
+	gen_pool_free(buffer->pool, buffer->paddr, buffer->len);
+free_buffer:
+	kfree(buffer);
+
+	return ERR_PTR(ret);
+}
+
+static struct dma_heap_ops carveout_dma_heap_ops = {
+	.allocate = carveout_dma_heap_allocate,
+};
+
+static int carveout_dma_heap_export(phys_addr_t base, size_t size, const char *name, bool cached)
+{
+	struct carveout_dma_heap *carveout_dma_heap;
+	struct dma_heap_export_info exp_info;
+	int ret;
+
+	carveout_dma_heap = kzalloc(sizeof(*carveout_dma_heap), GFP_KERNEL);
+	if (!carveout_dma_heap)
+		return -ENOMEM;
+
+	carveout_dma_heap->pool = gen_pool_create(PAGE_SHIFT, NUMA_NO_NODE);
+	if (IS_ERR(carveout_dma_heap->pool)) {
+		pr_err("Carveout Heap: Could not create memory pool\n");
+		ret = PTR_ERR(carveout_dma_heap->pool);
+		goto free_carveout_dma_heap;
+	}
+	ret = gen_pool_add(carveout_dma_heap->pool, base, size, NUMA_NO_NODE);
+	if (ret) {
+		pr_err("Carveout Heap: Could not add memory to pool\n");
+		goto free_pool;
+	}
+
+	carveout_dma_heap->cached = cached;
+
+	exp_info.name = kasprintf(GFP_KERNEL, "carveout_%s", name);
+	exp_info.ops = &carveout_dma_heap_ops;
+	exp_info.priv = carveout_dma_heap;
+	carveout_dma_heap->heap = dma_heap_add(&exp_info);
+	if (IS_ERR(carveout_dma_heap->heap)) {
+		pr_err("Carveout Heap: Could not add DMA-Heap\n");
+		ret = PTR_ERR(carveout_dma_heap->heap);
+		goto free_pool;
+	}
+
+	pr_info("Carveout Heap: Exported %zu MiB at %pa\n", size / SZ_1M, &base);
+
+	return 0;
+
+free_pool:
+	gen_pool_destroy(carveout_dma_heap->pool);
+free_carveout_dma_heap:
+	kfree(carveout_dma_heap);
+	return ret;
+}
+
+#ifdef CONFIG_OF_RESERVED_MEM
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_reserved_mem.h>
+
+#define MAX_HEAP_AREAS 7
+static struct reserved_mem heap_areas[MAX_HEAP_AREAS];
+static size_t heap_area_count;
+
+static int __init carveout_dma_heap_init_areas(void)
+{
+	int i;
+
+	for (i = 0; i < heap_area_count; i++) {
+		struct reserved_mem *rmem = &heap_areas[i];
+		bool cached = !of_get_flat_dt_prop(rmem->fdt_node, "no-map", NULL);
+		int ret = carveout_dma_heap_export(rmem->base, rmem->size, rmem->name, cached);
+		if (ret) {
+			pr_err("Carveout Heap: could not export as DMA-Heap\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+fs_initcall(carveout_dma_heap_init_areas);
+
+static int __init rmem_dma_heap_carveout_setup(struct reserved_mem *rmem)
+{
+	phys_addr_t align = PAGE_SIZE;
+	phys_addr_t mask = align - 1;
+
+	if ((rmem->base & mask) || (rmem->size & mask)) {
+		pr_err("Carveout Heap: incorrect alignment of region\n");
+		return -EINVAL;
+	}
+
+	/* Sanity check */
+	if (heap_area_count == ARRAY_SIZE(heap_areas)) {
+		pr_err("Not enough slots for DMA-Heap reserved regions!\n");
+		return -ENOSPC;
+	}
+
+	/*
+	 * Each reserved area must be initialized later, when more kernel
+	 * subsystems (like slab allocator) are available.
+	 */
+	heap_areas[heap_area_count] = *rmem;
+	heap_area_count++;
+
+	return 0;
+}
+RESERVEDMEM_OF_DECLARE(dma_heap_carveout, "dma-heap-carveout", rmem_dma_heap_carveout_setup);
+
+#endif
diff -Naur --no-dereference a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig
--- a/drivers/dma-buf/heaps/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/dma-buf/heaps/Kconfig	2025-10-23 09:30:40.284462176 -0400
@@ -12,3 +12,13 @@
 	  Choose this option to enable dma-buf CMA heap. This heap is backed
 	  by the Contiguous Memory Allocator (CMA). If your system has these
 	  regions, you should say Y here.
+
+config DMABUF_HEAPS_CARVEOUT
+	bool "DMA-BUF Carveout Heap"
+	depends on DMABUF_HEAPS && HAS_IOMEM
+	depends on OF_RESERVED_MEM
+	select GENERIC_ALLOCATOR
+	help
+	  Choose this option to enable dma-buf Carveout heap. This heap is
+	  backed by the a carved-out of memory. If your system has these
+	  regions, you should say Y here.
diff -Naur --no-dereference a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile
--- a/drivers/dma-buf/heaps/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/dma-buf/heaps/Makefile	2025-10-23 09:30:40.284462176 -0400
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_DMABUF_HEAPS_SYSTEM)	+= system_heap.o
 obj-$(CONFIG_DMABUF_HEAPS_CMA)		+= cma_heap.o
+obj-$(CONFIG_DMABUF_HEAPS_CARVEOUT)	+= carveout-heap.o
diff -Naur --no-dereference a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
--- a/drivers/firmware/ti_sci.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/firmware/ti_sci.c	2025-10-23 09:30:40.284462176 -0400
@@ -2,13 +2,14 @@
 /*
  * Texas Instruments System Control Interface Protocol Driver
  *
- * Copyright (C) 2015-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2015-2025 Texas Instruments Incorporated - https://www.ti.com/
  *	Nishanth Menon
  */
 
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 #include <linux/bitmap.h>
+#include <linux/cpu.h>
 #include <linux/debugfs.h>
 #include <linux/export.h>
 #include <linux/io.h>
@@ -19,11 +20,14 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm_qos.h>
 #include <linux/property.h>
 #include <linux/semaphore.h>
 #include <linux/slab.h>
 #include <linux/soc/ti/ti-msgmgr.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
+#include <linux/suspend.h>
+#include <linux/sys_soc.h>
 #include <linux/reboot.h>
 
 #include "ti_sci.h"
@@ -98,6 +102,7 @@
  * @minfo:	Message info
  * @node:	list head
  * @host_id:	Host ID
+ * @fw_caps:	FW/SoC low power capabilities
  * @users:	Number of users of this instance
  */
 struct ti_sci_info {
@@ -114,6 +119,7 @@
 	struct ti_sci_xfers_info minfo;
 	struct list_head node;
 	u8 host_id;
+	u64 fw_caps;
 	/* protected by ti_sci_list_mutex */
 	int users;
 };
@@ -392,10 +398,13 @@
 static inline int ti_sci_do_xfer(struct ti_sci_info *info,
 				 struct ti_sci_xfer *xfer)
 {
+	struct ti_sci_msg_hdr *hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
 	int ret;
 	int timeout;
 	struct device *dev = info->dev;
 	bool done_state = true;
+	bool response_expected = !!(hdr->flags & (TI_SCI_FLAG_REQ_ACK_ON_PROCESSED |
+						  TI_SCI_FLAG_REQ_ACK_ON_RECEIVED));
 
 	ret = mbox_send_message(info->chan_tx, &xfer->tx_message);
 	if (ret < 0)
@@ -403,6 +412,9 @@
 
 	ret = 0;
 
+	if (!response_expected)
+		goto no_response;
+
 	if (system_state <= SYSTEM_RUNNING) {
 		/* And we wait for the response. */
 		timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
@@ -423,6 +435,7 @@
 		dev_err(dev, "Mbox timedout in resp(caller: %pS)\n",
 			(void *)_RET_IP_);
 
+no_response:
 	/*
 	 * NOTE: we might prefer not to need the mailbox ticker to manage the
 	 * transfer queueing since the protocol layer queues things by itself.
@@ -1651,6 +1664,416 @@
 	return ret;
 }
 
+/**
+ * ti_sci_cmd_prepare_sleep() - Prepare system for system suspend
+ * @handle:		pointer to TI SCI handle
+ * @mode:		Device identifier
+ * @ctx_lo:		Low part of address for context save
+ * @ctx_hi:		High part of address for context save
+ * @debug_flags:	Debug flags to pass to firmware
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_prepare_sleep(const struct ti_sci_handle *handle, u8 mode,
+				    u32 ctx_lo, u32 ctx_hi, u32 debug_flags)
+{
+	struct ti_sci_info *info;
+	struct ti_sci_msg_req_prepare_sleep *req;
+	struct ti_sci_msg_hdr *resp;
+	struct ti_sci_xfer *xfer;
+	struct device *dev;
+	int ret = 0;
+
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	if (!handle)
+		return -EINVAL;
+
+	info = handle_to_ti_sci_info(handle);
+	dev = info->dev;
+
+	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PREPARE_SLEEP,
+				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+				   sizeof(*req), sizeof(*resp));
+	if (IS_ERR(xfer)) {
+		ret = PTR_ERR(xfer);
+		dev_err(dev, "Message alloc failed(%d)\n", ret);
+		return ret;
+	}
+
+	req = (struct ti_sci_msg_req_prepare_sleep *)xfer->xfer_buf;
+	req->mode = mode;
+	req->ctx_lo = ctx_lo;
+	req->ctx_hi = ctx_hi;
+	req->debug_flags = debug_flags;
+
+	ret = ti_sci_do_xfer(info, xfer);
+	if (ret) {
+		dev_err(dev, "Mbox send fail %d\n", ret);
+		goto fail;
+	}
+
+	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+	if (!ti_sci_is_response_ack(resp)) {
+		dev_err(dev, "Failed to prepare sleep\n");
+		ret = -ENODEV;
+	}
+
+fail:
+	ti_sci_put_one_xfer(&info->minfo, xfer);
+
+	return ret;
+}
+
+/**
+ * ti_sci_msg_cmd_query_fw_caps() - Get the FW/SoC capabilities
+ * @handle:		Pointer to TI SCI handle
+ * @fw_caps:		Each bit in fw_caps indicating one FW/SOC capability
+ *
+ * Check if the firmware supports any optional low power modes.
+ * Old revisions of TIFS (< 08.04) will NACK the request which results in
+ * -ENODEV being returned.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_msg_cmd_query_fw_caps(const struct ti_sci_handle *handle,
+					u64 *fw_caps)
+{
+	struct ti_sci_info *info;
+	struct ti_sci_xfer *xfer;
+	struct ti_sci_msg_resp_query_fw_caps *resp;
+	struct device *dev;
+	int ret = 0;
+
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	if (!handle)
+		return -EINVAL;
+
+	info = handle_to_ti_sci_info(handle);
+	dev = info->dev;
+
+	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_QUERY_FW_CAPS,
+				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+				   sizeof(struct ti_sci_msg_hdr),
+				   sizeof(*resp));
+	if (IS_ERR(xfer)) {
+		ret = PTR_ERR(xfer);
+		dev_err(dev, "Message alloc failed(%d)\n", ret);
+		return ret;
+	}
+
+	ret = ti_sci_do_xfer(info, xfer);
+	if (ret) {
+		dev_err(dev, "Mbox send fail %d\n", ret);
+		goto fail;
+	}
+
+	resp = (struct ti_sci_msg_resp_query_fw_caps *)xfer->xfer_buf;
+
+	if (!ti_sci_is_response_ack(resp)) {
+		dev_err(dev, "Failed to get capabilities\n");
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	if (fw_caps)
+		*fw_caps = resp->fw_caps;
+
+fail:
+	ti_sci_put_one_xfer(&info->minfo, xfer);
+
+	return ret;
+}
+
+/**
+ * ti_sci_cmd_set_io_isolation() - Enable IO isolation in LPM
+ * @handle:		Pointer to TI SCI handle
+ * @state:		The desired state of the IO isolation
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_set_io_isolation(const struct ti_sci_handle *handle,
+				       u8 state)
+{
+	struct ti_sci_info *info;
+	struct ti_sci_msg_req_set_io_isolation *req;
+	struct ti_sci_msg_hdr *resp;
+	struct ti_sci_xfer *xfer;
+	struct device *dev;
+	int ret = 0;
+
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	if (!handle)
+		return -EINVAL;
+
+	info = handle_to_ti_sci_info(handle);
+	dev = info->dev;
+
+	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_IO_ISOLATION,
+				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+				   sizeof(*req), sizeof(*resp));
+	if (IS_ERR(xfer)) {
+		ret = PTR_ERR(xfer);
+		dev_err(dev, "Message alloc failed(%d)\n", ret);
+		return ret;
+	}
+	req = (struct ti_sci_msg_req_set_io_isolation *)xfer->xfer_buf;
+	req->state = state;
+
+	ret = ti_sci_do_xfer(info, xfer);
+	if (ret) {
+		dev_err(dev, "Mbox send fail %d\n", ret);
+		goto fail;
+	}
+
+	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+	if (!ti_sci_is_response_ack(resp)) {
+		dev_err(dev, "Failed to set IO isolation\n");
+		ret = -ENODEV;
+	}
+
+fail:
+	ti_sci_put_one_xfer(&info->minfo, xfer);
+
+	return ret;
+}
+
+/**
+ * ti_sci_msg_cmd_lpm_wake_reason() - Get the wakeup source from LPM
+ * @handle:		Pointer to TI SCI handle
+ * @source:		The wakeup source that woke the SoC from LPM
+ * @timestamp:		Timestamp of the wakeup event
+ * @pin:		The pin that has triggered wake up
+ * @mode:		The last entered low power mode
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_msg_cmd_lpm_wake_reason(const struct ti_sci_handle *handle,
+					  u32 *source, u64 *timestamp, u8 *pin, u8 *mode)
+{
+	struct ti_sci_info *info;
+	struct ti_sci_xfer *xfer;
+	struct ti_sci_msg_resp_lpm_wake_reason *resp;
+	struct device *dev;
+	int ret = 0;
+
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	if (!handle)
+		return -EINVAL;
+
+	info = handle_to_ti_sci_info(handle);
+	dev = info->dev;
+
+	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_WAKE_REASON,
+				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+				   sizeof(struct ti_sci_msg_hdr),
+				   sizeof(*resp));
+	if (IS_ERR(xfer)) {
+		ret = PTR_ERR(xfer);
+		dev_err(dev, "Message alloc failed(%d)\n", ret);
+		return ret;
+	}
+
+	ret = ti_sci_do_xfer(info, xfer);
+	if (ret) {
+		dev_err(dev, "Mbox send fail %d\n", ret);
+		goto fail;
+	}
+
+	resp = (struct ti_sci_msg_resp_lpm_wake_reason *)xfer->xfer_buf;
+
+	if (!ti_sci_is_response_ack(resp)) {
+		dev_err(dev, "Failed to get wake reason\n");
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	if (source)
+		*source = resp->wake_source;
+	if (timestamp)
+		*timestamp = resp->wake_timestamp;
+	if (pin)
+		*pin = resp->wake_pin;
+	if (mode)
+		*mode = resp->mode;
+
+fail:
+	ti_sci_put_one_xfer(&info->minfo, xfer);
+
+	return ret;
+}
+
+/**
+ * ti_sci_cmd_set_device_constraint() - Set LPM constraint on behalf of a device
+ * @handle:	pointer to TI SCI handle
+ * @id:	Device identifier
+ * @state:	The desired state of device constraint: set or clear
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_set_device_constraint(const struct ti_sci_handle *handle,
+					    u32 id, u8 state)
+{
+	struct ti_sci_info *info;
+	struct ti_sci_msg_req_lpm_set_device_constraint *req;
+	struct ti_sci_msg_hdr *resp;
+	struct ti_sci_xfer *xfer;
+	struct device *dev;
+	int ret = 0;
+
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	if (!handle)
+		return -EINVAL;
+
+	info = handle_to_ti_sci_info(handle);
+	dev = info->dev;
+
+	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_SET_DEVICE_CONSTRAINT,
+				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+				   sizeof(*req), sizeof(*resp));
+	if (IS_ERR(xfer)) {
+		ret = PTR_ERR(xfer);
+		dev_err(dev, "Message alloc failed(%d)\n", ret);
+		return ret;
+	}
+	req = (struct ti_sci_msg_req_lpm_set_device_constraint *)xfer->xfer_buf;
+	req->id = id;
+	req->state = state;
+
+	ret = ti_sci_do_xfer(info, xfer);
+	if (ret) {
+		dev_err(dev, "Mbox send fail %d\n", ret);
+		goto fail;
+	}
+
+	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+	if (!ti_sci_is_response_ack(resp)) {
+		dev_err(dev, "Failed to set device constraint\n");
+		ret = -ENODEV;
+	}
+
+fail:
+	ti_sci_put_one_xfer(&info->minfo, xfer);
+
+	return ret;
+}
+
+/**
+ * ti_sci_cmd_set_latency_constraint() - Set LPM resume latency constraint
+ * @handle:	pointer to TI SCI handle
+ * @latency:	maximum acceptable latency (in ms) to wake up from LPM
+ * @state:	The desired state of latency constraint: set or clear
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_set_latency_constraint(const struct ti_sci_handle *handle,
+					     u16 latency, u8 state)
+{
+	struct ti_sci_info *info;
+	struct ti_sci_msg_req_lpm_set_latency_constraint *req;
+	struct ti_sci_msg_hdr *resp;
+	struct ti_sci_xfer *xfer;
+	struct device *dev;
+	int ret = 0;
+
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	if (!handle)
+		return -EINVAL;
+
+	info = handle_to_ti_sci_info(handle);
+	dev = info->dev;
+
+	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_SET_LATENCY_CONSTRAINT,
+				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+				   sizeof(*req), sizeof(*resp));
+	if (IS_ERR(xfer)) {
+		ret = PTR_ERR(xfer);
+		dev_err(dev, "Message alloc failed(%d)\n", ret);
+		return ret;
+	}
+	req = (struct ti_sci_msg_req_lpm_set_latency_constraint *)xfer->xfer_buf;
+	req->latency = latency;
+	req->state = state;
+
+	ret = ti_sci_do_xfer(info, xfer);
+	if (ret) {
+		dev_err(dev, "Mbox send fail %d\n", ret);
+		goto fail;
+	}
+
+	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+	if (!ti_sci_is_response_ack(resp)) {
+		dev_err(dev, "Failed to set device constraint\n");
+		ret = -ENODEV;
+	}
+
+fail:
+	ti_sci_put_one_xfer(&info->minfo, xfer);
+
+	return ret;
+}
+
+/**
+ * ti_sci_cmd_lpm_abort() - Abort entry to LPM
+ * @handle:     pointer to TI SCI handle
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_lpm_abort(const struct ti_sci_handle *handle)
+{
+	struct ti_sci_info *info;
+	struct ti_sci_msg_hdr *req;
+	struct ti_sci_msg_hdr *resp;
+	struct ti_sci_xfer *xfer;
+	struct device *dev;
+	int ret = 0;
+
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	if (!handle)
+		return -EINVAL;
+
+	info = handle_to_ti_sci_info(handle);
+	dev = info->dev;
+
+	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_ABORT,
+				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+				   sizeof(*req), sizeof(*resp));
+	if (IS_ERR(xfer)) {
+		ret = PTR_ERR(xfer);
+		dev_err(dev, "Message alloc failed(%d)\n", ret);
+		return ret;
+	}
+	req = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+	ret = ti_sci_do_xfer(info, xfer);
+	if (ret) {
+		dev_err(dev, "Mbox send fail %d\n", ret);
+		goto fail;
+	}
+
+	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+	if (!ti_sci_is_response_ack(resp))
+		ret = -ENODEV;
+	else
+		ret = 0;
+
+fail:
+	ti_sci_put_one_xfer(&info->minfo, xfer);
+
+	return ret;
+}
+
 static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
 {
 	struct ti_sci_info *info;
@@ -2793,6 +3216,7 @@
 	struct ti_sci_core_ops *core_ops = &ops->core_ops;
 	struct ti_sci_dev_ops *dops = &ops->dev_ops;
 	struct ti_sci_clk_ops *cops = &ops->clk_ops;
+	struct ti_sci_pm_ops *pmops = &ops->pm_ops;
 	struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
 	struct ti_sci_rm_irq_ops *iops = &ops->rm_irq_ops;
 	struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops;
@@ -2832,6 +3256,14 @@
 	cops->set_freq = ti_sci_cmd_clk_set_freq;
 	cops->get_freq = ti_sci_cmd_clk_get_freq;
 
+	if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
+		pr_debug("detected DM managed LPM in fw_caps\n");
+		pmops->lpm_wake_reason = ti_sci_msg_cmd_lpm_wake_reason;
+		pmops->set_device_constraint = ti_sci_cmd_set_device_constraint;
+		pmops->set_latency_constraint = ti_sci_cmd_set_latency_constraint;
+		pmops->lpm_abort = ti_sci_cmd_lpm_abort;
+	}
+
 	rm_core_ops->get_range = ti_sci_cmd_get_resource_range;
 	rm_core_ops->get_range_from_shost =
 				ti_sci_cmd_get_resource_range_from_shost;
@@ -3262,6 +3694,226 @@
 	return NOTIFY_BAD;
 }
 
+static int ti_sci_prepare_system_suspend(struct ti_sci_info *info)
+{
+	/*
+	 * Map and validate the target Linux suspend state to TISCI LPM.
+	 * Default is to let Device Manager select the low power mode.
+	 */
+	switch (pm_suspend_target_state) {
+	case PM_SUSPEND_MEM:
+		if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
+			/*
+			 * For the DM_MANAGED mode the context is reserved for
+			 * internal use and can be 0
+			 */
+			return ti_sci_cmd_prepare_sleep(&info->handle,
+							TISCI_MSG_VALUE_SLEEP_MODE_DM_MANAGED,
+							0, 0, 0);
+		} else {
+			/* DM Managed is not supported by the firmware. */
+			dev_err(info->dev, "Suspend to memory is not supported by the firmware\n");
+			return -EOPNOTSUPP;
+		}
+		break;
+	default:
+		/*
+		 * Do not fail if we don't have action to take for a
+		 * specific suspend mode.
+		 */
+		return 0;
+	}
+}
+
+static int __maybe_unused ti_sci_suspend(struct device *dev)
+{
+	struct ti_sci_info *info = dev_get_drvdata(dev);
+	struct device *cpu_dev, *cpu_dev_max = NULL;
+	s32 val, cpu_lat = 0;
+	u16 cpu_lat_ms;
+	int i, ret;
+
+	if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
+		for_each_possible_cpu(i) {
+			cpu_dev = get_cpu_device(i);
+			val = dev_pm_qos_read_value(cpu_dev, DEV_PM_QOS_RESUME_LATENCY);
+			if (val != PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) {
+				cpu_lat = max(cpu_lat, val);
+				cpu_dev_max = cpu_dev;
+			}
+		}
+		if (cpu_dev_max) {
+			/* PM QoS latency unit is usecs, TI SCI uses msecs */
+			cpu_lat_ms = cpu_lat / USEC_PER_MSEC;
+			dev_dbg(cpu_dev_max, "%s: sending max CPU latency=%u ms\n", __func__,
+				cpu_lat_ms);
+			ret = ti_sci_cmd_set_latency_constraint(&info->handle,
+								cpu_lat_ms,
+								TISCI_MSG_CONSTRAINT_SET);
+			if (ret)
+				return ret;
+		}
+	}
+
+	ret = ti_sci_prepare_system_suspend(info);
+	if (ret) {
+		dev_err(dev, "%s: Failed to prepare sleep. Abort entering low power mode.\n",
+				__func__);
+		if (ti_sci_cmd_lpm_abort(&info->handle))
+			dev_err(dev, "%s: Failed to abort.\n", __func__);
+		return ret;
+	}
+	return 0;
+}
+
+static int __maybe_unused ti_sci_suspend_noirq(struct device *dev)
+{
+	struct ti_sci_info *info = dev_get_drvdata(dev);
+	int ret = 0;
+
+	ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_ENABLE);
+	if (ret) {
+		dev_err(dev, "%s: Failed to suspend. Abort entering low power mode.\n", __func__);
+		if (ti_sci_cmd_lpm_abort(&info->handle))
+			dev_err(dev, "%s: Failed to abort.\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+extern int davinci_gpio_resume_all_devices(void);
+
+static int __maybe_unused ti_sci_resume_noirq(struct device *dev)
+{
+	struct ti_sci_info *info = dev_get_drvdata(dev);
+	int ret = 0;
+	int err;
+	u32 source;
+	u64 time;
+	u8 pin;
+	u8 mode;
+
+	/* Resume GPIO before disabling isolation to maintain GPIO state */
+	err = davinci_gpio_resume_all_devices();
+	if (err)
+		return err;
+
+	ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_DISABLE);
+	if (ret)
+		return ret;
+
+	ret = ti_sci_msg_cmd_lpm_wake_reason(&info->handle, &source, &time, &pin, &mode);
+	/* Do not fail to resume on error as the wake reason is not critical */
+	if (!ret)
+		dev_info(dev, "ti_sci: wakeup source:0x%x, pin:0x%x, mode:0x%x\n",
+			 source, pin, mode);
+
+	return 0;
+}
+
+static const struct dev_pm_ops ti_sci_pm_ops = {
+#ifdef CONFIG_PM_SLEEP
+	.suspend = ti_sci_suspend,
+	.suspend_noirq = ti_sci_suspend_noirq,
+	.resume_noirq = ti_sci_resume_noirq,
+#endif
+};
+
+/*
+ * Enter Partial-IO, which disables everything including DDR with only a small
+ * logic being active for wakeup.
+ */
+static int tisci_enter_partial_io(struct ti_sci_info *info)
+{
+	struct ti_sci_msg_req_prepare_sleep *req;
+	struct ti_sci_xfer *xfer;
+	struct device *dev = info->dev;
+	int ret = 0;
+
+	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PREPARE_SLEEP,
+				   TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
+				   sizeof(*req), sizeof(struct ti_sci_msg_hdr));
+	if (IS_ERR(xfer)) {
+		ret = PTR_ERR(xfer);
+		dev_err(dev, "Message alloc failed(%d)\n", ret);
+		return ret;
+	}
+
+	req = (struct ti_sci_msg_req_prepare_sleep *)xfer->xfer_buf;
+	req->mode = TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO;
+	req->ctx_lo = 0;
+	req->ctx_hi = 0;
+	req->debug_flags = 0;
+
+	dev_info(dev, "Entering Partial-IO because a powered wakeup-enabled device was found.\n");
+
+	ret = ti_sci_do_xfer(info, xfer);
+	if (ret) {
+		dev_err(dev, "Mbox send fail %d\n", ret);
+		goto fail;
+	}
+
+fail:
+	ti_sci_put_one_xfer(&info->minfo, xfer);
+
+	return ret;
+}
+
+static bool tisci_canuart_wakeup_enabled(struct ti_sci_info *info)
+{
+	struct device_node *wakeup_node = NULL;
+
+	for (wakeup_node = of_find_node_with_property(NULL, "wakeup-source");
+	     wakeup_node;
+	     wakeup_node = of_find_node_with_property(wakeup_node, "wakeup-source")) {
+		struct platform_device *pdev;
+		int index;
+
+		index = of_property_match_string(wakeup_node, "wakeup-source", "poweroff");
+		if (index < 0)
+			continue;
+
+		pdev = of_find_device_by_node(wakeup_node);
+		if (!pdev)
+			break;
+
+		if (device_may_wakeup(&pdev->dev)) {
+			dev_dbg(info->dev, "%pOF identified as wakeup source for Partial-IO\n",
+				wakeup_node);
+			put_device(&pdev->dev);
+			of_node_put(wakeup_node);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static int tisci_sys_off_handler(struct sys_off_data *data)
+{
+	struct ti_sci_info *info = data->cb_data;
+	bool enter_partial_io = tisci_canuart_wakeup_enabled(info);
+	int ret;
+
+	if (!enter_partial_io)
+		return NOTIFY_DONE;
+
+	ret = tisci_enter_partial_io(info);
+
+	if (ret) {
+		dev_err(info->dev,
+			"Failed to enter Partial-IO %pe, trying to do an emergency restart\n",
+			ERR_PTR(ret));
+		emergency_restart();
+	}
+
+	mdelay(5000);
+	emergency_restart();
+
+	return NOTIFY_DONE;
+}
+
 /* Description for K2G */
 static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
 	.default_host_id = 2,
@@ -3390,6 +4042,13 @@
 		goto out;
 	}
 
+	ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps);
+	dev_dbg(dev, "Detected firmware capabilities: %s%s%s\n",
+		info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "",
+		info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "",
+		info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : ""
+	);
+
 	ti_sci_setup_ops(info);
 
 	ret = devm_register_restart_handler(dev, tisci_reboot_handler, info);
@@ -3398,6 +4057,19 @@
 		goto out;
 	}
 
+	if (info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO) {
+		ret = devm_register_sys_off_handler(dev,
+						    SYS_OFF_MODE_POWER_OFF,
+						    SYS_OFF_PRIO_FIRMWARE,
+						    tisci_sys_off_handler,
+						    info);
+		if (ret) {
+			dev_err(dev, "Failed to register sys_off_handler %pe\n",
+				ERR_PTR(ret));
+			goto out;
+		}
+	}
+
 	dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n",
 		 info->handle.version.abi_major, info->handle.version.abi_minor,
 		 info->handle.version.firmware_revision,
@@ -3407,7 +4079,13 @@
 	list_add_tail(&info->node, &ti_sci_list);
 	mutex_unlock(&ti_sci_list_mutex);
 
-	return of_platform_populate(dev->of_node, NULL, NULL, dev);
+	ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
+	if (ret) {
+		dev_err(dev, "platform_populate failed %pe\n", ERR_PTR(ret));
+		goto out;
+	}
+	return 0;
+
 out:
 	if (!IS_ERR(info->chan_tx))
 		mbox_free_channel(info->chan_tx);
@@ -3423,6 +4101,7 @@
 		   .name = "ti-sci",
 		   .of_match_table = of_match_ptr(ti_sci_of_match),
 		   .suppress_bind_attrs = true,
+		   .pm = &ti_sci_pm_ops,
 	},
 };
 module_platform_driver(ti_sci_driver);
diff -Naur --no-dereference a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
--- a/drivers/firmware/ti_sci.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/firmware/ti_sci.h	2025-10-23 09:30:40.284462176 -0400
@@ -6,7 +6,7 @@
  * The system works in a message response protocol
  * See: https://software-dl.ti.com/tisci/esd/latest/index.html for details
  *
- * Copyright (C)  2015-2016 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C)  2015-2025 Texas Instruments Incorporated - https://www.ti.com/
  */
 
 #ifndef __TI_SCI_H
@@ -19,6 +19,7 @@
 #define TI_SCI_MSG_WAKE_REASON	0x0003
 #define TI_SCI_MSG_GOODBYE	0x0004
 #define TI_SCI_MSG_SYS_RESET	0x0005
+#define TI_SCI_MSG_QUERY_FW_CAPS	0x0022
 
 /* Device requests */
 #define TI_SCI_MSG_SET_DEVICE_STATE	0x0200
@@ -35,6 +36,14 @@
 #define TI_SCI_MSG_QUERY_CLOCK_FREQ	0x010d
 #define TI_SCI_MSG_GET_CLOCK_FREQ	0x010e
 
+/* Low Power Mode Requests */
+#define TI_SCI_MSG_PREPARE_SLEEP	0x0300
+#define TI_SCI_MSG_LPM_WAKE_REASON	0x0306
+#define TI_SCI_MSG_SET_IO_ISOLATION	0x0307
+#define TI_SCI_MSG_LPM_SET_DEVICE_CONSTRAINT	0x0309
+#define TI_SCI_MSG_LPM_SET_LATENCY_CONSTRAINT	0x030A
+#define TI_SCI_MSG_LPM_ABORT	0x0311
+
 /* Resource Management Requests */
 #define TI_SCI_MSG_GET_RESOURCE_RANGE	0x1500
 
@@ -133,6 +142,27 @@
 } __packed;
 
 /**
+ * struct ti_sci_msg_resp_query_fw_caps - Response for query firmware caps
+ * @hdr:	Generic header
+ * @fw_caps:	Each bit in fw_caps indicating one FW/SOC capability
+ *		MSG_FLAG_CAPS_GENERIC: Generic capability (LPM not supported)
+ *		MSG_FLAG_CAPS_LPM_PARTIAL_IO: Partial IO in LPM
+ *		MSG_FLAG_CAPS_LPM_DM_MANAGED: LPM can be managed by DM
+ *
+ * Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS
+ * providing currently available SOC/firmware capabilities. SoC that don't
+ * support low power modes return only MSG_FLAG_CAPS_GENERIC capability.
+ */
+struct ti_sci_msg_resp_query_fw_caps {
+	struct ti_sci_msg_hdr hdr;
+#define MSG_FLAG_CAPS_GENERIC		TI_SCI_MSG_FLAG(0)
+#define MSG_FLAG_CAPS_LPM_PARTIAL_IO	TI_SCI_MSG_FLAG(4)
+#define MSG_FLAG_CAPS_LPM_DM_MANAGED	TI_SCI_MSG_FLAG(5)
+#define MSG_MASK_CAPS_LPM		GENMASK_ULL(4, 1)
+	u64 fw_caps;
+} __packed;
+
+/**
  * struct ti_sci_msg_req_set_device_state - Set the desired state of the device
  * @hdr:		Generic header
  * @id:	Indicates which device to modify
@@ -545,6 +575,123 @@
 	u64 freq_hz;
 } __packed;
 
+/**
+ * struct tisci_msg_req_prepare_sleep - Request for TISCI_MSG_PREPARE_SLEEP.
+ *
+ * @hdr				TISCI header to provide ACK/NAK flags to the host.
+ * @mode			Low power mode to enter.
+ * @ctx_lo			Low 32-bits of physical pointer to address to use for context save.
+ * @ctx_hi			High 32-bits of physical pointer to address to use for context save.
+ * @debug_flags			Flags that can be set to halt the sequence during suspend or
+ *				resume to allow JTAG connection and debug.
+ *
+ * This message is used as the first step of entering a low power mode. It
+ * allows configurable information, including which state to enter to be
+ * easily shared from the application, as this is a non-secure message and
+ * therefore can be sent by anyone.
+ */
+struct ti_sci_msg_req_prepare_sleep {
+	struct ti_sci_msg_hdr	hdr;
+
+/*
+ * When sending perpare_sleep with MODE_PARTIAL_IO no response will be sent,
+ * no further steps are required.
+ */
+#define TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO				0x03
+#define TISCI_MSG_VALUE_SLEEP_MODE_DM_MANAGED				0xfd
+	u8			mode;
+	u32			ctx_lo;
+	u32			ctx_hi;
+	u32			debug_flags;
+} __packed;
+
+/**
+ * struct tisci_msg_set_io_isolation_req - Request for TI_SCI_MSG_SET_IO_ISOLATION.
+ *
+ * @hdr:	Generic header
+ * @state:	The deseared state of the IO isolation.
+ *
+ * This message is used to enable/disable IO isolation for low power modes.
+ * Response is generic ACK / NACK message.
+ */
+struct ti_sci_msg_req_set_io_isolation {
+	struct ti_sci_msg_hdr hdr;
+	u8 state;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_lpm_wake_reason - Response for TI_SCI_MSG_LPM_WAKE_REASON.
+ *
+ * @hdr:		Generic header.
+ * @wake_source:	The wake up source that woke soc from LPM.
+ * @wake_timestamp:	Timestamp at which soc woke.
+ * @wake_pin: The pin that has triggered wake up.
+ * @mode: The last entered low power mode.
+ * @rsvd:	Reserved for future use.
+ *
+ * Response to a generic message with message type TI_SCI_MSG_LPM_WAKE_REASON,
+ * used to query the wake up source, pin and entered low power mode.
+ */
+struct ti_sci_msg_resp_lpm_wake_reason {
+	struct ti_sci_msg_hdr hdr;
+	u32 wake_source;
+	u64 wake_timestamp;
+	u8 wake_pin;
+	u8 mode;
+	u32 rsvd[2];
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_lpm_set_device_constraint - Request for
+ * TISCI_MSG_LPM_SET_DEVICE_CONSTRAINT.
+ *
+ * @hdr:	TISCI header to provide ACK/NAK flags to the host.
+ * @id:	Device ID of device whose constraint has to be modified.
+ * @state:	The desired state of device constraint: set or clear.
+ * @rsvd:	Reserved for future use.
+ *
+ * This message is used by host to set constraint on the device. This can be
+ * sent anytime after boot before prepare sleep message. Any device can set a
+ * constraint on the low power mode that the SoC can enter. It allows
+ * configurable information to be easily shared from the application, as this
+ * is a non-secure message and therefore can be sent by anyone. By setting a
+ * constraint, the device ensures that it will not be powered off or reset in
+ * the selected mode. Note: Access Restriction: Exclusivity flag of Device will
+ * be honored. If some other host already has constraint on this device ID,
+ * NACK will be returned.
+ */
+struct ti_sci_msg_req_lpm_set_device_constraint {
+	struct ti_sci_msg_hdr hdr;
+	u32 id;
+	u8 state;
+	u32 rsvd[2];
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_lpm_set_latency_constraint - Request for
+ * TISCI_MSG_LPM_SET_LATENCY_CONSTRAINT.
+ *
+ * @hdr:	TISCI header to provide ACK/NAK flags to the host.
+ * @wkup_latency:	The maximum acceptable latency to wake up from low power mode
+ *			in milliseconds. The deeper the state, the higher the latency.
+ * @state:	The desired state of wakeup latency constraint: set or clear.
+ * @rsvd:	Reserved for future use.
+ *
+ * This message is used by host to set wakeup latency from low power mode. This can
+ * be sent anytime after boot before prepare sleep message, and can be sent after
+ * current low power mode is exited. Any device can set a constraint on the low power
+ * mode that the SoC can enter. It allows configurable information to be easily shared
+ * from the application, as this is a non-secure message and therefore can be sent by
+ * anyone. By setting a wakeup latency constraint, the host ensures that the resume time
+ * from selected low power mode will be less than the constraint value.
+ */
+struct ti_sci_msg_req_lpm_set_latency_constraint {
+	struct ti_sci_msg_hdr hdr;
+	u16 latency;
+	u8 state;
+	u32 rsvd;
+} __packed;
+
 #define TI_SCI_IRQ_SECONDARY_HOST_INVALID	0xff
 
 /**
diff -Naur --no-dereference a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c
--- a/drivers/gpio/gpio-davinci.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpio/gpio-davinci.c	2025-10-23 09:30:40.284462176 -0400
@@ -62,6 +62,7 @@
 	int			irqs[MAX_INT_PER_BANK];
 	struct davinci_gpio_regs context[MAX_REGS_BANKS];
 	u32			binten_context;
+	bool		needs_context_restore;
 };
 
 static inline u32 __gpio_mask(unsigned gpio)
@@ -79,6 +80,7 @@
 }
 
 static int davinci_gpio_irq_setup(struct platform_device *pdev);
+int davinci_gpio_resume_all_devices(void);
 
 /*--------------------------------------------------------------------------*/
 
@@ -221,6 +223,7 @@
 	chips->chip.request = gpiochip_generic_request;
 	chips->chip.free = gpiochip_generic_free;
 #endif
+	chips->needs_context_restore = false;
 	spin_lock_init(&chips->lock);
 
 	chips->gpio_unbanked = gpio_unbanked;
@@ -632,6 +635,7 @@
 	u32 nbank = DIV_ROUND_UP(chips->chip.ngpio, 32);
 
 	davinci_gpio_save_context(chips, nbank);
+	chips->needs_context_restore = true;
 
 	return 0;
 }
@@ -641,7 +645,10 @@
 	struct davinci_gpio_controller *chips = dev_get_drvdata(dev);
 	u32 nbank = DIV_ROUND_UP(chips->chip.ngpio, 32);
 
-	davinci_gpio_restore_context(chips, nbank);
+	if (chips->needs_context_restore) {
+		davinci_gpio_restore_context(chips, nbank);
+		chips->needs_context_restore = false;
+	}
 
 	return 0;
 }
@@ -666,6 +673,18 @@
 	},
 };
 
+static int davinci_gpio_resume_wrapper(struct device *dev, void *unused)
+{
+	return davinci_gpio_resume(dev);
+}
+
+int davinci_gpio_resume_all_devices(void)
+{
+	return driver_for_each_device(&davinci_gpio_driver.driver, NULL,
+					NULL, davinci_gpio_resume_wrapper);
+}
+EXPORT_SYMBOL(davinci_gpio_resume_all_devices);
+
 /*
  * GPIO driver registration needs to be done before machine_init functions
  * access GPIO. Hence davinci_gpio_drv_reg() is a postcore_initcall.
diff -Naur --no-dereference a/drivers/gpio/gpio-tps65219.c b/drivers/gpio/gpio-tps65219.c
--- a/drivers/gpio/gpio-tps65219.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpio/gpio-tps65219.c	2025-10-23 09:30:40.284462176 -0400
@@ -15,8 +15,6 @@
 #define TPS65219_GPIO0_DIR_MASK		BIT(3)
 #define TPS65219_GPIO0_OFFSET		2
 #define TPS65219_GPIO0_IDX		0
-#define TPS65219_GPIO_DIR_IN		1
-#define TPS65219_GPIO_DIR_OUT		0
 
 struct tps65219_gpio {
 	struct gpio_chip gpio_chip;
@@ -61,7 +59,7 @@
 	 * status bit.
 	 */
 
-	if (tps65219_gpio_get_direction(gc, offset) == TPS65219_GPIO_DIR_OUT)
+	if (tps65219_gpio_get_direction(gc, offset) == GPIO_LINE_DIRECTION_OUT)
 		return -ENOTSUPP;
 
 	return ret;
@@ -124,10 +122,10 @@
 		return -ENOTSUPP;
 	}
 
-	if (tps65219_gpio_get_direction(gc, offset) == TPS65219_GPIO_DIR_IN)
+	if (tps65219_gpio_get_direction(gc, offset) == GPIO_LINE_DIRECTION_IN)
 		return 0;
 
-	return tps65219_gpio_change_direction(gc, offset, TPS65219_GPIO_DIR_IN);
+	return tps65219_gpio_change_direction(gc, offset, GPIO_LINE_DIRECTION_IN);
 }
 
 static int tps65219_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, int value)
@@ -136,10 +134,10 @@
 	if (offset != TPS65219_GPIO0_IDX)
 		return 0;
 
-	if (tps65219_gpio_get_direction(gc, offset) == TPS65219_GPIO_DIR_OUT)
+	if (tps65219_gpio_get_direction(gc, offset) == GPIO_LINE_DIRECTION_OUT)
 		return 0;
 
-	return tps65219_gpio_change_direction(gc, offset, TPS65219_GPIO_DIR_OUT);
+	return tps65219_gpio_change_direction(gc, offset, GPIO_LINE_DIRECTION_OUT);
 }
 
 static const struct gpio_chip tps65219_template_chip = {
diff -Naur --no-dereference a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c
--- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c	2025-10-23 09:30:40.284462176 -0400
@@ -9,6 +9,7 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_probe_helper.h>
 #include <video/mipi_display.h>
+#include <video/videomode.h>
 
 #include <linux/clk.h>
 #include <linux/interrupt.h>
@@ -417,7 +418,8 @@
 #define DSI_OUTPUT_PORT			0
 #define DSI_INPUT_PORT(inputid)		(1 + (inputid))
 
-#define DSI_HBP_FRAME_OVERHEAD		12
+#define DSI_HBP_FRAME_PULSE_OVERHEAD	12
+#define DSI_HBP_FRAME_EVENT_OVERHEAD	16
 #define DSI_HSA_FRAME_OVERHEAD		14
 #define DSI_HFP_FRAME_OVERHEAD		6
 #define DSI_HSS_VSS_VSE_FRAME_OVERHEAD	4
@@ -425,6 +427,17 @@
 #define DSI_NULL_FRAME_OVERHEAD		6
 #define DSI_EOT_PKT_SIZE		4
 
+struct cdns_dsi_bridge_state {
+	struct drm_bridge_state base;
+	struct cdns_dsi_cfg dsi_cfg;
+};
+
+static inline struct cdns_dsi_bridge_state *
+to_cdns_dsi_bridge_state(struct drm_bridge_state *bridge_state)
+{
+	return container_of(bridge_state, struct cdns_dsi_bridge_state, base);
+}
+
 static inline struct cdns_dsi *input_to_dsi(struct cdns_dsi_input *input)
 {
 	return container_of(input, struct cdns_dsi, input);
@@ -441,15 +454,6 @@
 	return container_of(bridge, struct cdns_dsi_input, bridge);
 }
 
-static unsigned int mode_to_dpi_hfp(const struct drm_display_mode *mode,
-				    bool mode_valid_check)
-{
-	if (mode_valid_check)
-		return mode->hsync_start - mode->hdisplay;
-
-	return mode->crtc_hsync_start - mode->crtc_hdisplay;
-}
-
 static unsigned int dpi_to_dsi_timing(unsigned int dpi_timing,
 				      unsigned int dpi_bpp,
 				      unsigned int dsi_pkt_overhead)
@@ -465,120 +469,70 @@
 }
 
 static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi,
-			     const struct drm_display_mode *mode,
-			     struct cdns_dsi_cfg *dsi_cfg,
-			     bool mode_valid_check)
+			     const struct videomode *vm,
+			     struct cdns_dsi_cfg *dsi_cfg)
 {
 	struct cdns_dsi_output *output = &dsi->output;
-	unsigned int tmp;
-	bool sync_pulse = false;
+	u32 dpi_hsa, dpi_hbp, dpi_hfp, dpi_hact;
+	bool sync_pulse;
 	int bpp;
 
+	dpi_hsa = vm->hsync_len;
+	dpi_hbp = vm->hback_porch;
+	dpi_hfp = vm->hfront_porch;
+	dpi_hact = vm->hactive;
+
 	memset(dsi_cfg, 0, sizeof(*dsi_cfg));
 
-	if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
-		sync_pulse = true;
+	sync_pulse = output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
 
 	bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format);
 
-	if (mode_valid_check)
-		tmp = mode->htotal -
-		      (sync_pulse ? mode->hsync_end : mode->hsync_start);
-	else
-		tmp = mode->crtc_htotal -
-		      (sync_pulse ?
-		       mode->crtc_hsync_end : mode->crtc_hsync_start);
-
-	dsi_cfg->hbp = dpi_to_dsi_timing(tmp, bpp, DSI_HBP_FRAME_OVERHEAD);
-
 	if (sync_pulse) {
-		if (mode_valid_check)
-			tmp = mode->hsync_end - mode->hsync_start;
-		else
-			tmp = mode->crtc_hsync_end - mode->crtc_hsync_start;
+		dsi_cfg->hbp = dpi_to_dsi_timing(dpi_hbp, bpp,
+						 DSI_HBP_FRAME_PULSE_OVERHEAD);
 
-		dsi_cfg->hsa = dpi_to_dsi_timing(tmp, bpp,
+		dsi_cfg->hsa = dpi_to_dsi_timing(dpi_hsa, bpp,
 						 DSI_HSA_FRAME_OVERHEAD);
-	}
-
-	dsi_cfg->hact = dpi_to_dsi_timing(mode_valid_check ?
-					  mode->hdisplay : mode->crtc_hdisplay,
-					  bpp, 0);
-	dsi_cfg->hfp = dpi_to_dsi_timing(mode_to_dpi_hfp(mode, mode_valid_check),
-					 bpp, DSI_HFP_FRAME_OVERHEAD);
+	} else {
+		dsi_cfg->hbp = dpi_to_dsi_timing(dpi_hbp + dpi_hsa, bpp,
+						 DSI_HBP_FRAME_EVENT_OVERHEAD);
 
-	return 0;
-}
+		dsi_cfg->hsa = 0;
+	}
 
-static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi,
-			      struct cdns_dsi_cfg *dsi_cfg,
-			      struct phy_configure_opts_mipi_dphy *phy_cfg,
-			      const struct drm_display_mode *mode,
-			      bool mode_valid_check)
-{
-	struct cdns_dsi_output *output = &dsi->output;
-	unsigned long long dlane_bps;
-	unsigned long adj_dsi_htotal;
-	unsigned long dsi_htotal;
-	unsigned long dpi_htotal;
-	unsigned long dpi_hz;
-	unsigned int dsi_hfp_ext;
-	unsigned int lanes = output->dev->lanes;
+	dsi_cfg->hact = dpi_to_dsi_timing(dpi_hact, bpp, 0);
 
-	dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD;
-	if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
-		dsi_htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD;
+	dsi_cfg->hfp = dpi_to_dsi_timing(dpi_hfp, bpp, DSI_HFP_FRAME_OVERHEAD);
 
-	dsi_htotal += dsi_cfg->hact;
-	dsi_htotal += dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD;
+	dsi_cfg->htotal = dsi_cfg->hact + dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD;
 
-	/*
-	 * Make sure DSI htotal is aligned on a lane boundary when calculating
-	 * the expected data rate. This is done by extending HFP in case of
-	 * misalignment.
-	 */
-	adj_dsi_htotal = dsi_htotal;
-	if (dsi_htotal % lanes)
-		adj_dsi_htotal += lanes - (dsi_htotal % lanes);
-
-	dpi_hz = (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000;
-	dlane_bps = (unsigned long long)dpi_hz * adj_dsi_htotal;
-
-	/* data rate in bytes/sec is not an integer, refuse the mode. */
-	dpi_htotal = mode_valid_check ? mode->htotal : mode->crtc_htotal;
-	if (do_div(dlane_bps, lanes * dpi_htotal))
-		return -EINVAL;
-
-	/* data rate was in bytes/sec, convert to bits/sec. */
-	phy_cfg->hs_clk_rate = dlane_bps * 8;
-
-	dsi_hfp_ext = adj_dsi_htotal - dsi_htotal;
-	dsi_cfg->hfp += dsi_hfp_ext;
-	dsi_cfg->htotal = dsi_htotal + dsi_hfp_ext;
+	if (sync_pulse) {
+		dsi_cfg->htotal += dsi_cfg->hbp + DSI_HBP_FRAME_PULSE_OVERHEAD;
+		dsi_cfg->htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD;
+	} else {
+		dsi_cfg->htotal += dsi_cfg->hbp + DSI_HBP_FRAME_EVENT_OVERHEAD;
+	}
 
 	return 0;
 }
 
 static int cdns_dsi_check_conf(struct cdns_dsi *dsi,
-			       const struct drm_display_mode *mode,
-			       struct cdns_dsi_cfg *dsi_cfg,
-			       bool mode_valid_check)
+			       const struct videomode *vm,
+			       struct cdns_dsi_cfg *dsi_cfg)
 {
 	struct cdns_dsi_output *output = &dsi->output;
 	struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy;
-	unsigned long dsi_hss_hsa_hse_hbp;
 	unsigned int nlanes = output->dev->lanes;
 	int ret;
 
-	ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg, mode_valid_check);
+	ret = cdns_dsi_mode2cfg(dsi, vm, dsi_cfg);
 	if (ret)
 		return ret;
 
-	phy_mipi_dphy_get_default_config(mode->crtc_clock * 1000,
-					 mipi_dsi_pixel_format_to_bpp(output->dev->format),
-					 nlanes, phy_cfg);
-
-	ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, mode, mode_valid_check);
+	ret = phy_mipi_dphy_get_default_config(vm->pixelclock,
+					       mipi_dsi_pixel_format_to_bpp(output->dev->format),
+					       nlanes, phy_cfg);
 	if (ret)
 		return ret;
 
@@ -586,21 +540,6 @@
 	if (ret)
 		return ret;
 
-	dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD;
-	if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
-		dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD;
-
-	/*
-	 * Make sure DPI(HFP) > DSI(HSS+HSA+HSE+HBP) to guarantee that the FIFO
-	 * is empty before we start a receiving a new line on the DPI
-	 * interface.
-	 */
-	if ((u64)phy_cfg->hs_clk_rate *
-	    mode_to_dpi_hfp(mode, mode_valid_check) * nlanes <
-	    (u64)dsi_hss_hsa_hse_hbp *
-	    (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000)
-		return -EINVAL;
-
 	return 0;
 }
 
@@ -629,8 +568,7 @@
 	struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
 	struct cdns_dsi *dsi = input_to_dsi(input);
 	struct cdns_dsi_output *output = &dsi->output;
-	struct cdns_dsi_cfg dsi_cfg;
-	int bpp, ret;
+	int bpp;
 
 	/*
 	 * VFP_DSI should be less than VFP_DPI and VFP_DSI should be at
@@ -648,19 +586,31 @@
 	if ((mode->hdisplay * bpp) % 32)
 		return MODE_H_ILLEGAL;
 
-	ret = cdns_dsi_check_conf(dsi, mode, &dsi_cfg, true);
-	if (ret)
-		return MODE_BAD;
-
 	return MODE_OK;
 }
 
-static void cdns_dsi_bridge_disable(struct drm_bridge *bridge)
+static void cdns_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge,
+						struct drm_bridge_state *old_bridge_state)
 {
 	struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
 	struct cdns_dsi *dsi = input_to_dsi(input);
 	u32 val;
 
+	/*
+	 * The cdns-dsi controller needs to be disabled after it's DPI source
+	 * has stopped streaming. If this is not followed, there is a brief
+	 * window before DPI source is disabled and after cdns-dsi controller
+	 * has been disabled where the DPI stream is still on, but the cdns-dsi
+	 * controller is not ready anymore to accept the incoming signals. This
+	 * is one of the reasons why a shift in pixel colors is observed on
+	 * displays that have cdns-dsi as one of the bridges.
+	 *
+	 * To mitigate this, disable this bridge from the bridge post_disable()
+	 * hook, instead of the bridge _disable() hook. The bridge post_disable()
+	 * hook gets called after the CRTC disable, where often many DPI sources
+	 * disable their streams.
+	 */
+
 	val = readl(dsi->regs + MCTL_MAIN_DATA_CTL);
 	val &= ~(IF_VID_SELECT_MASK | IF_VID_MODE | VID_EN | HOST_EOT_GEN |
 		 DISP_EOT_GEN);
@@ -672,13 +622,10 @@
 	if (dsi->platform_ops && dsi->platform_ops->disable)
 		dsi->platform_ops->disable(dsi);
 
-	pm_runtime_put(dsi->base.dev);
-}
-
-static void cdns_dsi_bridge_post_disable(struct drm_bridge *bridge)
-{
-	struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
-	struct cdns_dsi *dsi = input_to_dsi(input);
+	dsi->phy_initialized = false;
+	dsi->link_initialized = false;
+	phy_power_off(dsi->dphy);
+	phy_exit(dsi->dphy);
 
 	pm_runtime_put(dsi->base.dev);
 }
@@ -752,31 +699,68 @@
 	dsi->link_initialized = true;
 }
 
-static void cdns_dsi_bridge_enable(struct drm_bridge *bridge)
+static void cdns_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
+					      struct drm_bridge_state *old_bridge_state)
 {
 	struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
 	struct cdns_dsi *dsi = input_to_dsi(input);
 	struct cdns_dsi_output *output = &dsi->output;
+	struct drm_atomic_state *state = old_bridge_state->base.state;
+	struct cdns_dsi_bridge_state *dsi_state;
+	struct drm_bridge_state *new_bridge_state;
 	struct drm_display_mode *mode;
 	struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy;
 	unsigned long tx_byte_period;
 	struct cdns_dsi_cfg dsi_cfg;
-	u32 tmp, reg_wakeup, div;
+	u32 tmp, reg_wakeup, div, status;
 	int nlanes;
 
+	/*
+	 * The cdns-dsi controller needs to be enabled before it's DPI source
+	 * has begun streaming. If this is not followed, there is a brief window
+	 * after DPI source enable and before cdns-dsi controller enable where
+	 * the DPI stream is on, but the cdns-dsi controller is not ready to
+	 * accept the incoming signals. This is one of the reasons why a shift
+	 * in pixel colors is observed on displays that have cdns-dsi as one of
+	 * the bridges.
+	 *
+	 * To mitigate this, enable this bridge from the bridge pre_enable()
+	 * hook, instead of the bridge _enable() hook. The bridge pre_enable()
+	 * hook gets called before the CRTC enable, where often many DPI sources
+	 * enable their streams.
+	 */
+
 	if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0))
 		return;
 
+	new_bridge_state = drm_atomic_get_new_bridge_state(state, bridge);
+	if (WARN_ON(!new_bridge_state))
+		return;
+
+	dsi_state = to_cdns_dsi_bridge_state(new_bridge_state);
+	dsi_cfg = dsi_state->dsi_cfg;
+
 	if (dsi->platform_ops && dsi->platform_ops->enable)
 		dsi->platform_ops->enable(dsi);
 
 	mode = &bridge->encoder->crtc->state->adjusted_mode;
 	nlanes = output->dev->lanes;
 
-	WARN_ON_ONCE(cdns_dsi_check_conf(dsi, mode, &dsi_cfg, false));
-
-	cdns_dsi_hs_init(dsi);
 	cdns_dsi_init_link(dsi);
+	cdns_dsi_hs_init(dsi);
+
+	/*
+	 * Now that the DSI Link and DSI Phy are initialized,
+	 * wait for the CLK and Data Lanes to be ready.
+	 */
+	tmp = CLK_LANE_RDY;
+	for (int i = 0; i < nlanes; i++)
+		tmp |= DATA_LANE_RDY(i);
+
+	if (readl_poll_timeout(dsi->regs + MCTL_MAIN_STS, status,
+			       (tmp == (status & tmp)), 100, 500000))
+		dev_err(dsi->base.dev,
+			"Timed Out: DSI-DPhy Clock and Data Lanes not ready.\n");
 
 	writel(HBP_LEN(dsi_cfg.hbp) | HSA_LEN(dsi_cfg.hsa),
 	       dsi->regs + VID_HSIZE1);
@@ -812,7 +796,13 @@
 
 	tx_byte_period = DIV_ROUND_DOWN_ULL((u64)NSEC_PER_SEC * 8,
 					    phy_cfg->hs_clk_rate);
-	reg_wakeup = (phy_cfg->hs_prepare + phy_cfg->hs_zero) / tx_byte_period;
+
+	/*
+	 * Estimated time [in clock cycles] to perform LP->HS on D-PHY.
+	 * It is not clear how to calculate this, so for now,
+	 * set it to 1/10 of the total number of clocks in a line.
+	 */
+	reg_wakeup = dsi_cfg.htotal / nlanes / 10;
 	writel(REG_WAKEUP_TIME(reg_wakeup) | REG_LINE_DURATION(tmp),
 	       dsi->regs + VID_DPHY_TIME);
 
@@ -892,25 +882,151 @@
 	writel(tmp, dsi->regs + MCTL_MAIN_EN);
 }
 
-static void cdns_dsi_bridge_pre_enable(struct drm_bridge *bridge)
+static u32 *cdns_dsi_bridge_get_input_bus_fmts(struct drm_bridge *bridge,
+					       struct drm_bridge_state *bridge_state,
+					       struct drm_crtc_state *crtc_state,
+					       struct drm_connector_state *conn_state,
+					       u32 output_fmt,
+					       unsigned int *num_input_fmts)
 {
 	struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
 	struct cdns_dsi *dsi = input_to_dsi(input);
+	struct cdns_dsi_output *output = &dsi->output;
+	u32 *input_fmts;
 
-	if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0))
-		return;
+	*num_input_fmts = 0;
 
-	cdns_dsi_init_link(dsi);
-	cdns_dsi_hs_init(dsi);
+	input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL);
+	if (!input_fmts)
+		return NULL;
+
+	input_fmts[0] = drm_mipi_dsi_get_input_bus_fmt(output->dev->format);
+	if (!input_fmts[0])
+		return NULL;
+
+	*num_input_fmts = 1;
+
+	return input_fmts;
+}
+
+static long cdns_dsi_round_pclk(struct cdns_dsi *dsi, unsigned long pclk)
+{
+	struct cdns_dsi_output *output = &dsi->output;
+	unsigned int nlanes = output->dev->lanes;
+	union phy_configure_opts phy_opts = { 0 };
+	u32 bitspp;
+	int ret;
+
+	bitspp = mipi_dsi_pixel_format_to_bpp(output->dev->format);
+
+	ret = phy_mipi_dphy_get_default_config(pclk, bitspp, nlanes,
+					       &phy_opts.mipi_dphy);
+	if (ret)
+		return ret;
+
+	ret = phy_validate(dsi->dphy, PHY_MODE_MIPI_DPHY, 0, &phy_opts);
+	if (ret)
+		return ret;
+
+	return div_u64((u64)phy_opts.mipi_dphy.hs_clk_rate * nlanes, bitspp);
+}
+
+static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge,
+					struct drm_bridge_state *bridge_state,
+					struct drm_crtc_state *crtc_state,
+					struct drm_connector_state *conn_state)
+{
+	struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
+	struct cdns_dsi *dsi = input_to_dsi(input);
+	struct cdns_dsi_bridge_state *dsi_state = to_cdns_dsi_bridge_state(bridge_state);
+	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
+	struct cdns_dsi_cfg *dsi_cfg = &dsi_state->dsi_cfg;
+	struct videomode vm;
+	long pclk;
+
+	/* cdns-dsi requires negative syncs */
+	adjusted_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+	adjusted_mode->flags |= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC;
+
+	/*
+	 * The DPHY PLL has quite a coarsely grained clock rate options. See
+	 * what hsclk rate we can achieve based on the pixel clock, convert it
+	 * back to pixel clock, set that to the adjusted_mode->clock. This is
+	 * all in hopes that the CRTC will be able to provide us the requested
+	 * clock, as otherwise the DPI and DSI clocks will be out of sync.
+	 */
+
+	pclk = cdns_dsi_round_pclk(dsi, adjusted_mode->clock * 1000);
+	if (pclk < 0)
+		return (int)pclk;
+
+	adjusted_mode->clock = pclk / 1000;
+
+	drm_display_mode_to_videomode(adjusted_mode, &vm);
+
+	return cdns_dsi_check_conf(dsi, &vm, dsi_cfg);
+}
+
+static struct drm_bridge_state *
+cdns_dsi_bridge_atomic_duplicate_state(struct drm_bridge *bridge)
+{
+	struct cdns_dsi_bridge_state *dsi_state, *old_dsi_state;
+	struct drm_bridge_state *bridge_state;
+
+	if (WARN_ON(!bridge->base.state))
+		return NULL;
+
+	bridge_state = drm_priv_to_bridge_state(bridge->base.state);
+	old_dsi_state = to_cdns_dsi_bridge_state(bridge_state);
+
+	dsi_state = kzalloc(sizeof(*dsi_state), GFP_KERNEL);
+	if (!dsi_state)
+		return NULL;
+
+	__drm_atomic_helper_bridge_duplicate_state(bridge, &dsi_state->base);
+
+	memcpy(&dsi_state->dsi_cfg, &old_dsi_state->dsi_cfg,
+	       sizeof(dsi_state->dsi_cfg));
+
+	return &dsi_state->base;
+}
+
+static void
+cdns_dsi_bridge_atomic_destroy_state(struct drm_bridge *bridge,
+				     struct drm_bridge_state *state)
+{
+	struct cdns_dsi_bridge_state *dsi_state;
+
+	dsi_state = to_cdns_dsi_bridge_state(state);
+
+	kfree(dsi_state);
+}
+
+static struct drm_bridge_state *
+cdns_dsi_bridge_atomic_reset(struct drm_bridge *bridge)
+{
+	struct cdns_dsi_bridge_state *dsi_state;
+
+	dsi_state = kzalloc(sizeof(*dsi_state), GFP_KERNEL);
+	if (!dsi_state)
+		return NULL;
+
+	memset(dsi_state, 0, sizeof(*dsi_state));
+	dsi_state->base.bridge = bridge;
+
+	return &dsi_state->base;
 }
 
 static const struct drm_bridge_funcs cdns_dsi_bridge_funcs = {
 	.attach = cdns_dsi_bridge_attach,
 	.mode_valid = cdns_dsi_bridge_mode_valid,
-	.disable = cdns_dsi_bridge_disable,
-	.pre_enable = cdns_dsi_bridge_pre_enable,
-	.enable = cdns_dsi_bridge_enable,
-	.post_disable = cdns_dsi_bridge_post_disable,
+	.atomic_pre_enable = cdns_dsi_bridge_atomic_pre_enable,
+	.atomic_post_disable = cdns_dsi_bridge_atomic_post_disable,
+	.atomic_check = cdns_dsi_bridge_atomic_check,
+	.atomic_duplicate_state = cdns_dsi_bridge_atomic_duplicate_state,
+	.atomic_destroy_state = cdns_dsi_bridge_atomic_destroy_state,
+	.atomic_reset = cdns_dsi_bridge_atomic_reset,
+	.atomic_get_input_bus_fmts = cdns_dsi_bridge_get_input_bus_fmts,
 };
 
 static int cdns_dsi_attach(struct mipi_dsi_host *host,
@@ -920,8 +1036,6 @@
 	struct cdns_dsi_output *output = &dsi->output;
 	struct cdns_dsi_input *input = &dsi->input;
 	struct drm_bridge *bridge;
-	struct drm_panel *panel;
-	struct device_node *np;
 	int ret;
 
 	/*
@@ -932,33 +1046,13 @@
 	if (output->dev)
 		return -EBUSY;
 
-	/* We do not support burst mode yet. */
-	if (dev->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
-		return -ENOTSUPP;
-
 	/*
 	 * The host <-> device link might be described using an OF-graph
 	 * representation, in this case we extract the device of_node from
-	 * this representation, otherwise we use dsidev->dev.of_node which
-	 * should have been filled by the core.
+	 * this representation.
 	 */
-	np = of_graph_get_remote_node(dsi->base.dev->of_node, DSI_OUTPUT_PORT,
-				      dev->channel);
-	if (!np)
-		np = of_node_get(dev->dev.of_node);
-
-	panel = of_drm_find_panel(np);
-	if (!IS_ERR(panel)) {
-		bridge = drm_panel_bridge_add_typed(panel,
-						    DRM_MODE_CONNECTOR_DSI);
-	} else {
-		bridge = of_drm_find_bridge(dev->dev.of_node);
-		if (!bridge)
-			bridge = ERR_PTR(-EINVAL);
-	}
-
-	of_node_put(np);
-
+	bridge = devm_drm_of_get_bridge(dsi->base.dev, dsi->base.dev->of_node,
+					DSI_OUTPUT_PORT, dev->channel);
 	if (IS_ERR(bridge)) {
 		ret = PTR_ERR(bridge);
 		dev_err(host->dev, "failed to add DSI device %s (err = %d)",
@@ -968,7 +1062,6 @@
 
 	output->dev = dev;
 	output->bridge = bridge;
-	output->panel = panel;
 
 	/*
 	 * The DSI output has been properly configured, we can now safely
@@ -984,12 +1077,9 @@
 			   struct mipi_dsi_device *dev)
 {
 	struct cdns_dsi *dsi = to_cdns_dsi(host);
-	struct cdns_dsi_output *output = &dsi->output;
 	struct cdns_dsi_input *input = &dsi->input;
 
 	drm_bridge_remove(&input->bridge);
-	if (output->panel)
-		drm_panel_bridge_remove(output->bridge);
 
 	return 0;
 }
@@ -1152,7 +1242,6 @@
 	clk_disable_unprepare(dsi->dsi_sys_clk);
 	clk_disable_unprepare(dsi->dsi_p_clk);
 	reset_control_assert(dsi->dsi_p_rst);
-	dsi->link_initialized = false;
 	return 0;
 }
 
@@ -1313,4 +1402,3 @@
 MODULE_DESCRIPTION("Cadence DSI driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:cdns-dsi");
-
diff -Naur --no-dereference a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h
--- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h	2025-10-23 09:30:40.284462176 -0400
@@ -10,7 +10,6 @@
 
 #include <drm/drm_bridge.h>
 #include <drm/drm_mipi_dsi.h>
-#include <drm/drm_panel.h>
 
 #include <linux/bits.h>
 #include <linux/completion.h>
@@ -21,7 +20,6 @@
 
 struct cdns_dsi_output {
 	struct mipi_dsi_device *dev;
-	struct drm_panel *panel;
 	struct drm_bridge *bridge;
 	union phy_configure_opts phy_opts;
 };
diff -Naur --no-dereference a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c	2025-10-23 09:30:40.284462176 -0400
@@ -53,6 +53,8 @@
 #include "cdns-mhdp8546-hdcp.h"
 #include "cdns-mhdp8546-j721e.h"
 
+static int cdns_mhdp_update_link_status(struct cdns_mhdp_device *mhdp);
+
 static void cdns_mhdp_bridge_hpd_enable(struct drm_bridge *bridge)
 {
 	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
@@ -768,7 +770,8 @@
 	 * MHDP_HW_STOPPED happens only due to driver removal when
 	 * bridge should already be detached.
 	 */
-	cdns_mhdp_bridge_hpd_enable(&mhdp->bridge);
+	if (!mhdp->no_hpd)
+		cdns_mhdp_bridge_hpd_enable(&mhdp->bridge);
 
 	spin_unlock(&mhdp->start_lock);
 
@@ -862,7 +865,7 @@
 		ret = cdns_mhdp_dpcd_read(mhdp, msg->address,
 					  msg->buffer, msg->size);
 		if (ret) {
-			dev_err(mhdp->dev,
+			dev_dbg(mhdp->dev,
 				"Failed to read DPCD addr %u\n",
 				msg->address);
 
@@ -1617,24 +1620,6 @@
 	return true;
 }
 
-static
-enum drm_mode_status cdns_mhdp_mode_valid(struct drm_connector *conn,
-					  struct drm_display_mode *mode)
-{
-	struct cdns_mhdp_device *mhdp = connector_to_mhdp(conn);
-
-	mutex_lock(&mhdp->link_mutex);
-
-	if (!cdns_mhdp_bandwidth_ok(mhdp, mode, mhdp->link.num_lanes,
-				    mhdp->link.rate)) {
-		mutex_unlock(&mhdp->link_mutex);
-		return MODE_CLOCK_HIGH;
-	}
-
-	mutex_unlock(&mhdp->link_mutex);
-	return MODE_OK;
-}
-
 static int cdns_mhdp_connector_atomic_check(struct drm_connector *conn,
 					    struct drm_atomic_state *state)
 {
@@ -1678,7 +1663,6 @@
 static const struct drm_connector_helper_funcs cdns_mhdp_conn_helper_funcs = {
 	.detect_ctx = cdns_mhdp_connector_detect,
 	.get_modes = cdns_mhdp_get_modes,
-	.mode_valid = cdns_mhdp_mode_valid,
 	.atomic_check = cdns_mhdp_connector_atomic_check,
 };
 
@@ -1752,6 +1736,19 @@
 
 	spin_unlock(&mhdp->start_lock);
 
+	if (mhdp->no_hpd) {
+		ret = wait_event_timeout(mhdp->fw_load_wq,
+					 mhdp->hw_state == MHDP_HW_READY,
+					 msecs_to_jiffies(100));
+		if (ret == 0) {
+			dev_err(mhdp->dev, "%s: Timeout waiting for fw loading\n",
+				__func__);
+			return -ETIMEDOUT;
+		}
+
+		cdns_mhdp_update_link_status(mhdp);
+		return 0;
+	}
 	/* Enable SW event interrupts */
 	if (hw_ready)
 		cdns_mhdp_bridge_hpd_enable(bridge);
@@ -2217,6 +2214,19 @@
 {
 	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
 
+	if (mhdp->no_hpd) {
+		int ret = cdns_mhdp_update_link_status(mhdp);
+
+		if (mhdp->connector.dev) {
+			if (ret < 0)
+				schedule_work(&mhdp->modeset_retry_work);
+			else
+				drm_kms_helper_hotplug_event(mhdp->bridge.dev);
+		} else {
+			drm_bridge_hpd_notify(&mhdp->bridge, cdns_mhdp_detect(mhdp));
+		}
+	}
+
 	return cdns_mhdp_detect(mhdp);
 }
 
@@ -2228,6 +2238,25 @@
 	return cdns_mhdp_edid_read(mhdp, connector);
 }
 
+static enum drm_mode_status
+cdns_mhdp_bridge_mode_valid(struct drm_bridge *bridge,
+			    const struct drm_display_info *info,
+			    const struct drm_display_mode *mode)
+{
+	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
+
+	mutex_lock(&mhdp->link_mutex);
+
+	if (!cdns_mhdp_bandwidth_ok(mhdp, mode, mhdp->link.num_lanes,
+				    mhdp->link.rate)) {
+		mutex_unlock(&mhdp->link_mutex);
+		return MODE_CLOCK_HIGH;
+	}
+
+	mutex_unlock(&mhdp->link_mutex);
+	return MODE_OK;
+}
+
 static const struct drm_bridge_funcs cdns_mhdp_bridge_funcs = {
 	.atomic_enable = cdns_mhdp_atomic_enable,
 	.atomic_disable = cdns_mhdp_atomic_disable,
@@ -2242,6 +2271,7 @@
 	.edid_read = cdns_mhdp_bridge_edid_read,
 	.hpd_enable = cdns_mhdp_bridge_hpd_enable,
 	.hpd_disable = cdns_mhdp_bridge_hpd_disable,
+	.mode_valid = cdns_mhdp_bridge_mode_valid,
 };
 
 static bool cdns_mhdp_detect_hpd(struct cdns_mhdp_device *mhdp, bool *hpd_pulse)
@@ -2284,7 +2314,16 @@
 
 	mutex_lock(&mhdp->link_mutex);
 
-	mhdp->plugged = cdns_mhdp_detect_hpd(mhdp, &hpd_pulse);
+	if (mhdp->no_hpd) {
+		ret = drm_dp_dpcd_read_link_status(&mhdp->aux, status);
+		hpd_pulse = false;
+		if (ret < 0)
+			mhdp->plugged = false;
+		else
+			mhdp->plugged = true;
+	} else {
+		mhdp->plugged = cdns_mhdp_detect_hpd(mhdp, &hpd_pulse);
+	}
 
 	if (!mhdp->plugged) {
 		cdns_mhdp_link_down(mhdp);
@@ -2363,18 +2402,20 @@
 
 	mhdp = container_of(work, typeof(*mhdp), modeset_retry_work);
 
-	conn = &mhdp->connector;
-
-	/* Grab the locks before changing connector property */
-	mutex_lock(&conn->dev->mode_config.mutex);
-
-	/*
-	 * Set connector link status to BAD and send a Uevent to notify
-	 * userspace to do a modeset.
-	 */
-	drm_connector_set_link_status_property(conn, DRM_MODE_LINK_STATUS_BAD);
-	mutex_unlock(&conn->dev->mode_config.mutex);
+	if (mhdp->connector.dev) {
+		conn = &mhdp->connector;
+		/* Grab the locks before changing connector property */
+		mutex_lock(&conn->dev->mode_config.mutex);
 
+		/*
+		 * Set connector link status to BAD and send a Uevent to notify
+		 * userspace to do a modeset.
+		 */
+		drm_connector_set_link_status_property(conn, DRM_MODE_LINK_STATUS_BAD);
+		mutex_unlock(&conn->dev->mode_config.mutex);
+	} else {
+		mhdp->plugged = false;
+	}
 	/* Send Hotplug uevent so userspace can reprobe */
 	drm_kms_helper_hotplug_event(mhdp->bridge.dev);
 }
@@ -2479,6 +2520,8 @@
 	mhdp->aux.dev = dev;
 	mhdp->aux.transfer = cdns_mhdp_transfer;
 
+	mhdp->no_hpd = of_property_read_bool(dev->of_node, "cdns,no-hpd");
+
 	mhdp->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(mhdp->regs)) {
 		dev_err(dev, "Failed to get memory resource\n");
@@ -2552,8 +2595,9 @@
 
 	mhdp->bridge.of_node = pdev->dev.of_node;
 	mhdp->bridge.funcs = &cdns_mhdp_bridge_funcs;
-	mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
-			   DRM_BRIDGE_OP_HPD;
+	mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID;
+	if (!mhdp->no_hpd)
+		mhdp->bridge.ops |= DRM_BRIDGE_OP_HPD;
 	mhdp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
 
 	ret = phy_init(mhdp->phy);
diff -Naur --no-dereference a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h	2025-10-23 09:30:40.284462176 -0400
@@ -388,6 +388,7 @@
 
 	bool link_up;
 	bool plugged;
+	bool no_hpd;
 
 	/*
 	 * "start_lock" protects the access to bridge_attached and
diff -Naur --no-dereference a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c
--- a/drivers/gpu/drm/bridge/ite-it66121.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/bridge/ite-it66121.c	2025-10-23 09:30:40.284462176 -0400
@@ -298,7 +298,7 @@
 	struct regmap *regmap;
 	struct drm_bridge bridge;
 	struct drm_bridge *next_bridge;
-	struct drm_connector *connector;
+	struct drm_connector connector;
 	struct device *dev;
 	struct gpio_desc *gpio_reset;
 	struct i2c_client *client;
@@ -315,6 +315,11 @@
 	const struct it66121_chip_info *info;
 };
 
+static inline struct it66121_ctx *connector_to_it66121(struct drm_connector *con)
+{
+	return container_of(con, struct it66121_ctx, connector);
+}
+
 static const struct regmap_range_cfg it66121_regmap_banks[] = {
 	{
 		.name = "it66121",
@@ -585,19 +590,125 @@
 	return val & IT66121_SYS_STATUS_HPDETECT;
 }
 
+static enum drm_mode_status it66121_mode_valid(struct drm_connector *connector,
+					       struct drm_display_mode *mode)
+{
+	struct it66121_ctx *ctx = connector_to_it66121(connector);
+	unsigned long max_clock;
+
+	max_clock = (ctx->bus_width == 12) ? 74250 : 148500;
+
+	if (mode->clock > max_clock)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->clock < 25000)
+		return MODE_CLOCK_LOW;
+
+	return MODE_OK;
+}
+
+static const struct drm_edid *it66121_get_edid(struct it66121_ctx *ctx,
+				     struct drm_connector *connector)
+{
+	const struct drm_edid *drm_edid;
+	int ret;
+
+	mutex_lock(&ctx->lock);
+	ret = it66121_preamble_ddc(ctx);
+	if (ret) {
+		drm_edid = NULL;
+		goto out_unlock;
+	}
+
+	ret = regmap_write(ctx->regmap, IT66121_DDC_HEADER_REG,
+			   IT66121_DDC_HEADER_EDID);
+	if (ret) {
+		drm_edid = NULL;
+		goto out_unlock;
+	}
+
+	drm_edid = drm_edid_read_custom(connector, it66121_get_edid_block, ctx);
+
+out_unlock:
+	mutex_unlock(&ctx->lock);
+
+	return drm_edid;
+}
+
+static int it66121_get_modes(struct drm_connector *connector)
+{
+	struct it66121_ctx *ctx = connector_to_it66121(connector);
+	const struct drm_edid *drm_edid;
+	int num = 0;
+
+	drm_edid = it66121_get_edid(ctx, connector);
+	drm_edid_connector_update(connector, drm_edid);
+	if (drm_edid) {
+		num = drm_edid_connector_add_modes(connector);
+		drm_edid_free(drm_edid);
+	}
+
+	return num;
+}
+
+static const struct drm_connector_helper_funcs it66121_connector_helper_funcs = {
+	.get_modes = it66121_get_modes,
+	.mode_valid = it66121_mode_valid,
+};
+
+static enum drm_connector_status
+it66121_connector_detect(struct drm_connector *connector, bool force)
+{
+	struct it66121_ctx *ctx = connector_to_it66121(connector);
+
+	return it66121_is_hpd_detect(ctx) ? connector_status_connected
+					  : connector_status_disconnected;
+}
+
+static const struct drm_connector_funcs it66121_connector_funcs = {
+	.detect = it66121_connector_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = drm_connector_cleanup,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static void it66121_bridge_hpd_enable(struct drm_bridge *bridge);
+
 static int it66121_bridge_attach(struct drm_bridge *bridge,
 				 enum drm_bridge_attach_flags flags)
 {
 	struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge);
+	u32 bus_format;
 	int ret;
 
-	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
+	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
+		DRM_ERROR("DRM_BRIDGE_ATTACH_NO_CONNECTOR mode is not supported.\n");
 		return -EINVAL;
+	}
+
+	if (ctx->bus_width == 12)
+		bus_format = MEDIA_BUS_FMT_RGB888_2X12_LE;
+	else
+		bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 
-	ret = drm_bridge_attach(bridge->encoder, ctx->next_bridge, bridge, flags);
+	drm_connector_helper_add(&ctx->connector,
+				 &it66121_connector_helper_funcs);
+
+	ret = drm_connector_init(bridge->dev, &ctx->connector,
+				 &it66121_connector_funcs,
+				 DRM_MODE_CONNECTOR_HDMIA);
 	if (ret)
 		return ret;
 
+	ret = drm_display_info_set_bus_formats(&ctx->connector.display_info,
+					       &bus_format, 1);
+	if (ret)
+		return ret;
+
+	drm_connector_attach_encoder(&ctx->connector, bridge->encoder);
+
 	if (ctx->info->id == ID_IT66121) {
 		ret = regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG,
 					IT66121_CLK_BANK_PWROFF_RCLK, 0);
@@ -649,6 +760,9 @@
 	/* Per programming manual, sleep here for bridge to settle */
 	msleep(50);
 
+	/* HACK For some part of missing hotplug somewhere.. */
+	it66121_bridge_hpd_enable(bridge);
+
 	return 0;
 }
 
@@ -724,9 +838,6 @@
 				  struct drm_bridge_state *bridge_state)
 {
 	struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge);
-	struct drm_atomic_state *state = bridge_state->base.state;
-
-	ctx->connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
 
 	it66121_set_mute(ctx, false);
 }
@@ -737,8 +848,6 @@
 	struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge);
 
 	it66121_set_mute(ctx, true);
-
-	ctx->connector = NULL;
 }
 
 static int it66121_bridge_check(struct drm_bridge *bridge,
@@ -770,9 +879,7 @@
 
 	mutex_lock(&ctx->lock);
 
-	hdmi_avi_infoframe_init(&ctx->hdmi_avi_infoframe);
-
-	ret = drm_hdmi_avi_infoframe_from_display_mode(&ctx->hdmi_avi_infoframe, ctx->connector,
+	ret = drm_hdmi_avi_infoframe_from_display_mode(&ctx->hdmi_avi_infoframe, &ctx->connector,
 						       adjusted_mode);
 	if (ret) {
 		DRM_ERROR("Failed to setup AVI infoframe: %d\n", ret);
@@ -878,29 +985,8 @@
 						       struct drm_connector *connector)
 {
 	struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge);
-	const struct drm_edid *drm_edid;
-	int ret;
-
-	mutex_lock(&ctx->lock);
-	ret = it66121_preamble_ddc(ctx);
-	if (ret) {
-		drm_edid = NULL;
-		goto out_unlock;
-	}
-
-	ret = regmap_write(ctx->regmap, IT66121_DDC_HEADER_REG,
-			   IT66121_DDC_HEADER_EDID);
-	if (ret) {
-		drm_edid = NULL;
-		goto out_unlock;
-	}
-
-	drm_edid = drm_edid_read_custom(connector, it66121_get_edid_block, ctx);
-
-out_unlock:
-	mutex_unlock(&ctx->lock);
 
-	return drm_edid;
+	return it66121_get_edid(ctx, connector);
 }
 
 static const struct drm_bridge_funcs it66121_bridge_funcs = {
@@ -1447,16 +1533,10 @@
 	struct it66121_ctx *ctx = dev_get_drvdata(dev);
 
 	mutex_lock(&ctx->lock);
-	if (!ctx->connector) {
-		/* Pass en empty ELD if connector not available */
-		dev_dbg(dev, "No connector present, passing empty EDID data");
-		memset(buf, 0, len);
-	} else {
-		mutex_lock(&ctx->connector->eld_mutex);
-		memcpy(buf, ctx->connector->eld,
-		       min(sizeof(ctx->connector->eld), len));
-		mutex_unlock(&ctx->connector->eld_mutex);
-	}
+
+	memcpy(buf, ctx->connector.eld,
+	       min(sizeof(ctx->connector.eld), len));
+
 	mutex_unlock(&ctx->lock);
 
 	return 0;
@@ -1482,7 +1562,7 @@
 
 	dev_dbg(dev, "%s\n", __func__);
 
-	if (!of_property_read_bool(dev->of_node, "#sound-dai-cells")) {
+	if (!of_property_present(dev->of_node, "#sound-dai-cells")) {
 		dev_info(dev, "No \"#sound-dai-cells\", no audio\n");
 		return 0;
 	}
@@ -1501,6 +1581,14 @@
 	return PTR_ERR_OR_ZERO(ctx->audio.pdev);
 }
 
+static void it66121_hpd_event(void* arg, enum drm_connector_status status)
+{
+    struct it66121_ctx* ctx = (struct it66121_ctx*)arg;
+
+    if (ctx->connector.dev)
+        drm_kms_helper_hotplug_event(ctx->connector.dev);
+}
+
 static const char * const it66121_supplies[] = {
 	"vcn33", "vcn18", "vrf12"
 };
@@ -1586,6 +1674,7 @@
 	if (client->irq > 0) {
 		ctx->bridge.ops |= DRM_BRIDGE_OP_HPD;
 
+		drm_bridge_hpd_enable(&ctx->bridge, it66121_hpd_event, ctx);
 		ret = devm_request_threaded_irq(dev, client->irq, NULL,
 						it66121_irq_threaded_handler,
 						IRQF_ONESHOT, dev_name(dev),
@@ -1619,6 +1708,12 @@
 	.pid = 0x0612,
 };
 
+static const struct it66121_chip_info it66122_chip_info = {
+	.id = ID_IT66121,
+	.vid = 0x4954,
+	.pid = 0x0622,
+};
+
 static const struct it66121_chip_info it6610_chip_info = {
 	.id = ID_IT6610,
 	.vid = 0xca00,
@@ -1627,6 +1722,7 @@
 
 static const struct of_device_id it66121_dt_match[] = {
 	{ .compatible = "ite,it66121", &it66121_chip_info },
+	{ .compatible = "ite,it66122", &it66122_chip_info },
 	{ .compatible = "ite,it6610", &it6610_chip_info },
 	{ }
 };
@@ -1634,6 +1730,7 @@
 
 static const struct i2c_device_id it66121_id[] = {
 	{ "it66121", (kernel_ulong_t) &it66121_chip_info },
+	{ "it66122", (kernel_ulong_t) &it66122_chip_info },
 	{ "it6610", (kernel_ulong_t) &it6610_chip_info },
 	{ }
 };
diff -Naur --no-dereference a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
--- a/drivers/gpu/drm/bridge/sii902x.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/bridge/sii902x.c	2025-10-23 09:30:40.284462176 -0400
@@ -180,6 +180,10 @@
 	struct gpio_desc *reset_gpio;
 	struct i2c_mux_core *i2cmux;
 	bool sink_is_hdmi;
+	struct device_link *link;
+	unsigned int ctx_tpi;
+	unsigned int ctx_interrupt;
+
 	/*
 	 * Mutex protects audio and video functions from interfering
 	 * each other, by keeping their i2c command sequences atomic.
@@ -419,8 +423,15 @@
 	struct sii902x *sii902x = bridge_to_sii902x(bridge);
 	u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 	struct drm_device *drm = bridge->dev;
+	struct device *dev = &sii902x->i2c->dev;
 	int ret;
 
+	sii902x->link = device_link_add(drm->dev, dev, DL_FLAG_STATELESS);
+	if (!sii902x->link) {
+		dev_err(dev, "failed to create device link");
+		return -EINVAL;
+	}
+
 	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
 		return drm_bridge_attach(bridge->encoder, sii902x->next_bridge,
 					 bridge, flags);
@@ -429,16 +440,17 @@
 				 &sii902x_connector_helper_funcs);
 
 	if (!drm_core_check_feature(drm, DRIVER_ATOMIC)) {
-		dev_err(&sii902x->i2c->dev,
+		dev_err(dev,
 			"sii902x driver is only compatible with DRM devices supporting atomic updates\n");
-		return -ENOTSUPP;
+		ret = -EOPNOTSUPP;
+		goto err_bridge_attach;
 	}
 
 	ret = drm_connector_init(drm, &sii902x->connector,
 				 &sii902x_connector_funcs,
 				 DRM_MODE_CONNECTOR_HDMIA);
 	if (ret)
-		return ret;
+		goto err_bridge_attach;
 
 	if (sii902x->i2c->irq > 0)
 		sii902x->connector.polled = DRM_CONNECTOR_POLL_HPD;
@@ -448,11 +460,24 @@
 	ret = drm_display_info_set_bus_formats(&sii902x->connector.display_info,
 					       &bus_format, 1);
 	if (ret)
-		return ret;
+		goto err_bridge_attach;
 
 	drm_connector_attach_encoder(&sii902x->connector, bridge->encoder);
 
 	return 0;
+
+err_bridge_attach:
+	device_link_del(sii902x->link);
+
+	return ret;
+}
+
+static void sii902x_bridge_detach(struct drm_bridge *bridge)
+{
+	struct sii902x *sii902x = bridge_to_sii902x(bridge);
+
+	if (sii902x->link)
+		device_link_del(sii902x->link);
 }
 
 static enum drm_connector_status sii902x_bridge_detect(struct drm_bridge *bridge)
@@ -525,6 +550,7 @@
 
 static const struct drm_bridge_funcs sii902x_bridge_funcs = {
 	.attach = sii902x_bridge_attach,
+	.detach = sii902x_bridge_detach,
 	.mode_set = sii902x_bridge_mode_set,
 	.atomic_disable = sii902x_bridge_atomic_disable,
 	.atomic_enable = sii902x_bridge_atomic_enable,
@@ -1054,6 +1080,58 @@
 		 | DRM_BUS_FLAG_DE_HIGH,
 };
 
+static int __maybe_unused sii902x_resume(struct device *dev)
+{
+	struct sii902x *sii902x = dev_get_drvdata(dev);
+	unsigned int tpi_reg, status;
+	int ret;
+
+	ret = regmap_read(sii902x->regmap, SII902X_REG_TPI_RQB, &tpi_reg);
+	if (ret)
+		return ret;
+
+	if (tpi_reg != sii902x->ctx_tpi) {
+		/*
+		 * TPI register context has changed. SII902X power supply
+		 * device has been turned off and on.
+		 */
+
+		sii902x_reset(sii902x);
+
+		/* Configure the device to enter TPI mode. */
+		ret = regmap_write(sii902x->regmap, SII902X_REG_TPI_RQB, 0x0);
+		if (ret)
+			return ret;
+
+		/* Re enable the interrupts */
+		regmap_write(sii902x->regmap, SII902X_INT_ENABLE,
+			     sii902x->ctx_interrupt);
+	}
+
+	/* Clear all pending interrupts */
+	regmap_read(sii902x->regmap, SII902X_INT_STATUS, &status);
+	regmap_write(sii902x->regmap, SII902X_INT_STATUS, status);
+
+	return 0;
+}
+
+static int __maybe_unused sii902x_suspend(struct device *dev)
+{
+	struct sii902x *sii902x = dev_get_drvdata(dev);
+
+	regmap_read(sii902x->regmap, SII902X_REG_TPI_RQB,
+		    &sii902x->ctx_tpi);
+
+	regmap_read(sii902x->regmap, SII902X_INT_ENABLE,
+		    &sii902x->ctx_interrupt);
+
+	return 0;
+}
+
+static const struct dev_pm_ops sii902x_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(sii902x_suspend, sii902x_resume)
+};
+
 static int sii902x_init(struct sii902x *sii902x)
 {
 	struct device *dev = &sii902x->i2c->dev;
@@ -1227,6 +1305,7 @@
 	.remove = sii902x_remove,
 	.driver = {
 		.name = "sii902x",
+		.pm = &sii902x_pm_ops,
 		.of_match_table = sii902x_dt_ids,
 	},
 	.id_table = sii902x_i2c_ids,
diff -Naur --no-dereference a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c	2025-10-23 09:30:40.284462176 -0400
@@ -152,6 +152,7 @@
  * @ln_assign:    Value to program to the LN_ASSIGN register.
  * @ln_polrs:     Value for the 4-bit LN_POLRS field of SN_ENH_FRAME_REG.
  * @comms_enabled: If true then communication over the aux channel is enabled.
+ * @plugged:       Plug connection status
  * @comms_mutex:   Protects modification of comms_enabled.
  *
  * @gchip:        If we expose our GPIOs, this is used.
@@ -190,6 +191,7 @@
 	u8				ln_assign;
 	u8				ln_polrs;
 	bool				comms_enabled;
+	bool				plugged;
 	struct mutex			comms_mutex;
 
 #if defined(CONFIG_OF_GPIO)
@@ -715,10 +717,12 @@
 	if (IS_ERR(dsi))
 		return PTR_ERR(dsi);
 
-	/* TODO: setting to 4 MIPI lanes always for now */
-	dsi->lanes = 4;
+	/* TODO: setting to 2 MIPI lanes always for now */
+	dsi->lanes = 2;
 	dsi->format = MIPI_DSI_FMT_RGB888;
-	dsi->mode_flags = MIPI_DSI_MODE_VIDEO;
+	dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
+			  MIPI_DSI_MODE_NO_EOT_PACKET |
+			  MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
 
 	/* check if continuous dsi clock is required or not */
 	pm_runtime_get_sync(dev);
@@ -1093,6 +1097,15 @@
 		return;
 	}
 
+	/*
+	 * Disable ASSR Display Authentication, since its supported only in eDP
+	 * and not spupperted in DP
+	 */
+	regmap_write(pdata->regmap, 0xFF, 0x7);
+	regmap_write(pdata->regmap, 0x16, 0x1);
+	regmap_write(pdata->regmap, 0xFF, 0x0);
+	regmap_update_bits(pdata->regmap, 0x5A, BIT(0), 0);
+
 	max_dp_lanes = ti_sn_get_max_lanes(pdata);
 	pdata->dp_lanes = min(pdata->dp_lanes, max_dp_lanes);
 
@@ -1108,26 +1121,6 @@
 	/* set dsi clk frequency value */
 	ti_sn_bridge_set_dsi_rate(pdata);
 
-	/*
-	 * The SN65DSI86 only supports ASSR Display Authentication method and
-	 * this method is enabled for eDP panels. An eDP panel must support this
-	 * authentication method. We need to enable this method in the eDP panel
-	 * at DisplayPort address 0x0010A prior to link training.
-	 *
-	 * As only ASSR is supported by SN65DSI86, for full DisplayPort displays
-	 * we need to disable the scrambler.
-	 */
-	if (pdata->bridge.type == DRM_MODE_CONNECTOR_eDP) {
-		drm_dp_dpcd_writeb(&pdata->aux, DP_EDP_CONFIGURATION_SET,
-				   DP_ALTERNATE_SCRAMBLER_RESET_ENABLE);
-
-		regmap_update_bits(pdata->regmap, SN_TRAINING_SETTING_REG,
-				   SCRAMBLE_DISABLE, 0);
-	} else {
-		regmap_update_bits(pdata->regmap, SN_TRAINING_SETTING_REG,
-				   SCRAMBLE_DISABLE, SCRAMBLE_DISABLE);
-	}
-
 	bpp = ti_sn_bridge_get_bpp(connector);
 	/* Set the DP output format (18 bpp or 24 bpp) */
 	val = bpp == 18 ? BPP_18_RGB : 0;
@@ -1199,14 +1192,19 @@
 static enum drm_connector_status ti_sn_bridge_detect(struct drm_bridge *bridge)
 {
 	struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
-	int val = 0;
+	int val;
+	u8 link_status[DP_LINK_STATUS_SIZE];
 
-	pm_runtime_get_sync(pdata->dev);
-	regmap_read(pdata->regmap, SN_HPD_DISABLE_REG, &val);
-	pm_runtime_put_autosuspend(pdata->dev);
+	if (!pdata->plugged) {
+		pm_runtime_get_sync(pdata->dev);
+		val = drm_dp_dpcd_read_link_status(&pdata->aux, link_status);
+		pm_runtime_put_autosuspend(pdata->dev);
+		if (val > 0)
+			pdata->plugged = true;
+	}
 
-	return val & HPD_DEBOUNCED_STATE ? connector_status_connected
-					 : connector_status_disconnected;
+	return pdata->plugged ? connector_status_connected
+			      : connector_status_disconnected;
 }
 
 static const struct drm_edid *ti_sn_bridge_edid_read(struct drm_bridge *bridge,
@@ -1318,8 +1316,11 @@
 	pdata->bridge.type = pdata->next_bridge->type == DRM_MODE_CONNECTOR_DisplayPort
 			   ? DRM_MODE_CONNECTOR_DisplayPort : DRM_MODE_CONNECTOR_eDP;
 
+	pdata->plugged = false;
+	pdata->bridge.ops |= DRM_BRIDGE_OP_DETECT;
+
 	if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort)
-		pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT;
+		pdata->bridge.ops |= DRM_BRIDGE_OP_EDID;
 
 	drm_bridge_add(&pdata->bridge);
 
diff -Naur --no-dereference a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
--- a/drivers/gpu/drm/drm_atomic_helper.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/drm_atomic_helper.c	2025-10-23 09:30:40.284462176 -0400
@@ -1150,11 +1150,10 @@
 }
 
 static void
-disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
+encoder_bridge_disable(struct drm_device *dev, struct drm_atomic_state *old_state)
 {
 	struct drm_connector *connector;
 	struct drm_connector_state *old_conn_state, *new_conn_state;
-	struct drm_crtc *crtc;
 	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
 	int i;
 
@@ -1214,9 +1213,15 @@
 			else if (funcs->dpms)
 				funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
 		}
-
-		drm_atomic_bridge_chain_post_disable(bridge, old_state);
 	}
+}
+
+static void
+crtc_disable(struct drm_device *dev, struct drm_atomic_state *old_state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
+	int i;
 
 	for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
 		const struct drm_crtc_helper_funcs *funcs;
@@ -1264,6 +1269,68 @@
 	}
 }
 
+static void
+encoder_bridge_post_disable(struct drm_device *dev, struct drm_atomic_state *old_state)
+{
+	struct drm_connector *connector;
+	struct drm_connector_state *old_conn_state, *new_conn_state;
+	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
+	int i;
+
+	for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, new_conn_state, i) {
+		struct drm_encoder *encoder;
+		struct drm_bridge *bridge;
+
+		/*
+		 * Shut down everything that's in the changeset and currently
+		 * still on. So need to check the old, saved state.
+		 */
+		if (!old_conn_state->crtc)
+			continue;
+
+		old_crtc_state = drm_atomic_get_old_crtc_state(old_state, old_conn_state->crtc);
+
+		if (new_conn_state->crtc)
+			new_crtc_state = drm_atomic_get_new_crtc_state(
+						old_state,
+						new_conn_state->crtc);
+		else
+			new_crtc_state = NULL;
+
+		if (!crtc_needs_disable(old_crtc_state, new_crtc_state) ||
+		    !drm_atomic_crtc_needs_modeset(old_conn_state->crtc->state))
+			continue;
+
+		encoder = old_conn_state->best_encoder;
+
+		/* We shouldn't get this far if we didn't previously have
+		 * an encoder.. but WARN_ON() rather than explode.
+		 */
+		if (WARN_ON(!encoder))
+			continue;
+
+		drm_dbg_atomic(dev, "post-disabling bridges [ENCODER:%d:%s]\n",
+			       encoder->base.id, encoder->name);
+
+		/*
+		 * Each encoder has at most one connector (since we always steal
+		 * it away), so we won't call disable hooks twice.
+		 */
+		bridge = drm_bridge_chain_get_first_bridge(encoder);
+		drm_atomic_bridge_chain_post_disable(bridge, old_state);
+	}
+}
+
+static void
+disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
+{
+	encoder_bridge_disable(dev, old_state);
+
+	crtc_disable(dev, old_state);
+
+	encoder_bridge_post_disable(dev, old_state);
+}
+
 /**
  * drm_atomic_helper_update_legacy_modeset_state - update legacy modeset state
  * @dev: DRM device
@@ -1473,28 +1540,44 @@
 	}
 }
 
-/**
- * drm_atomic_helper_commit_modeset_enables - modeset commit to enable outputs
- * @dev: DRM device
- * @old_state: atomic state object with old state structures
- *
- * This function enables all the outputs with the new configuration which had to
- * be turned off for the update.
- *
- * For compatibility with legacy CRTC helpers this should be called after
- * drm_atomic_helper_commit_planes(), which is what the default commit function
- * does. But drivers with different needs can group the modeset commits together
- * and do the plane commits at the end. This is useful for drivers doing runtime
- * PM since planes updates then only happen when the CRTC is actually enabled.
- */
-void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
-					      struct drm_atomic_state *old_state)
+static void
+encoder_bridge_pre_enable(struct drm_device *dev, struct drm_atomic_state *old_state)
+{
+	struct drm_connector *connector;
+	struct drm_connector_state *new_conn_state;
+	int i;
+
+	for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
+		struct drm_encoder *encoder;
+		struct drm_bridge *bridge;
+
+		if (!new_conn_state->best_encoder)
+			continue;
+
+		if (!new_conn_state->crtc->state->active ||
+		    !drm_atomic_crtc_needs_modeset(new_conn_state->crtc->state))
+			continue;
+
+		encoder = new_conn_state->best_encoder;
+
+		drm_dbg_atomic(dev, "pre-enabling bridges [ENCODER:%d:%s]\n",
+			       encoder->base.id, encoder->name);
+
+		/*
+		 * Each encoder has at most one connector (since we always steal
+		 * it away), so we won't call enable hooks twice.
+		 */
+		bridge = drm_bridge_chain_get_first_bridge(encoder);
+		drm_atomic_bridge_chain_pre_enable(bridge, old_state);
+	}
+}
+
+static void
+crtc_enable(struct drm_device *dev, struct drm_atomic_state *old_state)
 {
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *old_crtc_state;
 	struct drm_crtc_state *new_crtc_state;
-	struct drm_connector *connector;
-	struct drm_connector_state *new_conn_state;
 	int i;
 
 	for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
@@ -1518,6 +1601,14 @@
 				funcs->commit(crtc);
 		}
 	}
+}
+
+static void
+encoder_bridge_enable(struct drm_device *dev, struct drm_atomic_state *old_state)
+{
+	struct drm_connector *connector;
+	struct drm_connector_state *new_conn_state;
+	int i;
 
 	for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
 		const struct drm_encoder_helper_funcs *funcs;
@@ -1542,7 +1633,7 @@
 		 * it away), so we won't call enable hooks twice.
 		 */
 		bridge = drm_bridge_chain_get_first_bridge(encoder);
-		drm_atomic_bridge_chain_pre_enable(bridge, old_state);
+		drm_atomic_bridge_chain_enable(bridge, old_state);
 
 		if (funcs) {
 			if (funcs->atomic_enable)
@@ -1552,9 +1643,31 @@
 			else if (funcs->commit)
 				funcs->commit(encoder);
 		}
-
-		drm_atomic_bridge_chain_enable(bridge, old_state);
 	}
+}
+
+/**
+ * drm_atomic_helper_commit_modeset_enables - modeset commit to enable outputs
+ * @dev: DRM device
+ * @old_state: atomic state object with old state structures
+ *
+ * This function enables all the outputs with the new configuration which had to
+ * be turned off for the update.
+ *
+ * For compatibility with legacy CRTC helpers this should be called after
+ * drm_atomic_helper_commit_planes(), which is what the default commit function
+ * does. But drivers with different needs can group the modeset commits together
+ * and do the plane commits at the end. This is useful for drivers doing runtime
+ * PM since planes updates then only happen when the CRTC is actually enabled.
+ */
+void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
+					      struct drm_atomic_state *old_state)
+{
+	encoder_bridge_pre_enable(dev, old_state);
+
+	crtc_enable(dev, old_state);
+
+	encoder_bridge_enable(dev, old_state);
 
 	drm_atomic_helper_commit_writebacks(dev, old_state);
 }
diff -Naur --no-dereference a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
--- a/drivers/gpu/drm/drm_mipi_dsi.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/drm_mipi_dsi.c	2025-10-23 09:30:40.285462207 -0400
@@ -36,6 +36,8 @@
 #include <drm/drm_mipi_dsi.h>
 #include <drm/drm_print.h>
 
+#include <linux/media-bus-format.h>
+
 #include <video/mipi_display.h>
 
 /**
@@ -871,6 +873,41 @@
 EXPORT_SYMBOL(mipi_dsi_generic_read);
 
 /**
+ * drm_mipi_dsi_get_input_bus_fmt() - Get the required MEDIA_BUS_FMT_* based
+ *				      input pixel format for a given DSI output
+ *				      pixel format
+ * @dsi_format: pixel format that a DSI host needs to output
+ *
+ * Various DSI hosts can use this function during their
+ * &drm_bridge_funcs.atomic_get_input_bus_fmts operation to ascertain
+ * the MEDIA_BUS_FMT_* pixel format required as input.
+ *
+ * RETURNS:
+ * a 32-bit MEDIA_BUS_FMT_* value on success or 0 in case of failure.
+ */
+u32 drm_mipi_dsi_get_input_bus_fmt(enum mipi_dsi_pixel_format dsi_format)
+{
+	switch (dsi_format) {
+	case MIPI_DSI_FMT_RGB888:
+		return MEDIA_BUS_FMT_RGB888_1X24;
+
+	case MIPI_DSI_FMT_RGB666:
+		return MEDIA_BUS_FMT_RGB666_1X24_CPADHI;
+
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		return MEDIA_BUS_FMT_RGB666_1X18;
+
+	case MIPI_DSI_FMT_RGB565:
+		return MEDIA_BUS_FMT_RGB565_1X16;
+
+	default:
+		/* Unsupported DSI Format */
+		return 0;
+	}
+}
+EXPORT_SYMBOL(drm_mipi_dsi_get_input_bus_fmt);
+
+/**
  * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload
  * @dsi: DSI peripheral device
  * @data: buffer containing data to be transmitted
diff -Naur --no-dereference a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
--- a/drivers/gpu/drm/panel/panel-edp.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/panel/panel-edp.c	2025-10-23 09:30:40.285462207 -0400
@@ -878,7 +878,8 @@
 		if (!panel->ddc)
 			return -EPROBE_DEFER;
 	} else if (aux) {
-		panel->ddc = &aux->ddc;
+		if (!of_device_is_compatible(dev->of_node, "ti,panel-edp"))
+			panel->ddc = &aux->ddc;
 	}
 
 	if (!of_get_display_timing(dev->of_node, "panel-timing", &dt))
@@ -915,19 +916,21 @@
 		dev_warn(dev, "Expected bpc in {6,8,10} but got: %u\n", desc->bpc);
 	}
 
-	if (!panel->base.backlight && panel->aux) {
-		pm_runtime_get_sync(dev);
-		err = drm_panel_dp_aux_backlight(&panel->base, panel->aux);
-		pm_runtime_mark_last_busy(dev);
-		pm_runtime_put_autosuspend(dev);
-
-		/*
-		 * Warn if we get an error, but don't consider it fatal. Having
-		 * a panel where we can't control the backlight is better than
-		 * no panel.
-		 */
-		if (err)
-			dev_warn(dev, "failed to register dp aux backlight: %d\n", err);
+	if (!of_device_is_compatible(dev->of_node, "ti,panel-edp")) {
+		if (!panel->base.backlight && panel->aux) {
+			pm_runtime_get_sync(dev);
+			err = drm_panel_dp_aux_backlight(&panel->base, panel->aux);
+			pm_runtime_mark_last_busy(dev);
+			pm_runtime_put_autosuspend(dev);
+
+			/*
+			 * Warn if we get an error, but don't consider it fatal. Having
+			 * a panel where we can't control the backlight is better than
+			 * no panel.
+			 */
+			if (err)
+				dev_warn(dev, "failed to register dp aux backlight: %d\n", err);
+		}
 	}
 
 	drm_panel_add(&panel->base);
@@ -1616,6 +1619,36 @@
 	},
 };
 
+static const struct drm_display_mode ti_panel_edp_mode = {
+	.clock = 40000,
+	.hdisplay = 800,
+	.hsync_start = 800 + 40,
+	.hsync_end = 800 + 40 + 128,
+	.htotal = 800 + 40 + 128 + 88,
+	.vdisplay = 600,
+	.vsync_start = 600 + 1,
+	.vsync_end = 600 + 1 + 4,
+	.vtotal = 600 + 1 + 4 + 23,
+
+	.crtc_clock = 40000,
+	.crtc_hdisplay = 800,
+	.crtc_hsync_start = 800 + 40,
+	.crtc_hsync_end = 800 + 40 + 128,
+	.crtc_htotal = 800 + 40 + 128 + 88,
+	.crtc_vdisplay = 600,
+	.crtc_vsync_start = 600 + 1,
+	.crtc_vsync_end = 600 + 1 + 4,
+	.crtc_vtotal = 600 + 1 + 4 + 23,
+
+	.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
+};
+
+static const struct panel_desc ti_panel_edp = {
+	.modes = &ti_panel_edp_mode,
+	.num_modes = 1,
+	.bpc = 8,
+};
+
 static const struct of_device_id platform_of_match[] = {
 	{
 		/* Must be first */
@@ -1707,6 +1740,9 @@
 		.compatible = "sharp,lq123p1jx31",
 		.data = &sharp_lq123p1jx31,
 	}, {
+		.compatible = "ti,panel-edp",
+		.data = &ti_panel_edp,
+	}, {
 		/* sentinel */
 	}
 };
diff -Naur --no-dereference a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
--- a/drivers/gpu/drm/panel/panel-simple.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/panel/panel-simple.c	2025-10-23 09:30:40.285462207 -0400
@@ -3856,6 +3856,32 @@
 	.connector_type = DRM_MODE_CONNECTOR_DPI,
 };
 
+static const struct drm_display_mode raspberrypi_7inch_mode = {
+	.clock = 28569600 / 1000,
+	.hdisplay = 800,
+	.hsync_start = 800 + 48,
+	.hsync_end = 800 + 48 + 32,
+	.htotal = 800 + 48 + 32 + 80,
+	.vdisplay = 480,
+	.vsync_start = 480 + 3,
+	.vsync_end = 480 + 3 + 7,
+	.vtotal = 480 + 3 + 7 + 6,
+
+	.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
+};
+
+static const struct panel_desc raspberrypi_7inch = {
+	.modes = &raspberrypi_7inch_mode,
+	.num_modes = 1,
+	.bpc = 8,
+	.size = {
+		.width = 154,
+		.height = 86,
+	},
+	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+	.connector_type = DRM_MODE_CONNECTOR_DSI,
+};
+
 static const struct display_timing rocktech_rk070er9427_timing = {
 	.pixelclock = { 26400000, 33300000, 46800000 },
 	.hactive = { 800, 800, 800 },
@@ -4980,6 +5006,9 @@
 		.compatible = "rocktech,rk043fn48h",
 		.data = &rocktech_rk043fn48h,
 	}, {
+		.compatible = "raspberrypi,7inch-dsi",
+		.data = &raspberrypi_7inch,
+	}, {
 		.compatible = "rocktech,rk070er9427",
 		.data = &rocktech_rk070er9427,
 	}, {
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/Makefile b/drivers/gpu/drm/tidss/Makefile
--- a/drivers/gpu/drm/tidss/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/tidss/Makefile	2025-10-23 09:30:40.285462207 -0400
@@ -7,6 +7,7 @@
 	tidss_irq.o \
 	tidss_plane.o \
 	tidss_scale_coefs.o \
-	tidss_dispc.o
+	tidss_dispc.o \
+	tidss_oldi.o
 
 obj-$(CONFIG_DRM_TIDSS) += tidss.o
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c
--- a/drivers/gpu/drm/tidss/tidss_crtc.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/tidss/tidss_crtc.c	2025-10-23 09:30:40.285462207 -0400
@@ -31,13 +31,19 @@
 	/*
 	 * New settings are taken into use at VFP, and GO bit is cleared at
 	 * the same time. This happens before the vertical blank interrupt.
-	 * So there is a small change that the driver sets GO bit after VFP, but
+	 * So there is a small chance that the driver sets GO bit after VFP, but
 	 * before vblank, and we have to check for that case here.
+	 *
+	 * For a video port shared between Linux and remote core but owned by remote core,
+	 * this is not required since Linux just attaches to mode that was preset by remote
+	 * core with which display is being shared.
 	 */
-	busy = dispc_vp_go_busy(tidss->dispc, tcrtc->hw_videoport);
-	if (busy) {
-		spin_unlock_irqrestore(&ddev->event_lock, flags);
-		return;
+	if (!tidss->shared_mode || tidss->shared_mode_owned_vps[tcrtc->hw_videoport]) {
+		busy = dispc_vp_go_busy(tidss->dispc, tcrtc->hw_videoport);
+		if (busy) {
+			spin_unlock_irqrestore(&ddev->event_lock, flags);
+			return;
+		}
 	}
 
 	event = tcrtc->event;
@@ -108,6 +114,7 @@
 		return -EINVAL;
 	}
 
+	drm_mode_set_crtcinfo(&crtc_state->adjusted_mode, 0);
 	return dispc_vp_bus_check(dispc, hw_videoport, crtc_state);
 }
 
@@ -208,6 +215,44 @@
 	spin_unlock_irqrestore(&ddev->event_lock, flags);
 }
 
+static void tidss_shared_vp_crtc_atomic_flush(struct drm_crtc *crtc,
+					      struct drm_atomic_state *state)
+{
+	struct tidss_crtc *tcrtc = to_tidss_crtc(crtc);
+	struct drm_device *ddev = crtc->dev;
+	unsigned long flags;
+
+	dev_dbg(ddev->dev,
+		"%s: %s enabled %d, needs modeset %d, event %p\n", __func__,
+		crtc->name, drm_atomic_crtc_needs_modeset(crtc->state),
+		crtc->state->enable, crtc->state->event);
+
+	/* There is nothing to do if CRTC is not going to be enabled. */
+	if (!crtc->state->enable)
+		return;
+	/*
+	 * Flush CRTC changes with go bit only if new modeset is not
+	 * coming, so CRTC is enabled trough out the commit.
+	 */
+	if (drm_atomic_crtc_needs_modeset(crtc->state))
+		return;
+
+	/* We should have event if CRTC is enabled through out this commit. */
+	if (WARN_ON(!crtc->state->event))
+		return;
+
+	WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+
+	spin_lock_irqsave(&ddev->event_lock, flags);
+
+	WARN_ON(tcrtc->event);
+
+	tcrtc->event = crtc->state->event;
+	crtc->state->event = NULL;
+
+	spin_unlock_irqrestore(&ddev->event_lock, flags);
+}
+
 static void tidss_crtc_atomic_enable(struct drm_crtc *crtc,
 				     struct drm_atomic_state *state)
 {
@@ -225,7 +270,7 @@
 	tidss_runtime_get(tidss);
 
 	r = dispc_vp_set_clk_rate(tidss->dispc, tcrtc->hw_videoport,
-				  mode->clock * 1000);
+				  mode->crtc_clock * 1000);
 	if (r != 0)
 		return;
 
@@ -253,6 +298,27 @@
 	spin_unlock_irqrestore(&ddev->event_lock, flags);
 }
 
+static void tidss_shared_vp_crtc_atomic_enable(struct drm_crtc *crtc,
+					       struct drm_atomic_state *state)
+{
+	struct drm_device *ddev = crtc->dev;
+	unsigned long flags;
+
+	dev_dbg(ddev->dev, "%s, event %p\n", __func__, crtc->state->event);
+
+	/* Turn vertical blanking interrupt reporting on. */
+	drm_crtc_vblank_on(crtc);
+
+	spin_lock_irqsave(&ddev->event_lock, flags);
+
+	if (crtc->state->event) {
+		drm_crtc_send_vblank_event(crtc, crtc->state->event);
+		crtc->state->event = NULL;
+	}
+
+	spin_unlock_irqrestore(&ddev->event_lock, flags);
+}
+
 static void tidss_crtc_atomic_disable(struct drm_crtc *crtc,
 				      struct drm_atomic_state *state)
 {
@@ -298,6 +364,27 @@
 	tidss_runtime_put(tidss);
 }
 
+static void tidss_shared_vp_crtc_atomic_disable(struct drm_crtc *crtc,
+						struct drm_atomic_state *state)
+{
+	struct tidss_crtc *tcrtc = to_tidss_crtc(crtc);
+	struct drm_device *ddev = crtc->dev;
+	unsigned long flags;
+
+	dev_dbg(ddev->dev, "%s, event %p\n", __func__, crtc->state->event);
+
+	reinit_completion(&tcrtc->framedone_completion);
+
+	spin_lock_irqsave(&ddev->event_lock, flags);
+	if (crtc->state->event) {
+		drm_crtc_send_vblank_event(crtc, crtc->state->event);
+		crtc->state->event = NULL;
+	}
+	spin_unlock_irqrestore(&ddev->event_lock, flags);
+
+	drm_crtc_vblank_off(crtc);
+}
+
 static
 enum drm_mode_status tidss_crtc_mode_valid(struct drm_crtc *crtc,
 					   const struct drm_display_mode *mode)
@@ -314,7 +401,14 @@
 	.atomic_flush = tidss_crtc_atomic_flush,
 	.atomic_enable = tidss_crtc_atomic_enable,
 	.atomic_disable = tidss_crtc_atomic_disable,
+	.mode_valid = tidss_crtc_mode_valid,
+};
 
+static const struct drm_crtc_helper_funcs tidss_shared_vp_crtc_helper_funcs = {
+	.atomic_check = tidss_crtc_atomic_check,
+	.atomic_flush = tidss_shared_vp_crtc_atomic_flush,
+	.atomic_enable = tidss_shared_vp_crtc_atomic_enable,
+	.atomic_disable = tidss_shared_vp_crtc_atomic_disable,
 	.mode_valid = tidss_crtc_mode_valid,
 };
 
@@ -416,6 +510,10 @@
 	bool has_ctm = tidss->feat->vp_feat.color.has_ctm;
 	int ret;
 
+	dev_dbg(tidss->dev, "%s: tidss->shared_mode: %d tidss->shared_mode_owned_vps[%d] = %d\n",
+		__func__, tidss->shared_mode, hw_videoport,
+		tidss->shared_mode_owned_vps[hw_videoport]);
+
 	tcrtc = kzalloc(sizeof(*tcrtc), GFP_KERNEL);
 	if (!tcrtc)
 		return ERR_PTR(-ENOMEM);
@@ -432,8 +530,17 @@
 		return ERR_PTR(ret);
 	}
 
-	drm_crtc_helper_add(crtc, &tidss_crtc_helper_funcs);
-
+	/* Use shared video port CRTC helpers which don't access associated
+	 * video port and overlay register spaces when Linux is not owning the
+	 * video port.
+	 */
+	if (tidss->shared_mode && !tidss->shared_mode_owned_vps[hw_videoport]) {
+		drm_crtc_helper_add(crtc, &tidss_shared_vp_crtc_helper_funcs);
+		dev_dbg(tidss->dev, "%s: vp%d is being shared with Linux\n", __func__,
+			hw_videoport + 1);
+	} else {
+		drm_crtc_helper_add(crtc, &tidss_crtc_helper_funcs);
+	}
 	/*
 	 * The dispc gamma functions adapt to what ever size we ask
 	 * from it no matter what HW supports. X-server assumes 256
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c
--- a/drivers/gpu/drm/tidss/tidss_dispc.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c	2025-10-23 09:30:40.285462207 -0400
@@ -136,6 +136,29 @@
 	[DISPC_SECURE_DISABLE_OFF] =		0xac,
 };
 
+static const u16 tidss_am62l_common_regs[DISPC_COMMON_REG_TABLE_LEN] = {
+	[DSS_REVISION_OFF] =			0x4,
+	[DSS_SYSCONFIG_OFF] =			0x8,
+	[DSS_SYSSTATUS_OFF] =			0x20,
+	[DISPC_IRQ_EOI_OFF] =			0x24,
+	[DISPC_IRQSTATUS_RAW_OFF] =		0x28,
+	[DISPC_IRQSTATUS_OFF] =			0x2c,
+	[DISPC_IRQENABLE_SET_OFF] =		0x30,
+	[DISPC_IRQENABLE_CLR_OFF] =		0x40,
+	[DISPC_VID_IRQENABLE_OFF] =		0x48,
+	[DISPC_VID_IRQSTATUS_OFF] =		0x5c,
+	[DISPC_VP_IRQENABLE_OFF] =		0x70,
+	[DISPC_VP_IRQSTATUS_OFF] =		0x7c,
+
+	[DISPC_GLOBAL_MFLAG_ATTRIBUTE_OFF] =	0x90,
+	[DISPC_GLOBAL_OUTPUT_ENABLE_OFF] =	0x94,
+	[DSS_CBA_CFG_OFF] =			0x9c,
+	[DISPC_DBG_CONTROL_OFF] =		0xa0,
+	[DISPC_DBG_STATUS_OFF] =		0xa4,
+	[DISPC_CLKGATING_DISABLE_OFF] =		0xa8,
+	[DISPC_SECURE_DISABLE_OFF] =		0xac,
+};
+
 const struct dispc_features dispc_am65x_feats = {
 	.max_pclk_khz = {
 		[DISPC_VP_DPI] = 165000,
@@ -273,6 +296,18 @@
 	.vid_order = { 1, 3, 0, 2 },
 };
 
+static const u16 tidss_am62_common1_regs[DISPC_COMMON_REG_TABLE_LEN] = {
+	[DISPC_IRQ_EOI_OFF] =			0x24,
+	[DISPC_IRQSTATUS_RAW_OFF] =		0x28,
+	[DISPC_IRQSTATUS_OFF] =			0x2c,
+	[DISPC_IRQENABLE_SET_OFF] =		0x30,
+	[DISPC_IRQENABLE_CLR_OFF] =		0x40,
+	[DISPC_VID_IRQENABLE_OFF] =		0x44,
+	[DISPC_VID_IRQSTATUS_OFF] =		0x58,
+	[DISPC_VP_IRQENABLE_OFF] =		0x70,
+	[DISPC_VP_IRQSTATUS_OFF] =		0x7c,
+};
+
 const struct dispc_features dispc_am625_feats = {
 	.max_pclk_khz = {
 		[DISPC_VP_DPI] = 165000,
@@ -376,6 +411,133 @@
 	.vid_order = { 1, 0 },
 };
 
+const struct dispc_features dispc_am62p51_feats = {
+	.max_pclk_khz = {
+		[DISPC_VP_DPI] = 165000,
+		[DISPC_VP_INTERNAL] = 300000,
+	},
+
+	.scaling = {
+		.in_width_max_5tap_rgb = 1280,
+		.in_width_max_3tap_rgb = 2560,
+		.in_width_max_5tap_yuv = 2560,
+		.in_width_max_3tap_yuv = 4096,
+		.upscale_limit = 16,
+		.downscale_limit_5tap = 4,
+		.downscale_limit_3tap = 2,
+		/*
+		 * The max supported pixel inc value is 255. The value
+		 * of pixel inc is calculated like this: 1+(xinc-1)*bpp.
+		 * The maximum bpp of all formats supported by the HW
+		 * is 8. So the maximum supported xinc value is 32,
+		 * because 1+(32-1)*8 < 255 < 1+(33-1)*4.
+		 */
+		.xinc_max = 32,
+	},
+
+	.subrev = DISPC_AM62P51,
+
+	.common = "common",
+	.common_regs = tidss_am65x_common_regs,
+
+	.num_vps = 2,
+	.vp_name = { "vp1", "vp2" },
+	.ovr_name = { "ovr1", "ovr2" },
+	.vpclk_name =  { "vp1", "vp2" },
+	.vp_bus_type = { DISPC_VP_INTERNAL, DISPC_VP_DPI },
+
+	.vp_feat = { .color = {
+			.has_ctm = true,
+			.gamma_size = 256,
+			.gamma_type = TIDSS_GAMMA_8BIT,
+		},
+	},
+
+	.num_planes = 2,
+	/* note: vid is plane_id 0 and vidl1 is plane_id 1 */
+	.vid_name = { "vid", "vidl1" },
+	.vid_lite = { false, true, },
+	.vid_order = { 1, 0 },
+};
+
+const struct dispc_features dispc_am62p52_feats = {
+	.max_pclk_khz = {
+		[DISPC_VP_DPI] = 165000,
+		[DISPC_VP_INTERNAL] = 300000,
+	},
+
+	.scaling = {
+		.in_width_max_5tap_rgb = 1280,
+		.in_width_max_3tap_rgb = 2560,
+		.in_width_max_5tap_yuv = 2560,
+		.in_width_max_3tap_yuv = 4096,
+		.upscale_limit = 16,
+		.downscale_limit_5tap = 4,
+		.downscale_limit_3tap = 2,
+		/*
+		 * The max supported pixel inc value is 255. The value
+		 * of pixel inc is calculated like this: 1+(xinc-1)*bpp.
+		 * The maximum bpp of all formats supported by the HW
+		 * is 8. So the maximum supported xinc value is 32,
+		 * because 1+(32-1)*8 < 255 < 1+(33-1)*4.
+		 */
+		.xinc_max = 32,
+	},
+
+	.subrev = DISPC_AM62P52,
+
+	.common = "common",
+	.common_regs = tidss_am65x_common_regs,
+
+	.num_vps = 2,
+	.vp_name = { "vp1", "vp2" },
+	.ovr_name = { "ovr1", "ovr2" },
+	.vpclk_name =  { "vp1", "vp2" },
+	.vp_bus_type = { DISPC_VP_INTERNAL, DISPC_VP_INTERNAL },
+
+	.vp_feat = { .color = {
+			.has_ctm = true,
+			.gamma_size = 256,
+			.gamma_type = TIDSS_GAMMA_8BIT,
+		},
+	},
+
+	.num_planes = 2,
+	/* note: vid is plane_id 0 and vidl1 is plane_id 1 */
+	.vid_name = { "vid", "vidl1" },
+	.vid_lite = { false, true, },
+	.vid_order = { 1, 0 },
+};
+
+const struct dispc_features dispc_am62l_feats = {
+	.max_pclk_khz = {
+		[DISPC_VP_DPI] = 165000,
+	},
+
+	.subrev = DISPC_AM62L,
+
+	.common = "common",
+	.common_regs = tidss_am62l_common_regs,
+
+	.num_vps = 1,
+	.vp_name = { "vp1" },
+	.ovr_name = { "ovr1" },
+	.vpclk_name =  { "vp1" },
+	.vp_bus_type = { DISPC_VP_DPI },
+
+	.vp_feat = { .color = {
+			.has_ctm = true,
+			.gamma_size = 256,
+			.gamma_type = TIDSS_GAMMA_8BIT,
+		},
+	},
+
+	.num_planes = 1,
+	.vid_name = { "vidl1" },
+	.vid_lite = { true },
+	.vid_order = { 0 },
+};
+
 static const u16 *dispc_common_regmap;
 
 struct dss_vp_data {
@@ -466,6 +628,25 @@
 	return ioread32(base + reg);
 }
 
+void tidss_configure_oldi(struct tidss_device *tidss, u32 hw_videoport,
+			  u32 oldi_cfg)
+{
+	u32 count = 0;
+	u32 oldi_reset_bit = BIT(5 + hw_videoport);
+
+	dispc_vp_write(tidss->dispc, hw_videoport, DISPC_VP_DSS_OLDI_CFG, oldi_cfg);
+
+	if (oldi_cfg != 0) {
+		while (!(oldi_reset_bit & dispc_read(tidss->dispc, DSS_SYSSTATUS)) &&
+		       count < 10000)
+			count++;
+
+		if (!(oldi_reset_bit & dispc_read(tidss->dispc, DSS_SYSSTATUS)))
+			dev_warn(tidss->dispc->dev, "%s: timeout waiting OLDI reset done\n",
+				 __func__);
+	}
+}
+
 /*
  * TRM gives bitfields as start:end, where start is the higher bit
  * number. For example 7:0
@@ -792,8 +973,6 @@
 		if (clearmask & DSS_IRQ_PLANE_MASK(i))
 			dispc_k3_vid_write_irqstatus(dispc, i, clearmask);
 	}
-	if (dispc->feat->subrev == DISPC_K2G)
-		return;
 
 	/* always clear the top level irqstatus */
 	dispc_write(dispc, DISPC_IRQSTATUS, dispc_read(dispc, DISPC_IRQSTATUS));
@@ -803,6 +982,41 @@
 }
 
 static
+void dispc_am62l_clear_irqstatus(struct dispc_device *dispc, dispc_irq_t clearmask)
+{
+	u32 top_clear = 0;
+
+	if (clearmask & DSS_IRQ_VP_MASK(0)) {
+		dispc_k3_vp_write_irqstatus(dispc, 0, clearmask);
+		top_clear |= BIT(0);
+	}
+
+	if (clearmask & DSS_IRQ_PLANE_MASK(0)) {
+		dispc_k3_vid_write_irqstatus(dispc, 0, clearmask);
+		top_clear |= BIT(5);
+	}
+
+	/* always clear the top level irqstatus */
+	dispc_write(dispc, DISPC_IRQSTATUS, dispc_read(dispc, DISPC_IRQSTATUS));
+
+	/* Flush posted writes */
+	dispc_read(dispc, DISPC_IRQSTATUS);
+}
+
+static
+dispc_irq_t dispc_am62l_read_and_clear_irqstatus(struct dispc_device *dispc)
+{
+	dispc_irq_t status = 0;
+
+	status |= dispc_k3_vp_read_irqstatus(dispc, 0);
+	status |= dispc_k3_vid_read_irqstatus(dispc, 0);
+
+	dispc_am62l_clear_irqstatus(dispc, status);
+
+	return status;
+}
+
+static
 dispc_irq_t dispc_k3_read_and_clear_irqstatus(struct dispc_device *dispc)
 {
 	dispc_irq_t status = 0;
@@ -833,6 +1047,39 @@
 	return enable;
 }
 
+static void dispc_am62l_set_irqenable(struct dispc_device *dispc,
+				      dispc_irq_t mask)
+{
+	u32 main_enable = 0, main_disable = 0;
+	dispc_irq_t old_mask;
+
+	old_mask = dispc_k3_read_irqenable(dispc);
+
+	/* clear the irqstatus for newly enabled irqs */
+	dispc_am62l_clear_irqstatus(dispc, (old_mask ^ mask) & mask);
+
+	dispc_k3_vp_set_irqenable(dispc, 0, mask);
+	if (mask & DSS_IRQ_VP_MASK(0))
+		main_enable |= BIT(0);		/* VP IRQ */
+	else
+		main_disable |= BIT(0);		/* VP IRQ */
+
+	dispc_k3_vid_set_irqenable(dispc, 0, mask);
+	if (mask & DSS_IRQ_PLANE_MASK(0))
+		main_enable |= BIT(5);	/* VIDL IRQ */
+	else
+		main_disable |= BIT(5);	/* VIDL IRQ */
+
+	if (main_enable)
+		dispc_write(dispc, DISPC_IRQENABLE_SET, main_enable);
+
+	if (main_disable)
+		dispc_write(dispc, DISPC_IRQENABLE_CLR, main_disable);
+
+	/* Flush posted writes */
+	dispc_read(dispc, DISPC_IRQENABLE_SET);
+}
+
 static void dispc_k3_set_irqenable(struct dispc_device *dispc,
 				   dispc_irq_t mask)
 {
@@ -879,8 +1126,12 @@
 	switch (dispc->feat->subrev) {
 	case DISPC_K2G:
 		return dispc_k2g_read_and_clear_irqstatus(dispc);
+	case DISPC_AM62L:
+		return dispc_am62l_read_and_clear_irqstatus(dispc);
 	case DISPC_AM625:
 	case DISPC_AM62A7:
+	case DISPC_AM62P51:
+	case DISPC_AM62P52:
 	case DISPC_AM65X:
 	case DISPC_J721E:
 		return dispc_k3_read_and_clear_irqstatus(dispc);
@@ -896,8 +1147,13 @@
 	case DISPC_K2G:
 		dispc_k2g_set_irqenable(dispc, mask);
 		break;
+	case DISPC_AM62L:
+		dispc_am62l_set_irqenable(dispc, mask);
+		break;
 	case DISPC_AM625:
 	case DISPC_AM62A7:
+	case DISPC_AM62P51:
+	case DISPC_AM62P52:
 	case DISPC_AM65X:
 	case DISPC_J721E:
 		dispc_k3_set_irqenable(dispc, mask);
@@ -1086,13 +1342,13 @@
 
 	dispc_set_num_datalines(dispc, hw_videoport, fmt->data_width);
 
-	hfp = mode->hsync_start - mode->hdisplay;
-	hsw = mode->hsync_end - mode->hsync_start;
-	hbp = mode->htotal - mode->hsync_end;
-
-	vfp = mode->vsync_start - mode->vdisplay;
-	vsw = mode->vsync_end - mode->vsync_start;
-	vbp = mode->vtotal - mode->vsync_end;
+	hfp = mode->crtc_hsync_start - mode->crtc_hdisplay;
+	hsw = mode->crtc_hsync_end - mode->crtc_hsync_start;
+	hbp = mode->crtc_htotal - mode->crtc_hsync_end;
+
+	vfp = mode->crtc_vsync_start - mode->crtc_vdisplay;
+	vsw = mode->crtc_vsync_end - mode->crtc_vsync_start;
+	vbp = mode->crtc_vtotal - mode->crtc_vsync_end;
 
 	dispc_vp_write(dispc, hw_videoport, DISPC_VP_TIMING_H,
 		       FLD_VAL(hsw - 1, 7, 0) |
@@ -1134,8 +1390,8 @@
 		       FLD_VAL(ivs, 12, 12));
 
 	dispc_vp_write(dispc, hw_videoport, DISPC_VP_SIZE_SCREEN,
-		       FLD_VAL(mode->hdisplay - 1, 11, 0) |
-		       FLD_VAL(mode->vdisplay - 1, 27, 16));
+		       FLD_VAL(mode->crtc_hdisplay - 1, 11, 0) |
+		       FLD_VAL(mode->crtc_vdisplay - 1, 27, 16));
 
 	VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, 1, 0, 0);
 }
@@ -1230,6 +1486,22 @@
 
 	max_pclk = dispc->feat->max_pclk_khz[bus_type];
 
+	/*
+	 * For shared mode, with remote core driving the video port, make sure that Linux
+	 * controlled primary plane doesn't exceed video port screen size set by remote core
+	 */
+	if (dispc->tidss->shared_mode && !dispc->tidss->shared_mode_owned_vps[hw_videoport]) {
+		int vp_hdisplay = VP_REG_GET(dispc, hw_videoport, DISPC_VP_SIZE_SCREEN, 11, 0) + 1;
+		int vp_vdisplay = VP_REG_GET(dispc, hw_videoport, DISPC_VP_SIZE_SCREEN, 27, 16) + 1;
+
+		if (mode->hdisplay > vp_hdisplay ||
+		    mode->vdisplay > vp_vdisplay) {
+			dev_err(dispc->dev, "%dx%d exceeds VP screen size %dx%d in shared mode\n",
+				mode->hdisplay, mode->vdisplay, vp_hdisplay, vp_vdisplay);
+			return MODE_BAD;
+		}
+	}
+
 	if (WARN_ON(max_pclk == 0))
 		return MODE_BAD;
 
@@ -1278,15 +1550,18 @@
 		return MODE_BAD_VVALUE;
 
 	if (dispc->memory_bandwidth_limit) {
-		const unsigned int bpp = 4;
-		u64 bandwidth;
+		if (!dispc->tidss->shared_mode ||
+		    dispc->tidss->shared_mode_owned_vps[hw_videoport]) {
+			const unsigned int bpp = 4;
+			u64 bandwidth;
+
+			bandwidth = 1000 * mode->clock;
+			bandwidth = bandwidth * mode->hdisplay * mode->vdisplay * bpp;
+			bandwidth = div_u64(bandwidth, mode->htotal * mode->vtotal);
 
-		bandwidth = 1000 * mode->clock;
-		bandwidth = bandwidth * mode->hdisplay * mode->vdisplay * bpp;
-		bandwidth = div_u64(bandwidth, mode->htotal * mode->vtotal);
-
-		if (dispc->memory_bandwidth_limit < bandwidth)
-			return MODE_BAD;
+			if (dispc->memory_bandwidth_limit < bandwidth)
+				return MODE_BAD;
+		}
 	}
 
 	return MODE_OK;
@@ -1312,7 +1587,6 @@
  * Calculate the percentage difference between the requested pixel clock rate
  * and the effective rate resulting from calculating the clock divider value.
  */
-static
 unsigned int dispc_pclk_diff(unsigned long rate, unsigned long real_rate)
 {
 	int r = rate / 100, rr = real_rate / 100;
@@ -1327,6 +1601,7 @@
 	unsigned long new_rate;
 
 	r = clk_set_rate(dispc->vp_clk[hw_videoport], rate);
+
 	if (r) {
 		dev_err(dispc->dev, "vp%d: failed to set clk rate to %lu\n",
 			hw_videoport, rate);
@@ -1356,6 +1631,17 @@
 			x | (y << 16));
 }
 
+static void dispc_am62l_ovr_set_plane(struct dispc_device *dispc,
+				      u32 x, u32 y)
+{
+	OVR_REG_FLD_MOD(dispc, 0, DISPC_OVR_ATTRIBUTES(0),
+			1, 4, 1);
+	OVR_REG_FLD_MOD(dispc, 0, DISPC_OVR_ATTRIBUTES(0),
+			x, 17, 6);
+	OVR_REG_FLD_MOD(dispc, 0, DISPC_OVR_ATTRIBUTES(0),
+			y, 30, 19);
+}
+
 static void dispc_am65x_ovr_set_plane(struct dispc_device *dispc,
 				      u32 hw_plane, u32 hw_videoport,
 				      u32 x, u32 y, u32 layer)
@@ -1388,8 +1674,13 @@
 		dispc_k2g_ovr_set_plane(dispc, hw_plane, hw_videoport,
 					x, y, layer);
 		break;
+	case DISPC_AM62L:
+		dispc_am62l_ovr_set_plane(dispc, x, y);
+		break;
 	case DISPC_AM625:
 	case DISPC_AM62A7:
+	case DISPC_AM62P51:
+	case DISPC_AM62P52:
 	case DISPC_AM65X:
 		dispc_am65x_ovr_set_plane(dispc, hw_plane, hw_videoport,
 					  x, y, layer);
@@ -2310,6 +2601,9 @@
 		break;
 	case DISPC_AM625:
 	case DISPC_AM62A7:
+	case DISPC_AM62L:
+	case DISPC_AM62P51:
+	case DISPC_AM62P52:
 	case DISPC_AM65X:
 	case DISPC_J721E:
 		dispc_k3_plane_init(dispc);
@@ -2418,6 +2712,9 @@
 		break;
 	case DISPC_AM625:
 	case DISPC_AM62A7:
+	case DISPC_AM62P51:
+	case DISPC_AM62P52:
+	case DISPC_AM62L:
 	case DISPC_AM65X:
 		dispc_am65x_vp_write_gamma_table(dispc, hw_videoport);
 		break;
@@ -2657,6 +2954,147 @@
 		dispc_k3_vp_set_ctm(dispc, hw_videoport, ctm);
 }
 
+static int get_vp_idx_from_vp(const char *vp_name)
+{
+	u32 vp_idx;
+
+	if (!strcmp("vp1", vp_name))
+		vp_idx = 0;
+	else if (!strcmp("vp2", vp_name))
+		vp_idx = 1;
+	else if (!strcmp("vp3", vp_name))
+		vp_idx = 2;
+	else if (!strcmp("vp4", vp_name))
+		vp_idx = 3;
+	else
+		return 0;
+
+	return vp_idx;
+}
+
+static const char *get_ovr_from_vp(const char *vp_name)
+{
+	const char *ovr_name = NULL;
+
+	if (!strcmp("vp1", vp_name))
+		ovr_name = "ovr1";
+	else if (!strcmp("vp2", vp_name))
+		ovr_name = "ovr2";
+	else if (!strcmp("vp3", vp_name))
+		ovr_name = "ovr3";
+	else if (!strcmp("vp4", vp_name))
+		ovr_name = "ovr4";
+	else
+		return NULL;
+
+	return ovr_name;
+}
+
+static void dispc_shared_mode_update_bus_type(struct dispc_features *shared_mode_feat,
+					      struct dispc_device *dispc)
+{
+	u32 i, vp_idx;
+	int num_vps = shared_mode_feat->num_vps;
+	enum dispc_vp_bus_type vp_bus_type[TIDSS_MAX_PORTS];
+
+	memcpy((void *)vp_bus_type, (void *)shared_mode_feat->vp_bus_type,
+	       sizeof(vp_bus_type));
+	memset(shared_mode_feat->vp_bus_type, 0, sizeof(vp_bus_type));
+
+	for (i = 0; i < num_vps; i++) {
+		/*
+		 * Find corresponding vp bus type.
+		 */
+		vp_idx = get_vp_idx_from_vp(shared_mode_feat->vp_name[i]);
+		shared_mode_feat->vp_bus_type[i] = vp_bus_type[vp_idx];
+	}
+}
+
+static int dispc_update_shared_mode_features(struct dispc_features *shared_mode_feat,
+					     struct dispc_device *dispc)
+{
+	int r = 0, i = 0;
+
+	dev_dbg(dispc->dev, "Start updating dispc feature list for shared mode:\n");
+
+	/*
+	 * Start with a shallow copy from existing features and prune the list
+	 * as per what is actually made available to Linux
+	 */
+	memcpy((void *)shared_mode_feat, (void *)dispc->feat, sizeof(*shared_mode_feat));
+	shared_mode_feat->num_vps = device_property_string_array_count(dispc->dev,
+								       "ti,dss-shared-mode-vp");
+	shared_mode_feat->num_planes = device_property_string_array_count(dispc->dev,
+									  "ti,dss-shared-mode-planes");
+
+	r = device_property_read_string(dispc->dev, "ti,dss-shared-mode-common",
+					(const char **)&shared_mode_feat->common);
+	if (r) {
+		dev_err(dispc->dev, "failed to read shared video port name: %d\n", r);
+		return r;
+	}
+
+	memset(shared_mode_feat->vid_name, 0, sizeof(shared_mode_feat->vid_name));
+	r = device_property_read_string_array(dispc->dev, "ti,dss-shared-mode-planes",
+					      shared_mode_feat->vid_name, TIDSS_MAX_PLANES);
+	if (r < 0) {
+		dev_err(dispc->dev, "failed to read client vid layer name: %d\n", r);
+		return r;
+	}
+
+	r = device_property_read_u32_array(dispc->dev, "ti,dss-shared-mode-vp-owned",
+					   dispc->tidss->shared_mode_owned_vps,
+					   shared_mode_feat->num_vps);
+	if (r < 0) {
+		dev_err(dispc->dev, "failed to read owned vp list: %d\n", r);
+		return r;
+	}
+
+	memset(shared_mode_feat->vp_name, 0, sizeof(shared_mode_feat->vp_name));
+	r = device_property_read_string_array(dispc->dev, "ti,dss-shared-mode-vp",
+					      shared_mode_feat->vp_name, TIDSS_MAX_PORTS);
+	if (r < 0) {
+		dev_err(dispc->dev, "failed to read shared video port name: %d\n", r);
+		return r;
+	}
+
+	memset(shared_mode_feat->vid_order, 0, sizeof(shared_mode_feat->vid_order));
+	r = device_property_read_u32_array(dispc->dev, "ti,dss-shared-mode-plane-zorder",
+					   shared_mode_feat->vid_order,
+					   shared_mode_feat->num_planes);
+	if (r < 0) {
+		dev_err(dispc->dev, "failed to read vid_order array name: %d\n", r);
+		return r;
+	}
+	memcpy((void *)shared_mode_feat->vpclk_name, (void *)shared_mode_feat->vp_name,
+	       sizeof(shared_mode_feat->vpclk_name));
+	memset(shared_mode_feat->ovr_name, 0, sizeof(shared_mode_feat->ovr_name));
+
+	for (i = 0; i < shared_mode_feat->num_vps; i++) {
+		shared_mode_feat->ovr_name[i] = get_ovr_from_vp(shared_mode_feat->vp_name[i]);
+		dev_dbg(dispc->dev, "vp[%d] = %s, ovr[%d] = %s vpclk[%d] = %s vp_owned[%d] = %d\n",
+			i,  shared_mode_feat->vp_name[i], i, shared_mode_feat->ovr_name[i], i,
+			shared_mode_feat->vpclk_name[i], i, dispc->tidss->shared_mode_owned_vps[i]);
+	}
+
+	for (i = 0; i < shared_mode_feat->num_planes; i++) {
+		if (!strncmp("vidl", shared_mode_feat->vid_name[i], 4))
+			shared_mode_feat->vid_lite[i] = true;
+		dev_dbg(dispc->dev, "vid[%d] = %s, vid_order[%d] = %u vid_lite[%d] = %u\n", i,
+			shared_mode_feat->vid_name[i], i, shared_mode_feat->vid_order[i], i,
+			shared_mode_feat->vid_lite[i]);
+	}
+
+	if (!strcmp(shared_mode_feat->common, "common1"))
+		shared_mode_feat->common_regs = tidss_am62_common1_regs;
+
+	dev_dbg(dispc->dev, "common : %s\n", shared_mode_feat->common);
+	dispc_shared_mode_update_bus_type(shared_mode_feat, dispc);
+	dev_dbg(dispc->dev, "Feature list updated for shared mode\n");
+
+	return 0;
+}
+
 void dispc_vp_setup(struct dispc_device *dispc, u32 hw_videoport,
 		    const struct drm_crtc_state *state, bool newmodeset)
 {
@@ -2664,10 +3102,28 @@
 	dispc_vp_set_color_mgmt(dispc, hw_videoport, state, newmodeset);
 }
 
+static bool dispc_is_idle(struct dispc_device *dispc)
+{
+	return REG_GET(dispc, DSS_SYSSTATUS, 9, 9);
+}
+
+static bool dispc_owns_global_common_in_shared_mode(struct dispc_device *dispc)
+{
+	if ((!strcmp(dispc->feat->common, "common") ||
+	     !strcmp(dispc->feat->common, "common_m")) &&
+	     dispc->tidss->shared_mode)
+		return true;
+	else
+		return false;
+}
+
 int dispc_runtime_suspend(struct dispc_device *dispc)
 {
 	dev_dbg(dispc->dev, "suspend\n");
 
+	if (!dispc_is_idle(dispc))
+		dev_warn(dispc->dev, "Bad HW state: DSS not idle when suspending");
+
 	dispc->is_enabled = false;
 
 	clk_disable_unprepare(dispc->fclk);
@@ -2681,6 +3137,9 @@
 
 	clk_prepare_enable(dispc->fclk);
 
+	if (!dispc_is_idle(dispc))
+		dev_warn(dispc->dev, "Bad HW state: DSS not idle when resuming");
+
 	if (REG_GET(dispc, DSS_SYSSTATUS, 0, 0) == 0)
 		dev_warn(dispc->dev, "DSS FUNC RESET not done!\n");
 
@@ -2771,10 +3230,10 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&dispc->tidss->wait_lock, flags);
+	spin_lock_irqsave(&dispc->tidss->irq_lock, flags);
 	dispc_set_irqenable(dispc, 0);
 	dispc_read_and_clear_irqstatus(dispc);
-	spin_unlock_irqrestore(&dispc->tidss->wait_lock, flags);
+	spin_unlock_irqrestore(&dispc->tidss->irq_lock, flags);
 
 	for (unsigned int vp_idx = 0; vp_idx < dispc->feat->num_vps; ++vp_idx)
 		VP_REG_FLD_MOD(dispc, vp_idx, DISPC_VP_CONTROL, 0, 0, 0);
@@ -2820,15 +3279,74 @@
 		goto err_runtime_suspend;
 	}
 
-	ret = dispc_softreset(dispc);
-	if (ret)
-		goto err_clk_disable;
+	dispc->tidss->boot_enabled_vp_mask = 0;
 
-	clk_disable_unprepare(dispc->fclk);
-	ret = pm_runtime_set_suspended(dev);
-	if (ret) {
-		dev_err(dev, "Failed to set DSS PM to suspended\n");
-		return ret;
+	/* HACK: If simple-framebuffer device is absent, then soft reset dispc even if it is not
+	 * idle. This is to avoid powering-off of DSS (which can happen due
+	 * to probe deferral waiting for child drivers) while DSS is active thus leading to system
+	 * hang.
+	 */
+	if (dispc_is_idle(dispc) || !dispc->tidss->simplefb_enabled) {
+		ret = dispc_softreset(dispc);
+		if (ret)
+			goto err_clk_disable;
+	} else {
+		for (u32 vp_idx = 0; vp_idx < dispc->feat->num_vps; vp_idx++) {
+			bool enabled = VP_REG_GET(dispc, vp_idx,
+						  DISPC_VP_CONTROL, 0, 0);
+
+			if (!enabled)
+				continue;
+
+			dispc->tidss->boot_enabled_vp_mask |= BIT(vp_idx);
+
+			/* Keep the VP clk enabled */
+			ret = clk_prepare_enable(dispc->vp_clk[vp_idx]);
+			if (ret) {
+				while (vp_idx--) {
+					if (!(dispc->tidss->boot_enabled_vp_mask &
+					      BIT(vp_idx)))
+						continue;
+
+					clk_disable_unprepare(dispc->vp_clk[vp_idx]);
+				}
+
+				goto err_clk_disable;
+			}
+		}
+
+		if (!dispc->tidss->boot_enabled_vp_mask) {
+			dev_warn(dev,
+				 "Bad HW state: DSS not idle but no VPs are enabled. Resetting.\n");
+			ret = dispc_softreset(dispc);
+			if (ret)
+				goto err_clk_disable;
+		} else {
+			/*
+			 * Do basic HW init here, which won't interrupt the
+			 * splash-screen.
+			 */
+
+			/* Ensure we won't get interrupts */
+			dispc_set_irqenable(dispc, 0);
+			dispc_read_and_clear_irqstatus(dispc);
+		}
+	}
+
+	if (dispc->tidss->boot_enabled_vp_mask) {
+		dev_dbg(dev,
+			"Bootloader splash-screen detected, leaving DSS active.\n");
+		pm_runtime_get_noresume(dev);
+	} else {
+		/*
+		 * No splash-screen. Disable the clock and set DSS back to suspended.
+		 */
+		clk_disable_unprepare(dispc->fclk);
+		ret = pm_runtime_set_suspended(dev);
+		if (ret) {
+			dev_err(dev, "Failed to set DSS PM to suspended\n");
+			return ret;
+		}
 	}
 
 	return 0;
@@ -2852,6 +3370,7 @@
 	struct platform_device *pdev = to_platform_device(dev);
 	struct dispc_device *dispc;
 	const struct dispc_features *feat;
+	struct dispc_features *shared_mode_feat;
 	unsigned int i, num_fourccs;
 	int r = 0;
 
@@ -2893,6 +3412,21 @@
 
 	dispc->num_fourccs = num_fourccs;
 
+	if (tidss->shared_mode) {
+		dev_dbg(dev, "%s : DSS is being shared with remote core\n", __func__);
+		shared_mode_feat = devm_kzalloc(dev, sizeof(*shared_mode_feat), GFP_KERNEL);
+		if (!shared_mode_feat)
+			return -ENOMEM;
+
+		r = dispc_update_shared_mode_features(shared_mode_feat, dispc);
+		if (r)
+			return r;
+
+		tidss->feat = (const struct dispc_features *)shared_mode_feat;
+		feat = tidss->feat;
+		dispc->feat = feat;
+	}
+
 	dispc_common_regmap = dispc->feat->common_regs;
 
 	r = dispc_iomap_resource(pdev, dispc->feat->common,
@@ -2939,27 +3473,74 @@
 	}
 
 	if (feat->subrev == DISPC_AM65X) {
-		r = dispc_init_am65x_oldi_io_ctrl(dev, dispc);
-		if (r)
-			return r;
+		/*
+		 * For shared mode, Initialize the OLDI IO control only if we own
+		 * the OLDI Tx ports
+		 */
+		if (!tidss->shared_mode || tidss->shared_mode_own_oldi) {
+			r = dispc_init_am65x_oldi_io_ctrl(dev, dispc);
+			if (r)
+				return r;
+		}
 	}
 
-	dispc->fclk = devm_clk_get(dev, "fck");
-	if (IS_ERR(dispc->fclk)) {
-		dev_err(dev, "%s: Failed to get fclk: %ld\n",
-			__func__, PTR_ERR(dispc->fclk));
-		return PTR_ERR(dispc->fclk);
-	}
-	dev_dbg(dev, "DSS fclk %lu Hz\n", clk_get_rate(dispc->fclk));
+	/*
+	 * For shared mode, Initialize the hardware and clocking only if processing core running
+	 * Linux has ownership of DSS global register space
+	 */
+	if (!tidss->shared_mode || dispc_owns_global_common_in_shared_mode(dispc)) {
+		dispc->fclk = devm_clk_get(dev, "fck");
+		if (IS_ERR(dispc->fclk)) {
+			dev_err(dev, "%s: Failed to get fclk: %ld\n",
+				__func__, PTR_ERR(dispc->fclk));
+			return PTR_ERR(dispc->fclk);
+		}
+		dev_dbg(dev, "DSS fclk %lu Hz\n", clk_get_rate(dispc->fclk));
 
-	of_property_read_u32(dispc->dev->of_node, "max-memory-bandwidth",
-			     &dispc->memory_bandwidth_limit);
+		of_property_read_u32(dispc->dev->of_node, "max-memory-bandwidth",
+				     &dispc->memory_bandwidth_limit);
 
-	r = dispc_init_hw(dispc);
-	if (r)
-		return r;
+		r = dispc_init_hw(dispc);
+		if (r)
+			return r;
+	}
 
 	tidss->dispc = dispc;
 
 	return 0;
 }
+
+void dispc_splash_fini(struct dispc_device *dispc)
+{
+	if (WARN_ON(!dispc->tidss->boot_enabled_vp_mask))
+		return;
+
+	/*
+	 * Do a reset now, to clean up the bootloader setup, as we're about to
+	 * do a modeset.
+	 */
+	dispc_softreset(dispc);
+
+	/*
+	 * Call resume manually. This will clk_prepare_enable() the fclk, and do
+	 * the common basic HW configuration.
+	 */
+	dispc_runtime_resume(dispc);
+
+	/*
+	 * Call clk_disable_unprepare() to counter the clk_prepare_enable() we
+	 * did in the dispc_check_hw_state(). The fclk will still be enabled,
+	 * as the dispc_runtime_resume() above does a clk_prepare_enable().
+	 */
+	clk_disable_unprepare(dispc->fclk);
+
+	for (u32 vp_idx = 0; vp_idx < dispc->feat->num_vps; vp_idx++) {
+		if (dispc->tidss->boot_enabled_vp_mask & BIT(vp_idx))
+			clk_disable_unprepare(dispc->vp_clk[vp_idx]);
+	}
+
+	/* counter the pm_runtime_get_noresume() */
+	pm_runtime_put_noidle(dispc->dev);
+
+	dispc->tidss->boot_enabled_vp_mask = 0;
+}
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/tidss_dispc.h
--- a/drivers/gpu/drm/tidss/tidss_dispc.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/tidss/tidss_dispc.h	2025-10-23 09:30:40.285462207 -0400
@@ -62,6 +62,9 @@
 	DISPC_K2G,
 	DISPC_AM625,
 	DISPC_AM62A7,
+	DISPC_AM62P51,
+	DISPC_AM62P52,
+	DISPC_AM62L,
 	DISPC_AM65X,
 	DISPC_J721E,
 };
@@ -80,7 +83,7 @@
 	const char *vp_name[TIDSS_MAX_PORTS]; /* Should match dt reg names */
 	const char *ovr_name[TIDSS_MAX_PORTS]; /* Should match dt reg names */
 	const char *vpclk_name[TIDSS_MAX_PORTS]; /* Should match dt clk names */
-	const enum dispc_vp_bus_type vp_bus_type[TIDSS_MAX_PORTS];
+	enum dispc_vp_bus_type vp_bus_type[TIDSS_MAX_PORTS];
 	struct tidss_vp_feat vp_feat;
 	u32 num_planes;
 	const char *vid_name[TIDSS_MAX_PLANES]; /* Should match dt reg names */
@@ -91,9 +94,16 @@
 extern const struct dispc_features dispc_k2g_feats;
 extern const struct dispc_features dispc_am625_feats;
 extern const struct dispc_features dispc_am62a7_feats;
+extern const struct dispc_features dispc_am62l_feats;
+extern const struct dispc_features dispc_am62p51_feats;
+extern const struct dispc_features dispc_am62p52_feats;
 extern const struct dispc_features dispc_am65x_feats;
 extern const struct dispc_features dispc_j721e_feats;
 
+void tidss_configure_oldi(struct tidss_device *tidss, u32 hw_videoport,
+			  u32 oldi_cfg);
+unsigned int dispc_pclk_diff(unsigned long rate, unsigned long real_rate);
+
 void dispc_set_irqenable(struct dispc_device *dispc, dispc_irq_t mask);
 dispc_irq_t dispc_read_and_clear_irqstatus(struct dispc_device *dispc);
 
@@ -137,4 +147,6 @@
 int dispc_init(struct tidss_device *tidss);
 void dispc_remove(struct tidss_device *tidss);
 
+void dispc_splash_fini(struct dispc_device *dispc);
+
 #endif
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/tidss_dispc_regs.h b/drivers/gpu/drm/tidss/tidss_dispc_regs.h
--- a/drivers/gpu/drm/tidss/tidss_dispc_regs.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/tidss/tidss_dispc_regs.h	2025-10-23 09:30:40.285462207 -0400
@@ -226,6 +226,20 @@
 #define DISPC_VP_DSS_DMA_THREADSIZE		0x170 /* J721E */
 #define DISPC_VP_DSS_DMA_THREADSIZE_STATUS	0x174 /* J721E */
 
+/* OLDI Config Bits (DISPC_VP_DSS_OLDI_CFG) */
+#define OLDI_ENABLE		BIT(0)
+#define OLDI_MAP		(BIT(1) | BIT(2) | BIT(3))
+#define OLDI_SRC		BIT(4)
+#define OLDI_CLONE_MODE		BIT(5)
+#define OLDI_MASTERSLAVE	BIT(6)
+#define OLDI_DEPOL		BIT(7)
+#define OLDI_MSB		BIT(8)
+#define OLDI_LBEN		BIT(9)
+#define OLDI_LBDATA		BIT(10)
+#define OLDI_DUALMODESYNC	BIT(11)
+#define OLDI_SOFTRST		BIT(12)
+#define OLDI_TPATCFG		BIT(13)
+
 /*
  * OLDI IO_CTRL register offsets. On AM654 the registers are found
  * from CTRL_MMR0, there the syscon regmap should map 0x14 bytes from
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
--- a/drivers/gpu/drm/tidss/tidss_drv.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/tidss/tidss_drv.c	2025-10-23 09:30:40.285462207 -0400
@@ -8,6 +8,7 @@
 #include <linux/of.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
+#include <linux/pm_domain.h>
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
@@ -23,6 +24,7 @@
 #include "tidss_drv.h"
 #include "tidss_kms.h"
 #include "tidss_irq.h"
+#include "tidss_oldi.h"
 
 /* Power management */
 
@@ -32,9 +34,27 @@
 
 	dev_dbg(tidss->dev, "%s\n", __func__);
 
+	/* No PM in display sharing mode */
+	if (tidss->shared_mode)
+		return 0;
+
 	r = pm_runtime_resume_and_get(tidss->dev);
-	WARN_ON(r < 0);
-	return r;
+	if (WARN_ON(r < 0))
+		return r;
+
+	if (tidss->boot_enabled_vp_mask) {
+		/*
+		 * If 'boot_enabled_vp_mask' is set, it means that the DSS is
+		 * enabled and bootloader splash-screen is still on the screen,
+		 * using bootloader's DSS HW config.
+		 *
+		 * This is the first time the driver is about to use the HW, and
+		 * we need to do some cleanup and initial setup.
+		 */
+		dispc_splash_fini(tidss->dispc);
+	}
+
+	return 0;
 }
 
 void tidss_runtime_put(struct tidss_device *tidss)
@@ -43,6 +63,9 @@
 
 	dev_dbg(tidss->dev, "%s\n", __func__);
 
+	if (tidss->shared_mode)
+		return;
+
 	pm_runtime_mark_last_busy(tidss->dev);
 
 	r = pm_runtime_put_autosuspend(tidss->dev);
@@ -116,6 +139,95 @@
 	.minor			= 0,
 };
 
+static int tidss_detach_pm_domains(struct tidss_device *tidss)
+{
+	int i;
+
+	if (tidss->num_domains <= 1)
+		return 0;
+
+	for (i = 0; i < tidss->num_domains; i++) {
+		if (tidss->pd_link[i] && !IS_ERR(tidss->pd_link[i]))
+			device_link_del(tidss->pd_link[i]);
+		if (tidss->pd_dev[i] && !IS_ERR(tidss->pd_dev[i]))
+			dev_pm_domain_detach(tidss->pd_dev[i], true);
+		tidss->pd_dev[i] = NULL;
+		tidss->pd_link[i] = NULL;
+	}
+
+	return 0;
+}
+
+static int tidss_attach_pm_domains(struct tidss_device *tidss)
+{
+	struct device *dev = tidss->dev;
+	int i;
+	int ret;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct device_node *np = pdev->dev.of_node;
+
+	tidss->num_domains = of_count_phandle_with_args(np, "power-domains",
+							"#power-domain-cells");
+	if (tidss->num_domains <= 1) {
+		dev_dbg(dev, "One or less power domains, no need to do attach domains\n");
+		return 0;
+	}
+
+	tidss->pd_dev = devm_kmalloc_array(dev, tidss->num_domains,
+					   sizeof(*tidss->pd_dev), GFP_KERNEL);
+	if (!tidss->pd_dev)
+		return -ENOMEM;
+
+	tidss->pd_link = devm_kmalloc_array(dev, tidss->num_domains,
+					    sizeof(*tidss->pd_link), GFP_KERNEL);
+	if (!tidss->pd_link)
+		return -ENOMEM;
+
+	for (i = 0; i < tidss->num_domains; i++) {
+		tidss->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
+		if (IS_ERR(tidss->pd_dev[i])) {
+			ret = PTR_ERR(tidss->pd_dev[i]);
+			goto fail;
+		}
+
+		tidss->pd_link[i] = device_link_add(dev, tidss->pd_dev[i],
+						    DL_FLAG_STATELESS |
+						    DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
+		if (!tidss->pd_link[i]) {
+			ret = -EINVAL;
+			goto fail;
+		}
+	}
+
+	return 0;
+fail:
+	tidss_detach_pm_domains(tidss);
+	return ret;
+}
+
+static void check_for_simplefb_device(struct tidss_device *tidss)
+{
+	if (IS_ENABLED(CONFIG_FB_SIMPLE)) {
+		struct device *simplefb_dev;
+		struct device_node *simplefb_node;
+
+		simplefb_node = of_find_compatible_node(NULL, NULL, "simple-framebuffer");
+		if (!simplefb_node)
+			return;
+
+		simplefb_dev = bus_find_device_by_of_node(&platform_bus_type, simplefb_node);
+		if (!simplefb_dev) {
+			of_node_put(simplefb_node);
+			return;
+		}
+
+		tidss->simplefb_enabled = true;
+		dev_dbg(tidss->dev, "simple-framebuffer detected\n");
+		put_device(simplefb_dev);
+		of_node_put(simplefb_node);
+	}
+}
+
 static int tidss_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -138,23 +250,41 @@
 
 	platform_set_drvdata(pdev, tidss);
 
-	spin_lock_init(&tidss->wait_lock);
+	spin_lock_init(&tidss->irq_lock);
+
+	tidss->shared_mode = device_property_read_bool(dev, "ti,dss-shared-mode");
+	if (!tidss->shared_mode) {
+		/* powering up associated OLDI domains */
+		ret = tidss_attach_pm_domains(tidss);
+		if (ret < 0) {
+			dev_err(dev, "failed to attach power domains %d\n", ret);
+			goto err_detach_pm_domains;
+		}
+	}
 
 	ret = dispc_init(tidss);
 	if (ret) {
 		dev_err(dev, "failed to initialize dispc: %d\n", ret);
-		return ret;
+		goto err_detach_pm_domains;
 	}
 
-	pm_runtime_enable(dev);
+	check_for_simplefb_device(tidss);
 
-	pm_runtime_set_autosuspend_delay(dev, 1000);
-	pm_runtime_use_autosuspend(dev);
+	ret = tidss_oldi_init(tidss);
+	if (ret) {
+		dev_dbg(dev, "failed to init OLDI: %d\n", ret);
+		goto err_oldi_deinit;
+	}
 
+	if (!tidss->shared_mode) {
+		pm_runtime_enable(dev);
+		pm_runtime_set_autosuspend_delay(dev, 1000);
+		pm_runtime_use_autosuspend(dev);
 #ifndef CONFIG_PM
-	/* If we don't have PM, we need to call resume manually */
-	dispc_runtime_resume(tidss->dispc);
+		/* If we don't have PM, we need to call resume manually */
+		dispc_runtime_resume(tidss->dispc);
 #endif
+	}
 
 	ret = tidss_modeset_init(tidss);
 	if (ret < 0) {
@@ -196,12 +326,20 @@
 	tidss_irq_uninstall(ddev);
 
 err_runtime_suspend:
+	if (tidss->shared_mode)
+		return ret;
 #ifndef CONFIG_PM
 	dispc_runtime_suspend(tidss->dispc);
 #endif
 	pm_runtime_dont_use_autosuspend(dev);
 	pm_runtime_disable(dev);
 
+err_oldi_deinit:
+	tidss_oldi_deinit(tidss);
+
+err_detach_pm_domains:
+	tidss_detach_pm_domains(tidss);
+
 	return ret;
 }
 
@@ -219,16 +357,21 @@
 
 	tidss_irq_uninstall(ddev);
 
+	if (!tidss->shared_mode) {
 #ifndef CONFIG_PM
-	/* If we don't have PM, we need to call suspend manually */
-	dispc_runtime_suspend(tidss->dispc);
+		/* If we don't have PM, we need to call suspend manually */
+		dispc_runtime_suspend(tidss->dispc);
 #endif
-	pm_runtime_dont_use_autosuspend(dev);
-	pm_runtime_disable(dev);
+		pm_runtime_dont_use_autosuspend(dev);
+		pm_runtime_disable(dev);
+	}
+
+	tidss_oldi_deinit(tidss);
 
 	/* devm allocated dispc goes away with the dev so mark it NULL */
 	dispc_remove(tidss);
 
+	tidss_detach_pm_domains(tidss);
 	dev_dbg(dev, "%s done\n", __func__);
 }
 
@@ -241,6 +384,9 @@
 	{ .compatible = "ti,k2g-dss", .data = &dispc_k2g_feats, },
 	{ .compatible = "ti,am625-dss", .data = &dispc_am625_feats, },
 	{ .compatible = "ti,am62a7-dss", .data = &dispc_am62a7_feats, },
+	{ .compatible = "ti,am62l-dss", .data = &dispc_am62l_feats, },
+	{ .compatible = "ti,am62p51-dss", .data = &dispc_am62p51_feats, },
+	{ .compatible = "ti,am62p52-dss", .data = &dispc_am62p52_feats, },
 	{ .compatible = "ti,am65x-dss", .data = &dispc_am65x_feats, },
 	{ .compatible = "ti,j721e-dss", .data = &dispc_j721e_feats, },
 	{ }
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h
--- a/drivers/gpu/drm/tidss/tidss_drv.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/tidss/tidss_drv.h	2025-10-23 09:30:40.285462207 -0400
@@ -11,8 +11,10 @@
 
 #define TIDSS_MAX_PORTS 4
 #define TIDSS_MAX_PLANES 4
+#define TIDSS_MAX_OLDI_TXES 2
 
 typedef u32 dispc_irq_t;
+struct tidss_oldi;
 
 struct tidss_device {
 	struct drm_device ddev;		/* DRM device for DSS */
@@ -27,10 +29,26 @@
 	unsigned int num_planes;
 	struct drm_plane *planes[TIDSS_MAX_PLANES];
 
+	unsigned int num_oldis;
+	struct tidss_oldi *oldis[TIDSS_MAX_OLDI_TXES];
+
 	unsigned int irq;
 
-	spinlock_t wait_lock;	/* protects the irq masks */
-	dispc_irq_t irq_mask;	/* enabled irqs in addition to wait_list */
+	/* protects the irq masks field and irqenable/irqstatus registers */
+	spinlock_t irq_lock;
+	dispc_irq_t irq_mask;	/* enabled irqs */
+
+	bool shared_mode; /* DSS resources shared between remote core and Linux */
+	/* 1: VP owned by Linux 0: VP is owned by remote and shared with Linux */
+	u32 shared_mode_owned_vps[TIDSS_MAX_PORTS];
+	bool shared_mode_own_oldi; /* Linux needs to configure OLDI in shared mode */
+
+	int num_domains; /* Handle attached PM domains */
+	struct device **pd_dev;
+	struct device_link **pd_link;
+
+	u32 boot_enabled_vp_mask;
+	bool simplefb_enabled;
 };
 
 #define to_tidss(__dev) container_of(__dev, struct tidss_device, ddev)
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/tidss_irq.c b/drivers/gpu/drm/tidss/tidss_irq.c
--- a/drivers/gpu/drm/tidss/tidss_irq.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/tidss/tidss_irq.c	2025-10-23 09:30:40.285462207 -0400
@@ -15,10 +15,9 @@
 #include "tidss_irq.h"
 #include "tidss_plane.h"
 
-/* call with wait_lock and dispc runtime held */
 static void tidss_irq_update(struct tidss_device *tidss)
 {
-	assert_spin_locked(&tidss->wait_lock);
+	assert_spin_locked(&tidss->irq_lock);
 
 	dispc_set_irqenable(tidss->dispc, tidss->irq_mask);
 }
@@ -31,11 +30,11 @@
 	u32 hw_videoport = tcrtc->hw_videoport;
 	unsigned long flags;
 
-	spin_lock_irqsave(&tidss->wait_lock, flags);
+	spin_lock_irqsave(&tidss->irq_lock, flags);
 	tidss->irq_mask |= DSS_IRQ_VP_VSYNC_EVEN(hw_videoport) |
 			   DSS_IRQ_VP_VSYNC_ODD(hw_videoport);
 	tidss_irq_update(tidss);
-	spin_unlock_irqrestore(&tidss->wait_lock, flags);
+	spin_unlock_irqrestore(&tidss->irq_lock, flags);
 }
 
 void tidss_irq_disable_vblank(struct drm_crtc *crtc)
@@ -46,11 +45,11 @@
 	u32 hw_videoport = tcrtc->hw_videoport;
 	unsigned long flags;
 
-	spin_lock_irqsave(&tidss->wait_lock, flags);
+	spin_lock_irqsave(&tidss->irq_lock, flags);
 	tidss->irq_mask &= ~(DSS_IRQ_VP_VSYNC_EVEN(hw_videoport) |
 			     DSS_IRQ_VP_VSYNC_ODD(hw_videoport));
 	tidss_irq_update(tidss);
-	spin_unlock_irqrestore(&tidss->wait_lock, flags);
+	spin_unlock_irqrestore(&tidss->irq_lock, flags);
 }
 
 static irqreturn_t tidss_irq_handler(int irq, void *arg)
@@ -60,9 +59,9 @@
 	unsigned int id;
 	dispc_irq_t irqstatus;
 
-	spin_lock(&tidss->wait_lock);
+	spin_lock(&tidss->irq_lock);
 	irqstatus = dispc_read_and_clear_irqstatus(tidss->dispc);
-	spin_unlock(&tidss->wait_lock);
+	spin_unlock(&tidss->irq_lock);
 
 	for (id = 0; id < tidss->num_crtcs; id++) {
 		struct drm_crtc *crtc = tidss->crtcs[id];
@@ -80,8 +79,13 @@
 			tidss_crtc_error_irq(crtc, irqstatus);
 	}
 
-	if (irqstatus & DSS_IRQ_DEVICE_OCP_ERR)
-		dev_err_ratelimited(tidss->dev, "OCP error\n");
+	for (unsigned int i = 0; i < tidss->num_planes; ++i) {
+		struct drm_plane *plane = tidss->planes[i];
+		struct tidss_plane *tplane = to_tidss_plane(plane);
+
+		if (irqstatus & DSS_IRQ_PLANE_FIFO_UNDERFLOW(tplane->hw_plane_id))
+			tidss_plane_error_irq(plane, irqstatus);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -90,9 +94,9 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&tidss->wait_lock, flags);
+	spin_lock_irqsave(&tidss->irq_lock, flags);
 	tidss_irq_update(tidss);
-	spin_unlock_irqrestore(&tidss->wait_lock, flags);
+	spin_unlock_irqrestore(&tidss->irq_lock, flags);
 }
 
 int tidss_irq_install(struct drm_device *ddev, unsigned int irq)
@@ -107,7 +111,7 @@
 	if (ret)
 		return ret;
 
-	tidss->irq_mask = DSS_IRQ_DEVICE_OCP_ERR;
+	tidss->irq_mask = 0;
 
 	for (unsigned int i = 0; i < tidss->num_crtcs; ++i) {
 		struct tidss_crtc *tcrtc = to_tidss_crtc(tidss->crtcs[i]);
@@ -117,6 +121,12 @@
 		tidss->irq_mask |= DSS_IRQ_VP_FRAME_DONE(tcrtc->hw_videoport);
 	}
 
+	for (unsigned int i = 0; i < tidss->num_planes; ++i) {
+		struct tidss_plane *tplane = to_tidss_plane(tidss->planes[i]);
+
+		tidss->irq_mask |= DSS_IRQ_PLANE_FIFO_UNDERFLOW(tplane->hw_plane_id);
+	}
+
 	return 0;
 }
 
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/tidss_irq.h b/drivers/gpu/drm/tidss/tidss_irq.h
--- a/drivers/gpu/drm/tidss/tidss_irq.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/tidss/tidss_irq.h	2025-10-23 09:30:40.285462207 -0400
@@ -19,15 +19,13 @@
  * bit use   |D  |fou|FEOL|FEOL|FEOL|FEOL|  UUUU  |          |
  * bit number|0  |1-3|4-7 |8-11|  12-19  | 20-23  |  24-31   |
  *
- * device bits:	D = OCP error
+ * device bits:	D = Unused
  * WB bits:	f = frame done wb, o = wb buffer overflow,
  *		u = wb buffer uncomplete
  * vp bits:	F = frame done, E = vsync even, O = vsync odd, L = sync lost
  * plane bits:	U = fifo underflow
  */
 
-#define DSS_IRQ_DEVICE_OCP_ERR			BIT(0)
-
 #define DSS_IRQ_DEVICE_FRAMEDONEWB		BIT(1)
 #define DSS_IRQ_DEVICE_WBBUFFEROVERFLOW		BIT(2)
 #define DSS_IRQ_DEVICE_WBUNCOMPLETEERROR	BIT(3)
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/tidss_oldi.c b/drivers/gpu/drm/tidss/tidss_oldi.c
--- a/drivers/gpu/drm/tidss/tidss_oldi.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/gpu/drm/tidss/tidss_oldi.c	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,543 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 - Texas Instruments Incorporated
+ *
+ * Aradhya Bhatia <a-bhatia1@ti.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/mfd/syscon.h>
+#include <linux/media-bus-format.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_of.h>
+
+#include "tidss_dispc.h"
+#include "tidss_dispc_regs.h"
+#include "tidss_oldi.h"
+
+struct tidss_oldi {
+	struct tidss_device	*tidss;
+	struct device		*dev;
+
+	struct drm_bridge	bridge;
+	struct drm_bridge	*next_bridge;
+
+	enum tidss_oldi_link_type link_type;
+	const struct oldi_bus_format *bus_format;
+	u32 oldi_instance;
+	u32 companion_instance;
+	u32 parent_vp;
+
+	struct clk *serial;
+	struct regmap *io_ctrl;
+};
+
+static const struct oldi_bus_format oldi_bus_formats[] = {
+	{ MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,	18, SPWG_18,	MEDIA_BUS_FMT_RGB666_1X18 },
+	{ MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,	24, SPWG_24,	MEDIA_BUS_FMT_RGB888_1X24 },
+	{ MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,	24, JEIDA_24,	MEDIA_BUS_FMT_RGB888_1X24 },
+};
+
+#define OLDI_IDLE_CLK_HZ	25000000 /*25 MHz */
+
+static inline struct tidss_oldi *
+drm_bridge_to_tidss_oldi(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct tidss_oldi, bridge);
+}
+
+static int tidss_oldi_bridge_attach(struct drm_bridge *bridge,
+				    enum drm_bridge_attach_flags flags)
+{
+	struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge);
+
+	if (!oldi->next_bridge) {
+		dev_err(oldi->dev,
+			"%s: OLDI%u Failure attach next bridge\n",
+			__func__, oldi->oldi_instance);
+		return -ENODEV;
+	}
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		dev_err(oldi->dev,
+			"%s: OLDI%u DRM_BRIDGE_ATTACH_NO_CONNECTOR is mandatory.\n",
+			__func__, oldi->oldi_instance);
+		return -EINVAL;
+	}
+
+	return drm_bridge_attach(bridge->encoder, oldi->next_bridge,
+				 bridge, flags);
+}
+
+static int
+tidss_oldi_set_serial_clk(struct tidss_oldi *oldi, unsigned long rate)
+{
+	unsigned long new_rate;
+	int ret;
+
+	ret = clk_set_rate(oldi->serial, rate);
+	if (ret) {
+		dev_err(oldi->dev,
+			"OLDI%u: failed to set serial clk rate to %lu Hz\n",
+			 oldi->oldi_instance, rate);
+		return ret;
+	}
+
+	new_rate = clk_get_rate(oldi->serial);
+
+	if (dispc_pclk_diff(rate, new_rate) > 5)
+		dev_warn(oldi->dev,
+			 "OLDI%u Clock rate %lu differs over 5%% from requested %lu\n",
+			 oldi->oldi_instance, new_rate, rate);
+
+	dev_dbg(oldi->dev, "OLDI%u: new rate %lu Hz (requested %lu Hz)\n",
+		oldi->oldi_instance, clk_get_rate(oldi->serial), rate);
+
+	return 0;
+}
+
+static void tidss_oldi_tx_power(struct tidss_oldi *oldi, bool enable)
+{
+	u32 mask;
+
+	/*
+	 * The power control bits are Active Low, and remain powered off by
+	 * default. That is, the bits are set to 1. To power on the OLDI TXes,
+	 * the bits must be cleared to 0. Since there are cases where not all
+	 * OLDI TXes are being used, the power logic selectively powers them
+	 * on.
+	 * Setting the variable 'val' to particular bit masks, makes sure that
+	 * the unrequired OLDI TXes remain powered off.
+	 */
+
+	if (enable) {
+		switch (oldi->link_type) {
+		case OLDI_MODE_SINGLE_LINK:
+			/* Power-on only the required OLDI TX's IO*/
+			mask = OLDI_PWRDOWN_TX(oldi->oldi_instance) | OLDI_PWRDN_BG;
+			break;
+		case OLDI_MODE_CLONE_SINGLE_LINK:
+		case OLDI_MODE_DUAL_LINK:
+			/* Power-on both the OLDI TXes' IOs */
+			mask = OLDI_PWRDOWN_TX(oldi->oldi_instance) |
+			       OLDI_PWRDOWN_TX(oldi->companion_instance) |
+			       OLDI_PWRDN_BG;
+			break;
+		default:
+			/*
+			 * This code execution should never reach here as any
+			 * OLDI with an unsupported OLDI mode would never get
+			 * registered in the first place.
+			 * However, power-off the OLDI in concern just in case.
+			 */
+			mask = OLDI_PWRDOWN_TX(oldi->oldi_instance);
+			enable = false;
+			break;
+		}
+	} else {
+		switch (oldi->link_type) {
+		case OLDI_MODE_CLONE_SINGLE_LINK:
+		case OLDI_MODE_DUAL_LINK:
+			mask = OLDI_PWRDOWN_TX(oldi->oldi_instance) |
+			       OLDI_PWRDOWN_TX(oldi->companion_instance) |
+			       OLDI_PWRDN_BG;
+			break;
+		case OLDI_MODE_SINGLE_LINK:
+		default:
+			mask = OLDI_PWRDOWN_TX(oldi->oldi_instance);
+			break;
+		}
+	}
+
+	regmap_update_bits(oldi->io_ctrl, OLDI_PD_CTRL, mask, enable ? 0 : mask);
+}
+
+static int tidss_oldi_config(struct tidss_oldi *oldi)
+{
+	const struct oldi_bus_format *bus_fmt = NULL;
+	u32 oldi_cfg = 0;
+
+	bus_fmt = oldi->bus_format;
+
+	/*
+	 * MASTERSLAVE and SRC bits of OLDI Config are always set to 0.
+	 */
+
+	if (bus_fmt->data_width == 24)
+		oldi_cfg |= OLDI_MSB;
+	else if (bus_fmt->data_width != 18)
+		dev_warn(oldi->dev,
+			 "OLDI%u: DSS port width %d not supported\n",
+			 oldi->oldi_instance, bus_fmt->data_width);
+
+	oldi_cfg |= OLDI_DEPOL;
+
+	oldi_cfg = (oldi_cfg & (~OLDI_MAP)) | (bus_fmt->oldi_mode_reg_val << 1);
+
+	oldi_cfg |= OLDI_SOFTRST;
+
+	oldi_cfg |= OLDI_ENABLE;
+
+	switch (oldi->link_type) {
+	case OLDI_MODE_SINGLE_LINK:
+		/* All configuration is done for this mode.  */
+		break;
+
+	case OLDI_MODE_CLONE_SINGLE_LINK:
+		oldi_cfg |= OLDI_CLONE_MODE;
+		break;
+
+	case OLDI_MODE_DUAL_LINK:
+		/* data-mapping field also indicates dual-link mode */
+		oldi_cfg |= BIT(3);
+		oldi_cfg |= OLDI_DUALMODESYNC;
+		break;
+
+	default:
+		dev_err(oldi->dev, "OLDI%u: Unsupported mode.\n",
+			oldi->oldi_instance);
+		return -EINVAL;
+	}
+
+	tidss_configure_oldi(oldi->tidss, oldi->parent_vp, oldi_cfg);
+
+	return 0;
+}
+
+static void tidss_oldi_atomic_pre_enable(struct drm_bridge *bridge,
+					 struct drm_bridge_state *old_bridge_state)
+{
+	struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge);
+	struct drm_atomic_state *state = old_bridge_state->base.state;
+	struct drm_connector *connector;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_display_mode *mode;
+
+	if (oldi->tidss->shared_mode)
+		return;
+
+	connector = drm_atomic_get_new_connector_for_encoder(state,
+							     bridge->encoder);
+	if (WARN_ON(!connector))
+		return;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (WARN_ON(!conn_state))
+		return;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+	if (WARN_ON(!crtc_state))
+		return;
+
+	mode = &crtc_state->adjusted_mode;
+
+	/* Configure the OLDI params*/
+	tidss_oldi_config(oldi);
+
+	/* Set the OLDI serial clock (7 times the pixel clock) */
+	tidss_oldi_set_serial_clk(oldi, mode->clock * 7 * 1000);
+
+	/* Enable OLDI IO power */
+	tidss_oldi_tx_power(oldi, true);
+}
+
+static void tidss_oldi_atomic_post_disable(struct drm_bridge *bridge,
+					   struct drm_bridge_state *old_bridge_state)
+{
+	struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge);
+
+	if (oldi->tidss->shared_mode)
+		return;
+
+	/* Disable OLDI IO power */
+	tidss_oldi_tx_power(oldi, false);
+
+	/* Set the OLDI serial clock to IDLE Frequency */
+	tidss_oldi_set_serial_clk(oldi, OLDI_IDLE_CLK_HZ);
+
+	/* Clear OLDI Config */
+	tidss_configure_oldi(oldi->tidss, oldi->parent_vp, 0);
+}
+
+#define MAX_INPUT_SEL_FORMATS	1
+
+static u32 *tidss_oldi_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
+						 struct drm_bridge_state *bridge_state,
+						 struct drm_crtc_state *crtc_state,
+						 struct drm_connector_state *conn_state,
+						 u32 output_fmt,
+						 unsigned int *num_input_fmts)
+{
+	struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge);
+	u32 *input_fmts;
+	int i;
+
+	*num_input_fmts = 0;
+
+	for (i = 0; i < ARRAY_SIZE(oldi_bus_formats); i++)
+		if (oldi_bus_formats[i].bus_fmt == output_fmt)
+			break;
+
+	if (i == ARRAY_SIZE(oldi_bus_formats))
+		return NULL;
+
+	input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
+			     GFP_KERNEL);
+	if (!input_fmts)
+		return NULL;
+
+	*num_input_fmts = 1;
+	input_fmts[0] = oldi_bus_formats[i].input_bus_fmt;
+	oldi->bus_format = &oldi_bus_formats[i];
+
+	return input_fmts;
+}
+
+static const struct drm_bridge_funcs tidss_oldi_bridge_funcs = {
+	.attach		= tidss_oldi_bridge_attach,
+	.atomic_pre_enable = tidss_oldi_atomic_pre_enable,
+	.atomic_post_disable = tidss_oldi_atomic_post_disable,
+	.atomic_get_input_bus_fmts = tidss_oldi_atomic_get_input_bus_fmts,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+};
+
+static int get_oldi_mode(struct device_node *oldi_tx, u32 *companion_instance)
+{
+	struct device_node *companion;
+	struct device_node *port0, *port1;
+	int pixel_order;
+
+	/*
+	 * Find if the OLDI is paired with another OLDI for combined OLDI
+	 * operation (dual-lvds or clone).
+	 */
+	companion = of_parse_phandle(oldi_tx, "ti,companion-oldi", 0);
+	if (!companion) {
+		/*
+		 * OLDI TXes in Single Link mode do not have companion
+		 * OLDI TXes and, Secondary OLDI nodes don't need this
+		 * information.
+		 */
+		*companion_instance = -1;
+
+		if (of_property_read_bool(oldi_tx, "ti,secondary-oldi"))
+			return OLDI_MODE_SECONDARY;
+
+		/*
+		 * The OLDI TX does not have a companion, nor is it a
+		 * secondary OLDI. It will operate independently.
+		 */
+		return OLDI_MODE_SINGLE_LINK;
+	}
+
+	if (of_property_read_u32(companion, "reg", companion_instance))
+		return OLDI_MODE_UNSUPPORTED;
+
+	/*
+	 * We need to work out if the sink is expecting us to function in
+	 * dual-link mode. We do this by looking at the DT port nodes we are
+	 * connected to, if they are marked as expecting even pixels and
+	 * odd pixels than we need to enable vertical stripe output.
+	 */
+	port0 = of_graph_get_port_by_id(oldi_tx, 1);
+	port1 = of_graph_get_port_by_id(companion, 1);
+	pixel_order = drm_of_lvds_get_dual_link_pixel_order(port0, port1);
+	of_node_put(port0);
+	of_node_put(port1);
+	of_node_put(companion);
+
+	switch (pixel_order) {
+	case -EINVAL:
+		/*
+		 * The dual link properties were not found in at least
+		 * one of the sink nodes. Since 2 OLDI ports are present
+		 * in the DT, it can be safely assumed that the required
+		 * configuration is Clone Mode.
+		 */
+		return OLDI_MODE_CLONE_SINGLE_LINK;
+
+	case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
+		return OLDI_MODE_DUAL_LINK;
+
+	/* Unsupported OLDI Modes */
+	case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
+	default:
+		return OLDI_MODE_UNSUPPORTED;
+	}
+}
+
+static int get_parent_dss_vp(struct device_node *oldi_tx, u32 *parent_vp)
+{
+	struct device_node *ep, *dss_port;
+	int ret;
+
+	ep = of_graph_get_endpoint_by_regs(oldi_tx, OLDI_INPUT_PORT, -1);
+	if (ep) {
+		dss_port = of_graph_get_remote_port(ep);
+		if (!dss_port) {
+			ret = -ENODEV;
+			goto err_return_ep_port;
+		}
+
+		ret = of_property_read_u32(dss_port, "reg", parent_vp);
+
+		of_node_put(dss_port);
+err_return_ep_port:
+		of_node_put(ep);
+		return ret;
+	}
+
+	return -ENODEV;
+}
+
+static const struct drm_bridge_timings default_tidss_oldi_timings = {
+	.input_bus_flags = DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE
+			 | DRM_BUS_FLAG_DE_HIGH,
+};
+
+void tidss_oldi_deinit(struct tidss_device *tidss)
+{
+	for (int i = 0; i < tidss->num_oldis; i++) {
+		if (tidss->oldis[i]) {
+			drm_bridge_remove(&tidss->oldis[i]->bridge);
+			tidss->oldis[i] = NULL;
+		}
+	}
+}
+
+int tidss_oldi_init(struct tidss_device *tidss)
+{
+	struct tidss_oldi *oldi;
+	struct device_node *child;
+	struct drm_bridge *bridge;
+	u32 parent_vp, oldi_instance, companion_instance;
+	enum tidss_oldi_link_type link_type = OLDI_MODE_UNSUPPORTED;
+	struct device_node *oldi_parent;
+	int ret = 0;
+
+	tidss->num_oldis = 0;
+
+	oldi_parent = of_get_child_by_name(tidss->dev->of_node, "oldi-transmitters");
+	if (!oldi_parent)
+		/* Return gracefully */
+		return 0;
+
+	for_each_child_of_node(oldi_parent, child) {
+		ret = get_parent_dss_vp(child, &parent_vp);
+		if (ret) {
+			if (ret == -ENODEV) {
+				/*
+				 * ENODEV means that this particular OLDI node
+				 * is not connected with the DSS, which is not
+				 * a harmful case. There could be another OLDI
+				 * which may still be connected.
+				 * Continue to search for that.
+				 */
+				ret = 0;
+				continue;
+			}
+			goto err_put_node;
+		}
+
+		ret = of_property_read_u32(child, "reg", &oldi_instance);
+		if (ret)
+			goto err_put_node;
+
+		/*
+		 * Now that its confirmed that OLDI is connected with DSS, let's
+		 * continue getting the OLDI sinks ahead and other OLDI
+		 * properties.
+		 */
+		bridge = devm_drm_of_get_bridge(tidss->dev, child,
+						OLDI_OURPUT_PORT, 0);
+		if (IS_ERR(bridge)) {
+			/*
+			 * Either there was no OLDI sink in the devicetree, or
+			 * the OLDI sink has not been added yet. In any case,
+			 * return.
+			 * We don't want to have an OLDI node connected to DSS
+			 * but not to any sink.
+			 */
+			ret = dev_err_probe(tidss->dev, PTR_ERR(bridge),
+					    "no panel/bridge for OLDI%u.\n",
+					    oldi_instance);
+			goto err_put_node;
+		}
+
+		link_type = get_oldi_mode(child, &companion_instance);
+		if (link_type == OLDI_MODE_UNSUPPORTED) {
+			ret = dev_err_probe(tidss->dev, -EINVAL,
+					    "OLDI%u: Unsupported OLDI connection.\n",
+					    oldi_instance);
+			goto err_put_node;
+		} else if (link_type == OLDI_MODE_SECONDARY) {
+			/*
+			 * This is the secondary OLDI node, which serves as a
+			 * companinon to the primary OLDI, when it is configured
+			 * for the dual-lvds mode. Since the primary OLDI will
+			 * be a part of bridge chain, no need to put this one
+			 * too. Continue onto the next OLDI node.
+			 */
+			continue;
+		}
+
+		oldi = devm_kzalloc(tidss->dev, sizeof(*oldi), GFP_KERNEL);
+		if (!oldi) {
+			ret = -ENOMEM;
+			goto err_put_node;
+		}
+
+		oldi->parent_vp = parent_vp;
+		oldi->oldi_instance = oldi_instance;
+		oldi->companion_instance = companion_instance;
+		oldi->link_type = link_type;
+		oldi->dev = tidss->dev;
+		oldi->next_bridge = bridge;
+
+		oldi->io_ctrl = syscon_regmap_lookup_by_phandle(child,
+								"ti,oldi-io-ctrl");
+		if (IS_ERR(oldi->io_ctrl)) {
+			ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->io_ctrl),
+					    "OLDI%u: syscon_regmap_lookup_by_phandle failed.\n",
+					    oldi_instance);
+			goto err_put_node;
+		}
+
+		oldi->serial = of_clk_get_by_name(child, "serial");
+		if (IS_ERR(oldi->serial)) {
+			ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->serial),
+					    "OLDI%u: Failed to get serial clock.\n",
+					    oldi_instance);
+			goto err_put_node;
+		}
+
+		/* Register the bridge. */
+		oldi->bridge.of_node = child;
+		oldi->bridge.driver_private = oldi;
+		oldi->bridge.funcs = &tidss_oldi_bridge_funcs;
+		oldi->bridge.timings = &default_tidss_oldi_timings;
+
+		tidss->oldis[tidss->num_oldis++] = oldi;
+		oldi->tidss = tidss;
+
+		drm_bridge_add(&oldi->bridge);
+	}
+
+	of_node_put(child);
+	of_node_put(oldi_parent);
+
+	return 0;
+
+err_put_node:
+	of_node_put(child);
+	of_node_put(oldi_parent);
+	return ret;
+}
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/tidss_oldi.h b/drivers/gpu/drm/tidss/tidss_oldi.h
--- a/drivers/gpu/drm/tidss/tidss_oldi.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/gpu/drm/tidss/tidss_oldi.h	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024 - Texas Instruments Incorporated
+ *
+ * Aradhya Bhatia <a-bhatia1@ti.com>
+ */
+
+#ifndef __TIDSS_OLDI_H__
+#define __TIDSS_OLDI_H__
+
+#include "tidss_drv.h"
+
+struct tidss_oldi;
+
+/* OLDI PORTS */
+#define OLDI_INPUT_PORT		0
+#define OLDI_OURPUT_PORT	1
+
+/* Control MMR Registers */
+
+/* Register offsets */
+#define OLDI_PD_CTRL            0x100
+#define OLDI_LB_CTRL            0x104
+
+/* Power control bits */
+#define OLDI_PWRDOWN_TX(n)	BIT(n)
+
+/* LVDS Bandgap reference Enable/Disable */
+#define OLDI_PWRDN_BG		BIT(8)
+
+enum tidss_oldi_link_type {
+	OLDI_MODE_UNSUPPORTED,
+	OLDI_MODE_SINGLE_LINK,
+	OLDI_MODE_CLONE_SINGLE_LINK,
+	OLDI_MODE_DUAL_LINK,
+	OLDI_MODE_SECONDARY,
+};
+
+enum oldi_mode_reg_val { SPWG_18 = 0, JEIDA_24 = 1, SPWG_24 = 2 };
+
+struct oldi_bus_format {
+	u32 bus_fmt;
+	u32 data_width;
+	enum oldi_mode_reg_val oldi_mode_reg_val;
+	u32 input_bus_fmt;
+};
+
+int tidss_oldi_init(struct tidss_device *tidss);
+void tidss_oldi_deinit(struct tidss_device *tidss);
+
+#endif /* __TIDSS_OLDI_H__ */
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c
--- a/drivers/gpu/drm/tidss/tidss_plane.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/tidss/tidss_plane.c	2025-10-23 09:30:40.285462207 -0400
@@ -18,6 +18,14 @@
 #include "tidss_drv.h"
 #include "tidss_plane.h"
 
+void tidss_plane_error_irq(struct drm_plane *plane, u64 irqstatus)
+{
+	struct tidss_plane *tplane = to_tidss_plane(plane);
+
+	dev_err_ratelimited(plane->dev->dev, "Plane%u underflow (irq %llx)\n",
+			    tplane->hw_plane_id, irqstatus);
+}
+
 /* drm_plane_helper_funcs */
 
 static int tidss_plane_atomic_check(struct drm_plane *plane,
diff -Naur --no-dereference a/drivers/gpu/drm/tidss/tidss_plane.h b/drivers/gpu/drm/tidss/tidss_plane.h
--- a/drivers/gpu/drm/tidss/tidss_plane.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/gpu/drm/tidss/tidss_plane.h	2025-10-23 09:30:40.285462207 -0400
@@ -22,4 +22,6 @@
 				       u32 crtc_mask, const u32 *formats,
 				       u32 num_formats);
 
+void tidss_plane_error_irq(struct drm_plane *plane, u64 irqstatus);
+
 #endif
diff -Naur --no-dereference a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
--- a/drivers/i2c/busses/i2c-omap.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/i2c/busses/i2c-omap.c	2025-10-23 09:30:40.285462207 -0400
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/mux/consumer.h>
 #include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/platform_data/i2c-omap.h>
@@ -211,6 +212,7 @@
 	u16			syscstate;
 	u16			westate;
 	u16			errata;
+	struct mux_state	*mux_state;
 };
 
 static const u8 reg_map_ip_v1[] = {
@@ -1452,6 +1454,23 @@
 				       (1000 * omap->speed / 8);
 	}
 
+	if (of_property_read_bool(node, "mux-states")) {
+		struct mux_state *mux_state;
+
+		mux_state = devm_mux_state_get(&pdev->dev, NULL);
+		if (IS_ERR(mux_state)) {
+			r = PTR_ERR(mux_state);
+			dev_dbg(&pdev->dev, "failed to get I2C mux: %d\n", r);
+			goto err_disable_pm;
+		}
+		omap->mux_state = mux_state;
+		r = mux_state_select(omap->mux_state);
+		if (r) {
+			dev_err(&pdev->dev, "failed to select I2C mux: %d\n", r);
+			goto err_disable_pm;
+		}
+	}
+
 	/* reset ASAP, clearing any IRQs */
 	omap_i2c_init(omap);
 
@@ -1511,6 +1530,9 @@
 
 	i2c_del_adapter(&omap->adapter);
 
+	if (omap->mux_state)
+		mux_state_deselect(omap->mux_state);
+
 	ret = pm_runtime_get_sync(&pdev->dev);
 	if (ret < 0)
 		dev_err(omap->dev, "Failed to resume hardware, skip disable\n");
diff -Naur --no-dereference a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/i2c/busses/Kconfig	2025-10-23 09:30:40.285462207 -0400
@@ -937,6 +937,7 @@
 	tristate "OMAP I2C adapter"
 	depends on ARCH_OMAP || ARCH_K3 || COMPILE_TEST
 	default MACH_OMAP_OSK
+	select MULTIPLEXER
 	help
 	  If you say yes to this option, support will be included for the
 	  I2C interface on the Texas Instruments OMAP1/2 family of processors.
diff -Naur --no-dereference a/drivers/input/misc/tps65219-pwrbutton.c b/drivers/input/misc/tps65219-pwrbutton.c
--- a/drivers/input/misc/tps65219-pwrbutton.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/input/misc/tps65219-pwrbutton.c	2025-10-23 09:30:40.285462207 -0400
@@ -137,7 +137,7 @@
 
 static struct platform_driver tps65219_pb_driver = {
 	.probe = tps65219_pb_probe,
-	.remove_new = tps65219_pb_remove,
+	.remove = tps65219_pb_remove,
 	.driver = {
 		.name = "tps65219_pwrbutton",
 	},
diff -Naur --no-dereference a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
--- a/drivers/input/touchscreen/edt-ft5x06.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/input/touchscreen/edt-ft5x06.c	2025-10-23 09:30:40.285462207 -0400
@@ -69,6 +69,7 @@
 #define TOUCH_EVENT_RESERVED		0x03
 
 #define EDT_NAME_LEN			23
+#define EDT_NAME_PREFIX_LEN		8
 #define EDT_SWITCH_MODE_RETRIES		10
 #define EDT_SWITCH_MODE_DELAY		5 /* msec */
 #define EDT_RAW_DATA_RETRIES		100
@@ -80,6 +81,10 @@
 #define M06_REG_CMD(factory) ((factory) ? 0xf3 : 0xfc)
 #define M06_REG_ADDR(factory, addr) ((factory) ? (addr) & 0x7f : (addr) & 0x3f)
 
+#define RESET_DELAY_MS			300	/* reset deassert to I2C */
+#define FIRST_POLL_DELAY_MS		300	/* in addition to the above */
+#define POLL_INTERVAL_MS		17	/* 17ms = 60fps */
+
 enum edt_pmode {
 	EDT_PMODE_NOT_SUPPORTED,
 	EDT_PMODE_HIBERNATE,
@@ -139,14 +144,19 @@
 	u8 tdata_cmd;
 	int tdata_len;
 	int tdata_offset;
+	unsigned int known_ids;
 
-	char name[EDT_NAME_LEN];
+	char name[EDT_NAME_PREFIX_LEN + EDT_NAME_LEN];
 	char fw_version[EDT_NAME_LEN];
+	int init_td_status;
 
 	struct edt_reg_addr reg_addr;
 	enum edt_ver version;
 	unsigned int crc_errors;
 	unsigned int header_errors;
+
+	struct timer_list timer;
+	struct work_struct work_i2c_poll;
 };
 
 struct edt_i2c_chip_data {
@@ -303,17 +313,49 @@
 	u8 rdbuf[63];
 	int i, type, x, y, id;
 	int error;
+	int num_points;
+	unsigned int active_ids = 0, known_ids = tsdata->known_ids;
+	long released_ids;
+	int b = 0;
 
 	memset(rdbuf, 0, sizeof(rdbuf));
 	error = regmap_bulk_read(tsdata->regmap, tsdata->tdata_cmd, rdbuf,
 				 tsdata->tdata_len);
+	if (tsdata->version == EDT_M06) {
+		num_points = tsdata->max_support_points;
+	} else {
+		/* Register 2 is TD_STATUS, containing the number of touch
+		 * points.
+		 */
+		num_points = min(rdbuf[2] & 0xf, tsdata->max_support_points);
+
+		/* When polling FT5x06 without IRQ: initial register contents
+		 * could be stale or undefined; discard all readings until
+		 * TD_STATUS changes for the first time (or num_points is 0).
+		 */
+		if (tsdata->init_td_status) {
+			if (tsdata->init_td_status < 0)
+				tsdata->init_td_status = rdbuf[2];
+
+			if (num_points && rdbuf[2] == tsdata->init_td_status)
+				goto out;
+
+			tsdata->init_td_status = 0;
+		}
+
+		if (!error && num_points)
+			error = regmap_bulk_read(tsdata->regmap,
+						 tsdata->tdata_offset,
+						 &rdbuf[tsdata->tdata_offset],
+						 tsdata->point_len * num_points);
+	}
 	if (error) {
 		dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
 				    error);
 		goto out;
 	}
 
-	for (i = 0; i < tsdata->max_support_points; i++) {
+	for (i = 0; i < num_points; i++) {
 		u8 *buf = &rdbuf[i * tsdata->point_len + tsdata->tdata_offset];
 
 		type = buf[0] >> 6;
@@ -335,10 +377,25 @@
 
 		input_mt_slot(tsdata->input, id);
 		if (input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER,
-					       type != TOUCH_EVENT_UP))
+					       type != TOUCH_EVENT_UP)) {
 			touchscreen_report_pos(tsdata->input, &tsdata->prop,
 					       x, y, true);
+			active_ids |= BIT(id);
+		} else {
+			known_ids &= ~BIT(id);
+		}
+	}
+
+	/* One issue with the device is the TOUCH_UP message is not always
+	 * returned. Instead track which ids we know about and report when they
+	 * are no longer updated
+	 */
+	released_ids = known_ids & ~active_ids;
+	for_each_set_bit_from(b, &released_ids, tsdata->max_support_points) {
+		input_mt_slot(tsdata->input, b);
+		input_mt_report_slot_inactive(tsdata->input);
 	}
+	tsdata->known_ids = active_ids;
 
 	input_mt_report_pointer_emulation(tsdata->input, true);
 	input_sync(tsdata->input);
@@ -347,6 +404,22 @@
 	return IRQ_HANDLED;
 }
 
+static void edt_ft5x06_ts_irq_poll_timer(struct timer_list *t)
+{
+	struct edt_ft5x06_ts_data *tsdata = from_timer(tsdata, t, timer);
+
+	schedule_work(&tsdata->work_i2c_poll);
+	mod_timer(&tsdata->timer, jiffies + msecs_to_jiffies(POLL_INTERVAL_MS));
+}
+
+static void edt_ft5x06_ts_work_i2c_poll(struct work_struct *work)
+{
+	struct edt_ft5x06_ts_data *tsdata = container_of(work,
+			struct edt_ft5x06_ts_data, work_i2c_poll);
+
+	edt_ft5x06_ts_isr(0, tsdata);
+}
+
 struct edt_ft5x06_attribute {
 	struct device_attribute dattr;
 	size_t field_offset;
@@ -862,6 +935,9 @@
 	char *model_name = tsdata->name;
 	char *fw_version = tsdata->fw_version;
 
+	snprintf(model_name, EDT_NAME_PREFIX_LEN + 1, "%s ", dev_name(&client->dev));
+	model_name += strlen(model_name);
+
 	/* see what we find if we assume it is a M06 *
 	 * if we get less than EDT_NAME_LEN, we don't want
 	 * to have garbage in there
@@ -1050,20 +1126,23 @@
 static void edt_ft5x06_ts_set_tdata_parameters(struct edt_ft5x06_ts_data *tsdata)
 {
 	int crclen;
+	int points;
 
 	if (tsdata->version == EDT_M06) {
 		tsdata->tdata_cmd = 0xf9;
 		tsdata->tdata_offset = 5;
 		tsdata->point_len = 4;
 		crclen = 1;
+		points = tsdata->max_support_points;
 	} else {
 		tsdata->tdata_cmd = 0x0;
 		tsdata->tdata_offset = 3;
 		tsdata->point_len = 6;
 		crclen = 0;
+		points = 0;
 	}
 
-	tsdata->tdata_len = tsdata->point_len * tsdata->max_support_points +
+	tsdata->tdata_len = tsdata->point_len * points +
 		tsdata->tdata_offset + crclen;
 }
 
@@ -1258,7 +1337,7 @@
 	if (tsdata->reset_gpio) {
 		usleep_range(5000, 6000);
 		gpiod_set_value_cansleep(tsdata->reset_gpio, 0);
-		msleep(300);
+		msleep(RESET_DELAY_MS);
 	}
 
 	input = devm_input_allocate_device(&client->dev);
@@ -1332,17 +1411,28 @@
 		return error;
 	}
 
-	irq_flags = irq_get_trigger_type(client->irq);
-	if (irq_flags == IRQF_TRIGGER_NONE)
-		irq_flags = IRQF_TRIGGER_FALLING;
-	irq_flags |= IRQF_ONESHOT;
-
-	error = devm_request_threaded_irq(&client->dev, client->irq,
-					  NULL, edt_ft5x06_ts_isr, irq_flags,
-					  client->name, tsdata);
-	if (error) {
-		dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
-		return error;
+	if (client->irq) {
+		irq_flags = irq_get_trigger_type(client->irq);
+		if (irq_flags == IRQF_TRIGGER_NONE)
+			irq_flags = IRQF_TRIGGER_FALLING;
+		irq_flags |= IRQF_ONESHOT;
+
+		error = devm_request_threaded_irq(&client->dev, client->irq,
+						  NULL, edt_ft5x06_ts_isr,
+						  irq_flags, client->name,
+						  tsdata);
+		if (error) {
+			dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
+			return error;
+		}
+	} else {
+		tsdata->init_td_status = -1; /* filter bogus initial data */
+		INIT_WORK(&tsdata->work_i2c_poll,
+			  edt_ft5x06_ts_work_i2c_poll);
+		timer_setup(&tsdata->timer, edt_ft5x06_ts_irq_poll_timer, 0);
+		tsdata->timer.expires =
+			jiffies + msecs_to_jiffies(FIRST_POLL_DELAY_MS);
+		add_timer(&tsdata->timer);
 	}
 
 	error = input_register_device(input);
@@ -1364,6 +1454,10 @@
 {
 	struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
 
+	if (!client->irq) {
+		del_timer(&tsdata->timer);
+		cancel_work_sync(&tsdata->work_i2c_poll);
+	}
 	edt_ft5x06_ts_teardown_debugfs(tsdata);
 }
 
diff -Naur --no-dereference a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
--- a/drivers/iommu/iommu.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/iommu/iommu.c	2025-10-23 09:30:40.285462207 -0400
@@ -90,6 +90,7 @@
 #define IOMMU_CMD_LINE_DMA_API		BIT(0)
 #define IOMMU_CMD_LINE_STRICT		BIT(1)
 
+static int bus_iommu_probe(const struct bus_type *bus);
 static int iommu_bus_notifier(struct notifier_block *nb,
 			      unsigned long action, void *data);
 static void iommu_release_device(struct device *dev);
@@ -1798,7 +1799,7 @@
 		ops->probe_finalize(dev);
 }
 
-int bus_iommu_probe(const struct bus_type *bus)
+static int bus_iommu_probe(const struct bus_type *bus)
 {
 	struct iommu_group *group, *next;
 	LIST_HEAD(group_list);
diff -Naur --no-dereference a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
--- a/drivers/iommu/omap-iommu.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/iommu/omap-iommu.c	2025-10-23 09:30:40.285462207 -0400
@@ -1230,25 +1230,24 @@
 		if (err)
 			return err;
 
-		err = iommu_device_register(&obj->iommu, &omap_iommu_ops, &pdev->dev);
-		if (err)
-			goto out_sysfs;
 		obj->has_iommu_driver = true;
 	}
 
+	err = iommu_device_register(&obj->iommu, &omap_iommu_ops, &pdev->dev);
+	if (err)
+		goto out_sysfs;
+
 	pm_runtime_enable(obj->dev);
 
 	omap_iommu_debugfs_add(obj);
 
 	dev_info(&pdev->dev, "%s registered\n", obj->name);
 
-	/* Re-probe bus to probe device attached to this IOMMU */
-	bus_iommu_probe(&platform_bus_type);
-
 	return 0;
 
 out_sysfs:
-	iommu_device_sysfs_remove(&obj->iommu);
+	if (obj->has_iommu_driver)
+		iommu_device_sysfs_remove(&obj->iommu);
 	return err;
 }
 
@@ -1256,10 +1255,10 @@
 {
 	struct omap_iommu *obj = platform_get_drvdata(pdev);
 
-	if (obj->has_iommu_driver) {
+	if (obj->has_iommu_driver)
 		iommu_device_sysfs_remove(&obj->iommu);
-		iommu_device_unregister(&obj->iommu);
-	}
+
+	iommu_device_unregister(&obj->iommu);
 
 	omap_iommu_debugfs_remove(obj);
 
@@ -1723,12 +1722,19 @@
 
 }
 
+static int omap_iommu_of_xlate(struct device *dev, const struct of_phandle_args *args)
+{
+	/* TODO: collect args->np to save re-parsing in probe above */
+	return 0;
+}
+
 static const struct iommu_ops omap_iommu_ops = {
 	.identity_domain = &omap_iommu_identity_domain,
 	.domain_alloc_paging = omap_iommu_domain_alloc_paging,
 	.probe_device	= omap_iommu_probe_device,
 	.release_device	= omap_iommu_release_device,
 	.device_group	= generic_single_device_group,
+	.of_xlate	= omap_iommu_of_xlate,
 	.pgsize_bitmap	= OMAP_IOMMU_PGSIZES,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= omap_iommu_attach_dev,
diff -Naur --no-dereference a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c
--- a/drivers/irqchip/irq-pruss-intc.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/irqchip/irq-pruss-intc.c	2025-10-23 09:30:40.285462207 -0400
@@ -70,6 +70,8 @@
 #define MAX_PRU_SYS_EVENTS 160
 #define MAX_PRU_CHANNELS 20
 
+#define MAX_PRU_INT_EVENTS	64
+
 /**
  * struct pruss_intc_map_record - keeps track of actual mapping state
  * @value: The currently mapped value (channel or host)
@@ -85,10 +87,13 @@
  * @num_system_events: number of input system events handled by the PRUSS INTC
  * @num_host_events: number of host events (which is equal to number of
  *		     channels) supported by the PRUSS INTC
+ * @quirky_events: bitmask of events that need quirky IRQ handling (limited to
+ *		   (internal sources only for now, so 64 bits suffice)
  */
 struct pruss_intc_match_data {
 	u8 num_system_events;
 	u8 num_host_events;
+	u64 quirky_events;
 };
 
 /**
@@ -101,6 +106,7 @@
  * @soc_config: cached PRUSS INTC IP configuration data
  * @dev: PRUSS INTC device pointer
  * @lock: mutex to serialize interrupts mapping
+ * @irqs_reserved: bit-mask of reserved host interrupts
  */
 struct pruss_intc {
 	struct pruss_intc_map_record event_channel[MAX_PRU_SYS_EVENTS];
@@ -111,6 +117,7 @@
 	const struct pruss_intc_match_data *soc_config;
 	struct device *dev;
 	struct mutex lock; /* PRUSS INTC lock */
+	u8 irqs_reserved;
 };
 
 /**
@@ -178,6 +185,7 @@
 static void pruss_intc_map(struct pruss_intc *intc, unsigned long hwirq)
 {
 	struct device *dev = intc->dev;
+	bool enable_hwirq = false;
 	u8 ch, host, reg_idx;
 	u32 val;
 
@@ -187,6 +195,9 @@
 
 	ch = intc->event_channel[hwirq].value;
 	host = intc->channel_host[ch].value;
+	enable_hwirq = (host < FIRST_PRU_HOST_INT ||
+			host >= FIRST_PRU_HOST_INT + MAX_NUM_HOST_IRQS ||
+			intc->irqs_reserved & BIT(host - FIRST_PRU_HOST_INT));
 
 	pruss_intc_update_cmr(intc, hwirq, ch);
 
@@ -194,8 +205,10 @@
 	val = BIT(hwirq  % 32);
 
 	/* clear and enable system event */
-	pruss_intc_write_reg(intc, PRU_INTC_ESR(reg_idx), val);
 	pruss_intc_write_reg(intc, PRU_INTC_SECR(reg_idx), val);
+	/* unmask only events going to various PRU and other cores by default */
+	if (enable_hwirq)
+		pruss_intc_write_reg(intc, PRU_INTC_ESR(reg_idx), val);
 
 	if (++intc->channel_host[ch].ref_count == 1) {
 		pruss_intc_update_hmr(intc, ch, host);
@@ -204,7 +217,8 @@
 		pruss_intc_write_reg(intc, PRU_INTC_HIEISR, host);
 	}
 
-	dev_dbg(dev, "mapped system_event = %lu channel = %d host = %d",
+	dev_dbg(dev, "mapped%s system_event = %lu channel = %d host = %d",
+		enable_hwirq ? " and enabled" : "",
 		hwirq, ch, host);
 
 	mutex_unlock(&intc->lock);
@@ -268,11 +282,14 @@
 
 	/*
 	 * configure polarity (SIPR register) to active high and
-	 * type (SITR register) to level interrupt for all system events
+	 * type (SITR register) to level interrupt for all system events,
+	 * and disable and clear all the system events
 	 */
 	for (i = 0; i < num_event_type_regs; i++) {
 		pruss_intc_write_reg(intc, PRU_INTC_SIPR(i), 0xffffffff);
 		pruss_intc_write_reg(intc, PRU_INTC_SITR(i), 0);
+		pruss_intc_write_reg(intc, PRU_INTC_ECR(i), 0xffffffff);
+		pruss_intc_write_reg(intc, PRU_INTC_SECR(i), 0xffffffff);
 	}
 
 	/* clear all interrupt channel map registers, 4 events per register */
@@ -292,6 +309,10 @@
 	struct pruss_intc *intc = irq_data_get_irq_chip_data(data);
 	unsigned int hwirq = data->hwirq;
 
+	if (hwirq < MAX_PRU_INT_EVENTS &&
+	    intc->soc_config->quirky_events & BIT_ULL(hwirq))
+		return;
+
 	pruss_intc_write_reg(intc, PRU_INTC_SICR, hwirq);
 }
 
@@ -308,6 +329,9 @@
 	struct pruss_intc *intc = irq_data_get_irq_chip_data(data);
 	unsigned int hwirq = data->hwirq;
 
+	if (hwirq < MAX_PRU_INT_EVENTS &&
+	    intc->soc_config->quirky_events & BIT_ULL(hwirq))
+		pruss_intc_write_reg(intc, PRU_INTC_SICR, hwirq);
 	pruss_intc_write_reg(intc, PRU_INTC_EISR, hwirq);
 }
 
@@ -361,6 +385,14 @@
 	return 0;
 }
 
+static int pruss_intc_irq_irq_set_type(struct irq_data *data, unsigned int type)
+{
+	if (type != IRQ_TYPE_LEVEL_HIGH)
+		return -EINVAL;
+
+	return 0;
+}
+
 static struct irq_chip pruss_irqchip = {
 	.name			= "pruss-intc",
 	.irq_ack		= pruss_intc_irq_ack,
@@ -370,6 +402,7 @@
 	.irq_release_resources	= pruss_intc_irq_relres,
 	.irq_get_irqchip_state	= pruss_intc_irq_get_irqchip_state,
 	.irq_set_irqchip_state	= pruss_intc_irq_set_irqchip_state,
+	.irq_set_type		= pruss_intc_irq_irq_set_type,
 };
 
 static int pruss_intc_validate_mapping(struct pruss_intc *intc, int event,
@@ -521,7 +554,7 @@
 	struct pruss_intc *intc;
 	struct pruss_host_irq_data *host_data;
 	int i, irq, ret;
-	u8 max_system_events, irqs_reserved = 0;
+	u8 max_system_events;
 
 	data = of_device_get_match_data(dev);
 	if (!data)
@@ -542,7 +575,7 @@
 		return PTR_ERR(intc->base);
 
 	ret = of_property_read_u8(dev->of_node, "ti,irqs-reserved",
-				  &irqs_reserved);
+				  &intc->irqs_reserved);
 
 	/*
 	 * The irqs-reserved is used only for some SoC's therefore not having
@@ -561,7 +594,7 @@
 		return -ENOMEM;
 
 	for (i = 0; i < MAX_NUM_HOST_IRQS; i++) {
-		if (irqs_reserved & BIT(i))
+		if (intc->irqs_reserved & BIT(i))
 			continue;
 
 		irq = platform_get_irq_byname(pdev, irq_names[i]);
@@ -621,11 +654,13 @@
 static const struct pruss_intc_match_data pruss_intc_data = {
 	.num_system_events = 64,
 	.num_host_events = 10,
+	.quirky_events = BIT_ULL(7), /* IEP capture/compare event */
 };
 
 static const struct pruss_intc_match_data icssg_intc_data = {
 	.num_system_events = 160,
 	.num_host_events = 20,
+	.quirky_events = BIT_ULL(7) | BIT_ULL(56), /* IEP{0,1} capture/compare events */
 };
 
 static const struct of_device_id pruss_intc_of_match[] = {
diff -Naur --no-dereference a/drivers/irqchip/irq-ti-sci-inta.c b/drivers/irqchip/irq-ti-sci-inta.c
--- a/drivers/irqchip/irq-ti-sci-inta.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/irqchip/irq-ti-sci-inta.c	2025-10-23 09:30:40.285462207 -0400
@@ -64,6 +64,7 @@
  * @events:		Array of event descriptors assigned to this vint.
  * @parent_virq:	Linux IRQ number that gets attached to parent
  * @vint_id:		TISCI vint ID
+ * @affinity_managed:	flag to indicate VINT affinity is managed
  */
 struct ti_sci_inta_vint_desc {
 	struct irq_domain *domain;
@@ -72,6 +73,7 @@
 	struct ti_sci_inta_event_desc events[MAX_EVENTS_PER_VINT];
 	unsigned int parent_virq;
 	u16 vint_id;
+	bool affinity_managed;
 };
 
 /**
@@ -199,10 +201,12 @@
 /**
  * ti_sci_inta_alloc_parent_irq() - Allocate parent irq to Interrupt aggregator
  * @domain:	IRQ domain corresponding to Interrupt Aggregator
+ * @vint_id:	vint_id to which event is to be mapped to
  *
  * Return 0 if all went well else corresponding error value.
  */
-static struct ti_sci_inta_vint_desc *ti_sci_inta_alloc_parent_irq(struct irq_domain *domain)
+static struct ti_sci_inta_vint_desc *ti_sci_inta_alloc_parent_irq(struct irq_domain *domain,
+								  u16 vint_id)
 {
 	struct ti_sci_inta_irq_domain *inta = domain->host_data;
 	struct ti_sci_inta_vint_desc *vint_desc;
@@ -210,11 +214,6 @@
 	struct device_node *parent_node;
 	unsigned int parent_virq;
 	int p_hwirq, ret;
-	u16 vint_id;
-
-	vint_id = ti_sci_get_free_resource(inta->vint);
-	if (vint_id == TI_SCI_RESOURCE_NULL)
-		return ERR_PTR(-EINVAL);
 
 	p_hwirq = ti_sci_inta_xlate_irq(inta, vint_id);
 	if (p_hwirq < 0) {
@@ -328,29 +327,42 @@
 	struct ti_sci_inta_vint_desc *vint_desc = NULL;
 	struct ti_sci_inta_event_desc *event_desc;
 	u16 free_bit;
+	u16 vint_id;
 
 	mutex_lock(&inta->vint_mutex);
-	list_for_each_entry(vint_desc, &inta->vint_list, list) {
+	/*
+	 * Allocate new VINT each time until we runout, then start
+	 * aggregating
+	 */
+	vint_id = ti_sci_get_free_resource(inta->vint);
+	if (vint_id == TI_SCI_RESOURCE_NULL) {
+		list_for_each_entry(vint_desc, &inta->vint_list, list) {
+			if (vint_desc->affinity_managed)
+				continue;
+			free_bit = find_first_zero_bit(vint_desc->event_map,
+						       MAX_EVENTS_PER_VINT);
+			if (free_bit != MAX_EVENTS_PER_VINT) {
+				set_bit(free_bit, vint_desc->event_map);
+				break;
+			}
+		}
+	} else  {
+		vint_desc = ti_sci_inta_alloc_parent_irq(domain, vint_id);
+		if (IS_ERR(vint_desc)) {
+			event_desc = ERR_CAST(vint_desc);
+			goto unlock;
+		}
+
 		free_bit = find_first_zero_bit(vint_desc->event_map,
 					       MAX_EVENTS_PER_VINT);
-		if (free_bit != MAX_EVENTS_PER_VINT) {
-			set_bit(free_bit, vint_desc->event_map);
-			goto alloc_event;
-		}
+		set_bit(free_bit, vint_desc->event_map);
 	}
 
-	/* No free bits available. Allocate a new vint */
-	vint_desc = ti_sci_inta_alloc_parent_irq(domain);
-	if (IS_ERR(vint_desc)) {
-		event_desc = ERR_CAST(vint_desc);
+	if (free_bit == MAX_EVENTS_PER_VINT) {
+		event_desc = ERR_PTR(-EINVAL);
 		goto unlock;
 	}
 
-	free_bit = find_first_zero_bit(vint_desc->event_map,
-				       MAX_EVENTS_PER_VINT);
-	set_bit(free_bit, vint_desc->event_map);
-
-alloc_event:
 	event_desc = ti_sci_inta_alloc_event(vint_desc, free_bit, hwirq);
 	if (IS_ERR(event_desc))
 		clear_bit(free_bit, vint_desc->event_map);
@@ -429,6 +441,7 @@
 		return PTR_ERR(event_desc);
 
 	data->chip_data = event_desc;
+	irq_data_update_effective_affinity(data, cpu_online_mask);
 
 	return 0;
 }
@@ -499,11 +512,48 @@
 		ti_sci_inta_manage_event(data, VINT_STATUS_OFFSET);
 }
 
+#ifdef CONFIG_SMP
+static int ti_sci_inta_set_affinity(struct irq_data *d,
+				    const struct cpumask *mask_val, bool force)
+{
+	struct ti_sci_inta_event_desc *event_desc;
+	struct ti_sci_inta_vint_desc *vint_desc;
+	struct irq_data *parent_irq_data;
+
+	if (cpumask_equal(irq_data_get_effective_affinity_mask(d), mask_val))
+		return 0;
+
+	event_desc = irq_data_get_irq_chip_data(d);
+	if (event_desc) {
+		vint_desc = to_vint_desc(event_desc, event_desc->vint_bit);
+		parent_irq_data = irq_get_irq_data(vint_desc->parent_virq);
+
+		if (!parent_irq_data || !parent_irq_data->chip->irq_set_affinity)
+			return -EINVAL;
+
+		/*
+		 * Cannot set affinity if there is more than one event
+		 * mapped to same VINT
+		 */
+		if (bitmap_weight(vint_desc->event_map, MAX_EVENTS_PER_VINT) > 1)
+			return -EINVAL;
+
+		vint_desc->affinity_managed = true;
+
+		irq_data_update_effective_affinity(d, mask_val);
+
+		return parent_irq_data->chip->irq_set_affinity(parent_irq_data, mask_val, force);
+	}
+
+	return -EINVAL;
+}
+#else
 static int ti_sci_inta_set_affinity(struct irq_data *d,
 				    const struct cpumask *mask_val, bool force)
 {
 	return -EINVAL;
 }
+#endif
 
 /**
  * ti_sci_inta_set_type() - Update the trigger type of the irq.
diff -Naur --no-dereference a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c
--- a/drivers/media/i2c/ds90ub960.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/i2c/ds90ub960.c	2025-10-23 09:30:40.285462207 -0400
@@ -27,6 +27,7 @@
  */
 
 #include <linux/bitops.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/fwnode.h>
@@ -59,11 +60,14 @@
 #define UB960_MAX_RX_NPORTS	4
 #define UB960_MAX_TX_NPORTS	2
 #define UB960_MAX_NPORTS	(UB960_MAX_RX_NPORTS + UB960_MAX_TX_NPORTS)
+#define UB960_MAX_VC		4
 
 #define UB960_MAX_PORT_ALIASES	8
 
 #define UB960_NUM_BC_GPIOS		4
 
+#define UB960_CSI_TX0			BIT(4)
+
 /*
  * Register map
  *
@@ -102,6 +106,7 @@
 #define UB960_SR_SCL_HIGH_TIME			0x0a
 #define UB960_SR_SCL_LOW_TIME			0x0b
 #define UB960_SR_RX_PORT_CTL			0x0c
+#define UB960_SR_RX_PORT_CTL_BCC_MAP		GENMASK(7, 4)
 #define UB960_SR_IO_CTL				0x0d
 #define UB960_SR_GPIO_PIN_STS			0x0e
 #define UB960_SR_GPIO_INPUT_CTL			0x0f
@@ -410,6 +415,7 @@
 	u8 num_txports;
 	bool is_ub9702;
 	bool is_fpdlink4;
+	bool ignore_strobe_pos;
 };
 
 enum ub960_rxport_mode {
@@ -516,6 +522,8 @@
 
 	u32 tx_data_rate;		/* Nominal data rate (Gb/s) */
 	s64 tx_link_freq[1];
+	u8 rx_mask;
+	u8 tx_mask;
 
 	struct i2c_atr *atr;
 
@@ -580,6 +588,24 @@
 	{ .code = MEDIA_BUS_FMT_SGBRG12_1X12, .bpp = 12, .datatype = MIPI_CSI2_DT_RAW12, },
 	{ .code = MEDIA_BUS_FMT_SGRBG12_1X12, .bpp = 12, .datatype = MIPI_CSI2_DT_RAW12, },
 	{ .code = MEDIA_BUS_FMT_SRGGB12_1X12, .bpp = 12, .datatype = MIPI_CSI2_DT_RAW12, },
+
+	{ .code	= MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, .datatype = MIPI_CSI2_DT_RAW8, },
+	{ .code	= MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, .datatype = MIPI_CSI2_DT_RAW8, },
+	{ .code	= MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, .datatype = MIPI_CSI2_DT_RAW8, },
+	{ .code	= MEDIA_BUS_FMT_SBGGR8_1X8, .bpp = 8, .datatype = MIPI_CSI2_DT_RAW8, },
+	{ .code	= MEDIA_BUS_FMT_SRGGB10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, },
+	{ .code	= MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, },
+	{ .code	= MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, },
+	{ .code	= MEDIA_BUS_FMT_SBGGR10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, },
+
+	{ .code	= MEDIA_BUS_FMT_SRGGI10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, },
+	{ .code	= MEDIA_BUS_FMT_SGRIG10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, },
+	{ .code	= MEDIA_BUS_FMT_SBGGI10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, },
+	{ .code	= MEDIA_BUS_FMT_SGBIG10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, },
+	{ .code	= MEDIA_BUS_FMT_SGIRG10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, },
+	{ .code	= MEDIA_BUS_FMT_SIGGR10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, },
+	{ .code	= MEDIA_BUS_FMT_SGIBG10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, },
+	{ .code	= MEDIA_BUS_FMT_SIGGB10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, },
 };
 
 static const struct ub960_format_info *ub960_find_format(u32 code)
@@ -1415,7 +1441,7 @@
 
 	if (priv->strobe.manual)
 		ub960_rxport_set_strobe_pos(priv, nport, rxport->eq.strobe_pos);
-	else
+	else if (!priv->hw_data->ignore_strobe_pos)
 		ub960_rxport_set_strobe_pos(priv, nport, 0);
 
 	if (rxport->eq.manual_eq) {
@@ -2143,6 +2169,17 @@
 static int ub960_init_rx_ports(struct ub960_data *priv)
 {
 	unsigned int nport;
+	u8 enabled_rxports_mask;
+	u8 enabled_rxports;
+	int ret;
+
+	/* Configure I2C interface for RX ports */
+	enabled_rxports_mask = FIELD_PREP(UB960_SR_RX_PORT_CTL_BCC_MAP, priv->rx_mask);
+	enabled_rxports = (priv->tx_mask & UB960_CSI_TX0)  ? 0x00 : enabled_rxports_mask;
+
+	ret = ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, enabled_rxports_mask, enabled_rxports);
+	if (ret)
+		return ret;
 
 	for (nport = 0; nport < priv->hw_data->num_rxports; nport++) {
 		struct ub960_rxport *rxport = priv->rxports[nport];
@@ -2284,40 +2321,78 @@
  */
 
 /*
- * The current implementation only supports a simple VC mapping, where all VCs
- * from a one RX port will be mapped to the same VC. Also, the hardware
- * dictates that all streams from an RX port must go to a single TX port.
- *
- * This function decides the target VC numbers for each RX port with a simple
- * algorithm, so that for each TX port, we get VC numbers starting from 0,
- * and counting up.
+ * Map incoming streams with different virtual channels from 1-4 sensors to
+ * unique VCs on CSI TX0. Sensors using multiple VCs will work, but due to
+ * limited total channels (4) this will reduce the total number of sensors that
+ * can work simultaneously.
  *
- * E.g. if all four RX ports are in use, of which the first two go to the
- * first TX port and the secont two go to the second TX port, we would get
- * the following VCs for the four RX ports: 0, 1, 0, 1.
+ * The current implementation is limited to using a single CSI TX port (TX0),
+ * as that is the most common HW configuration found on boards with DS90UB960.
+ * For using both CSI TX0 & TX1 the below method will need significant changes.
  *
  * TODO: implement a more sophisticated VC mapping. As the driver cannot know
  * what VCs the sinks expect (say, an FPGA with hardcoded VC routing), this
  * probably needs to be somehow configurable. Device tree?
  */
-static void ub960_get_vc_maps(struct ub960_data *priv,
-			      struct v4l2_subdev_state *state, u8 *vc)
+static void ub960_get_vc_maps(struct ub960_data *priv, u8 *vc_map)
 {
-	u8 cur_vc[UB960_MAX_TX_NPORTS] = {};
-	struct v4l2_subdev_route *route;
-	u8 handled_mask = 0;
+	struct device *dev = &priv->client->dev;
+	u8 nport, available_vc = 0;
 
-	for_each_active_route(&state->routing, route) {
-		unsigned int rx, tx;
+	for (nport = 0;
+	     nport < priv->hw_data->num_rxports && priv->rxports[nport];
+	     ++nport) {
+		struct v4l2_mbus_frame_desc source_fd;
+		bool used_vc[UB960_MAX_VC] = {false};
+		u8 vc, cur_vc = available_vc;
+		int j, ret;
+		u8 map;
+
+		ret = v4l2_subdev_call(priv->rxports[nport]->source.sd, pad,
+				       get_frame_desc,
+				       priv->rxports[nport]->source.pad,
+				       &source_fd);
+		/* Mark channels used in source in used_vc[] */
+		if (!ret) {
+			for (j = 0; j < source_fd.num_entries; ++j) {
+				u8 source_vc = source_fd.entry[j].bus.csi2.vc;
 
-		rx = ub960_pad_to_port(priv, route->sink_pad);
-		if (BIT(rx) & handled_mask)
+				if (source_vc < UB960_MAX_VC)
+					used_vc[source_vc] = true;
+			}
+		} else if (ret == -ENOIOCTLCMD) {
+			/* assume VC=0 is used if sensor driver doesn't provide info */
+			used_vc[0] = true;
+		} else {
 			continue;
+		}
 
-		tx = ub960_pad_to_port(priv, route->source_pad);
+		/* Start with all channels mapped to first free output */
+		map = (cur_vc << 6) | (cur_vc << 4) | (cur_vc << 2) |
+			(cur_vc << 0);
+
+		/* Map actually used to channels to distinct free outputs */
+		for (vc = 0; vc < UB960_MAX_VC; ++vc) {
+			if (used_vc[vc]) {
+				map &= ~(0x03 << (2 * vc));
+				map |= (cur_vc << (2 * vc));
+				++cur_vc;
+			}
+		}
 
-		vc[rx] = cur_vc[tx]++;
-		handled_mask |= BIT(rx);
+		/* Don't enable port if we ran out of available channels */
+		if (cur_vc > UB960_MAX_VC) {
+			dev_err(dev,
+				"No VCs available for RX port %d\n",
+				nport);
+			continue;
+		}
+
+		/* Enable port and update map */
+		vc_map[nport] = map;
+		available_vc = cur_vc;
+		dev_dbg(dev, "%s: VC map for port %d is 0x%02x",
+			__func__, nport, map);
 	}
 }
 
@@ -2365,55 +2440,10 @@
 			  UB960_SR_FWD_CTL1_PORT_DIS(nport));
 }
 
-/*
- * The driver only supports using a single VC for each source. This function
- * checks that each source only provides streams using a single VC.
- */
-static int ub960_validate_stream_vcs(struct ub960_data *priv)
-{
-	unsigned int nport;
-	unsigned int i;
-
-	for (nport = 0; nport < priv->hw_data->num_rxports; nport++) {
-		struct ub960_rxport *rxport = priv->rxports[nport];
-		struct v4l2_mbus_frame_desc desc;
-		int ret;
-		u8 vc;
-
-		if (!rxport)
-			continue;
-
-		ret = v4l2_subdev_call(rxport->source.sd, pad, get_frame_desc,
-				       rxport->source.pad, &desc);
-		if (ret)
-			return ret;
-
-		if (desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2)
-			continue;
-
-		if (desc.num_entries == 0)
-			continue;
-
-		vc = desc.entry[0].bus.csi2.vc;
-
-		for (i = 1; i < desc.num_entries; i++) {
-			if (vc == desc.entry[i].bus.csi2.vc)
-				continue;
-
-			dev_err(&priv->client->dev,
-				"rx%u: source with multiple virtual-channels is not supported\n",
-				nport);
-			return -ENODEV;
-		}
-	}
-
-	return 0;
-}
-
 static int ub960_configure_ports_for_streaming(struct ub960_data *priv,
 					       struct v4l2_subdev_state *state)
 {
-	u8 fwd_ctl;
+	u8 fwd_ctl = 0;
 	struct {
 		u32 num_streams;
 		u8 pixel_dt;
@@ -2426,11 +2456,7 @@
 	unsigned int nport;
 	int ret;
 
-	ret = ub960_validate_stream_vcs(priv);
-	if (ret)
-		return ret;
-
-	ub960_get_vc_maps(priv, state, vc_map);
+	ub960_get_vc_maps(priv, vc_map);
 
 	for_each_active_route(&state->routing, route) {
 		struct ub960_rxport *rxport;
@@ -2485,17 +2511,8 @@
 		}
 	}
 
-	/* Configure RX ports */
-
-	/*
-	 * Keep all port forwardings disabled by default. Forwarding will be
-	 * enabled in ub960_enable_rx_port.
-	 */
-	fwd_ctl = GENMASK(7, 4);
-
 	for (nport = 0; nport < priv->hw_data->num_rxports; nport++) {
 		struct ub960_rxport *rxport = priv->rxports[nport];
-		u8 vc = vc_map[nport];
 
 		if (rx_data[nport].num_streams == 0)
 			continue;
@@ -2503,7 +2520,7 @@
 		switch (rxport->rx_mode) {
 		case RXPORT_MODE_RAW10:
 			ub960_rxport_write(priv, nport, UB960_RR_RAW10_ID,
-				rx_data[nport].pixel_dt | (vc << UB960_RR_RAW10_ID_VC_SHIFT));
+				rx_data[nport].pixel_dt | (nport << UB960_RR_RAW10_ID_VC_SHIFT));
 
 			ub960_rxport_write(priv, rxport->nport,
 				UB960_RR_RAW_EMBED_DTYPE,
@@ -2520,12 +2537,9 @@
 		case RXPORT_MODE_CSI2_SYNC:
 		case RXPORT_MODE_CSI2_NONSYNC:
 			if (!priv->hw_data->is_ub9702) {
-				/* Map all VCs from this port to the same VC */
-				ub960_rxport_write(priv, nport, UB960_RR_CSI_VC_MAP,
-						   (vc << UB960_RR_CSI_VC_MAP_SHIFT(3)) |
-						   (vc << UB960_RR_CSI_VC_MAP_SHIFT(2)) |
-						   (vc << UB960_RR_CSI_VC_MAP_SHIFT(1)) |
-						   (vc << UB960_RR_CSI_VC_MAP_SHIFT(0)));
+				ub960_rxport_write(priv, nport,
+						   UB960_RR_CSI_VC_MAP,
+						   vc_map[nport]);
 			} else {
 				unsigned int i;
 
@@ -2545,9 +2559,9 @@
 			fwd_ctl &= ~BIT(nport); /* forward to TX0 */
 	}
 
-	ub960_write(priv, UB960_SR_FWD_CTL1, fwd_ctl);
+	ret = ub960_update_bits(priv, UB960_SR_FWD_CTL1, priv->rx_mask, fwd_ctl);
 
-	return 0;
+	return ret;
 }
 
 static void ub960_update_streaming_status(struct ub960_data *priv)
@@ -2782,6 +2796,11 @@
 	return _ub960_set_routing(sd, state, routing);
 }
 
+static inline u8 ub960_get_output_vc(u8 map, u8 input_vc)
+{
+	return (map >> (2 * input_vc)) & 0x03;
+}
+
 static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 				struct v4l2_mbus_frame_desc *fd)
 {
@@ -2799,7 +2818,7 @@
 
 	state = v4l2_subdev_lock_and_get_active_state(&priv->sd);
 
-	ub960_get_vc_maps(priv, state, vc_map);
+	ub960_get_vc_maps(priv, vc_map);
 
 	for_each_active_route(&state->routing, route) {
 		struct v4l2_mbus_frame_desc_entry *source_entry = NULL;
@@ -2842,7 +2861,12 @@
 		fd->entry[fd->num_entries].length = source_entry->length;
 		fd->entry[fd->num_entries].pixelcode = source_entry->pixelcode;
 
-		fd->entry[fd->num_entries].bus.csi2.vc = vc_map[nport];
+		fd->entry[fd->num_entries].bus.csi2.vc =
+			ub960_get_output_vc(vc_map[nport],
+					    source_entry->bus.csi2.vc);
+		dev_dbg(dev, "Mapping sink %d/%d to output VC %d",
+			route->sink_pad, route->sink_stream,
+			fd->entry[fd->num_entries].bus.csi2.vc);
 
 		if (source_fd.type == V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
 			fd->entry[fd->num_entries].bus.csi2.dt =
@@ -3542,6 +3566,30 @@
 	return 0;
 }
 
+static void ub960_parse_active_ports(struct ub960_data *priv)
+{
+	struct device *dev = &priv->client->dev;
+	int nport;
+
+	priv->rx_mask = 0;
+	priv->tx_mask = 0;
+
+	for (nport = 0; nport < priv->hw_data->num_rxports + priv->hw_data->num_txports; nport++) {
+		struct fwnode_handle *ep_fwnode;
+
+		ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), nport, 0, 0);
+		if (!ep_fwnode)
+			continue;
+
+		if (nport < priv->hw_data->num_rxports)
+			priv->rx_mask |= BIT(nport);
+		else
+			priv->tx_mask |= BIT(nport);
+
+		fwnode_handle_put(ep_fwnode);
+	}
+}
+
 static int ub960_parse_dt(struct ub960_data *priv)
 {
 	int ret;
@@ -3868,11 +3916,6 @@
 		!!(dev_sts & BIT(4)), refclk_freq,
 		clk_get_rate(priv->refclk) / 1000000);
 
-	/* Disable all RX ports by default */
-	ret = ub960_write(priv, UB960_SR_RX_PORT_CTL, 0);
-	if (ret)
-		goto err_pd_gpio;
-
 	/* release GPIO lock */
 	if (priv->hw_data->is_ub9702) {
 		ret = ub960_update_bits(priv, UB960_SR_RESET,
@@ -3937,6 +3980,8 @@
 	if (ret)
 		goto err_mutex_destroy;
 
+	ub960_parse_active_ports(priv);
+
 	ret = ub960_parse_dt(priv);
 	if (ret)
 		goto err_disable_core_hw;
@@ -4035,6 +4080,13 @@
 	mutex_destroy(&priv->reg_lock);
 }
 
+static const struct ub960_hw_data ds90ub954_hw = {
+	.model = "ub954",
+	.num_rxports = 2,
+	.num_txports = 1,
+	.ignore_strobe_pos = true,
+};
+
 static const struct ub960_hw_data ds90ub960_hw = {
 	.model = "ub960",
 	.num_rxports = 4,
@@ -4050,6 +4102,7 @@
 };
 
 static const struct i2c_device_id ub960_id[] = {
+	{ "ds90ub954-q1", (kernel_ulong_t)&ds90ub954_hw },
 	{ "ds90ub960-q1", (kernel_ulong_t)&ds90ub960_hw },
 	{ "ds90ub9702-q1", (kernel_ulong_t)&ds90ub9702_hw },
 	{}
@@ -4057,6 +4110,7 @@
 MODULE_DEVICE_TABLE(i2c, ub960_id);
 
 static const struct of_device_id ub960_dt_ids[] = {
+	{ .compatible = "ti,ds90ub954-q1", .data = &ds90ub954_hw },
 	{ .compatible = "ti,ds90ub960-q1", .data = &ds90ub960_hw },
 	{ .compatible = "ti,ds90ub9702-q1", .data = &ds90ub9702_hw },
 	{}
diff -Naur --no-dereference a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
--- a/drivers/media/i2c/imx219.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/i2c/imx219.c	2025-10-23 09:30:40.285462207 -0400
@@ -29,6 +29,7 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-mediabus.h>
+#include <media/v4l2-subdev.h>
 
 /* Chip ID */
 #define IMX219_REG_CHIP_ID		CCI_REG16(0x0000)
@@ -485,6 +486,49 @@
 	return (imx219->lanes == 2) ? IMX219_PIXEL_RATE : IMX219_PIXEL_RATE_4LANE;
 }
 
+
+static int imx219_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+				 struct v4l2_mbus_frame_desc *fd)
+{
+	struct v4l2_mbus_framefmt *format;
+	struct v4l2_subdev_state *state;
+	u32 bpp;
+	int ret = 0;
+
+	if (pad != 0)
+		return -EINVAL;
+
+	memset(fd, 0, sizeof(*fd));
+
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+
+	state = v4l2_subdev_lock_and_get_active_state(sd);
+	format = v4l2_subdev_state_get_format(state, 0);
+
+	/* pixel stream */
+
+	if (format->code == MEDIA_BUS_FMT_SRGGB10_1X10)
+		bpp = 10;
+	else
+		bpp = 8;
+
+	fd->entry[fd->num_entries].stream = 0;
+
+	fd->entry[fd->num_entries].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
+	fd->entry[fd->num_entries].length = (format->width * format->height * bpp) / 8;
+	fd->entry[fd->num_entries].pixelcode = format->code;
+	fd->entry[fd->num_entries].bus.csi2.vc = 0;
+	if (format->code == MEDIA_BUS_FMT_SRGGB8_1X8)
+		fd->entry[fd->num_entries].bus.csi2.dt = 0x2a; /* SRGGB8 */
+	else if (format->code == MEDIA_BUS_FMT_SRGGB10_1X10)
+		fd->entry[fd->num_entries].bus.csi2.dt = 0x2b; /* SRGGB10 */
+	fd->num_entries++;
+
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
 /* Initialize control handlers */
 static int imx219_init_controls(struct imx219 *imx219)
 {
@@ -963,6 +1007,7 @@
 	.get_fmt = v4l2_subdev_get_fmt,
 	.set_fmt = imx219_set_pad_format,
 	.get_selection = imx219_get_selection,
+	.get_frame_desc = imx219_get_frame_desc,
 	.enum_frame_size = imx219_enum_frame_size,
 };
 
diff -Naur --no-dereference a/drivers/media/i2c/imx390.c b/drivers/media/i2c/imx390.c
--- a/drivers/media/i2c/imx390.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/media/i2c/imx390.c	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,891 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Sony IMX390 CMOS Image Sensor Driver
+ *
+ * Copyright (c) 2021 Apurva Nandan <a-nandan@ti.com>
+ *
+ * Copyright (c) 2021 Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+
+#include "imx390.h"
+
+static inline struct imx390 *to_imx390(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct imx390, subdev);
+}
+
+static int imx390_read(struct imx390 *imx390, u16 addr, u32 *val, size_t nbytes)
+{
+	int ret;
+	__le32 val_le = 0;
+
+	ret = regmap_bulk_read(imx390->regmap, addr, &val_le, nbytes);
+	if (ret < 0) {
+		dev_err(imx390->dev, "%s: failed to read reg 0x%04x: %d\n",
+			__func__, addr, ret);
+		return ret;
+	}
+
+	*val = le32_to_cpu(val_le);
+	return 0;
+}
+
+static int imx390_write(struct imx390 *imx390, u16 addr, u32 val, size_t nbytes)
+{
+	int ret;
+	__le32 val_le = cpu_to_le32(val);
+
+	ret = regmap_bulk_write(imx390->regmap, addr, &val_le, nbytes);
+	if (ret < 0)
+		dev_err(imx390->dev, "%s: failed to write reg 0x%04x: %d\n",
+			__func__, addr, ret);
+	return ret;
+}
+
+static int imx390_update_bits(struct imx390 *imx390, u16 addr, u32 val,
+			      u32 mask, size_t nbytes)
+{
+	int ret;
+	u32 cfg;
+
+	ret = imx390_read(imx390, addr, &cfg, nbytes);
+	if (ret < 0)
+		return ret;
+
+	cfg = (val) ? (cfg | mask) : (cfg & (~mask));
+
+	return imx390_write(imx390, addr, cfg, nbytes);
+}
+
+static int imx390_write_table(struct imx390 *imx390,
+			      const struct reg_sequence *regs,
+			      unsigned int nr_regs)
+{
+	int ret;
+
+	ret = regmap_multi_reg_write(imx390->regmap, regs, nr_regs);
+	if (ret < 0)
+		dev_err(imx390->dev,
+			"%s: failed to write reg table (%d)!\n", __func__, ret);
+	return ret;
+}
+
+static void imx390_init_formats(struct v4l2_subdev_state *state)
+{
+	struct v4l2_mbus_framefmt *format;
+
+	format = v4l2_subdev_state_get_format(state, 0, 0);
+	format->code = imx390_mbus_formats[0];
+	format->width = imx390_framesizes[0].width;
+	format->height = imx390_framesizes[0].height;
+	format->field = V4L2_FIELD_NONE;
+	format->colorspace = V4L2_COLORSPACE_SMPTE170M;
+}
+
+static int _imx390_set_routing(struct v4l2_subdev *sd,
+			       struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_route routes[] = {
+		{
+			.source_pad = 0,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+		{
+			.source_pad = 0,
+			.source_stream = 1,
+		}
+	};
+
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+
+	int ret;
+
+	ret = v4l2_subdev_set_routing(sd, state, &routing);
+	if (ret < 0)
+		return ret;
+
+	imx390_init_formats(state);
+
+	return 0;
+}
+
+static int imx390_init_state(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state)
+{
+	int ret;
+
+	ret = _imx390_set_routing(sd, state);
+
+	return ret;
+}
+
+static int imx390_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *state,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index >= ARRAY_SIZE(imx390_mbus_formats))
+		return -EINVAL;
+
+	code->code = imx390_mbus_formats[code->index];
+
+	return 0;
+}
+
+static int imx390_enum_frame_sizes(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_state *state,
+				   struct v4l2_subdev_frame_size_enum *fse)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(imx390_mbus_formats); ++i) {
+		if (imx390_mbus_formats[i] == fse->code)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(imx390_mbus_formats))
+		return -EINVAL;
+
+	if (fse->index >= ARRAY_SIZE(imx390_framesizes))
+		return -EINVAL;
+
+	fse->min_width = imx390_framesizes[fse->index].width;
+	fse->max_width = fse->min_width;
+	fse->max_height = imx390_framesizes[fse->index].height;
+	fse->min_height = fse->max_height;
+
+	return 0;
+}
+
+static int imx390_set_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_state *state,
+			  struct v4l2_subdev_format *fmt)
+{
+	struct imx390 *imx390 = to_imx390(sd);
+	struct v4l2_mbus_framefmt *format;
+	const struct v4l2_area *fsize;
+	unsigned int i;
+	u32 code;
+	int ret = 0;
+
+	if (fmt->pad != 0)
+		return -EINVAL;
+
+	if (fmt->stream != 0)
+		return -EINVAL;
+
+	/*
+	 * Validate the media bus code, defaulting to the first one if the
+	 * requested code isn't supported.
+	 */
+	for (i = 0; i < ARRAY_SIZE(imx390_mbus_formats); ++i) {
+		if (imx390_mbus_formats[i] == fmt->format.code) {
+			code = fmt->format.code;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(imx390_mbus_formats))
+		code = imx390_mbus_formats[0];
+
+	/* Find the nearest supported frame size. */
+	fsize = v4l2_find_nearest_size(imx390_framesizes,
+				       ARRAY_SIZE(imx390_framesizes), width,
+				       height, fmt->format.width,
+				       fmt->format.height);
+
+	v4l2_subdev_lock_state(state);
+
+	/* Update the stored format and return it. */
+	format = v4l2_subdev_state_get_format(state, fmt->pad, fmt->stream);
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE && imx390->streaming) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	format->code = code;
+	format->width = fsize->width;
+	format->height = fsize->height;
+
+	fmt->format = *format;
+
+done:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int imx390_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+				 struct v4l2_mbus_frame_desc *fd)
+{
+	struct v4l2_subdev_state *state;
+	struct v4l2_mbus_framefmt *fmt;
+	u32 bpp;
+	int ret = 0;
+
+	if (pad != 0)
+		return -EINVAL;
+
+	state = v4l2_subdev_lock_and_get_active_state(sd);
+
+	fmt = v4l2_subdev_state_get_format(state, 0, 0);
+	if (!fmt) {
+		ret = -EPIPE;
+		goto out;
+	}
+
+	memset(fd, 0, sizeof(*fd));
+
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+
+	/* pixel stream */
+
+	bpp = 12;
+
+	fd->entry[fd->num_entries].stream = 0;
+
+	fd->entry[fd->num_entries].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
+	fd->entry[fd->num_entries].length = fmt->width * fmt->height * bpp / 8;
+	fd->entry[fd->num_entries].pixelcode = fmt->code;
+	fd->entry[fd->num_entries].bus.csi2.vc = 0;
+	fd->entry[fd->num_entries].bus.csi2.dt = 0x2c; /* SRGGB12 */
+
+	fd->num_entries++;
+
+out:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int imx390_set_routing(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_state *state,
+			      enum v4l2_subdev_format_whence which,
+			      struct v4l2_subdev_krouting *routing)
+{
+	int ret;
+
+	if (routing->num_routes == 0 || routing->num_routes > 1)
+		return -EINVAL;
+
+	ret = _imx390_set_routing(sd, state);
+
+	return ret;
+}
+
+static int imx390_check_non_wdr_mode_fps(struct imx390 *imx390, bool enable)
+{
+	if (!enable && imx390->fps > IMX390_FRAMERATE_MAX_LINEAR) {
+		dev_err(imx390->dev,
+			"%s: failed, %dFPS unsupported in non-WDR mode\n",
+			__func__, imx390->fps);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int imx390_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct imx390 *imx390 = container_of(ctrl->handler,
+					     struct imx390, ctrl.handler);
+	int ret;
+
+	dev_dbg(imx390->dev,
+		"%s: %s, value: %d\n", __func__, ctrl->name, ctrl->val);
+
+	/* V4L2 controls values will be applied only when power is already up */
+	if (!pm_runtime_get_if_in_use(imx390->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_WIDE_DYNAMIC_RANGE:
+		ret = imx390_check_non_wdr_mode_fps(imx390, ctrl->val);
+		break;
+
+	case V4L2_CID_EXPOSURE:
+		ret = imx390_write(imx390, IMX390_REG_CAT0_SHS1,
+				   IMX390_EXPOSURE_SHS_VAL(ctrl->val,
+							   imx390->fps), 3);
+		break;
+
+	case V4L2_CID_ANALOGUE_GAIN:
+		ret = imx390_write(imx390, IMX390_REG_CAT0_AGAIN_SP1H,
+				   ctrl->val, 2);
+		if (ret < 0)
+			break;
+
+		ret = imx390_write(imx390, IMX390_REG_CAT0_AGAIN_SP1L,
+				   ctrl->val / IMX390_AGAIN_CONV_GAIN_RATIO, 2);
+		break;
+
+	case V4L2_CID_DIGITAL_GAIN:
+		ret = imx390_write(imx390, IMX390_REG_CAT0_PGA_GAIN,
+				   ctrl->val, 2);
+		break;
+
+	case V4L2_CID_RED_BALANCE:
+		ret = imx390_write(imx390, IMX390_REG_CAT0_WBGAIN_R,
+				   ctrl->val, 2);
+		break;
+
+	case V4L2_CID_BLUE_BALANCE:
+		ret = imx390_write(imx390, IMX390_REG_CAT0_WBGAIN_B,
+				   ctrl->val, 2);
+		break;
+
+	case V4L2_CID_HFLIP:
+		ret = imx390_update_bits(imx390, IMX390_REG_CAT0_V_H_REVERSE,
+					 ctrl->val, IMX390_H_REV_MASK, 1);
+		if (ret < 0)
+			break;
+
+		ret = imx390_update_bits(imx390, IMX390_REG_SM_CFG_REVERSE_APL,
+					 ctrl->val, IMX390_H_REV_APL_MASK, 1);
+		break;
+
+	case V4L2_CID_VFLIP:
+		ret = imx390_update_bits(imx390, IMX390_REG_CAT0_V_H_REVERSE,
+					 ctrl->val, IMX390_V_REV_MASK, 1);
+		if (ret < 0)
+			break;
+
+		ret = imx390_update_bits(imx390, IMX390_REG_SM_CFG_REVERSE_APL,
+					 ctrl->val, IMX390_V_REV_APL_MASK, 1);
+		break;
+
+	case V4L2_CID_TEST_PATTERN:
+		ret = imx390_write(imx390, IMX390_REG_CAT0_PGMODE_PGREGEN,
+				   imx390_pg_mode_reg_val[ctrl->val], 1);
+		if (ret < 0)
+			break;
+
+		ret = imx390_update_bits(imx390, IMX390_SM_CFG_SM_PGREGEN_APL,
+					 ctrl->val, IMX390_SM_PG_APL_MASK, 1);
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+
+	pm_runtime_put_noidle(imx390->dev);
+	return ret;
+}
+
+static int imx390_detect(struct imx390 *imx390)
+{
+	int ret;
+	u32 id;
+
+	ret = imx390_read(imx390, IMX390_REG_VERSION_ROM_VERSION, &id, 2);
+	if (ret < 0)
+		return ret;
+
+	if (id != IMX390_ROM_VERSION) {
+		dev_err(imx390->dev,
+			"%s: unknown chip ID 0x%04x\n", __func__, id);
+		return -ENODEV;
+	}
+
+	dev_dbg(imx390->dev, "%s: detected chip ID 0x%04x\n", __func__, id);
+	return 0;
+}
+
+static int imx390_power_on(struct imx390 *imx390)
+{
+	int ret;
+
+	ret = clk_prepare_enable(imx390->clk);
+	if (ret < 0)
+		return ret;
+
+	if (imx390->xclr_gpio) {
+		gpiod_set_value_cansleep(imx390->xclr_gpio, 1);
+		/* Keep the XCLR pin on Low for 100 us or longer */
+		usleep_range(100, 1000);
+		gpiod_set_value_cansleep(imx390->xclr_gpio, 0);
+		/* It takes max 30 ms for the sensor to be ready */
+		msleep(30);
+	}
+	return 0;
+}
+
+static void imx390_power_off(struct imx390 *imx390)
+{
+	if (imx390->xclr_gpio) {
+		gpiod_set_value_cansleep(imx390->xclr_gpio, 1);
+		/* Wait for the XCLR pin to be Low for at least 1 us */
+		usleep_range(1, 10);
+	}
+
+	clk_disable_unprepare(imx390->clk);
+}
+
+static int imx390_get_frame_interval(struct v4l2_subdev *sd,
+				     struct v4l2_subdev_state *sd_state,
+				     struct v4l2_subdev_frame_interval *fi)
+{
+	struct imx390 *imx390 = to_imx390(sd);
+
+	fi->interval.numerator = 1;
+	fi->interval.denominator = imx390->fps;
+	return 0;
+}
+
+static int imx390_set_frame_interval(struct v4l2_subdev *sd,
+				     struct v4l2_subdev_state *sd_state,
+				     struct v4l2_subdev_frame_interval *fi)
+{
+	struct imx390 *imx390 = to_imx390(sd);
+	struct v4l2_ctrl *ctrl = imx390->ctrl.exposure;
+	u32 req_fps;
+	int ret;
+
+	mutex_lock(&imx390->lock);
+
+	if (fi->interval.numerator == 0 || fi->interval.denominator == 0) {
+		fi->interval.denominator = IMX390_FRAMERATE_DEFAULT;
+		fi->interval.numerator = 1;
+	}
+
+	req_fps = clamp_val(DIV_ROUND_CLOSEST(fi->interval.denominator,
+					      fi->interval.numerator),
+			    IMX390_FRAMERATE_MIN, IMX390_FRAMERATE_MAX);
+
+	fi->interval.numerator = 1;
+	fi->interval.denominator = req_fps;
+
+	imx390->fps = req_fps;
+
+	ret = __v4l2_ctrl_modify_range(ctrl, 0, IMX390_EXPOSURE_MAX(req_fps), 1,
+				       IMX390_EXPOSURE_DEFAULT);
+	if (ret < 0) {
+		dev_err(imx390->dev,
+			"%s: exposure ctrl range update failed %d\n",
+			__func__, ret);
+	}
+
+	mutex_unlock(&imx390->lock);
+	dev_dbg(imx390->dev, "%s frame rate = %d\n", __func__, imx390->fps);
+
+	return ret;
+}
+
+static int imx390_start_stream(struct imx390 *imx390)
+{
+	int ret;
+
+	if (!imx390->ctrl.wdr->val &&
+	    imx390->fps <= IMX390_FRAMERATE_MAX_LINEAR)
+		ret = imx390_write_table(imx390, imx390_linear_1936x1096,
+					 ARRAY_SIZE(imx390_linear_1936x1096));
+	else
+		ret = imx390_write_table(imx390, imx390_wdr_1936x1096,
+					 ARRAY_SIZE(imx390_wdr_1936x1096));
+	if (ret < 0)
+		return ret;
+
+	msleep(100);
+
+	/* Restore the V4L2 control values into the registers */
+	ret =  __v4l2_ctrl_handler_setup(imx390->subdev.ctrl_handler);
+	if (ret < 0) {
+		dev_err(imx390->dev,
+			"%s: failed to apply v4l2 ctrls: %d\n", __func__, ret);
+		return ret;
+	}
+
+	ret = imx390_write(imx390, IMX390_REG_MODE_HMAX,
+			   (u32)IMX390_FPS_TO_MODE_HMAX(imx390->fps), 2);
+	if (ret < 0)
+		return ret;
+
+	/* Set active */
+	ret = imx390_write(imx390, IMX390_REG_CAT0_STANDBY, 0, 1);
+	if (ret < 0)
+		return ret;
+
+	/* No communication is possible for a while after exiting standby */
+	msleep(20);
+
+	return 0;
+}
+
+static int imx390_stop_stream(struct imx390 *imx390)
+{
+	int ret;
+
+	/* Set standby */
+	ret = imx390_write(imx390, IMX390_REG_CAT0_STANDBY, 1, 1);
+	if (ret < 0)
+		return ret;
+
+	/* No communication is possible for a while after entering standby */
+	usleep_range(10000, 20000);
+	return 0;
+}
+
+static int imx390_set_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct imx390 *imx390 = to_imx390(sd);
+	int ret;
+
+	mutex_lock(&imx390->lock);
+	if (imx390->streaming == enable) {
+		mutex_unlock(&imx390->lock);
+		return 0;
+	}
+
+	if (enable) {
+		ret = pm_runtime_get_sync(imx390->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(imx390->dev);
+			goto err_unlock;
+		}
+
+		ret = imx390_start_stream(imx390);
+		if (ret < 0)
+			goto err_runtime_put;
+	} else {
+		ret = imx390_stop_stream(imx390);
+		if (ret < 0)
+			goto err_runtime_put;
+		pm_runtime_mark_last_busy(imx390->dev);
+		pm_runtime_put_autosuspend(imx390->dev);
+	}
+
+	imx390->streaming = enable;
+	/* WDR, HFLIP, VFLIP, TEST PATTERN cannot change during streaming */
+	__v4l2_ctrl_grab(imx390->ctrl.wdr, enable);
+	__v4l2_ctrl_grab(imx390->ctrl.h_flip, enable);
+	__v4l2_ctrl_grab(imx390->ctrl.v_flip, enable);
+	__v4l2_ctrl_grab(imx390->ctrl.pg_mode, enable);
+
+	mutex_unlock(&imx390->lock);
+	return 0;
+
+err_runtime_put:
+	pm_runtime_put(imx390->dev);
+
+err_unlock:
+	mutex_unlock(&imx390->lock);
+	dev_err(imx390->dev,
+		"%s: failed to setup streaming %d\n", __func__, ret);
+	return ret;
+}
+
+static const struct v4l2_subdev_video_ops imx390_subdev_video_ops = {
+	.s_stream = imx390_set_stream,
+};
+
+static const struct v4l2_subdev_pad_ops imx390_subdev_pad_ops = {
+	.enum_mbus_code	= imx390_enum_mbus_code,
+	.enum_frame_size = imx390_enum_frame_sizes,
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = imx390_set_fmt,
+	.set_routing = imx390_set_routing,
+	.get_frame_desc	= imx390_get_frame_desc,
+	.get_frame_interval = imx390_get_frame_interval,
+	.set_frame_interval = imx390_set_frame_interval,
+};
+
+static const struct v4l2_subdev_ops imx390_subdev_ops = {
+	.video	= &imx390_subdev_video_ops,
+	.pad	= &imx390_subdev_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops imx390_internal_ops = {
+	.init_state = imx390_init_state,
+};
+
+static const struct v4l2_ctrl_ops imx390_ctrl_ops = {
+	.s_ctrl	= imx390_set_ctrl,
+};
+
+static int imx390_probe(struct i2c_client *client)
+{
+	struct imx390 *imx390;
+	struct v4l2_subdev *sd;
+	struct v4l2_ctrl_handler *ctrl_hdr;
+	int ret;
+
+	imx390 = devm_kzalloc(&client->dev, sizeof(*imx390), GFP_KERNEL);
+	if (!imx390)
+		return -ENOMEM;
+
+	imx390->dev = &client->dev;
+
+	imx390->regmap = devm_regmap_init_i2c(client, &imx390_regmap_config);
+	if (IS_ERR(imx390->regmap))
+		return PTR_ERR(imx390->regmap);
+
+	imx390->xclr_gpio = devm_gpiod_get_optional(imx390->dev,
+						    "xclr", GPIOD_OUT_LOW);
+	if (IS_ERR(imx390->xclr_gpio))
+		return PTR_ERR(imx390->xclr_gpio);
+
+	imx390->clk = devm_clk_get(imx390->dev, "inck");
+	if (IS_ERR(imx390->clk))
+		return PTR_ERR(imx390->clk);
+
+	imx390->clk_rate = clk_get_rate(imx390->clk);
+	dev_info(imx390->dev, "inck rate: %lu Hz\n", imx390->clk_rate);
+
+	if (imx390->clk_rate < 5900000 || imx390->clk_rate > 27100000)
+		return -EINVAL;
+
+	ret = imx390_power_on(imx390);
+	if (ret < 0)
+		return ret;
+
+	ret = imx390_detect(imx390);
+	if (ret < 0)
+		return ret;
+
+	/* Initialize the subdev and its controls. */
+	sd = &imx390->subdev;
+	v4l2_i2c_subdev_init(sd, client, &imx390_subdev_ops);
+	sd->internal_ops = &imx390_internal_ops;
+
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS;
+
+	/* Initialize the media entity. */
+	imx390->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &imx390->pad);
+	if (ret < 0) {
+		dev_err(imx390->dev,
+			"%s: media entity init failed %d\n", __func__, ret);
+		return ret;
+	}
+
+	/* Initialize controls */
+	ctrl_hdr = &imx390->ctrl.handler;
+	ret = v4l2_ctrl_handler_init(ctrl_hdr, 9);
+	if (ret < 0) {
+		dev_err(imx390->dev,
+			"%s: ctrl handler init failed: %d\n", __func__, ret);
+		goto err_media_cleanup;
+	}
+
+	mutex_init(&imx390->lock);
+	imx390->ctrl.handler.lock = &imx390->lock;
+	imx390->fps = IMX390_FRAMERATE_DEFAULT;
+
+	/* Add new controls */
+	imx390->ctrl.exposure = v4l2_ctrl_new_std(ctrl_hdr, &imx390_ctrl_ops,
+						  V4L2_CID_EXPOSURE, 0,
+						  IMX390_EXPOSURE_MAX(imx390->fps),
+						  1, IMX390_EXPOSURE_DEFAULT);
+
+	imx390->ctrl.again = v4l2_ctrl_new_std(ctrl_hdr, &imx390_ctrl_ops,
+					       V4L2_CID_ANALOGUE_GAIN, 0,
+					       IMX390_ANALOG_GAIN_MAX, 1,
+					       IMX390_ANALOG_GAIN_DEFAULT);
+
+	imx390->ctrl.dgain = v4l2_ctrl_new_std(ctrl_hdr, &imx390_ctrl_ops,
+					       V4L2_CID_DIGITAL_GAIN, 0,
+					       IMX390_DIGITAL_GAIN_MAX, 1,
+					       IMX390_DIGITAL_GAIN_DEFAULT);
+
+	imx390->ctrl.r_balance = v4l2_ctrl_new_std(ctrl_hdr, &imx390_ctrl_ops,
+						   V4L2_CID_RED_BALANCE, 0,
+						   IMX390_R_B_BALANCE_MAX, 1,
+						   IMX390_R_B_BALANCE_DEFAULT);
+
+	imx390->ctrl.b_balance = v4l2_ctrl_new_std(ctrl_hdr, &imx390_ctrl_ops,
+						   V4L2_CID_BLUE_BALANCE, 0,
+						   IMX390_R_B_BALANCE_MAX, 1,
+						   IMX390_R_B_BALANCE_DEFAULT);
+
+	imx390->ctrl.wdr = v4l2_ctrl_new_std(ctrl_hdr, &imx390_ctrl_ops,
+					     V4L2_CID_WIDE_DYNAMIC_RANGE,
+					     0, 1, 1, 1);
+
+	imx390->ctrl.h_flip = v4l2_ctrl_new_std(ctrl_hdr, &imx390_ctrl_ops,
+						V4L2_CID_HFLIP, 0, 1, 1, 0);
+
+	imx390->ctrl.v_flip = v4l2_ctrl_new_std(ctrl_hdr, &imx390_ctrl_ops,
+						V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+	imx390->ctrl.pg_mode = v4l2_ctrl_new_std_menu_items(ctrl_hdr,
+					&imx390_ctrl_ops, V4L2_CID_TEST_PATTERN,
+					ARRAY_SIZE(imx390_ctrl_pg_qmenu) - 1,
+					0, 0, imx390_ctrl_pg_qmenu);
+
+	imx390->subdev.ctrl_handler = ctrl_hdr;
+	if (imx390->ctrl.handler.error) {
+		ret = imx390->ctrl.handler.error;
+		dev_err(imx390->dev,
+			"%s: failed to add the ctrls: %d\n", __func__, ret);
+		goto err_ctrl_free;
+	}
+
+	pm_runtime_set_active(imx390->dev);
+	pm_runtime_enable(imx390->dev);
+	pm_runtime_set_autosuspend_delay(imx390->dev, IMX390_PM_IDLE_TIMEOUT);
+	pm_runtime_use_autosuspend(imx390->dev);
+	pm_runtime_get_noresume(imx390->dev);
+
+	ret = v4l2_subdev_init_finalize(sd);
+	if (ret < 0)
+		goto err_pm_disable;
+
+	/* Finally, register the subdev. */
+	ret = v4l2_async_register_subdev(sd);
+	if (ret < 0) {
+		dev_err(imx390->dev,
+			"%s: v4l2 subdev register failed %d\n", __func__, ret);
+		goto err_subdev_cleanup;
+	}
+
+	dev_info(imx390->dev, "imx390 probed\n");
+	pm_runtime_mark_last_busy(imx390->dev);
+	pm_runtime_put_autosuspend(imx390->dev);
+	return 0;
+
+err_subdev_cleanup:
+	v4l2_subdev_cleanup(&imx390->subdev);
+
+err_pm_disable:
+	pm_runtime_dont_use_autosuspend(imx390->dev);
+	pm_runtime_put_noidle(imx390->dev);
+	pm_runtime_disable(imx390->dev);
+
+err_ctrl_free:
+	v4l2_ctrl_handler_free(ctrl_hdr);
+	mutex_destroy(&imx390->lock);
+
+err_media_cleanup:
+	media_entity_cleanup(&imx390->subdev.entity);
+
+	return ret;
+}
+
+static int __maybe_unused imx390_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx390 *imx390 = to_imx390(sd);
+	int ret;
+
+	ret = imx390_power_on(imx390);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int __maybe_unused imx390_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx390 *imx390 = to_imx390(sd);
+
+	imx390_power_off(imx390);
+
+	return 0;
+}
+
+static int __maybe_unused imx390_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx390 *imx390 = to_imx390(sd);
+	int ret;
+
+	if (imx390->streaming)
+		imx390_stop_stream(imx390);
+
+	ret = pm_runtime_force_suspend(dev);
+	if (ret < 0)
+		dev_warn(dev, "%s: failed to suspend: %i\n", __func__, ret);
+
+	return 0;
+}
+
+static int __maybe_unused imx390_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx390 *imx390 = to_imx390(sd);
+	int ret;
+
+	ret = pm_runtime_force_resume(dev);
+	if (ret < 0)
+		dev_warn(dev, "%s: failed to resume: %i\n", __func__, ret);
+
+	if (imx390->streaming)
+		ret = imx390_start_stream(imx390);
+
+	if (ret < 0) {
+		imx390_stop_stream(imx390);
+		imx390->streaming = 0;
+		return ret;
+	}
+
+	return 0;
+}
+
+static void imx390_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx390 *imx390 = to_imx390(sd);
+
+	v4l2_async_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&imx390->ctrl.handler);
+	v4l2_subdev_cleanup(&imx390->subdev);
+	media_entity_cleanup(&sd->entity);
+	mutex_destroy(&imx390->lock);
+
+	pm_runtime_disable(imx390->dev);
+	pm_runtime_dont_use_autosuspend(imx390->dev);
+	pm_runtime_set_suspended(imx390->dev);
+}
+
+static const struct dev_pm_ops imx390_pm_ops = {
+	SET_RUNTIME_PM_OPS(imx390_runtime_suspend,
+			   imx390_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(imx390_suspend, imx390_resume)
+};
+
+static const struct of_device_id imx390_dt_id[] = {
+	{ .compatible = "sony,imx390" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, imx390_dt_id);
+
+static struct i2c_driver imx390_i2c_driver = {
+	.driver = {
+		.name = "imx390",
+		.of_match_table = of_match_ptr(imx390_dt_id),
+		.pm = &imx390_pm_ops,
+	},
+	.probe = imx390_probe,
+	.remove = imx390_remove,
+};
+
+module_i2c_driver(imx390_i2c_driver);
+
+MODULE_DESCRIPTION("Camera Sensor Driver for Sony IMX390");
+MODULE_AUTHOR("Apurva Nandan <a-nandan@ti.com>");
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>");
+MODULE_LICENSE("GPL");
diff -Naur --no-dereference a/drivers/media/i2c/imx390.h b/drivers/media/i2c/imx390.h
--- a/drivers/media/i2c/imx390.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/media/i2c/imx390.h	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,7158 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Sony IMX390 CMOS Image Sensor Driver
+ *
+ * Copyright (c) 2021 Apurva Nandan <a-nandan@ti.com>
+ *
+ * Copyright (c) 2021 Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+ */
+
+#include <linux/types.h>
+
+#define IMX390_ACTIVE_AREA_WIDTH	1936
+#define IMX390_ACTIVE_AREA_HEIGHT	1096
+
+/* SMPG cannot be disabled, and datatype is the same as the pixel data */
+#define IMX390_SMPG_HEIGHT		4
+
+#define IMX390_OUT_WIDTH	IMX390_ACTIVE_AREA_WIDTH
+#define IMX390_OUT_HEIGHT	(IMX390_ACTIVE_AREA_HEIGHT + IMX390_SMPG_HEIGHT)
+
+#define IMX390_FRAMERATE_DEFAULT	30
+#define IMX390_FRAMERATE_MIN		25
+#define IMX390_FRAMERATE_MAX		60
+#define IMX390_FRAMERATE_MAX_LINEAR	30
+
+#define IMX390_MODE_VMAX		0x465
+#define IMX390_MODE_HMAX_DEFAULT	0x1130
+#define IMX390_REG_MODE_HMAX		0x200C
+#define IMX390_FPS_TO_MODE_HMAX(_fps)		\
+	((IMX390_MODE_HMAX_DEFAULT * IMX390_FRAMERATE_DEFAULT) / (_fps))
+
+#define IMX390_REG_VERSION_ROM_VERSION	0x0330
+#define IMX390_ROM_VERSION		0x3815
+
+#define IMX390_REG_CAT0_STANDBY		0x0000
+
+/* Exposure control */
+#define IMX390_REG_CAT0_SHS1		0x000C
+#define IMX390_EXPOSURE_LINES_MAX	(IMX390_MODE_VMAX - 2)
+#define IMX390_EXPOSURE_MAX(_fps)		\
+	((IMX390_EXPOSURE_LINES_MAX * 1000000) / (IMX390_MODE_VMAX * (_fps)))
+
+#define IMX390_EXPOSURE_SHS_VAL(_exp, _fps)	\
+	(IMX390_MODE_VMAX - ((_exp) * (_fps) * IMX390_MODE_VMAX) / 1000000)
+
+#define IMX390_EXPOSURE_DEFAULT		11111
+
+/* Analog gain control */
+#define IMX390_REG_CAT0_AGAIN_SP1H	0x0018
+#define IMX390_REG_CAT0_AGAIN_SP1L	0x001A
+#define IMX390_ANALOG_GAIN_MAX		0x3FF
+#define IMX390_ANALOG_GAIN_DEFAULT	0x20
+#define IMX390_AGAIN_CONV_GAIN_RATIO	4
+
+/* Digital gain control */
+#define IMX390_REG_CAT0_PGA_GAIN	0x0024
+#define IMX390_DIGITAL_GAIN_MAX		0x1FF
+#define IMX390_DIGITAL_GAIN_DEFAULT	0x20
+
+/* White Balance control */
+#define IMX390_REG_CAT0_WBGAIN_R	0x0030
+#define IMX390_REG_CAT0_WBGAIN_B	0x0036
+#define IMX390_R_B_BALANCE_MAX		0xFFF
+#define IMX390_R_B_BALANCE_DEFAULT	0x200
+
+/* Vertical and Horizontal Flip control */
+#define IMX390_REG_CAT0_V_H_REVERSE	0x0074
+#define IMX390_V_REV_MASK		BIT(0)
+#define IMX390_H_REV_MASK		BIT(1)
+#define IMX390_REG_SM_CFG_REVERSE_APL	0x03C0
+#define IMX390_V_REV_APL_MASK		BIT(2)
+#define IMX390_H_REV_APL_MASK		BIT(3)
+
+/* Test Pattern control */
+#define IMX390_REG_CAT0_PGMODE_PGREGEN	0x01DB
+#define IMX390_SM_CFG_SM_PGREGEN_APL	0x03C0
+#define IMX390_SM_PG_APL_MASK		BIT(1)
+
+#define IMX390_PM_IDLE_TIMEOUT		1000
+
+struct imx390_ctrl {
+	struct v4l2_ctrl_handler handler;
+	struct v4l2_ctrl *wdr;
+	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *again;
+	struct v4l2_ctrl *dgain;
+	struct v4l2_ctrl *r_balance;
+	struct v4l2_ctrl *b_balance;
+	struct v4l2_ctrl *h_flip;
+	struct v4l2_ctrl *v_flip;
+	struct v4l2_ctrl *pg_mode;
+};
+
+/*
+ * struct im390 - imx390 device structure
+ * @dev: Device handle
+ * @clk: Pointer to imx390 clock
+ * @client: Pointer to I2C client
+ * @regmap: Pointer to regmap structure
+ * @xclr_gpio: Pointer to XCLR gpio
+ * @subddev: V4L2 subdevice structure
+ * @format: V4L2 media bus frame format structure
+ *          (width and height are in sync with the compose rect)
+ * @pad: Media pad structure
+ * @ctrl: imx390 control structure
+ * @frame_interval: Time period of one frame in seconds
+ * @clk_rate: Frequency of imx390 clock
+ * @lock: Mutex structure for V4L2 ctrl handler
+ * @streaming: Flag to store the streaming on/off status
+ */
+struct imx390 {
+	struct device *dev;
+
+	struct clk *clk;
+	struct i2c_client *client;
+	struct regmap *regmap;
+	struct gpio_desc *xclr_gpio;
+
+	struct v4l2_subdev subdev;
+	struct v4l2_mbus_framefmt format;
+	struct media_pad pad;
+
+	struct imx390_ctrl ctrl;
+
+	unsigned long clk_rate;
+	u32 fps;
+
+	/* mutex for V4L2 ctrl handler */
+	struct mutex lock;
+	bool streaming;
+};
+
+static const struct v4l2_area imx390_framesizes[] = {
+	{
+		.width		= IMX390_OUT_WIDTH,
+		.height		= IMX390_OUT_HEIGHT,
+	},
+};
+
+static const u32 imx390_mbus_formats[] = {
+	MEDIA_BUS_FMT_SRGGB12_1X12,
+};
+
+static const struct regmap_config imx390_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 8,
+};
+
+static const u32 imx390_pg_mode_reg_val[] = {
+	0x00,
+	0x32,
+	0x33,
+	0x35,
+	0x3D,
+};
+
+static const char *const imx390_ctrl_pg_qmenu[] = {
+	"Disabled",
+	"Horizontal Color Bars",
+	"Vertical Color Bars",
+	"Gradation",
+	"Checker Pattern",
+};
+
+static const struct reg_sequence imx390_wdr_1936x1096[] = {
+	{ 0x000C, 0x7F },
+	{ 0x000D, 0x01 },
+	{ 0x000E, 0x00 },
+	{ 0x0010, 0x7F },
+	{ 0x0011, 0x01 },
+	{ 0x0012, 0x00 },
+	{ 0x0018, 0x20 },
+	{ 0x0019, 0x00 },
+	{ 0x001A, 0x0C },
+	{ 0x001B, 0x00 },
+	{ 0x0038, 0x00 },
+	{ 0x003C, 0x00 },
+	{ 0x003D, 0x00 },
+	{ 0x003E, 0x00 },
+	{ 0x0040, 0x00 },
+	{ 0x0041, 0x00 },
+	{ 0x0042, 0x00 },
+	{ 0x0044, 0x00 },
+	{ 0x0045, 0x00 },
+	{ 0x0046, 0x00 },
+	{ 0x0048, 0x00 },
+	{ 0x0049, 0x00 },
+	{ 0x004A, 0x00 },
+	{ 0x004C, 0x00 },
+	{ 0x004D, 0x00 },
+	{ 0x004E, 0x00 },
+	{ 0x0050, 0x00 },
+	{ 0x0051, 0x00 },
+	{ 0x0052, 0x00 },
+	{ 0x0054, 0x00 },
+	{ 0x0055, 0x00 },
+	{ 0x0056, 0x00 },
+	{ 0x0058, 0x00 },
+	{ 0x0059, 0x00 },
+	{ 0x005A, 0x00 },
+	{ 0x005C, 0x00 },
+	{ 0x005D, 0x00 },
+	{ 0x005E, 0x00 },
+	{ 0x0060, 0x00 },
+	{ 0x0061, 0x00 },
+	{ 0x0062, 0x00 },
+	{ 0x0064, 0x00 },
+	{ 0x0065, 0x00 },
+	{ 0x0066, 0x00 },
+	{ 0x0068, 0x00 },
+	{ 0x0069, 0x00 },
+	{ 0x006A, 0x00 },
+	{ 0x0078, 0x01 },
+	{ 0x007C, 0x08 },
+	{ 0x007D, 0x00 },
+	{ 0x0080, 0x08 },
+	{ 0x0081, 0x00 },
+	{ 0x0090, 0x00 },
+	{ 0x00F4, 0x1C },
+	{ 0x00F5, 0xF8 },
+	{ 0x00F6, 0x01 },
+	{ 0x00F8, 0x03 },
+	{ 0x00F9, 0x01 },
+	{ 0x00FA, 0x00 },
+	{ 0x00FB, 0x02 },
+	{ 0x0114, 0x00 },
+	{ 0x0115, 0x01 },
+	{ 0x0118, 0x20 },
+	{ 0x0119, 0x03 },
+	{ 0x011A, 0x00 },
+	{ 0x011B, 0x41 },
+	{ 0x011C, 0x80 },
+	{ 0x011D, 0x00 },
+	{ 0x0120, 0x20 },
+	{ 0x0121, 0x00 },
+	{ 0x0122, 0x00 },
+	{ 0x0123, 0x44 },
+	{ 0x0124, 0x00 },
+	{ 0x0125, 0x01 },
+	{ 0x0128, 0xAC },
+	{ 0x0129, 0x0D },
+	{ 0x012A, 0x00 },
+	{ 0x012B, 0xA4 },
+	{ 0x012C, 0x00 },
+	{ 0x012D, 0x01 },
+	{ 0x0130, 0xC4 },
+	{ 0x0131, 0x09 },
+	{ 0x0132, 0x00 },
+	{ 0x0133, 0xDA },
+	{ 0x0138, 0x00 }, /* DB_CMN_POST_PEDESTAL (0x0138: 0x0139) = 0 */
+	{ 0x0139, 0x00 }, /* DB_CMN_POST_PEDESTAL (0x0138: 0x0139) = 0 */
+	{ 0x013A, 0x00 },
+	{ 0x013B, 0x00 },
+	{ 0x013C, 0x00 },
+	{ 0x013D, 0x00 },
+	{ 0x013E, 0x00 },
+	{ 0x0140, 0x00 },
+	{ 0x0141, 0x00 },
+	{ 0x0142, 0x00 },
+	/* Start of PWL Registers */
+	{ 0x0144, 0x00 },	/* pwl_cp1_x 2048	*/
+	{ 0x0145, 0x08 },	/* pwl_cp1_x 2048	*/
+	{ 0x0146, 0x00 },	/* pwl_cp1_x 2048	*/
+	{ 0x0147, 0x00 },	/* pwl_cp1_x 2048	*/
+	{ 0x0148, 0x00 },	/* pwl_cp1_y 51		*/
+	{ 0x0149, 0x02 },	/* pwl_cp1_y 51		*/
+	{ 0x014A, 0x00 },	/* pwl_cp1_y 51		*/
+	{ 0x014B, 0x00 },	/* pwl_cp1_y 51		*/
+	{ 0x014C, 0x00 },	/* pwl_cp2_x 1638	*/
+	{ 0x014D, 0x40 },	/* pwl_cp2_x 1638	*/
+	{ 0x014E, 0x00 },	/* pwl_cp2_x 1638	*/
+	{ 0x014F, 0x00 },	/* pwl_cp2_x 1638	*/
+	{ 0x0150, 0x80 },	/* pwl_cp2_y 1408	*/
+	{ 0x0151, 0x05 },	/* pwl_cp2_y 1408	*/
+	{ 0x0152, 0x00 },	/* pwl_cp2_y 1408	*/
+	{ 0x0153, 0x00 },	/* pwl_cp2_y 1408	*/
+	{ 0x0154, 0x00 },	/* pwl_cp3_x 6553	*/
+	{ 0x0155, 0x00 },	/* pwl_cp3_x 6553	*/
+	{ 0x0156, 0x01 },	/* pwl_cp3_x 6553	*/
+	{ 0x0157, 0x00 },	/* pwl_cp3_x 6553	*/
+	{ 0x0158, 0x80 },	/* pwl_cp3_y 2176	*/
+	{ 0x0159, 0x08 },	/* pwl_cp3_y 2176	*/
+	{ 0x015A, 0x00 },	/* pwl_cp3_y 2176	*/
+	{ 0x015B, 0x00 },	/* pwl_cp3_y 2176	*/
+	{ 0x015C, 0x00 },	/* pwl_cp4_x 0x100000	*/
+	{ 0x015D, 0x00 },	/* pwl_cp4_x 0x100000	*/
+	{ 0x015E, 0x10 },	/* pwl_cp4_x 0x100000	*/
+	{ 0x015F, 0x00 },	/* pwl_cp4_x 0x100000	*/
+	{ 0x0160, 0x00 },	/* pwl_cp4_y 0x1000	*/
+	{ 0x0161, 0x10 },	/* pwl_cp4_y 0x1000	*/
+	{ 0x0162, 0x00 },	/* pwl_cp4_y 0x1000	*/
+	{ 0x0163, 0x00 },	/* pwl_cp4_y 0x1000	*/
+	{ 0x0164, 0x00 },	/* pwl_cp5_x 0x100000	*/
+	{ 0x0165, 0x00 },	/* pwl_cp5_x 0x100000	*/
+	{ 0x0166, 0x10 },	/* pwl_cp5_x 0x100000	*/
+	{ 0x0167, 0x00 },	/* pwl_cp5_x 0x100000	*/
+	{ 0x0168, 0x00 },	/* pwl_cp5_y 0x1000	*/
+	{ 0x0169, 0x10 },	/* pwl_cp5_y 0x1000	*/
+	{ 0x016A, 0x00 },	/* pwl_cp5_y 0x1000	*/
+	{ 0x016B, 0x00 },	/* pwl_cp5_y 0x1000	*/
+	{ 0x016C, 0x00 },	/* pwl_cp6_x 0x100000	*/
+	{ 0x016D, 0x00 },	/* pwl_cp6_x 0x100000	*/
+	{ 0x016E, 0x10 },	/* pwl_cp6_x 0x100000	*/
+	{ 0x016F, 0x00 },	/* pwl_cp6_x 0x100000	*/
+	{ 0x0170, 0x00 },	/* pwl_cp6_y 0x1000	*/
+	{ 0x0171, 0x10 },	/* pwl_cp6_y 0x1000	*/
+	{ 0x0172, 0x00 },	/* pwl_cp6_y 0x1000	*/
+	{ 0x0173, 0x00 },	/* pwl_cp6_y 0x1000	*/
+	{ 0x0174, 0x00 },	/* pwl_cp7_x 0x100000	*/
+	{ 0x0175, 0x00 },	/* pwl_cp7_x 0x100000	*/
+	{ 0x0176, 0x10 },	/* pwl_cp7_x 0x100000	*/
+	{ 0x0177, 0x00 },	/* pwl_cp7_x 0x100000	*/
+	{ 0x0178, 0x00 },	/* pwl_cp7_y 0x1000	*/
+	{ 0x0179, 0x10 },	/* pwl_cp7_y 0x1000	*/
+	{ 0x017A, 0x00 },	/* pwl_cp7_y 0x1000	*/
+	{ 0x017B, 0x00 },	/* pwl_cp7_y 0x1000	*/
+	{ 0x017C, 0x00 },	/* pwl_cp8_x 0x100000	*/
+	{ 0x017D, 0x00 },	/* pwl_cp8_x 0x100000	*/
+	{ 0x017E, 0x10 },	/* pwl_cp8_x 0x100000	*/
+	{ 0x017F, 0x00 },	/* pwl_cp8_x 0x100000	*/
+	{ 0x0180, 0x00 },	/* pwl_cp8_y 0x1000	*/
+	{ 0x0181, 0x10 },	/* pwl_cp8_y 0x1000	*/
+	{ 0x0182, 0x00 },	/* pwl_cp8_y 0x1000	*/
+	{ 0x0183, 0x00 },	/* pwl_cp8_y 0x1000	*/
+	{ 0x0184, 0x00 },	/* pwl_cp9_x 0x100000	*/
+	{ 0x0185, 0x00 },	/* pwl_cp9_x 0x100000	*/
+	{ 0x0186, 0x10 },	/* pwl_cp9_x 0x100000	*/
+	{ 0x0187, 0x00 },	/* pwl_cp9_x 0x100000	*/
+	{ 0x0188, 0x00 },	/* pwl_cp9_y 0x1000	*/
+	{ 0x0189, 0x10 },	/* pwl_cp9_y 0x1000	*/
+	{ 0x018A, 0x00 },	/* pwl_cp9_y 0x1000	*/
+	{ 0x018B, 0x00 },	/* pwl_cp9_y 0x1000	*/
+	{ 0x018C, 0x00 },	/* pwl_cp10_x 0x10000	*/
+	{ 0x018D, 0x00 },	/* pwl_cp10_x 0x10000	*/
+	{ 0x018E, 0x10 },	/* pwl_cp10_x 0x10000	*/
+	{ 0x018F, 0x00 },	/* pwl_cp10_x 0x10000	*/
+	{ 0x0190, 0x00 },	/* pwl_cp10_y 0x100	*/
+	{ 0x0191, 0x10 },	/* pwl_cp10_y 0x100	*/
+	{ 0x0192, 0x00 },	/* pwl_cp10_y 0x100	*/
+	{ 0x0193, 0x00 },	/* pwl_cp10_y 0x100	*/
+	{ 0x0198, 0x00 },	/* pwl gain0 0x040 0000	*/
+	{ 0x0199, 0x00 },
+	{ 0x019A, 0x40 },
+	{ 0x019B, 0x00 },
+	{ 0x019C, 0x00 },	/* pwl gain1 0x010 0000 */
+	{ 0x019D, 0x00 },
+	{ 0x019E, 0x10 },
+	{ 0x019F, 0x00 },
+	{ 0x01A0, 0x00 },	/* pwl gain2 0x004 0000 */
+	{ 0x01A1, 0x00 },
+	{ 0x01A2, 0x04 },
+	{ 0x01A3, 0x00 },
+	{ 0x01A4, 0x00 },	/* pwl gain3 0x000 8000 */
+	{ 0x01A5, 0x80 },
+	{ 0x01A6, 0x00 },
+	{ 0x01A7, 0x00 },
+	{ 0x01A8, 0x00 },
+	{ 0x01A9, 0x00 },
+	{ 0x01AA, 0x00 },
+	{ 0x01AB, 0x00 },
+	/* End of PWL Registers*/
+	{ 0x01AC, 0x00 },
+	{ 0x01AD, 0x00 },
+	{ 0x01AE, 0x00 },
+	{ 0x01AF, 0x00 },
+	{ 0x01B0, 0x00 },
+	{ 0x01B1, 0x00 },
+	{ 0x01B2, 0x00 },
+	{ 0x01B3, 0x00 },
+	{ 0x01B4, 0x00 },
+	{ 0x01B5, 0x00 },
+	{ 0x01B6, 0x00 },
+	{ 0x01B7, 0x00 },
+	{ 0x01B8, 0x00 },
+	{ 0x01B9, 0x00 },
+	{ 0x01BA, 0x00 },
+	{ 0x01BB, 0x00 },
+	{ 0x01BC, 0x00 },
+	{ 0x01BD, 0x00 },
+	{ 0x01BE, 0x00 },
+	{ 0x01BF, 0x00 },
+	{ 0x01C0, 0x00 },
+	{ 0x01C1, 0x00 },
+	{ 0x01C2, 0x00 },
+	{ 0x01C3, 0x00 },
+	{ 0x01C4, 0x00 },
+	{ 0x01C5, 0x00 },
+	{ 0x01CC, 0x01 },
+	{ 0x01D0, 0x09 },
+	{ 0x01D4, 0x01 },
+	{ 0x0332, 0x67 },
+	{ 0x0333, 0x02 },
+	{ 0x0390, 0x00 },
+	{ 0x0391, 0x00 },
+	{ 0x0392, 0x00 },
+	{ 0x03C0, 0x01 },
+	{ 0x2000, 0x55 },
+	{ 0x2001, 0x55 },
+	{ 0x2002, 0x55 },
+	{ 0x2003, 0x05 },
+	{ 0x2004, 0x02 },
+	{ 0x2008, 0x65 },
+	{ 0x2009, 0x04 },
+	{ 0x200A, 0x00 },
+	{ 0x200C, 0x98 },
+	{ 0x200D, 0x08 },
+	{ 0x2010, 0x04 },
+	{ 0x2014, 0x00 },
+	{ 0x2018, 0x02 },
+	{ 0x2019, 0x04 },
+	{ 0x201A, 0x00 },
+	{ 0x201C, 0x21 },
+	{ 0x201D, 0x11 },
+	{ 0x201E, 0x00 },
+	{ 0x201F, 0x00 },
+	{ 0x2020, 0xBC },
+	{ 0x2021, 0x00 },
+	{ 0x2022, 0x7F },
+	{ 0x2023, 0x00 },
+	{ 0x2024, 0xBA },
+	{ 0x2025, 0x00 },
+	{ 0x2026, 0x81 },
+	{ 0x2027, 0x00 },
+	{ 0x2028, 0x7D },
+	{ 0x2029, 0x90 },
+	{ 0x202A, 0x05 },
+	{ 0x202C, 0xFC },
+	{ 0x202D, 0x02 },
+	{ 0x202E, 0x25 },
+	{ 0x202F, 0x03 },
+	{ 0x2030, 0x05 },
+	{ 0x2031, 0x02 },
+	{ 0x2032, 0xCA },
+	{ 0x2033, 0x02 },
+	{ 0x2034, 0xFC },
+	{ 0x2035, 0x02 },
+	{ 0x2036, 0x25 },
+	{ 0x2037, 0x03 },
+	{ 0x2038, 0xF8 },
+	{ 0x2039, 0xE4 },
+	{ 0x203A, 0xE3 },
+	{ 0x203B, 0x01 },
+	{ 0x203C, 0xF5 },
+	{ 0x203D, 0x8E },
+	{ 0x203E, 0x0C },
+	{ 0x203F, 0x2D },
+	{ 0x2040, 0x69 },
+	{ 0x2041, 0x01 },
+	{ 0x2042, 0x8E },
+	{ 0x2043, 0x01 },
+	{ 0x2044, 0x0C },
+	{ 0x2045, 0x02 },
+	{ 0x2046, 0x31 },
+	{ 0x2047, 0x02 },
+	{ 0x2048, 0x6A },
+	{ 0x2049, 0x01 },
+	{ 0x204A, 0x8E },
+	{ 0x204B, 0x01 },
+	{ 0x204C, 0x0D },
+	{ 0x204D, 0x02 },
+	{ 0x204E, 0x31 },
+	{ 0x204F, 0x02 },
+	{ 0x2050, 0x7B },
+	{ 0x2051, 0x00 },
+	{ 0x2052, 0x7D },
+	{ 0x2053, 0x00 },
+	{ 0x2054, 0x95 },
+	{ 0x2055, 0x00 },
+	{ 0x2056, 0x97 },
+	{ 0x2057, 0x00 },
+	{ 0x2058, 0xAD },
+	{ 0x2059, 0x00 },
+	{ 0x205A, 0xAF },
+	{ 0x205B, 0x00 },
+	{ 0x205C, 0x92 },
+	{ 0x205D, 0x00 },
+	{ 0x205E, 0x94 },
+	{ 0x205F, 0x00 },
+	{ 0x2060, 0x8E },
+	{ 0x2061, 0x00 },
+	{ 0x2062, 0x90 },
+	{ 0x2063, 0x00 },
+	{ 0x2064, 0xB1 },
+	{ 0x2065, 0x00 },
+	{ 0x2066, 0xB3 },
+	{ 0x2067, 0x00 },
+	{ 0x2068, 0x08 },
+	{ 0x2069, 0x00 },
+	{ 0x206A, 0x04 },
+	{ 0x206B, 0x00 },
+	{ 0x206C, 0x84 },
+	{ 0x206D, 0x00 },
+	{ 0x206E, 0x80 },
+	{ 0x206F, 0x00 },
+	{ 0x2070, 0x04 },
+	{ 0x2071, 0x00 },
+	{ 0x2072, 0x46 },
+	{ 0x2073, 0x00 },
+	{ 0x2074, 0xE9 },
+	{ 0x2075, 0x01 },
+	{ 0x2076, 0x74 },
+	{ 0x2077, 0x02 },
+	{ 0x2078, 0x80 },
+	{ 0x2079, 0x00 },
+	{ 0x207A, 0xC1 },
+	{ 0x207B, 0x00 },
+	{ 0x207C, 0xFF },
+	{ 0x207D, 0x03 },
+	{ 0x207E, 0xFF },
+	{ 0x207F, 0x03 },
+	{ 0x2080, 0x78 },
+	{ 0x2081, 0x00 },
+	{ 0x2082, 0x6A },
+	{ 0x2083, 0x01 },
+	{ 0x2084, 0xE4 },
+	{ 0x2085, 0x01 },
+	{ 0x2086, 0x2B },
+	{ 0x2087, 0x03 },
+	{ 0x2088, 0x00 },
+	{ 0x2089, 0x00 },
+	{ 0x208A, 0xFF },
+	{ 0x208B, 0x03 },
+	{ 0x208C, 0xFF },
+	{ 0x208D, 0x03 },
+	{ 0x208E, 0xFF },
+	{ 0x208F, 0x03 },
+	{ 0x2090, 0x7D },
+	{ 0x2091, 0x00 },
+	{ 0x2092, 0x62 },
+	{ 0x2093, 0x01 },
+	{ 0x2094, 0xE9 },
+	{ 0x2095, 0x01 },
+	{ 0x2096, 0x00 },
+	{ 0x2097, 0x00 },
+	{ 0x2098, 0x7C },
+	{ 0x2099, 0x00 },
+	{ 0x209A, 0x21 },
+	{ 0x209B, 0x03 },
+	{ 0x209C, 0xE9 },
+	{ 0x209D, 0x01 },
+	{ 0x209E, 0x21 },
+	{ 0x209F, 0x03 },
+	{ 0x20A0, 0xFF },
+	{ 0x20A1, 0x03 },
+	{ 0x20A2, 0xFF },
+	{ 0x20A3, 0x03 },
+	{ 0x20A4, 0xFF },
+	{ 0x20A5, 0x03 },
+	{ 0x20A6, 0xFF },
+	{ 0x20A7, 0x03 },
+	{ 0x20A8, 0xFF },
+	{ 0x20A9, 0x03 },
+	{ 0x20AA, 0xFF },
+	{ 0x20AB, 0x03 },
+	{ 0x20AC, 0xFF },
+	{ 0x20AD, 0x03 },
+	{ 0x20AE, 0xFF },
+	{ 0x20AF, 0x03 },
+	{ 0x20B0, 0xFF },
+	{ 0x20B1, 0x03 },
+	{ 0x20B2, 0xFF },
+	{ 0x20B3, 0x03 },
+	{ 0x20B4, 0x87 },
+	{ 0x20B5, 0xCC },
+	{ 0x20B6, 0x87 },
+	{ 0x20B7, 0x08 },
+	{ 0x20B8, 0xF4 },
+	{ 0x20B9, 0xA5 },
+	{ 0x20BA, 0x07 },
+	{ 0x20BC, 0x1F },
+	{ 0x20BD, 0x01 },
+	{ 0x20BE, 0xF6 },
+	{ 0x20BF, 0x00 },
+	{ 0x20C0, 0x90 },
+	{ 0x20C1, 0x01 },
+	{ 0x20C2, 0x67 },
+	{ 0x20C3, 0x01 },
+	{ 0x20C4, 0xFF },
+	{ 0x20C5, 0x03 },
+	{ 0x20C6, 0xFF },
+	{ 0x20C7, 0x03 },
+	{ 0x20C8, 0x33 },
+	{ 0x20C9, 0x02 },
+	{ 0x20CA, 0x0A },
+	{ 0x20CB, 0x02 },
+	{ 0x20CC, 0x7F },
+	{ 0x20CD, 0x00 },
+	{ 0x20CE, 0xD2 },
+	{ 0x20CF, 0x00 },
+	{ 0x20D0, 0x81 },
+	{ 0x20D1, 0x00 },
+	{ 0x20D2, 0x87 },
+	{ 0x20D3, 0x00 },
+	{ 0x20D4, 0x09 },
+	{ 0x20D5, 0x00 },
+	{ 0x20D8, 0x7F },
+	{ 0x20D9, 0x00 },
+	{ 0x20DA, 0x62 },
+	{ 0x20DB, 0x01 },
+	{ 0x20DC, 0x7F },
+	{ 0x20DD, 0x00 },
+	{ 0x20DE, 0x62 },
+	{ 0x20DF, 0x01 },
+	{ 0x20E0, 0x65 },
+	{ 0x20E1, 0x00 },
+	{ 0x20E2, 0x75 },
+	{ 0x20E3, 0x00 },
+	{ 0x20E4, 0xE0 },
+	{ 0x20E5, 0x00 },
+	{ 0x20E6, 0xF0 },
+	{ 0x20E7, 0x00 },
+	{ 0x20E8, 0x4C },
+	{ 0x20E9, 0x01 },
+	{ 0x20EA, 0x5C },
+	{ 0x20EB, 0x01 },
+	{ 0x20EC, 0xD1 },
+	{ 0x20ED, 0x01 },
+	{ 0x20EE, 0xE1 },
+	{ 0x20EF, 0x01 },
+	{ 0x20F0, 0x93 },
+	{ 0x20F1, 0x02 },
+	{ 0x20F2, 0xA3 },
+	{ 0x20F3, 0x02 },
+	{ 0x20F4, 0x0D },
+	{ 0x20F5, 0x03 },
+	{ 0x20F6, 0x1D },
+	{ 0x20F7, 0x03 },
+	{ 0x20F8, 0x57 },
+	{ 0x20F9, 0x00 },
+	{ 0x20FA, 0x7B },
+	{ 0x20FB, 0x00 },
+	{ 0x20FC, 0xD2 },
+	{ 0x20FD, 0x00 },
+	{ 0x20FE, 0xF6 },
+	{ 0x20FF, 0x00 },
+	{ 0x2100, 0x3E },
+	{ 0x2101, 0x01 },
+	{ 0x2102, 0x60 },
+	{ 0x2103, 0x01 },
+	{ 0x2104, 0xC3 },
+	{ 0x2105, 0x01 },
+	{ 0x2106, 0xE5 },
+	{ 0x2107, 0x01 },
+	{ 0x2108, 0x85 },
+	{ 0x2109, 0x02 },
+	{ 0x210A, 0xA9 },
+	{ 0x210B, 0x02 },
+	{ 0x210C, 0xFF },
+	{ 0x210D, 0x02 },
+	{ 0x210E, 0x21 },
+	{ 0x210F, 0x03 },
+	{ 0x2110, 0xFF },
+	{ 0x2111, 0x03 },
+	{ 0x2112, 0x00 },
+	{ 0x2113, 0x00 },
+	{ 0x2114, 0xFF },
+	{ 0x2115, 0x03 },
+	{ 0x2116, 0xFF },
+	{ 0x2117, 0x03 },
+	{ 0x2118, 0xFF },
+	{ 0x2119, 0x03 },
+	{ 0x211A, 0xFF },
+	{ 0x211B, 0x03 },
+	{ 0x211C, 0xFF },
+	{ 0x211D, 0x03 },
+	{ 0x211E, 0xFF },
+	{ 0x211F, 0x03 },
+	{ 0x2120, 0xFF },
+	{ 0x2121, 0x03 },
+	{ 0x2122, 0xFF },
+	{ 0x2123, 0x03 },
+	{ 0x2124, 0xFF },
+	{ 0x2125, 0x03 },
+	{ 0x2126, 0xFF },
+	{ 0x2127, 0x03 },
+	{ 0x2128, 0x7D },
+	{ 0x2129, 0x90 },
+	{ 0x212A, 0xD5 },
+	{ 0x212B, 0x07 },
+	{ 0x212C, 0x64 },
+	{ 0x212D, 0x01 },
+	{ 0x2130, 0x5F },
+	{ 0x2131, 0x7D },
+	{ 0x2132, 0x05 },
+	{ 0x2134, 0x78 },
+	{ 0x2135, 0x00 },
+	{ 0x2136, 0x76 },
+	{ 0x2137, 0x00 },
+	{ 0x2138, 0xF3 },
+	{ 0x2139, 0x00 },
+	{ 0x213A, 0xF1 },
+	{ 0x213B, 0x00 },
+	{ 0x213C, 0xA6 },
+	{ 0x213D, 0x02 },
+	{ 0x213E, 0xA4 },
+	{ 0x213F, 0x02 },
+	{ 0x2140, 0x7D },
+	{ 0x2141, 0x00 },
+	{ 0x2142, 0x8D },
+	{ 0x2143, 0x00 },
+	{ 0x2144, 0xA1 },
+	{ 0x2145, 0x01 },
+	{ 0x2146, 0xB1 },
+	{ 0x2147, 0x01 },
+	{ 0x2148, 0xAB },
+	{ 0x2149, 0x02 },
+	{ 0x214A, 0xBB },
+	{ 0x214B, 0x02 },
+	{ 0x214C, 0x17 },
+	{ 0x214D, 0x5C },
+	{ 0x214E, 0x00 },
+	{ 0x2150, 0x00 },
+	{ 0x2151, 0x00 },
+	{ 0x2152, 0xF8 },
+	{ 0x2153, 0x00 },
+	{ 0x2154, 0xBE },
+	{ 0x2155, 0x00 },
+	{ 0x2156, 0x7D },
+	{ 0x2157, 0x00 },
+	{ 0x2158, 0x25 },
+	{ 0x2159, 0x00 },
+	{ 0x215A, 0x7D },
+	{ 0x215B, 0x00 },
+	{ 0x215C, 0x62 },
+	{ 0x215D, 0x01 },
+	{ 0x215E, 0xFF },
+	{ 0x215F, 0x03 },
+	{ 0x2160, 0x26 },
+	{ 0x2161, 0x00 },
+	{ 0x2162, 0x7D },
+	{ 0x2163, 0x00 },
+	{ 0x2164, 0x63 },
+	{ 0x2165, 0x01 },
+	{ 0x2166, 0xFF },
+	{ 0x2167, 0x03 },
+	{ 0x2168, 0xCB },
+	{ 0x2169, 0x02 },
+	{ 0x216A, 0xCF },
+	{ 0x216B, 0x02 },
+	{ 0x216C, 0xFF },
+	{ 0x216D, 0x03 },
+	{ 0x216E, 0xFF },
+	{ 0x216F, 0x03 },
+	{ 0x2170, 0xFF },
+	{ 0x2171, 0x03 },
+	{ 0x2172, 0xFF },
+	{ 0x2173, 0x03 },
+	{ 0x2174, 0xFF },
+	{ 0x2175, 0x03 },
+	{ 0x2176, 0xFF },
+	{ 0x2177, 0x03 },
+	{ 0x2178, 0x7E },
+	{ 0x2179, 0x00 },
+	{ 0x217A, 0xBD },
+	{ 0x217B, 0x00 },
+	{ 0x217C, 0xEC },
+	{ 0x217D, 0x01 },
+	{ 0x217E, 0x7B },
+	{ 0x217F, 0x02 },
+	{ 0x2180, 0xD1 },
+	{ 0x2181, 0x02 },
+	{ 0x2182, 0x25 },
+	{ 0x2183, 0x03 },
+	{ 0x2184, 0x7F },
+	{ 0x2185, 0x00 },
+	{ 0x2186, 0xBD },
+	{ 0x2187, 0x00 },
+	{ 0x2188, 0xED },
+	{ 0x2189, 0x01 },
+	{ 0x218A, 0x7B },
+	{ 0x218B, 0x02 },
+	{ 0x218C, 0xD2 },
+	{ 0x218D, 0x02 },
+	{ 0x218E, 0x25 },
+	{ 0x218F, 0x03 },
+	{ 0x2190, 0xFF },
+	{ 0x2191, 0x03 },
+	{ 0x2192, 0xFF },
+	{ 0x2193, 0x03 },
+	{ 0x2194, 0xE9 },
+	{ 0x2195, 0x01 },
+	{ 0x2196, 0x21 },
+	{ 0x2197, 0x03 },
+	{ 0x2198, 0x17 },
+	{ 0x2199, 0xFC },
+	{ 0x219A, 0x7F },
+	{ 0x219B, 0x01 },
+	{ 0x219C, 0xFF },
+	{ 0x219D, 0x03 },
+	{ 0x21A0, 0x1B },
+	{ 0x21A1, 0x1B },
+	{ 0x21A2, 0x1B },
+	{ 0x21A3, 0x1B },
+	{ 0x21A4, 0x2B },
+	{ 0x21A5, 0x80 },
+	{ 0x21A6, 0x00 },
+	{ 0x21A8, 0x04 },
+	{ 0x21A9, 0x98 },
+	{ 0x21AA, 0x60 },
+	{ 0x21AB, 0x03 },
+	{ 0x21AC, 0x7F },
+	{ 0x21AD, 0x80 },
+	{ 0x21AE, 0x09 },
+	{ 0x21B0, 0x1C },
+	{ 0x21B1, 0x00 },
+	{ 0x21B2, 0xA0 },
+	{ 0x21B3, 0x00 },
+	{ 0x21B4, 0x0C },
+	{ 0x21B5, 0x00 },
+	{ 0x21B6, 0x2D },
+	{ 0x21B7, 0x00 },
+	{ 0x21B8, 0x20 },
+	{ 0x21B9, 0x00 },
+	{ 0x21BA, 0x02 },
+	{ 0x21BB, 0x00 },
+	{ 0x21BC, 0xCC },
+	{ 0x21BD, 0x00 },
+	{ 0x21BE, 0x4A },
+	{ 0x21BF, 0x00 },
+	{ 0x21C0, 0xD0 },
+	{ 0x21C1, 0x00 },
+	{ 0x21C2, 0x44 },
+	{ 0x21C3, 0x00 },
+	{ 0x21C4, 0x00 },
+	{ 0x21C5, 0xE0 },
+	{ 0x21C6, 0x00 },
+	{ 0x21C8, 0x11 },
+	{ 0x21C9, 0x00 },
+	{ 0x21CA, 0x02 },
+	{ 0x21CC, 0x08 },
+	{ 0x21CD, 0xC0 },
+	{ 0x21CE, 0x0C },
+	{ 0x21D0, 0x44 },
+	{ 0x21D1, 0x00 },
+	{ 0x21D2, 0x02 },
+	{ 0x21D4, 0x02 },
+	{ 0x21D5, 0x20 },
+	{ 0x21D6, 0x2C },
+	{ 0x21D8, 0xFE },
+	{ 0x21D9, 0x9D },
+	{ 0x21DA, 0xDF },
+	{ 0x21DB, 0x03 },
+	{ 0x21DC, 0x62 },
+	{ 0x21DD, 0x01 },
+	{ 0x21DE, 0x7F },
+	{ 0x21DF, 0x00 },
+	{ 0x21E0, 0xB7 },
+	{ 0x21E1, 0x01 },
+	{ 0x21E2, 0xB5 },
+	{ 0x21E3, 0x01 },
+	{ 0x21E4, 0xC1 },
+	{ 0x21E5, 0x02 },
+	{ 0x21E6, 0xBF },
+	{ 0x21E7, 0x02 },
+	{ 0x21E8, 0xB3 },
+	{ 0x21E9, 0x0D },
+	{ 0x21EA, 0x00 },
+	{ 0x21EB, 0x04 },
+	{ 0x21EC, 0x90 },
+	{ 0x21ED, 0x07 },
+	{ 0x21EE, 0x58 },
+	{ 0x21EF, 0x04 },
+	{ 0x21F0, 0x54 },
+	{ 0x21F1, 0x04 },
+	{ 0x21F4, 0x02 },
+	{ 0x21F5, 0x00 },
+	{ 0x21F6, 0x00 },
+	{ 0x21F8, 0x3C },
+	{ 0x21F9, 0x00 },
+	{ 0x21FC, 0x28 },
+	{ 0x21FD, 0x00 },
+	{ 0x21FE, 0x3C },
+	{ 0x21FF, 0x00 },
+	{ 0x2200, 0x00 },
+	{ 0x2204, 0x4C },
+	{ 0x2205, 0x04 },
+	{ 0x2206, 0x65 },
+	{ 0x2207, 0x04 },
+	{ 0x2208, 0x0A },
+	{ 0x2209, 0x00 },
+	{ 0x220C, 0x57 },
+	{ 0x220D, 0x00 },
+	{ 0x220E, 0x37 },
+	{ 0x220F, 0x00 },
+	{ 0x2210, 0x1F },
+	{ 0x2211, 0x00 },
+	{ 0x2212, 0x1F },
+	{ 0x2213, 0x00 },
+	{ 0x2214, 0x1F },
+	{ 0x2215, 0x00 },
+	{ 0x2216, 0x77 },
+	{ 0x2217, 0x00 },
+	{ 0x2218, 0x1F },
+	{ 0x2219, 0x00 },
+	{ 0x221A, 0x17 },
+	{ 0x221B, 0x00 },
+	{ 0x221C, 0x03 },
+	{ 0x2220, 0x24 },
+	{ 0x2221, 0x00 },
+	{ 0x2222, 0x00 },
+	{ 0x2223, 0x00 },
+	{ 0x2224, 0xA7 },
+	{ 0x2225, 0xAA },
+	{ 0x2226, 0x80 },
+	{ 0x2227, 0x08 },
+	{ 0x2228, 0x01 },
+	{ 0x2260, 0xFF },
+	{ 0x2261, 0x1F },
+	{ 0x2262, 0x00 },
+	{ 0x2263, 0x00 },
+	{ 0x2264, 0x00 },
+	{ 0x2265, 0x00 },
+	{ 0x2266, 0xFF },
+	{ 0x2267, 0x1F },
+	{ 0x2268, 0x00 },
+	{ 0x2269, 0x00 },
+	{ 0x226A, 0xFF },
+	{ 0x226B, 0x1F },
+	{ 0x226C, 0x00 },
+	{ 0x226D, 0x00 },
+	{ 0x226E, 0xFF },
+	{ 0x226F, 0x1F },
+	{ 0x227C, 0xB2 },
+	{ 0x227D, 0x0C },
+	{ 0x227E, 0x6A },
+	{ 0x227F, 0x09 },
+	{ 0x2280, 0xD2 },
+	{ 0x2281, 0x0C },
+	{ 0x2282, 0x5A },
+	{ 0x2283, 0x09 },
+	{ 0x2284, 0xC4 },
+	{ 0x2285, 0x0C },
+	{ 0x2286, 0x54 },
+	{ 0x2287, 0x09 },
+	{ 0x22B2, 0x92 },
+	{ 0x22B4, 0x20 },
+	{ 0x22B5, 0x00 },
+	{ 0x22B6, 0x20 },
+	{ 0x22B7, 0x00 },
+	{ 0x22B8, 0x20 },
+	{ 0x22B9, 0x00 },
+	{ 0x22BA, 0x20 },
+	{ 0x22BB, 0x00 },
+	{ 0x22BC, 0x20 },
+	{ 0x22BD, 0x00 },
+	{ 0x22BE, 0x20 },
+	{ 0x22BF, 0x00 },
+	{ 0x22C0, 0x20 },
+	{ 0x22C1, 0x00 },
+	{ 0x22C2, 0x20 },
+	{ 0x22C3, 0x00 },
+	{ 0x22C4, 0x20 },
+	{ 0x22C5, 0x00 },
+	{ 0x22C6, 0x20 },
+	{ 0x22C7, 0x00 },
+	{ 0x22C8, 0x20 },
+	{ 0x22C9, 0x00 },
+	{ 0x22CA, 0x20 },
+	{ 0x22CB, 0x00 },
+	{ 0x22CC, 0x20 },
+	{ 0x22CD, 0x00 },
+	{ 0x22CE, 0x20 },
+	{ 0x22CF, 0x00 },
+	{ 0x22DA, 0x00 },
+	{ 0x22EF, 0x82 },
+	{ 0x2308, 0x01 },
+	{ 0x2310, 0x4B },
+	{ 0x2311, 0x09 },
+	{ 0x2318, 0x40 },
+	{ 0x2319, 0xCD },
+	{ 0x231A, 0x54 },
+	{ 0x2324, 0x20 },
+	{ 0x2325, 0x00 },
+	{ 0x2328, 0x00 },
+	{ 0x234A, 0x9F },
+	{ 0x234B, 0x07 },
+	{ 0x2354, 0x0C },
+	{ 0x23C0, 0x5D },
+	{ 0x244C, 0xFF },
+	{ 0x244D, 0x03 },
+	{ 0x244E, 0xFF },
+	{ 0x244F, 0x03 },
+	{ 0x24A0, 0x00 },
+	{ 0x24A4, 0x16 },
+	{ 0x24A5, 0x01 },
+	{ 0x24A6, 0xA6 },
+	{ 0x24A7, 0x02 },
+	{ 0x24A8, 0xD5 },
+	{ 0x24A9, 0x02 },
+	{ 0x24BC, 0x17 },
+	{ 0x24BD, 0x01 },
+	{ 0x24BE, 0xA7 },
+	{ 0x24BF, 0x02 },
+	{ 0x24C0, 0xD5 },
+	{ 0x24C1, 0x02 },
+	{ 0x24DA, 0x6F },
+	{ 0x24DB, 0x00 },
+	{ 0x24DC, 0x62 },
+	{ 0x24DD, 0x01 },
+	{ 0x24EA, 0x32 },
+	{ 0x24EB, 0x00 },
+	{ 0x24EC, 0xDC },
+	{ 0x24ED, 0x00 },
+	{ 0x24FA, 0x32 },
+	{ 0x24FB, 0x00 },
+	{ 0x24FC, 0xDD },
+	{ 0x24FD, 0x00 },
+	{ 0x254A, 0x15 },
+	{ 0x254B, 0x01 },
+	{ 0x255A, 0x15 },
+	{ 0x255B, 0x01 },
+	{ 0x2560, 0x01 },
+	{ 0x2561, 0x00 },
+	{ 0x2562, 0x2A },
+	{ 0x2563, 0x00 },
+	{ 0x2564, 0xF8 },
+	{ 0x2565, 0x00 },
+	{ 0x2566, 0x15 },
+	{ 0x2567, 0x01 },
+	{ 0x2568, 0x0C },
+	{ 0x2569, 0x02 },
+	{ 0x256A, 0x31 },
+	{ 0x256B, 0x02 },
+	{ 0x2578, 0x90 },
+	{ 0x2579, 0x01 },
+	{ 0x257A, 0x92 },
+	{ 0x257B, 0x01 },
+	{ 0x257C, 0xB8 },
+	{ 0x257D, 0x02 },
+	{ 0x257E, 0xBA },
+	{ 0x257F, 0x02 },
+	{ 0x2584, 0x90 },
+	{ 0x2585, 0x01 },
+	{ 0x2586, 0x92 },
+	{ 0x2587, 0x01 },
+	{ 0x2588, 0xB8 },
+	{ 0x2589, 0x02 },
+	{ 0x258A, 0xBA },
+	{ 0x258B, 0x02 },
+	{ 0x267A, 0xF8 },
+	{ 0x267B, 0x00 },
+	{ 0x267C, 0x16 },
+	{ 0x267D, 0x01 },
+	{ 0x267E, 0xA6 },
+	{ 0x267F, 0x02 },
+	{ 0x2680, 0xD5 },
+	{ 0x2681, 0x02 },
+	{ 0x2690, 0xF8 },
+	{ 0x2691, 0x00 },
+	{ 0x2694, 0xA6 },
+	{ 0x2695, 0x02 },
+	{ 0x2696, 0x16 },
+	{ 0x2697, 0x01 },
+	{ 0x269A, 0xD5 },
+	{ 0x269B, 0x02 },
+	{ 0x26B8, 0x10 },
+	{ 0x26B9, 0x00 },
+	{ 0x26BA, 0x33 },
+	{ 0x26BB, 0x00 },
+	{ 0x26BC, 0x89 },
+	{ 0x26BD, 0x00 },
+	{ 0x26BE, 0xB0 },
+	{ 0x26BF, 0x00 },
+	{ 0x26C4, 0x4E },
+	{ 0x26C5, 0x00 },
+	{ 0x26C8, 0xC9 },
+	{ 0x26C9, 0x00 },
+	{ 0x26CC, 0x35 },
+	{ 0x26CD, 0x01 },
+	{ 0x26D0, 0xBA },
+	{ 0x26D1, 0x01 },
+	{ 0x26D4, 0x7C },
+	{ 0x26D5, 0x02 },
+	{ 0x26D8, 0xF6 },
+	{ 0x26D9, 0x02 },
+	{ 0x26DE, 0x51 },
+	{ 0x26DF, 0x00 },
+	{ 0x26E0, 0x7F },
+	{ 0x26E1, 0x00 },
+	{ 0x26E2, 0xCC },
+	{ 0x26E3, 0x00 },
+	{ 0x26E4, 0xF8 },
+	{ 0x26E5, 0x00 },
+	{ 0x26E6, 0x38 },
+	{ 0x26E7, 0x01 },
+	{ 0x26E8, 0x65 },
+	{ 0x26E9, 0x01 },
+	{ 0x26EA, 0xBD },
+	{ 0x26EB, 0x01 },
+	{ 0x26EE, 0x7F },
+	{ 0x26EF, 0x02 },
+	{ 0x26F0, 0xAB },
+	{ 0x26F1, 0x02 },
+	{ 0x26F2, 0xF9 },
+	{ 0x26F3, 0x02 },
+	{ 0x2722, 0x59 },
+	{ 0x2723, 0x02 },
+	{ 0x2938, 0x55 },
+	{ 0x2939, 0x00 },
+	{ 0x293A, 0x17 },
+	{ 0x293B, 0x00 },
+	{ 0x293C, 0xD0 },
+	{ 0x293D, 0x00 },
+	{ 0x293E, 0x91 },
+	{ 0x293F, 0x00 },
+	{ 0x2940, 0x3C },
+	{ 0x2941, 0x01 },
+	{ 0x2942, 0x0C },
+	{ 0x2943, 0x01 },
+	{ 0x2944, 0xC1 },
+	{ 0x2945, 0x01 },
+	{ 0x2946, 0x76 },
+	{ 0x2947, 0x01 },
+	{ 0x2948, 0x83 },
+	{ 0x2949, 0x02 },
+	{ 0x294A, 0xFB },
+	{ 0x294B, 0x01 },
+	{ 0x294C, 0xFD },
+	{ 0x294D, 0x02 },
+	{ 0x294E, 0xBF },
+	{ 0x294F, 0x02 },
+	{ 0x2A06, 0x25 },
+	{ 0x2A07, 0x03 },
+	{ 0x2A0C, 0x45 },
+	{ 0x2A0D, 0x00 },
+	{ 0x2A0E, 0x00 },
+	{ 0x2A0F, 0x00 },
+	{ 0x2A20, 0x00 },
+	{ 0x2A21, 0x00 },
+	{ 0x2A22, 0x7D },
+	{ 0x2A23, 0x00 },
+	{ 0x2B11, 0x1A },
+	{ 0x2B13, 0x11 },
+	{ 0x2B14, 0x11 },
+	{ 0x2B15, 0x11 },
+	{ 0x2B16, 0x11 },
+	{ 0x2B17, 0x10 },
+	{ 0x2B18, 0x0F },
+	{ 0x2B19, 0x0E },
+	{ 0x2B1A, 0x0D },
+	{ 0x2B1B, 0x0C },
+	{ 0x2B1C, 0x0B },
+	{ 0x2B1D, 0x0B },
+	{ 0x2B1E, 0x0A },
+	{ 0x2B1F, 0x09 },
+	{ 0x2B20, 0x08 },
+	{ 0x2B21, 0x07 },
+	{ 0x2B22, 0x06 },
+	{ 0x2B23, 0x05 },
+	{ 0x2B24, 0x04 },
+	{ 0x2B25, 0x03 },
+	{ 0x2B26, 0x03 },
+	{ 0x2B38, 0x01 },
+	{ 0x2B45, 0xE3 },
+	{ 0x2B50, 0x01 },
+	{ 0x2B51, 0x00 },
+	{ 0x2B62, 0x66 },
+	{ 0x2B6D, 0x47 },
+	{ 0x2B70, 0x03 },
+	{ 0x2B71, 0x02 },
+	{ 0x2B72, 0x02 },
+	{ 0x2B7B, 0x42 },
+	{ 0x2B7F, 0x7F },
+	{ 0x2B80, 0x94 },
+	{ 0x2B81, 0x06 },
+	{ 0x2B87, 0x1B },
+	{ 0x2B88, 0x1A },
+	{ 0x2B89, 0x17 },
+	{ 0x2B8A, 0x17 },
+	{ 0x2B8B, 0x12 },
+	{ 0x2B8D, 0x2B },
+	{ 0x2B8E, 0x2B },
+	{ 0x2B8F, 0x2B },
+	{ 0x2B90, 0x7F },
+	{ 0x2B91, 0x0F },
+	{ 0x2B92, 0x31 },
+	{ 0x2B93, 0x07 },
+	{ 0x2B94, 0xFE },
+	{ 0x2B95, 0x26 },
+	{ 0x2B96, 0x84 },
+	{ 0x2B97, 0x0C },
+	{ 0x2B98, 0xFE },
+	{ 0x2B99, 0x56 },
+	{ 0x2B9B, 0x2A },
+	{ 0x2BA8, 0xBC },
+	{ 0x2BA9, 0x62 },
+	{ 0x2BC1, 0x70 },
+	{ 0x2BC5, 0x80 },
+	{ 0x2BD5, 0x30 },
+	{ 0x2BD6, 0xF0 },
+	{ 0x2BD8, 0xDB },
+	{ 0x2BD9, 0xF6 },
+	{ 0x2BDA, 0x21 },
+	{ 0x2BDB, 0x06 },
+	{ 0x2BDC, 0x57 },
+	{ 0x2BFE, 0x00 },
+	{ 0x2BFF, 0x00 },
+	{ 0x2C98, 0xE1 },
+	{ 0x2C99, 0x2E },
+	{ 0x2C9B, 0x80 },
+	{ 0x2CA9, 0x80 },
+	{ 0x2CAA, 0x01 },
+	{ 0x2CBF, 0x08 },
+	{ 0x2D39, 0x0E },
+	{ 0x2D50, 0x80 },
+	{ 0x2D54, 0x00 },
+	{ 0x2D5B, 0x58 },
+	{ 0x2DFD, 0x01 },
+	{ 0x2D64, 0x64 },
+	{ 0x2D65, 0x80 },
+	{ 0x3000, 0x00 },
+	{ 0x3001, 0x00 },
+	{ 0x3002, 0x23 },
+	{ 0x3003, 0xA1 },
+	{ 0x3004, 0x00 },
+	{ 0x3005, 0x20 },
+	{ 0x3006, 0x58 },
+	{ 0x3007, 0x00 },
+	{ 0x3008, 0x06 },
+	{ 0x3009, 0xB4 },
+	{ 0x300A, 0x1F },
+	{ 0x300B, 0x00 },
+	{ 0x300C, 0x00 },
+	{ 0x300D, 0x1B },
+	{ 0x300E, 0x90 },
+	{ 0x300F, 0x97 },
+	{ 0x3010, 0x00 },
+	{ 0x3011, 0x00 },
+	{ 0x3012, 0x20 },
+	{ 0x3013, 0x21 },
+	{ 0x3014, 0x00 },
+	{ 0x3015, 0x20 },
+	{ 0x3016, 0x84 },
+	{ 0x3017, 0x00 },
+	{ 0x3018, 0x30 },
+	{ 0x3019, 0x09 },
+	{ 0x301A, 0x46 },
+	{ 0x301B, 0x00 },
+	{ 0x3070, 0xC1 },
+	{ 0x3071, 0x81 },
+	{ 0x3072, 0x29 },
+	{ 0x3073, 0x81 },
+	{ 0x3080, 0xC4 },
+	{ 0x3081, 0x0C },
+	{ 0x3082, 0xD2 },
+	{ 0x3083, 0x0C },
+	{ 0x3084, 0x5C },
+	{ 0x3085, 0x00 },
+	{ 0x3086, 0x90 },
+	{ 0x3087, 0x00 },
+	{ 0x3088, 0x07 },
+	{ 0x3089, 0x0A },
+	{ 0x308A, 0x52 },
+	{ 0x308B, 0x09 },
+	{ 0x308C, 0x44 },
+	{ 0x308D, 0x03 },
+	{ 0x308E, 0x70 },
+	{ 0x308F, 0x03 },
+	{ 0x3090, 0x54 },
+	{ 0x3091, 0x09 },
+	{ 0x3092, 0x5A },
+	{ 0x3093, 0x09 },
+	{ 0x3094, 0x1C },
+	{ 0x3095, 0x00 },
+	{ 0x3096, 0x10 },
+	{ 0x3097, 0x00 },
+	{ 0x3098, 0x70 },
+	{ 0x3099, 0x03 },
+	{ 0x309A, 0xF8 },
+	{ 0x309B, 0x04 },
+	{ 0x309C, 0x74 },
+	{ 0x309D, 0x01 },
+	{ 0x309E, 0x60 },
+	{ 0x309F, 0x01 },
+	{ 0x3370, 0x01 },
+	{ 0x3374, 0xF0 },
+	{ 0x3375, 0x00 },
+	{ 0x3376, 0x01 },
+	{ 0x3377, 0x00 },
+	{ 0x3410, (IMX390_OUT_WIDTH & 0xFF) },
+	{ 0x3411, (IMX390_OUT_WIDTH >> 8) },
+	{ 0x3418, (IMX390_OUT_HEIGHT & 0xFF) },
+	{ 0x3419, (IMX390_OUT_HEIGHT >> 8) },
+	{ 0x34A0, 0x30 },
+	{ 0x34BE, 0x6A },
+	{ 0x34BF, 0x01 },
+	{ 0x34C0, 0x40 },
+	{ 0x34C1, 0x00 },
+	{ 0x34C2, 0x40 },
+	{ 0x34C3, 0x00 },
+	{ 0x34C4, 0x40 },
+	{ 0x34C5, 0x00 },
+	{ 0x34C6, 0x40 },
+	{ 0x34C7, 0x00 },
+	{ 0x34C8, 0x40 },
+	{ 0x34C9, 0x00 },
+	{ 0x34CA, 0x40 },
+	{ 0x34CB, 0x00 },
+	{ 0x34CC, 0x40 },
+	{ 0x34CD, 0x00 },
+	{ 0x34CE, 0x40 },
+	{ 0x34CF, 0x00 },
+	{ 0x3584, 0x00 },
+	{ 0x3586, 0x00 },
+	{ 0x3587, 0x01 },
+	{ 0x3588, 0xE6 },
+	{ 0x3589, 0x00 },
+	{ 0x3590, 0x00 },
+	{ 0x3591, 0x00 },
+	{ 0x3594, 0x40 },
+	{ 0x3598, 0x03 },
+	{ 0x3599, 0x00 },
+	{ 0x359A, 0x80 },
+	{ 0x359B, 0x00 },
+	{ 0x359C, 0x00 },
+	{ 0x359D, 0x01 },
+	{ 0x359E, 0x00 },
+	{ 0x359F, 0x02 },
+	{ 0x35A0, 0x00 },
+	{ 0x35A1, 0x04 },
+	{ 0x35A2, 0x20 },
+	{ 0x35A3, 0x00 },
+	{ 0x35A4, 0x40 },
+	{ 0x35A5, 0x00 },
+	{ 0x35A6, 0x80 },
+	{ 0x35A7, 0x00 },
+	{ 0x35A8, 0x00 },
+	{ 0x35A9, 0x01 },
+	{ 0x35AC, 0x80 },
+	{ 0x35AD, 0x00 },
+	{ 0x35AE, 0x00 },
+	{ 0x35AF, 0x01 },
+	{ 0x35B0, 0x00 },
+	{ 0x35B1, 0x02 },
+	{ 0x35B2, 0x00 },
+	{ 0x35B3, 0x04 },
+	{ 0x35B4, 0x02 },
+	{ 0x35B5, 0x00 },
+	{ 0x35B6, 0x04 },
+	{ 0x35B7, 0x00 },
+	{ 0x35B8, 0x08 },
+	{ 0x35B9, 0x00 },
+	{ 0x35BA, 0x10 },
+	{ 0x35BB, 0x00 },
+	{ 0x35C8, 0x00 },
+	{ 0x35C9, 0x01 },
+	{ 0x35CA, 0x00 },
+	{ 0x35CB, 0x04 },
+	{ 0x35CC, 0x00 },
+	{ 0x35CD, 0x10 },
+	{ 0x35CE, 0x00 },
+	{ 0x35CF, 0x40 },
+	{ 0x35D0, 0x00 },
+	{ 0x35D1, 0x0C },
+	{ 0x35D2, 0x00 },
+	{ 0x35D3, 0x0C },
+	{ 0x35D4, 0x00 },
+	{ 0x35D5, 0x0C },
+	{ 0x35D6, 0x00 },
+	{ 0x35D7, 0x0C },
+	{ 0x35D8, 0x00 },
+	{ 0x35D9, 0x00 },
+	{ 0x35DA, 0x08 },
+	{ 0x35DB, 0x00 },
+	{ 0x35DC, 0xD8 },
+	{ 0x35DD, 0x0E },
+	{ 0x35F0, 0x00 },
+	{ 0x35F1, 0x10 },
+	{ 0x35F2, 0x00 },
+	{ 0x35F3, 0x10 },
+	{ 0x35F4, 0x00 },
+	{ 0x35F5, 0x10 },
+	{ 0x35F6, 0x00 },
+	{ 0x35F7, 0x03 },
+	{ 0x35F8, 0x00 },
+	{ 0x35F9, 0x02 },
+	{ 0x35FA, 0x38 },
+	{ 0x35FB, 0x00 },
+	{ 0x35FC, 0xB3 },
+	{ 0x35FD, 0x01 },
+	{ 0x35FE, 0x00 },
+	{ 0x35FF, 0x00 },
+	{ 0x3600, 0x05 },
+	{ 0x3601, 0x06 },
+	{ 0x3604, 0x03 },
+	{ 0x3605, 0x00 },
+	{ 0x3608, 0x03 },
+	{ 0x3609, 0x00 },
+	{ 0x360C, 0x00 },
+	{ 0x360D, 0x00 },
+	{ 0x3610, 0x10 },
+	{ 0x3611, 0x01 },
+	{ 0x3612, 0x00 },
+	{ 0x3613, 0x00 },
+	{ 0x3614, 0x00 },
+	{ 0x3615, 0x00 },
+	{ 0x361C, 0x00 },
+	{ 0x361D, 0x01 },
+	{ 0x361E, 0x00 },
+	{ 0x361F, 0x01 },
+	{ 0x3620, 0x00 },
+	{ 0x3621, 0x00 },
+	{ 0x3622, 0xB0 },
+	{ 0x3623, 0x04 },
+	{ 0x3624, 0xDC },
+	{ 0x3625, 0x05 },
+	{ 0x3626, 0x00 },
+	{ 0x3627, 0x01 },
+	{ 0x3628, 0xFF },
+	{ 0x3629, 0x0F },
+	{ 0x362A, 0x00 },
+	{ 0x362B, 0x10 },
+	{ 0x362C, 0x00 },
+	{ 0x362D, 0x01 },
+	{ 0x3630, 0x41 },
+	{ 0x3631, 0x00 },
+	{ 0x3632, 0x41 },
+	{ 0x3633, 0x00 },
+	{ 0x3634, 0x41 },
+	{ 0x3635, 0x00 },
+	{ 0x3636, 0x41 },
+	{ 0x3637, 0x00 },
+	{ 0x3638, 0x44 },
+	{ 0x3639, 0x00 },
+	{ 0x363A, 0x47 },
+	{ 0x363B, 0x00 },
+	{ 0x363C, 0x47 },
+	{ 0x363D, 0x00 },
+	{ 0x363E, 0x44 },
+	{ 0x363F, 0x00 },
+	{ 0x36C4, 0xFF },
+	{ 0x36C5, 0x0F },
+	{ 0x36C6, 0xFF },
+	{ 0x36C7, 0x0F },
+	{ 0x36C8, 0xFF },
+	{ 0x36C9, 0x0F },
+	{ 0x36CC, 0x00 },
+	{ 0x36CD, 0x00 },
+	{ 0x36CE, 0x00 },
+	{ 0x36CF, 0x00 },
+	{ 0x36D0, 0x00 },
+	{ 0x36D1, 0x00 },
+	{ 0x36D4, 0xFF },
+	{ 0x36D5, 0x0F },
+	{ 0x36D6, 0xFF },
+	{ 0x36D7, 0x0F },
+	{ 0x36D8, 0xFF },
+	{ 0x36D9, 0x0F },
+	{ 0x36DC, 0xFF },
+	{ 0x36DD, 0x0F },
+	{ 0x36DE, 0xFF },
+	{ 0x36DF, 0x0F },
+	{ 0x36E0, 0xFF },
+	{ 0x36E1, 0x0F },
+	{ 0x36E4, 0xFF },
+	{ 0x36E5, 0x0F },
+	{ 0x36E6, 0xFF },
+	{ 0x36E7, 0x0F },
+	{ 0x36E8, 0xFF },
+	{ 0x36E9, 0x0F },
+	{ 0x36EE, 0x00 },
+	{ 0x36EF, 0x00 },
+	{ 0x36F0, 0x00 },
+	{ 0x36F1, 0x80 },
+	{ 0x36F8, 0x01 },
+	{ 0x3700, 0x03 },
+	{ 0x3701, 0x05 },
+	{ 0x3702, 0x03 },
+	{ 0x3703, 0x04 },
+	{ 0x3704, 0x08 },
+	{ 0x3705, 0x03 },
+	{ 0x3706, 0x03 },
+	{ 0x3707, 0x03 },
+	{ 0x3708, 0x03 },
+	{ 0x3709, 0x03 },
+	{ 0x370A, 0x03 },
+	{ 0x370B, 0x03 },
+	{ 0x370C, 0x03 },
+	{ 0x370D, 0x03 },
+	{ 0x370E, 0x0E },
+	{ 0x3718, 0x64 },
+	{ 0x3719, 0x47 },
+	{ 0x371A, 0x36 },
+	{ 0x371B, 0x1E },
+	{ 0x371C, 0x50 },
+	{ 0x371D, 0x41 },
+	{ 0x371E, 0x2F },
+	{ 0x371F, 0x1A },
+	{ 0x3720, 0x95 },
+	{ 0x3721, 0x9D },
+	{ 0x3722, 0xA5 },
+	{ 0x3723, 0xAD },
+	{ 0x3748, 0xA8 },
+	{ 0x3749, 0x9E },
+	{ 0x374A, 0x94 },
+	{ 0x374B, 0x80 },
+	{ 0x37C0, 0x00 },
+	{ 0x37C1, 0x00 },
+	{ 0x37C2, 0x00 },
+	{ 0x37C4, 0x00 },
+	{ 0x37C5, 0x00 },
+	{ 0x37C6, 0x00 },
+	{ 0x37C8, 0x00 },
+	{ 0x37C9, 0x00 },
+	{ 0x37CA, 0x00 },
+	{ 0x37CC, 0x00 },
+	{ 0x37CD, 0x00 },
+	{ 0x37CE, 0x00 },
+	{ 0x37D0, 0x00 },
+	{ 0x37D1, 0x00 },
+	{ 0x37D2, 0x00 },
+	{ 0x37D4, 0x00 },
+	{ 0x37D5, 0x00 },
+	{ 0x37D6, 0x00 },
+	{ 0x37D8, 0x00 },
+	{ 0x37D9, 0x00 },
+	{ 0x37DA, 0x00 },
+	{ 0x37DC, 0x00 },
+	{ 0x37DD, 0x00 },
+	{ 0x37DE, 0x00 },
+	{ 0x37E0, 0x00 },
+	{ 0x37E1, 0x00 },
+	{ 0x37E2, 0x00 },
+	{ 0x37E4, 0x00 },
+	{ 0x37E5, 0x00 },
+	{ 0x37E6, 0x00 },
+	{ 0x37E8, 0x00 },
+	{ 0x37E9, 0x00 },
+	{ 0x37EA, 0x00 },
+	{ 0x37EC, 0x00 },
+	{ 0x37ED, 0x00 },
+	{ 0x37EE, 0x00 },
+	{ 0x37F0, 0x00 },
+	{ 0x37F4, 0x00 },
+	{ 0x37F5, 0x1E },
+	{ 0x37F6, 0x34 },
+	{ 0x37F7, 0x00 },
+	{ 0x37F8, 0xFF },
+	{ 0x37F9, 0xFF },
+	{ 0x37FA, 0x03 },
+	{ 0x37FC, 0x00 },
+	{ 0x37FD, 0x00 },
+	{ 0x37FE, 0x04 },
+	{ 0x3800, 0xFF },
+	{ 0x3801, 0xFF },
+	{ 0x3802, 0x03 },
+	{ 0x3804, 0x00 },
+	{ 0x3805, 0x00 },
+	{ 0x3806, 0x04 },
+	{ 0x3808, 0x00 },
+	{ 0x3809, 0x00 },
+	{ 0x380A, 0x00 },
+	{ 0x380C, 0x00 },
+	{ 0x380D, 0x00 },
+	{ 0x380E, 0x00 },
+	{ 0x3810, 0x00 },
+	{ 0x3811, 0x00 },
+	{ 0x3812, 0x00 },
+	{ 0x3814, 0x00 },
+	{ 0x3815, 0x00 },
+	{ 0x3816, 0x00 },
+	{ 0x3818, 0x00 },
+	{ 0x3819, 0x00 },
+	{ 0x381A, 0x00 },
+	{ 0x381C, 0x00 },
+	{ 0x381D, 0x00 },
+	{ 0x381E, 0x00 },
+	{ 0x3820, 0x00 },
+	{ 0x3821, 0x00 },
+	{ 0x3822, 0x00 },
+	{ 0x3824, 0x00 },
+	{ 0x3825, 0x00 },
+	{ 0x3826, 0x00 },
+	{ 0x3828, 0x00 },
+	{ 0x3829, 0x00 },
+	{ 0x382A, 0x00 },
+	{ 0x382C, 0x00 },
+	{ 0x382D, 0x00 },
+	{ 0x382E, 0x00 },
+	{ 0x3830, 0x00 },
+	{ 0x3831, 0x00 },
+	{ 0x3832, 0x00 },
+	{ 0x3834, 0x00 },
+	{ 0x3835, 0x00 },
+	{ 0x3836, 0x00 },
+	{ 0x3838, 0x47 },
+	{ 0x3839, 0x00 },
+	{ 0x383A, 0x34 },
+	{ 0x383B, 0x00 },
+	{ 0x383C, 0x48 },
+	{ 0x383D, 0x00 },
+	{ 0x383E, 0x39 },
+	{ 0x383F, 0x00 },
+	{ 0x3840, 0x13 },
+	{ 0x3841, 0x00 },
+	{ 0x3842, 0x13 },
+	{ 0x3843, 0x00 },
+	{ 0x3844, 0x1D },
+	{ 0x3845, 0x00 },
+	{ 0x3846, 0x1D },
+	{ 0x3847, 0x00 },
+	{ 0x3848, 0x08 },
+	{ 0x3849, 0x00 },
+	{ 0x384A, 0x07 },
+	{ 0x384B, 0x00 },
+	{ 0x384C, 0x05 },
+	{ 0x384D, 0x00 },
+	{ 0x384E, 0x00 },
+	{ 0x384F, 0x00 },
+	{ 0x3850, 0xFF },
+	{ 0x3851, 0x0F },
+	{ 0x3852, 0x00 },
+	{ 0x3853, 0x10 },
+	{ 0x3854, 0xFF },
+	{ 0x3855, 0x0F },
+	{ 0x3856, 0x00 },
+	{ 0x3857, 0x10 },
+	{ 0x3858, 0xFF },
+	{ 0x3859, 0x0F },
+	{ 0x385A, 0x00 },
+	{ 0x385B, 0x10 },
+	{ 0x385C, 0x02 },
+	{ 0x385D, 0x00 },
+	{ 0x385E, 0x06 },
+	{ 0x385F, 0x00 },
+	{ 0x3860, 0x06 },
+	{ 0x3861, 0x00 },
+	{ 0x3862, 0x08 },
+	{ 0x3863, 0x00 },
+	{ 0x3864, 0x02 },
+	{ 0x3865, 0x00 },
+	{ 0x3870, 0x00 },
+	{ 0x3871, 0x01 },
+	{ 0x38A0, 0x01 },
+	{ 0x38A1, 0x01 },
+	{ 0x38A2, 0x00 },
+	{ 0x38A3, 0x01 },
+	{ 0x38A4, 0x07 },
+	{ 0x38A5, 0x00 },
+	{ 0x38A6, 0x04 },
+	{ 0x38A7, 0x04 },
+	{ 0x38A8, 0x00 },
+	{ 0x38A9, 0x00 },
+	{ 0x38AC, 0x00 },
+	{ 0x38AD, 0x00 },
+	{ 0x38AE, 0x01 },
+	{ 0x38B0, 0x02 },
+	{ 0x38B2, 0x43 },
+	{ 0x38B3, 0x00 },
+	{ 0x38B4, 0x10 },
+	{ 0x38B5, 0x00 },
+	{ 0x38B6, 0x09 },
+	{ 0x38B7, 0x00 },
+	{ 0x38B8, 0x09 },
+	{ 0x38B9, 0x00 },
+	{ 0x38BA, 0x47 },
+	{ 0x38BB, 0x00 },
+	{ 0x38BC, 0x16 },
+	{ 0x38BD, 0x00 },
+	{ 0x38BE, 0x0E },
+	{ 0x38BF, 0x00 },
+	{ 0x38C0, 0x0B },
+	{ 0x38C1, 0x00 },
+	{ 0x38C2, 0x4A },
+	{ 0x38C3, 0x00 },
+	{ 0x38C4, 0x1C },
+	{ 0x38C5, 0x00 },
+	{ 0x38C6, 0x12 },
+	{ 0x38C7, 0x00 },
+	{ 0x38C8, 0x0D },
+	{ 0x38C9, 0x00 },
+	{ 0x38CA, 0x51 },
+	{ 0x38CB, 0x00 },
+	{ 0x38CC, 0x24 },
+	{ 0x38CD, 0x00 },
+	{ 0x38CE, 0x19 },
+	{ 0x38CF, 0x00 },
+	{ 0x38D0, 0x10 },
+	{ 0x38D1, 0x00 },
+	{ 0x38D2, 0x5D },
+	{ 0x38D3, 0x00 },
+	{ 0x38D4, 0x30 },
+	{ 0x38D5, 0x00 },
+	{ 0x38D6, 0x23 },
+	{ 0x38D7, 0x00 },
+	{ 0x38D8, 0x17 },
+	{ 0x38D9, 0x00 },
+	{ 0x38DA, 0x72 },
+	{ 0x38DB, 0x00 },
+	{ 0x38DC, 0x43 },
+	{ 0x38DD, 0x00 },
+	{ 0x38DE, 0x31 },
+	{ 0x38DF, 0x00 },
+	{ 0x38E0, 0x20 },
+	{ 0x38E1, 0x00 },
+	{ 0x38E2, 0x96 },
+	{ 0x38E3, 0x00 },
+	{ 0x38E4, 0x5E },
+	{ 0x38E5, 0x00 },
+	{ 0x38E6, 0x46 },
+	{ 0x38E7, 0x00 },
+	{ 0x38E8, 0x2E },
+	{ 0x38E9, 0x00 },
+	{ 0x38EA, 0xD4 },
+	{ 0x38EB, 0x00 },
+	{ 0x38EC, 0x87 },
+	{ 0x38ED, 0x00 },
+	{ 0x38EE, 0x65 },
+	{ 0x38EF, 0x00 },
+	{ 0x38F0, 0x43 },
+	{ 0x38F1, 0x00 },
+	{ 0x38F2, 0x3F },
+	{ 0x38F3, 0x01 },
+	{ 0x38F4, 0xC4 },
+	{ 0x38F5, 0x00 },
+	{ 0x38F6, 0x94 },
+	{ 0x38F7, 0x00 },
+	{ 0x38F8, 0x64 },
+	{ 0x38F9, 0x00 },
+	{ 0x38FA, 0x00 },
+	{ 0x38FB, 0x01 },
+	{ 0x38FC, 0x00 },
+	{ 0x38FD, 0x01 },
+	{ 0x38FE, 0x00 },
+	{ 0x38FF, 0x01 },
+	{ 0x3900, 0x00 },
+	{ 0x3901, 0x01 },
+	{ 0x3902, 0x60 },
+	{ 0x3903, 0x00 },
+	{ 0x3904, 0x25 },
+	{ 0x3905, 0x00 },
+	{ 0x3906, 0x18 },
+	{ 0x3907, 0x00 },
+	{ 0x3908, 0x10 },
+	{ 0x3909, 0x00 },
+	{ 0x390A, 0xE6 },
+	{ 0x390B, 0x00 },
+	{ 0x390C, 0xD5 },
+	{ 0x390D, 0x00 },
+	{ 0x390E, 0xAA },
+	{ 0x390F, 0x00 },
+	{ 0x3910, 0x85 },
+	{ 0x3911, 0x00 },
+	{ 0x3912, 0xE6 },
+	{ 0x3913, 0x00 },
+	{ 0x3914, 0xD5 },
+	{ 0x3915, 0x00 },
+	{ 0x3916, 0xAA },
+	{ 0x3917, 0x00 },
+	{ 0x3918, 0x85 },
+	{ 0x3919, 0x00 },
+	{ 0x391A, 0xE6 },
+	{ 0x391B, 0x00 },
+	{ 0x391C, 0xD5 },
+	{ 0x391D, 0x00 },
+	{ 0x391E, 0xAA },
+	{ 0x391F, 0x00 },
+	{ 0x3920, 0x85 },
+	{ 0x3921, 0x00 },
+	{ 0x3922, 0x40 },
+	{ 0x3923, 0x00 },
+	{ 0x3924, 0x40 },
+	{ 0x3925, 0x00 },
+	{ 0x3926, 0x40 },
+	{ 0x3927, 0x00 },
+	{ 0x3928, 0x40 },
+	{ 0x3929, 0x00 },
+	{ 0x392A, 0x80 },
+	{ 0x392B, 0x00 },
+	{ 0x392C, 0x80 },
+	{ 0x392D, 0x00 },
+	{ 0x392E, 0x80 },
+	{ 0x392F, 0x00 },
+	{ 0x3930, 0x80 },
+	{ 0x3931, 0x00 },
+	{ 0x3932, 0x4C },
+	{ 0x3933, 0x4C },
+	{ 0x3934, 0x4C },
+	{ 0x3940, 0x01 },
+	{ 0x3941, 0x01 },
+	{ 0x3942, 0x00 },
+	{ 0x3943, 0x01 },
+	{ 0x3944, 0x07 },
+	{ 0x3945, 0x00 },
+	{ 0x3946, 0x04 },
+	{ 0x3947, 0x04 },
+	{ 0x3948, 0x00 },
+	{ 0x3949, 0x00 },
+	{ 0x394C, 0x00 },
+	{ 0x394D, 0x00 },
+	{ 0x394E, 0x01 },
+	{ 0x3950, 0x03 },
+	{ 0x3952, 0x1B },
+	{ 0x3953, 0x00 },
+	{ 0x3954, 0x0C },
+	{ 0x3955, 0x00 },
+	{ 0x3956, 0x09 },
+	{ 0x3957, 0x00 },
+	{ 0x3958, 0x07 },
+	{ 0x3959, 0x00 },
+	{ 0x395A, 0x1D },
+	{ 0x395B, 0x00 },
+	{ 0x395C, 0x0E },
+	{ 0x395D, 0x00 },
+	{ 0x395E, 0x0B },
+	{ 0x395F, 0x00 },
+	{ 0x3960, 0x08 },
+	{ 0x3961, 0x00 },
+	{ 0x3962, 0x1E },
+	{ 0x3963, 0x00 },
+	{ 0x3964, 0x10 },
+	{ 0x3965, 0x00 },
+	{ 0x3966, 0x0C },
+	{ 0x3967, 0x00 },
+	{ 0x3968, 0x09 },
+	{ 0x3969, 0x00 },
+	{ 0x396A, 0x21 },
+	{ 0x396B, 0x00 },
+	{ 0x396C, 0x13 },
+	{ 0x396D, 0x00 },
+	{ 0x396E, 0x0E },
+	{ 0x396F, 0x00 },
+	{ 0x3970, 0x0A },
+	{ 0x3971, 0x00 },
+	{ 0x3972, 0x25 },
+	{ 0x3973, 0x00 },
+	{ 0x3974, 0x19 },
+	{ 0x3975, 0x00 },
+	{ 0x3976, 0x12 },
+	{ 0x3977, 0x00 },
+	{ 0x3978, 0x0D },
+	{ 0x3979, 0x00 },
+	{ 0x397A, 0x2E },
+	{ 0x397B, 0x00 },
+	{ 0x397C, 0x21 },
+	{ 0x397D, 0x00 },
+	{ 0x397E, 0x19 },
+	{ 0x397F, 0x00 },
+	{ 0x3980, 0x11 },
+	{ 0x3981, 0x00 },
+	{ 0x3982, 0x3C },
+	{ 0x3983, 0x00 },
+	{ 0x3984, 0x2F },
+	{ 0x3985, 0x00 },
+	{ 0x3986, 0x23 },
+	{ 0x3987, 0x00 },
+	{ 0x3988, 0x19 },
+	{ 0x3989, 0x00 },
+	{ 0x398A, 0x56 },
+	{ 0x398B, 0x00 },
+	{ 0x398C, 0x44 },
+	{ 0x398D, 0x00 },
+	{ 0x398E, 0x35 },
+	{ 0x398F, 0x00 },
+	{ 0x3990, 0x27 },
+	{ 0x3991, 0x00 },
+	{ 0x3992, 0x84 },
+	{ 0x3993, 0x00 },
+	{ 0x3994, 0x68 },
+	{ 0x3995, 0x00 },
+	{ 0x3996, 0x53 },
+	{ 0x3997, 0x00 },
+	{ 0x3998, 0x40 },
+	{ 0x3999, 0x00 },
+	{ 0x399A, 0x00 },
+	{ 0x399B, 0x01 },
+	{ 0x399C, 0x00 },
+	{ 0x399D, 0x01 },
+	{ 0x399E, 0x00 },
+	{ 0x399F, 0x01 },
+	{ 0x39A0, 0x00 },
+	{ 0x39A1, 0x01 },
+	{ 0x39A2, 0x60 },
+	{ 0x39A3, 0x00 },
+	{ 0x39A4, 0x20 },
+	{ 0x39A5, 0x00 },
+	{ 0x39A6, 0x15 },
+	{ 0x39A7, 0x00 },
+	{ 0x39A8, 0x10 },
+	{ 0x39A9, 0x00 },
+	{ 0x39AA, 0xE6 },
+	{ 0x39AB, 0x00 },
+	{ 0x39AC, 0xD5 },
+	{ 0x39AD, 0x00 },
+	{ 0x39AE, 0xAA },
+	{ 0x39AF, 0x00 },
+	{ 0x39B0, 0x85 },
+	{ 0x39B1, 0x00 },
+	{ 0x39B2, 0xE6 },
+	{ 0x39B3, 0x00 },
+	{ 0x39B4, 0xD5 },
+	{ 0x39B5, 0x00 },
+	{ 0x39B6, 0xAA },
+	{ 0x39B7, 0x00 },
+	{ 0x39B8, 0x85 },
+	{ 0x39B9, 0x00 },
+	{ 0x39BA, 0xE6 },
+	{ 0x39BB, 0x00 },
+	{ 0x39BC, 0xD5 },
+	{ 0x39BD, 0x00 },
+	{ 0x39BE, 0xAA },
+	{ 0x39BF, 0x00 },
+	{ 0x39C0, 0x85 },
+	{ 0x39C1, 0x00 },
+	{ 0x39C2, 0x40 },
+	{ 0x39C3, 0x00 },
+	{ 0x39C4, 0x40 },
+	{ 0x39C5, 0x00 },
+	{ 0x39C6, 0x40 },
+	{ 0x39C7, 0x00 },
+	{ 0x39C8, 0x40 },
+	{ 0x39C9, 0x00 },
+	{ 0x39CA, 0x80 },
+	{ 0x39CB, 0x00 },
+	{ 0x39CC, 0x80 },
+	{ 0x39CD, 0x00 },
+	{ 0x39CE, 0x80 },
+	{ 0x39CF, 0x00 },
+	{ 0x39D0, 0x80 },
+	{ 0x39D1, 0x00 },
+	{ 0x39D2, 0x4C },
+	{ 0x39D3, 0x4C },
+	{ 0x39D4, 0x4C },
+	{ 0x39E0, 0x01 },
+	{ 0x39E1, 0x00 },
+	{ 0x39E4, 0x40 },
+	{ 0x39E5, 0x01 },
+	{ 0x39E6, 0x01 },
+	{ 0x39E8, 0x00 },
+	{ 0x39E9, 0x01 },
+	{ 0x39EA, 0x00 },
+	{ 0x39EB, 0x00 },
+	{ 0x39EC, 0x01 },
+	{ 0x39ED, 0x00 },
+	{ 0x39EE, 0x01 },
+	{ 0x39F0, 0x03 },
+	{ 0x39F1, 0x04 },
+	{ 0x39F2, 0x0E },
+	{ 0x39F4, 0x19 },
+	{ 0x39F5, 0x00 },
+	{ 0x39F6, 0x12 },
+	{ 0x39F7, 0x00 },
+	{ 0x39F8, 0x0D },
+	{ 0x39F9, 0x00 },
+	{ 0x39FA, 0x07 },
+	{ 0x39FB, 0x00 },
+	{ 0x39FC, 0x2B },
+	{ 0x39FD, 0x00 },
+	{ 0x39FE, 0x1B },
+	{ 0x39FF, 0x00 },
+	{ 0x3A00, 0x11 },
+	{ 0x3A01, 0x00 },
+	{ 0x3A02, 0x08 },
+	{ 0x3A03, 0x00 },
+	{ 0x3A04, 0x37 },
+	{ 0x3A05, 0x00 },
+	{ 0x3A06, 0x21 },
+	{ 0x3A07, 0x00 },
+	{ 0x3A08, 0x14 },
+	{ 0x3A09, 0x00 },
+	{ 0x3A0A, 0x09 },
+	{ 0x3A0B, 0x00 },
+	{ 0x3A0C, 0x4A },
+	{ 0x3A0D, 0x00 },
+	{ 0x3A0E, 0x2C },
+	{ 0x3A0F, 0x00 },
+	{ 0x3A10, 0x18 },
+	{ 0x3A11, 0x00 },
+	{ 0x3A12, 0x0B },
+	{ 0x3A13, 0x00 },
+	{ 0x3A14, 0x66 },
+	{ 0x3A15, 0x00 },
+	{ 0x3A16, 0x3B },
+	{ 0x3A17, 0x00 },
+	{ 0x3A18, 0x20 },
+	{ 0x3A19, 0x00 },
+	{ 0x3A1A, 0x0F },
+	{ 0x3A1B, 0x00 },
+	{ 0x3A1C, 0x8E },
+	{ 0x3A1D, 0x00 },
+	{ 0x3A1E, 0x51 },
+	{ 0x3A1F, 0x00 },
+	{ 0x3A20, 0x2B },
+	{ 0x3A21, 0x00 },
+	{ 0x3A22, 0x14 },
+	{ 0x3A23, 0x00 },
+	{ 0x3A24, 0xC8 },
+	{ 0x3A25, 0x00 },
+	{ 0x3A26, 0x72 },
+	{ 0x3A27, 0x00 },
+	{ 0x3A28, 0x3C },
+	{ 0x3A29, 0x00 },
+	{ 0x3A2A, 0x1B },
+	{ 0x3A2B, 0x00 },
+	{ 0x3A2C, 0x19 },
+	{ 0x3A2D, 0x01 },
+	{ 0x3A2E, 0xA0 },
+	{ 0x3A2F, 0x00 },
+	{ 0x3A30, 0x54 },
+	{ 0x3A31, 0x00 },
+	{ 0x3A32, 0x25 },
+	{ 0x3A33, 0x00 },
+	{ 0x3A34, 0x8D },
+	{ 0x3A35, 0x01 },
+	{ 0x3A36, 0xE1 },
+	{ 0x3A37, 0x00 },
+	{ 0x3A38, 0x76 },
+	{ 0x3A39, 0x00 },
+	{ 0x3A3A, 0x35 },
+	{ 0x3A3B, 0x00 },
+	{ 0x3A3C, 0x00 },
+	{ 0x3A3D, 0x01 },
+	{ 0x3A3E, 0x00 },
+	{ 0x3A3F, 0x01 },
+	{ 0x3A40, 0x00 },
+	{ 0x3A41, 0x01 },
+	{ 0x3A42, 0x00 },
+	{ 0x3A43, 0x01 },
+	{ 0x3A44, 0x70 },
+	{ 0x3A45, 0x00 },
+	{ 0x3A46, 0x25 },
+	{ 0x3A47, 0x00 },
+	{ 0x3A48, 0x18 },
+	{ 0x3A49, 0x00 },
+	{ 0x3A4A, 0x10 },
+	{ 0x3A4B, 0x00 },
+	{ 0x3A4C, 0xE6 },
+	{ 0x3A4D, 0x00 },
+	{ 0x3A4E, 0xD5 },
+	{ 0x3A4F, 0x00 },
+	{ 0x3A50, 0xAA },
+	{ 0x3A51, 0x00 },
+	{ 0x3A52, 0x85 },
+	{ 0x3A53, 0x00 },
+	{ 0x3A54, 0xE6 },
+	{ 0x3A55, 0x00 },
+	{ 0x3A56, 0xD5 },
+	{ 0x3A57, 0x00 },
+	{ 0x3A58, 0xAA },
+	{ 0x3A59, 0x00 },
+	{ 0x3A5A, 0x85 },
+	{ 0x3A5B, 0x00 },
+	{ 0x3A5C, 0xE6 },
+	{ 0x3A5D, 0x00 },
+	{ 0x3A5E, 0xD5 },
+	{ 0x3A5F, 0x00 },
+	{ 0x3A60, 0xAA },
+	{ 0x3A61, 0x00 },
+	{ 0x3A62, 0x85 },
+	{ 0x3A63, 0x00 },
+	{ 0x3A64, 0x19 },
+	{ 0x3A65, 0x00 },
+	{ 0x3A66, 0x12 },
+	{ 0x3A67, 0x00 },
+	{ 0x3A68, 0x0D },
+	{ 0x3A69, 0x00 },
+	{ 0x3A6A, 0x07 },
+	{ 0x3A6B, 0x00 },
+	{ 0x3A6C, 0x0C },
+	{ 0x3A6D, 0x00 },
+	{ 0x3A6E, 0x07 },
+	{ 0x3A6F, 0x00 },
+	{ 0x3A70, 0x05 },
+	{ 0x3A71, 0x00 },
+	{ 0x3A72, 0x04 },
+	{ 0x3A73, 0x00 },
+	{ 0x3A74, 0x1B },
+	{ 0x3A75, 0x00 },
+	{ 0x3A76, 0x15 },
+	{ 0x3A77, 0x00 },
+	{ 0x3A78, 0x0C },
+	{ 0x3A79, 0x00 },
+	{ 0x3A7A, 0x08 },
+	{ 0x3A7B, 0x00 },
+	{ 0x3A7C, 0x80 },
+	{ 0x3A7D, 0x00 },
+	{ 0x3A7E, 0x80 },
+	{ 0x3A7F, 0x00 },
+	{ 0x3A80, 0x80 },
+	{ 0x3A81, 0x00 },
+	{ 0x3A82, 0x80 },
+	{ 0x3A83, 0x00 },
+	{ 0x3A84, 0x09 },
+	{ 0x3A85, 0x00 },
+	{ 0x3A86, 0x06 },
+	{ 0x3A87, 0x00 },
+	{ 0x3A88, 0x04 },
+	{ 0x3A89, 0x00 },
+	{ 0x3A8A, 0x03 },
+	{ 0x3A8B, 0x00 },
+	{ 0x3A8C, 0xFA },
+	{ 0x3A8D, 0x00 },
+	{ 0x3A8E, 0xC8 },
+	{ 0x3A8F, 0x00 },
+	{ 0x3A90, 0x96 },
+	{ 0x3A91, 0x00 },
+	{ 0x3A92, 0x64 },
+	{ 0x3A93, 0x00 },
+	{ 0x3A94, 0xE1 },
+	{ 0x3A95, 0x00 },
+	{ 0x3A96, 0xC8 },
+	{ 0x3A97, 0x00 },
+	{ 0x3A98, 0x96 },
+	{ 0x3A99, 0x00 },
+	{ 0x3A9A, 0x64 },
+	{ 0x3A9B, 0x00 },
+	{ 0x3A9C, 0x08 },
+	{ 0x3A9D, 0x10 },
+	{ 0x3A9E, 0x4C },
+	{ 0x3A9F, 0x4C },
+	{ 0x3AA0, 0x4C },
+	{ 0x3AA1, 0x04 },
+	{ 0x3AA2, 0x04 },
+	{ 0x3AC0, 0x01 },
+	{ 0x3AC4, 0x81 },
+	{ 0x3AC5, 0x00 },
+	{ 0x3AC6, 0x00 },
+	{ 0x3AC7, 0x00 },
+	{ 0x3AC8, 0x00 },
+	{ 0x3AC9, 0x00 },
+	{ 0x3ACA, 0x00 },
+	{ 0x3ACB, 0x00 },
+	{ 0x3ACC, 0x02 },
+	{ 0x3ACD, 0x00 },
+	{ 0x3ACE, 0x81 },
+	{ 0x3ACF, 0x00 },
+	{ 0x3AD0, 0x00 },
+	{ 0x3AD1, 0x00 },
+	{ 0x3AD2, 0xFD },
+	{ 0x3AD3, 0x03 },
+	{ 0x3AD4, 0x02 },
+	{ 0x3AD5, 0x00 },
+	{ 0x3AD6, 0x00 },
+	{ 0x3AD7, 0x00 },
+	{ 0x3AD8, 0x81 },
+	{ 0x3AD9, 0x00 },
+	{ 0x3ADA, 0xFD },
+	{ 0x3ADB, 0x03 },
+	{ 0x3ADC, 0xFF },
+	{ 0x3ADD, 0x03 },
+	{ 0x3ADE, 0x01 },
+	{ 0x3ADF, 0x00 },
+	{ 0x3AE0, 0x01 },
+	{ 0x3AE1, 0x00 },
+	{ 0x3AE2, 0x7E },
+	{ 0x3AE3, 0x00 },
+	{ 0x3AF4, 0x00 },
+	{ 0x3AF6, 0x40 },
+	{ 0x3AF7, 0x1E },
+	{ 0x3AF8, 0x00 },
+	{ 0x3AFA, 0x00 },
+	{ 0x3AFB, 0x00 },
+	{ 0x3AFC, 0x00 },
+	{ 0x3AFD, 0x00 },
+	{ 0x3AFE, 0x00 },
+	{ 0x3AFF, 0x00 },
+	{ 0x3B00, 0x00 },
+	{ 0x3B01, 0x00 },
+	{ 0x3B02, 0x00 },
+	{ 0x3B03, 0x00 },
+	{ 0x3B04, 0x00 },
+	{ 0x3B05, 0x00 },
+	{ 0x3B06, 0x00 },
+	{ 0x3B07, 0x00 },
+	{ 0x3B08, 0x00 },
+	{ 0x3B09, 0x00 },
+	{ 0x3B0A, 0x00 },
+	{ 0x3B0B, 0x00 },
+	{ 0x3B0C, 0x00 },
+	{ 0x3B0D, 0x00 },
+	{ 0x3B0E, 0x00 },
+	{ 0x3B0F, 0x00 },
+	{ 0x3B10, 0x00 },
+	{ 0x3B11, 0x00 },
+	{ 0x3B12, 0x00 },
+	{ 0x3B13, 0x00 },
+	{ 0x3B14, 0x00 },
+	{ 0x3B15, 0x00 },
+	{ 0x3B16, 0x00 },
+	{ 0x3B17, 0x00 },
+	{ 0x3B18, 0x00 },
+	{ 0x3B19, 0x00 },
+	{ 0x3B1A, 0x00 },
+	{ 0x3B1B, 0x00 },
+	{ 0x3B1C, 0x00 },
+	{ 0x3B1D, 0x00 },
+	{ 0x3B1E, 0x00 },
+	{ 0x3B1F, 0x00 },
+	{ 0x3B20, 0x00 },
+	{ 0x3B21, 0x00 },
+	{ 0x3B22, 0x00 },
+	{ 0x3B23, 0x00 },
+	{ 0x3B24, 0x00 },
+	{ 0x3B25, 0x00 },
+	{ 0x3B26, 0x00 },
+	{ 0x3B27, 0x00 },
+	{ 0x3B28, 0x00 },
+	{ 0x3B29, 0x00 },
+	{ 0x3B2A, 0x00 },
+	{ 0x3B2C, 0x00 },
+	{ 0x3B2E, 0x00 },
+	{ 0x3B30, 0x00 },
+	{ 0x3B32, 0x0C },
+	{ 0x4000, 0xAF },
+	{ 0x4001, 0xA7 },
+	{ 0x4002, 0xA8 },
+	{ 0x4003, 0xA5 },
+	{ 0x4004, 0x98 },
+	{ 0x4005, 0x93 },
+	{ 0x4006, 0x94 },
+	{ 0x4007, 0x93 },
+	{ 0x4008, 0x8E },
+	{ 0x4009, 0x8C },
+	{ 0x400A, 0x8C },
+	{ 0x400B, 0x8C },
+	{ 0x400C, 0x89 },
+	{ 0x400D, 0x88 },
+	{ 0x400E, 0x89 },
+	{ 0x400F, 0x89 },
+	{ 0x4010, 0x87 },
+	{ 0x4011, 0x87 },
+	{ 0x4012, 0x87 },
+	{ 0x4013, 0x86 },
+	{ 0x4014, 0x88 },
+	{ 0x4015, 0x87 },
+	{ 0x4016, 0x87 },
+	{ 0x4017, 0x87 },
+	{ 0x4018, 0x8B },
+	{ 0x4019, 0x89 },
+	{ 0x401A, 0x89 },
+	{ 0x401B, 0x8A },
+	{ 0x401C, 0x92 },
+	{ 0x401D, 0x8F },
+	{ 0x401E, 0x8F },
+	{ 0x401F, 0x8F },
+	{ 0x4020, 0xA2 },
+	{ 0x4021, 0x9C },
+	{ 0x4022, 0x9B },
+	{ 0x4023, 0x9C },
+	{ 0x4024, 0xA1 },
+	{ 0x4025, 0x9A },
+	{ 0x4026, 0x9B },
+	{ 0x4027, 0x99 },
+	{ 0x4028, 0x94 },
+	{ 0x4029, 0x90 },
+	{ 0x402A, 0x90 },
+	{ 0x402B, 0x90 },
+	{ 0x402C, 0x8B },
+	{ 0x402D, 0x89 },
+	{ 0x402E, 0x89 },
+	{ 0x402F, 0x89 },
+	{ 0x4030, 0x86 },
+	{ 0x4031, 0x85 },
+	{ 0x4032, 0x86 },
+	{ 0x4033, 0x85 },
+	{ 0x4034, 0x84 },
+	{ 0x4035, 0x84 },
+	{ 0x4036, 0x84 },
+	{ 0x4037, 0x84 },
+	{ 0x4038, 0x85 },
+	{ 0x4039, 0x85 },
+	{ 0x403A, 0x85 },
+	{ 0x403B, 0x85 },
+	{ 0x403C, 0x88 },
+	{ 0x403D, 0x87 },
+	{ 0x403E, 0x87 },
+	{ 0x403F, 0x87 },
+	{ 0x4040, 0x8E },
+	{ 0x4041, 0x8C },
+	{ 0x4042, 0x8C },
+	{ 0x4043, 0x8C },
+	{ 0x4044, 0x98 },
+	{ 0x4045, 0x93 },
+	{ 0x4046, 0x93 },
+	{ 0x4047, 0x94 },
+	{ 0x4048, 0x9D },
+	{ 0x4049, 0x96 },
+	{ 0x404A, 0x97 },
+	{ 0x404B, 0x96 },
+	{ 0x404C, 0x91 },
+	{ 0x404D, 0x8C },
+	{ 0x404E, 0x8D },
+	{ 0x404F, 0x8C },
+	{ 0x4050, 0x89 },
+	{ 0x4051, 0x86 },
+	{ 0x4052, 0x87 },
+	{ 0x4053, 0x86 },
+	{ 0x4054, 0x83 },
+	{ 0x4055, 0x82 },
+	{ 0x4056, 0x82 },
+	{ 0x4057, 0x82 },
+	{ 0x4058, 0x80 },
+	{ 0x4059, 0x80 },
+	{ 0x405A, 0x80 },
+	{ 0x405B, 0x80 },
+	{ 0x405C, 0x82 },
+	{ 0x405D, 0x82 },
+	{ 0x405E, 0x82 },
+	{ 0x405F, 0x82 },
+	{ 0x4060, 0x86 },
+	{ 0x4061, 0x85 },
+	{ 0x4062, 0x85 },
+	{ 0x4063, 0x85 },
+	{ 0x4064, 0x8B },
+	{ 0x4065, 0x8A },
+	{ 0x4066, 0x89 },
+	{ 0x4067, 0x89 },
+	{ 0x4068, 0x94 },
+	{ 0x4069, 0x91 },
+	{ 0x406A, 0x90 },
+	{ 0x406B, 0x91 },
+	{ 0x406C, 0x9E },
+	{ 0x406D, 0x95 },
+	{ 0x406E, 0x96 },
+	{ 0x406F, 0x95 },
+	{ 0x4070, 0x91 },
+	{ 0x4071, 0x8C },
+	{ 0x4072, 0x8C },
+	{ 0x4073, 0x8C },
+	{ 0x4074, 0x89 },
+	{ 0x4075, 0x86 },
+	{ 0x4076, 0x86 },
+	{ 0x4077, 0x86 },
+	{ 0x4078, 0x83 },
+	{ 0x4079, 0x82 },
+	{ 0x407A, 0x82 },
+	{ 0x407B, 0x82 },
+	{ 0x407C, 0x80 },
+	{ 0x407D, 0x80 },
+	{ 0x407E, 0x80 },
+	{ 0x407F, 0x80 },
+	{ 0x4080, 0x82 },
+	{ 0x4081, 0x81 },
+	{ 0x4082, 0x81 },
+	{ 0x4083, 0x81 },
+	{ 0x4084, 0x85 },
+	{ 0x4085, 0x85 },
+	{ 0x4086, 0x85 },
+	{ 0x4087, 0x84 },
+	{ 0x4088, 0x8B },
+	{ 0x4089, 0x8A },
+	{ 0x408A, 0x89 },
+	{ 0x408B, 0x89 },
+	{ 0x408C, 0x93 },
+	{ 0x408D, 0x90 },
+	{ 0x408E, 0x8F },
+	{ 0x408F, 0x8F },
+	{ 0x4090, 0xA3 },
+	{ 0x4091, 0x99 },
+	{ 0x4092, 0x9A },
+	{ 0x4093, 0x99 },
+	{ 0x4094, 0x95 },
+	{ 0x4095, 0x8F },
+	{ 0x4096, 0x8F },
+	{ 0x4097, 0x8F },
+	{ 0x4098, 0x8B },
+	{ 0x4099, 0x87 },
+	{ 0x409A, 0x87 },
+	{ 0x409B, 0x87 },
+	{ 0x409C, 0x86 },
+	{ 0x409D, 0x84 },
+	{ 0x409E, 0x84 },
+	{ 0x409F, 0x84 },
+	{ 0x40A0, 0x84 },
+	{ 0x40A1, 0x83 },
+	{ 0x40A2, 0x83 },
+	{ 0x40A3, 0x82 },
+	{ 0x40A4, 0x84 },
+	{ 0x40A5, 0x84 },
+	{ 0x40A6, 0x83 },
+	{ 0x40A7, 0x83 },
+	{ 0x40A8, 0x88 },
+	{ 0x40A9, 0x87 },
+	{ 0x40AA, 0x86 },
+	{ 0x40AB, 0x86 },
+	{ 0x40AC, 0x8E },
+	{ 0x40AD, 0x8C },
+	{ 0x40AE, 0x8C },
+	{ 0x40AF, 0x8B },
+	{ 0x40B0, 0x9A },
+	{ 0x40B1, 0x96 },
+	{ 0x40B2, 0x96 },
+	{ 0x40B3, 0x95 },
+	{ 0x40B4, 0xBA },
+	{ 0x40B5, 0xAC },
+	{ 0x40B6, 0xAD },
+	{ 0x40B7, 0xAC },
+	{ 0x40B8, 0x99 },
+	{ 0x40B9, 0x90 },
+	{ 0x40BA, 0x91 },
+	{ 0x40BB, 0x90 },
+	{ 0x40BC, 0x90 },
+	{ 0x40BD, 0x8A },
+	{ 0x40BE, 0x8A },
+	{ 0x40BF, 0x8A },
+	{ 0x40C0, 0x89 },
+	{ 0x40C1, 0x86 },
+	{ 0x40C2, 0x86 },
+	{ 0x40C3, 0x87 },
+	{ 0x40C4, 0x87 },
+	{ 0x40C5, 0x85 },
+	{ 0x40C6, 0x85 },
+	{ 0x40C7, 0x85 },
+	{ 0x40C8, 0x87 },
+	{ 0x40C9, 0x86 },
+	{ 0x40CA, 0x85 },
+	{ 0x40CB, 0x85 },
+	{ 0x40CC, 0x8A },
+	{ 0x40CD, 0x88 },
+	{ 0x40CE, 0x88 },
+	{ 0x40CF, 0x87 },
+	{ 0x40D0, 0x92 },
+	{ 0x40D1, 0x8F },
+	{ 0x40D2, 0x8E },
+	{ 0x40D3, 0x8E },
+	{ 0x40D4, 0xA2 },
+	{ 0x40D5, 0x9D },
+	{ 0x40D6, 0x9D },
+	{ 0x40D7, 0x9B },
+	{ 0x4100, 0x80 },
+	{ 0x4101, 0x80 },
+	{ 0x4102, 0x80 },
+	{ 0x4103, 0x80 },
+	{ 0x4104, 0x80 },
+	{ 0x4105, 0x80 },
+	{ 0x4106, 0x80 },
+	{ 0x4107, 0x80 },
+	{ 0x4108, 0x80 },
+	{ 0x4109, 0x80 },
+	{ 0x410A, 0x80 },
+	{ 0x410B, 0x80 },
+	{ 0x410C, 0x80 },
+	{ 0x410D, 0x80 },
+	{ 0x410E, 0x80 },
+	{ 0x410F, 0x80 },
+	{ 0x4110, 0x80 },
+	{ 0x4111, 0x80 },
+	{ 0x4112, 0x80 },
+	{ 0x4113, 0x80 },
+	{ 0x4114, 0x80 },
+	{ 0x4115, 0x80 },
+	{ 0x4116, 0x80 },
+	{ 0x4117, 0x80 },
+	{ 0x4118, 0x80 },
+	{ 0x4119, 0x80 },
+	{ 0x411A, 0x80 },
+	{ 0x411B, 0x80 },
+	{ 0x411C, 0x80 },
+	{ 0x411D, 0x80 },
+	{ 0x411E, 0x80 },
+	{ 0x411F, 0x80 },
+	{ 0x4120, 0x80 },
+	{ 0x4121, 0x80 },
+	{ 0x4122, 0x80 },
+	{ 0x4123, 0x80 },
+	{ 0x4124, 0x80 },
+	{ 0x4125, 0x80 },
+	{ 0x4126, 0x80 },
+	{ 0x4127, 0x80 },
+	{ 0x4128, 0x80 },
+	{ 0x4129, 0x80 },
+	{ 0x412A, 0x80 },
+	{ 0x412B, 0x80 },
+	{ 0x412C, 0x80 },
+	{ 0x412D, 0x80 },
+	{ 0x412E, 0x80 },
+	{ 0x412F, 0x80 },
+	{ 0x4130, 0x80 },
+	{ 0x4131, 0x80 },
+	{ 0x4132, 0x80 },
+	{ 0x4133, 0x80 },
+	{ 0x4134, 0x80 },
+	{ 0x4135, 0x80 },
+	{ 0x4136, 0x80 },
+	{ 0x4137, 0x80 },
+	{ 0x4138, 0x80 },
+	{ 0x4139, 0x80 },
+	{ 0x413A, 0x80 },
+	{ 0x413B, 0x80 },
+	{ 0x413C, 0x80 },
+	{ 0x413D, 0x80 },
+	{ 0x413E, 0x80 },
+	{ 0x413F, 0x80 },
+	{ 0x4140, 0x80 },
+	{ 0x4141, 0x80 },
+	{ 0x4142, 0x80 },
+	{ 0x4143, 0x80 },
+	{ 0x4144, 0x80 },
+	{ 0x4145, 0x80 },
+	{ 0x4146, 0x80 },
+	{ 0x4147, 0x80 },
+	{ 0x4148, 0x80 },
+	{ 0x4149, 0x80 },
+	{ 0x414A, 0x80 },
+	{ 0x414B, 0x80 },
+	{ 0x414C, 0x80 },
+	{ 0x414D, 0x80 },
+	{ 0x414E, 0x80 },
+	{ 0x414F, 0x80 },
+	{ 0x4150, 0x80 },
+	{ 0x4151, 0x80 },
+	{ 0x4152, 0x80 },
+	{ 0x4153, 0x80 },
+	{ 0x4154, 0x80 },
+	{ 0x4155, 0x80 },
+	{ 0x4156, 0x80 },
+	{ 0x4157, 0x80 },
+	{ 0x4158, 0x80 },
+	{ 0x4159, 0x80 },
+	{ 0x415A, 0x80 },
+	{ 0x415B, 0x80 },
+	{ 0x415C, 0x80 },
+	{ 0x415D, 0x80 },
+	{ 0x415E, 0x80 },
+	{ 0x415F, 0x80 },
+	{ 0x4160, 0x80 },
+	{ 0x4161, 0x80 },
+	{ 0x4162, 0x80 },
+	{ 0x4163, 0x80 },
+	{ 0x4164, 0x80 },
+	{ 0x4165, 0x80 },
+	{ 0x4166, 0x80 },
+	{ 0x4167, 0x80 },
+	{ 0x4168, 0x80 },
+	{ 0x4169, 0x80 },
+	{ 0x416A, 0x80 },
+	{ 0x416B, 0x80 },
+	{ 0x416C, 0x80 },
+	{ 0x416D, 0x80 },
+	{ 0x416E, 0x80 },
+	{ 0x416F, 0x80 },
+	{ 0x4170, 0x80 },
+	{ 0x4171, 0x80 },
+	{ 0x4172, 0x80 },
+	{ 0x4173, 0x80 },
+	{ 0x4174, 0x80 },
+	{ 0x4175, 0x80 },
+	{ 0x4176, 0x80 },
+	{ 0x4177, 0x80 },
+	{ 0x4178, 0x80 },
+	{ 0x4179, 0x80 },
+	{ 0x417A, 0x80 },
+	{ 0x417B, 0x80 },
+	{ 0x417C, 0x80 },
+	{ 0x417D, 0x80 },
+	{ 0x417E, 0x80 },
+	{ 0x417F, 0x80 },
+	{ 0x4180, 0x80 },
+	{ 0x4181, 0x80 },
+	{ 0x4182, 0x80 },
+	{ 0x4183, 0x80 },
+	{ 0x4184, 0x80 },
+	{ 0x4185, 0x80 },
+	{ 0x4186, 0x80 },
+	{ 0x4187, 0x80 },
+	{ 0x4188, 0x80 },
+	{ 0x4189, 0x80 },
+	{ 0x418A, 0x80 },
+	{ 0x418B, 0x80 },
+	{ 0x418C, 0x80 },
+	{ 0x418D, 0x80 },
+	{ 0x418E, 0x80 },
+	{ 0x418F, 0x80 },
+	{ 0x4190, 0x80 },
+	{ 0x4191, 0x80 },
+	{ 0x4192, 0x80 },
+	{ 0x4193, 0x80 },
+	{ 0x4194, 0x80 },
+	{ 0x4195, 0x80 },
+	{ 0x4196, 0x80 },
+	{ 0x4197, 0x80 },
+	{ 0x4198, 0x80 },
+	{ 0x4199, 0x80 },
+	{ 0x419A, 0x80 },
+	{ 0x419B, 0x80 },
+	{ 0x419C, 0x80 },
+	{ 0x419D, 0x80 },
+	{ 0x419E, 0x80 },
+	{ 0x419F, 0x80 },
+	{ 0x41A0, 0x80 },
+	{ 0x41A1, 0x80 },
+	{ 0x41A2, 0x80 },
+	{ 0x41A3, 0x80 },
+	{ 0x41A4, 0x80 },
+	{ 0x41A5, 0x80 },
+	{ 0x41A6, 0x80 },
+	{ 0x41A7, 0x80 },
+	{ 0x41A8, 0x80 },
+	{ 0x41A9, 0x80 },
+	{ 0x41AA, 0x80 },
+	{ 0x41AB, 0x80 },
+	{ 0x41AC, 0x80 },
+	{ 0x41AD, 0x80 },
+	{ 0x41AE, 0x80 },
+	{ 0x41AF, 0x80 },
+	{ 0x41B0, 0x80 },
+	{ 0x41B1, 0x80 },
+	{ 0x41B2, 0x80 },
+	{ 0x41B3, 0x80 },
+	{ 0x41B4, 0x80 },
+	{ 0x41B5, 0x80 },
+	{ 0x41B6, 0x80 },
+	{ 0x41B7, 0x80 },
+	{ 0x41B8, 0x80 },
+	{ 0x41B9, 0x80 },
+	{ 0x41BA, 0x80 },
+	{ 0x41BB, 0x80 },
+	{ 0x41BC, 0x80 },
+	{ 0x41BD, 0x80 },
+	{ 0x41BE, 0x80 },
+	{ 0x41BF, 0x80 },
+	{ 0x41C0, 0x80 },
+	{ 0x41C1, 0x80 },
+	{ 0x41C2, 0x80 },
+	{ 0x41C3, 0x80 },
+	{ 0x41C4, 0x80 },
+	{ 0x41C5, 0x80 },
+	{ 0x41C6, 0x80 },
+	{ 0x41C7, 0x80 },
+	{ 0x41C8, 0x80 },
+	{ 0x41C9, 0x80 },
+	{ 0x41CA, 0x80 },
+	{ 0x41CB, 0x80 },
+	{ 0x41CC, 0x80 },
+	{ 0x41CD, 0x80 },
+	{ 0x41CE, 0x80 },
+	{ 0x41CF, 0x80 },
+	{ 0x41D0, 0x80 },
+	{ 0x41D1, 0x80 },
+	{ 0x41D2, 0x80 },
+	{ 0x41D3, 0x80 },
+	{ 0x41D4, 0x80 },
+	{ 0x41D5, 0x80 },
+	{ 0x41D6, 0x80 },
+	{ 0x41D7, 0x80 },
+	{ 0x4200, 0x80 },
+	{ 0x4201, 0x80 },
+	{ 0x4202, 0x80 },
+	{ 0x4203, 0x80 },
+	{ 0x4204, 0x80 },
+	{ 0x4205, 0x80 },
+	{ 0x4206, 0x80 },
+	{ 0x4207, 0x80 },
+	{ 0x4208, 0x80 },
+	{ 0x4209, 0x80 },
+	{ 0x420A, 0x80 },
+	{ 0x420B, 0x80 },
+	{ 0x420C, 0x80 },
+	{ 0x420D, 0x80 },
+	{ 0x420E, 0x80 },
+	{ 0x420F, 0x80 },
+	{ 0x4210, 0x80 },
+	{ 0x4211, 0x80 },
+	{ 0x4212, 0x80 },
+	{ 0x4213, 0x80 },
+	{ 0x4214, 0x80 },
+	{ 0x4215, 0x80 },
+	{ 0x4216, 0x80 },
+	{ 0x4217, 0x80 },
+	{ 0x4218, 0x80 },
+	{ 0x4219, 0x80 },
+	{ 0x421A, 0x80 },
+	{ 0x421B, 0x80 },
+	{ 0x421C, 0x80 },
+	{ 0x421D, 0x80 },
+	{ 0x421E, 0x80 },
+	{ 0x421F, 0x80 },
+	{ 0x4220, 0x80 },
+	{ 0x4221, 0x80 },
+	{ 0x4222, 0x80 },
+	{ 0x4223, 0x80 },
+	{ 0x4224, 0x80 },
+	{ 0x4225, 0x80 },
+	{ 0x4226, 0x80 },
+	{ 0x4227, 0x80 },
+	{ 0x4228, 0x80 },
+	{ 0x4229, 0x80 },
+	{ 0x422A, 0x80 },
+	{ 0x422B, 0x80 },
+	{ 0x422C, 0x80 },
+	{ 0x422D, 0x80 },
+	{ 0x422E, 0x80 },
+	{ 0x422F, 0x80 },
+	{ 0x4230, 0x80 },
+	{ 0x4231, 0x80 },
+	{ 0x4232, 0x80 },
+	{ 0x4233, 0x80 },
+	{ 0x4234, 0x80 },
+	{ 0x4235, 0x80 },
+	{ 0x4236, 0x80 },
+	{ 0x4237, 0x80 },
+	{ 0x4238, 0x80 },
+	{ 0x4239, 0x80 },
+	{ 0x423A, 0x80 },
+	{ 0x423B, 0x80 },
+	{ 0x423C, 0x80 },
+	{ 0x423D, 0x80 },
+	{ 0x423E, 0x80 },
+	{ 0x423F, 0x80 },
+	{ 0x4240, 0x80 },
+	{ 0x4241, 0x80 },
+	{ 0x4242, 0x80 },
+	{ 0x4243, 0x80 },
+	{ 0x4244, 0x80 },
+	{ 0x4245, 0x80 },
+	{ 0x4246, 0x80 },
+	{ 0x4247, 0x80 },
+	{ 0x4248, 0x80 },
+	{ 0x4249, 0x80 },
+	{ 0x424A, 0x80 },
+	{ 0x424B, 0x80 },
+	{ 0x424C, 0x80 },
+	{ 0x424D, 0x80 },
+	{ 0x424E, 0x80 },
+	{ 0x424F, 0x80 },
+	{ 0x4250, 0x80 },
+	{ 0x4251, 0x80 },
+	{ 0x4252, 0x80 },
+	{ 0x4253, 0x80 },
+	{ 0x4254, 0x80 },
+	{ 0x4255, 0x80 },
+	{ 0x4256, 0x80 },
+	{ 0x4257, 0x80 },
+	{ 0x4258, 0x80 },
+	{ 0x4259, 0x80 },
+	{ 0x425A, 0x80 },
+	{ 0x425B, 0x80 },
+	{ 0x425C, 0x80 },
+	{ 0x425D, 0x80 },
+	{ 0x425E, 0x80 },
+	{ 0x425F, 0x80 },
+	{ 0x4260, 0x80 },
+	{ 0x4261, 0x80 },
+	{ 0x4262, 0x80 },
+	{ 0x4263, 0x80 },
+	{ 0x4264, 0x80 },
+	{ 0x4265, 0x80 },
+	{ 0x4266, 0x80 },
+	{ 0x4267, 0x80 },
+	{ 0x4268, 0x80 },
+	{ 0x4269, 0x80 },
+	{ 0x426A, 0x80 },
+	{ 0x426B, 0x80 },
+	{ 0x426C, 0x80 },
+	{ 0x426D, 0x80 },
+	{ 0x426E, 0x80 },
+	{ 0x426F, 0x80 },
+	{ 0x4270, 0x80 },
+	{ 0x4271, 0x80 },
+	{ 0x4272, 0x80 },
+	{ 0x4273, 0x80 },
+	{ 0x4274, 0x80 },
+	{ 0x4275, 0x80 },
+	{ 0x4276, 0x80 },
+	{ 0x4277, 0x80 },
+	{ 0x4278, 0x80 },
+	{ 0x4279, 0x80 },
+	{ 0x427A, 0x80 },
+	{ 0x427B, 0x80 },
+	{ 0x427C, 0x80 },
+	{ 0x427D, 0x80 },
+	{ 0x427E, 0x80 },
+	{ 0x427F, 0x80 },
+	{ 0x4280, 0x80 },
+	{ 0x4281, 0x80 },
+	{ 0x4282, 0x80 },
+	{ 0x4283, 0x80 },
+	{ 0x4284, 0x80 },
+	{ 0x4285, 0x80 },
+	{ 0x4286, 0x80 },
+	{ 0x4287, 0x80 },
+	{ 0x4288, 0x80 },
+	{ 0x4289, 0x80 },
+	{ 0x428A, 0x80 },
+	{ 0x428B, 0x80 },
+	{ 0x428C, 0x80 },
+	{ 0x428D, 0x80 },
+	{ 0x428E, 0x80 },
+	{ 0x428F, 0x80 },
+	{ 0x4290, 0x80 },
+	{ 0x4291, 0x80 },
+	{ 0x4292, 0x80 },
+	{ 0x4293, 0x80 },
+	{ 0x4294, 0x80 },
+	{ 0x4295, 0x80 },
+	{ 0x4296, 0x80 },
+	{ 0x4297, 0x80 },
+	{ 0x4298, 0x80 },
+	{ 0x4299, 0x80 },
+	{ 0x429A, 0x80 },
+	{ 0x429B, 0x80 },
+	{ 0x429C, 0x80 },
+	{ 0x429D, 0x80 },
+	{ 0x429E, 0x80 },
+	{ 0x429F, 0x80 },
+	{ 0x42A0, 0x80 },
+	{ 0x42A1, 0x80 },
+	{ 0x42A2, 0x80 },
+	{ 0x42A3, 0x80 },
+	{ 0x42A4, 0x80 },
+	{ 0x42A5, 0x80 },
+	{ 0x42A6, 0x80 },
+	{ 0x42A7, 0x80 },
+	{ 0x42A8, 0x80 },
+	{ 0x42A9, 0x80 },
+	{ 0x42AA, 0x80 },
+	{ 0x42AB, 0x80 },
+	{ 0x42AC, 0x80 },
+	{ 0x42AD, 0x80 },
+	{ 0x42AE, 0x80 },
+	{ 0x42AF, 0x80 },
+	{ 0x42B0, 0x80 },
+	{ 0x42B1, 0x80 },
+	{ 0x42B2, 0x80 },
+	{ 0x42B3, 0x80 },
+	{ 0x42B4, 0x80 },
+	{ 0x42B5, 0x80 },
+	{ 0x42B6, 0x80 },
+	{ 0x42B7, 0x80 },
+	{ 0x42B8, 0x80 },
+	{ 0x42B9, 0x80 },
+	{ 0x42BA, 0x80 },
+	{ 0x42BB, 0x80 },
+	{ 0x42BC, 0x80 },
+	{ 0x42BD, 0x80 },
+	{ 0x42BE, 0x80 },
+	{ 0x42BF, 0x80 },
+	{ 0x42C0, 0x80 },
+	{ 0x42C1, 0x80 },
+	{ 0x42C2, 0x80 },
+	{ 0x42C3, 0x80 },
+	{ 0x42C4, 0x80 },
+	{ 0x42C5, 0x80 },
+	{ 0x42C6, 0x80 },
+	{ 0x42C7, 0x80 },
+	{ 0x42C8, 0x80 },
+	{ 0x42C9, 0x80 },
+	{ 0x42CA, 0x80 },
+	{ 0x42CB, 0x80 },
+	{ 0x42CC, 0x80 },
+	{ 0x42CD, 0x80 },
+	{ 0x42CE, 0x80 },
+	{ 0x42CF, 0x80 },
+	{ 0x42D0, 0x80 },
+	{ 0x42D1, 0x80 },
+	{ 0x42D2, 0x80 },
+	{ 0x42D3, 0x80 },
+	{ 0x42D4, 0x80 },
+	{ 0x42D5, 0x80 },
+	{ 0x42D6, 0x80 },
+	{ 0x42D7, 0x80 },
+	{ 0x42D8, 0x00 },
+	{ 0x42D9, 0x00 },
+	{ 0x4300, 0xA2 },
+	{ 0x4301, 0xAA },
+	{ 0x4302, 0xA7 },
+	{ 0x4303, 0xAD },
+	{ 0x4304, 0x8E },
+	{ 0x4305, 0x92 },
+	{ 0x4306, 0x90 },
+	{ 0x4307, 0x93 },
+	{ 0x4308, 0x86 },
+	{ 0x4309, 0x89 },
+	{ 0x430A, 0x87 },
+	{ 0x430B, 0x88 },
+	{ 0x430C, 0x82 },
+	{ 0x430D, 0x84 },
+	{ 0x430E, 0x83 },
+	{ 0x430F, 0x84 },
+	{ 0x4310, 0x80 },
+	{ 0x4311, 0x82 },
+	{ 0x4312, 0x82 },
+	{ 0x4313, 0x82 },
+	{ 0x4314, 0x83 },
+	{ 0x4315, 0x85 },
+	{ 0x4316, 0x84 },
+	{ 0x4317, 0x85 },
+	{ 0x4318, 0x8D },
+	{ 0x4319, 0x8D },
+	{ 0x431A, 0x8D },
+	{ 0x431B, 0x8D },
+	{ 0x431C, 0x99 },
+	{ 0x431D, 0x9A },
+	{ 0x431E, 0x9A },
+	{ 0x431F, 0x9A },
+	{ 0x4320, 0xAE },
+	{ 0x4321, 0xB4 },
+	{ 0x4322, 0xB4 },
+	{ 0x4323, 0xB5 },
+	{ 0x4324, 0x9A },
+	{ 0x4325, 0x9D },
+	{ 0x4326, 0x9B },
+	{ 0x4327, 0x9E },
+	{ 0x4328, 0x8C },
+	{ 0x4329, 0x8F },
+	{ 0x432A, 0x8D },
+	{ 0x432B, 0x8F },
+	{ 0x432C, 0x83 },
+	{ 0x432D, 0x85 },
+	{ 0x432E, 0x85 },
+	{ 0x432F, 0x85 },
+	{ 0x4330, 0x80 },
+	{ 0x4331, 0x81 },
+	{ 0x4332, 0x81 },
+	{ 0x4333, 0x81 },
+	{ 0x4334, 0x80 },
+	{ 0x4335, 0x80 },
+	{ 0x4336, 0x80 },
+	{ 0x4337, 0x81 },
+	{ 0x4338, 0x83 },
+	{ 0x4339, 0x83 },
+	{ 0x433A, 0x83 },
+	{ 0x433B, 0x83 },
+	{ 0x433C, 0x88 },
+	{ 0x433D, 0x88 },
+	{ 0x433E, 0x88 },
+	{ 0x433F, 0x88 },
+	{ 0x4340, 0x93 },
+	{ 0x4341, 0x93 },
+	{ 0x4342, 0x93 },
+	{ 0x4343, 0x93 },
+	{ 0x4344, 0xA2 },
+	{ 0x4345, 0xA4 },
+	{ 0x4346, 0xA4 },
+	{ 0x4347, 0xA4 },
+	{ 0x4348, 0x97 },
+	{ 0x4349, 0x99 },
+	{ 0x434A, 0x97 },
+	{ 0x434B, 0x97 },
+	{ 0x434C, 0x89 },
+	{ 0x434D, 0x8C },
+	{ 0x434E, 0x8B },
+	{ 0x434F, 0x8A },
+	{ 0x4350, 0x81 },
+	{ 0x4351, 0x83 },
+	{ 0x4352, 0x83 },
+	{ 0x4353, 0x83 },
+	{ 0x4354, 0x7F },
+	{ 0x4355, 0x80 },
+	{ 0x4356, 0x80 },
+	{ 0x4357, 0x80 },
+	{ 0x4358, 0x7F },
+	{ 0x4359, 0x7F },
+	{ 0x435A, 0x7F },
+	{ 0x435B, 0x7F },
+	{ 0x435C, 0x82 },
+	{ 0x435D, 0x81 },
+	{ 0x435E, 0x81 },
+	{ 0x435F, 0x82 },
+	{ 0x4360, 0x86 },
+	{ 0x4361, 0x86 },
+	{ 0x4362, 0x86 },
+	{ 0x4363, 0x87 },
+	{ 0x4364, 0x8F },
+	{ 0x4365, 0x8F },
+	{ 0x4366, 0x8F },
+	{ 0x4367, 0x90 },
+	{ 0x4368, 0x9E },
+	{ 0x4369, 0x9E },
+	{ 0x436A, 0x9E },
+	{ 0x436B, 0x9F },
+	{ 0x436C, 0x99 },
+	{ 0x436D, 0x9B },
+	{ 0x436E, 0x9A },
+	{ 0x436F, 0x98 },
+	{ 0x4370, 0x8B },
+	{ 0x4371, 0x8D },
+	{ 0x4372, 0x8D },
+	{ 0x4373, 0x8B },
+	{ 0x4374, 0x83 },
+	{ 0x4375, 0x84 },
+	{ 0x4376, 0x84 },
+	{ 0x4377, 0x83 },
+	{ 0x4378, 0x80 },
+	{ 0x4379, 0x81 },
+	{ 0x437A, 0x81 },
+	{ 0x437B, 0x80 },
+	{ 0x437C, 0x81 },
+	{ 0x437D, 0x80 },
+	{ 0x437E, 0x80 },
+	{ 0x437F, 0x80 },
+	{ 0x4380, 0x83 },
+	{ 0x4381, 0x83 },
+	{ 0x4382, 0x83 },
+	{ 0x4383, 0x83 },
+	{ 0x4384, 0x88 },
+	{ 0x4385, 0x87 },
+	{ 0x4386, 0x87 },
+	{ 0x4387, 0x88 },
+	{ 0x4388, 0x91 },
+	{ 0x4389, 0x90 },
+	{ 0x438A, 0x90 },
+	{ 0x438B, 0x91 },
+	{ 0x438C, 0x9E },
+	{ 0x438D, 0x9E },
+	{ 0x438E, 0x9E },
+	{ 0x438F, 0xA0 },
+	{ 0x4390, 0xA0 },
+	{ 0x4391, 0xA2 },
+	{ 0x4392, 0xA2 },
+	{ 0x4393, 0xA0 },
+	{ 0x4394, 0x92 },
+	{ 0x4395, 0x94 },
+	{ 0x4396, 0x94 },
+	{ 0x4397, 0x91 },
+	{ 0x4398, 0x89 },
+	{ 0x4399, 0x8A },
+	{ 0x439A, 0x89 },
+	{ 0x439B, 0x88 },
+	{ 0x439C, 0x85 },
+	{ 0x439D, 0x85 },
+	{ 0x439E, 0x85 },
+	{ 0x439F, 0x84 },
+	{ 0x43A0, 0x85 },
+	{ 0x43A1, 0x84 },
+	{ 0x43A2, 0x84 },
+	{ 0x43A3, 0x84 },
+	{ 0x43A4, 0x88 },
+	{ 0x43A5, 0x86 },
+	{ 0x43A6, 0x86 },
+	{ 0x43A7, 0x87 },
+	{ 0x43A8, 0x8E },
+	{ 0x43A9, 0x8B },
+	{ 0x43AA, 0x8B },
+	{ 0x43AB, 0x8D },
+	{ 0x43AC, 0x97 },
+	{ 0x43AD, 0x96 },
+	{ 0x43AE, 0x96 },
+	{ 0x43AF, 0x98 },
+	{ 0x43B0, 0xA5 },
+	{ 0x43B1, 0xA5 },
+	{ 0x43B2, 0xA5 },
+	{ 0x43B3, 0xA9 },
+	{ 0x43B4, 0xB7 },
+	{ 0x43B5, 0xBB },
+	{ 0x43B6, 0xBB },
+	{ 0x43B7, 0xB8 },
+	{ 0x43B8, 0x9C },
+	{ 0x43B9, 0x9C },
+	{ 0x43BA, 0x9C },
+	{ 0x43BB, 0x9A },
+	{ 0x43BC, 0x92 },
+	{ 0x43BD, 0x92 },
+	{ 0x43BE, 0x92 },
+	{ 0x43BF, 0x8F },
+	{ 0x43C0, 0x8B },
+	{ 0x43C1, 0x8B },
+	{ 0x43C2, 0x8B },
+	{ 0x43C3, 0x89 },
+	{ 0x43C4, 0x8A },
+	{ 0x43C5, 0x89 },
+	{ 0x43C6, 0x89 },
+	{ 0x43C7, 0x88 },
+	{ 0x43C8, 0x8D },
+	{ 0x43C9, 0x8B },
+	{ 0x43CA, 0x8B },
+	{ 0x43CB, 0x8C },
+	{ 0x43CC, 0x94 },
+	{ 0x43CD, 0x91 },
+	{ 0x43CE, 0x92 },
+	{ 0x43CF, 0x93 },
+	{ 0x43D0, 0x9E },
+	{ 0x43D1, 0x9D },
+	{ 0x43D2, 0x9D },
+	{ 0x43D3, 0xA1 },
+	{ 0x43D4, 0xB2 },
+	{ 0x43D5, 0xB4 },
+	{ 0x43D6, 0xB5 },
+	{ 0x43D7, 0xBD },
+	{ 0x4400, 0x80 },
+	{ 0x4401, 0x80 },
+	{ 0x4402, 0x80 },
+	{ 0x4403, 0x80 },
+	{ 0x4404, 0x80 },
+	{ 0x4405, 0x80 },
+	{ 0x4406, 0x80 },
+	{ 0x4407, 0x80 },
+	{ 0x4408, 0x80 },
+	{ 0x4409, 0x80 },
+	{ 0x440A, 0x80 },
+	{ 0x440B, 0x80 },
+	{ 0x440C, 0x80 },
+	{ 0x440D, 0x80 },
+	{ 0x440E, 0x80 },
+	{ 0x440F, 0x80 },
+	{ 0x4410, 0x80 },
+	{ 0x4411, 0x80 },
+	{ 0x4412, 0x80 },
+	{ 0x4413, 0x80 },
+	{ 0x4414, 0x80 },
+	{ 0x4415, 0x80 },
+	{ 0x4416, 0x80 },
+	{ 0x4417, 0x80 },
+	{ 0x4418, 0x80 },
+	{ 0x4419, 0x80 },
+	{ 0x441A, 0x80 },
+	{ 0x441B, 0x80 },
+	{ 0x441C, 0x80 },
+	{ 0x441D, 0x80 },
+	{ 0x441E, 0x80 },
+	{ 0x441F, 0x80 },
+	{ 0x4420, 0x80 },
+	{ 0x4421, 0x80 },
+	{ 0x4422, 0x80 },
+	{ 0x4423, 0x80 },
+	{ 0x4424, 0x80 },
+	{ 0x4425, 0x80 },
+	{ 0x4426, 0x80 },
+	{ 0x4427, 0x80 },
+	{ 0x4428, 0x80 },
+	{ 0x4429, 0x80 },
+	{ 0x442A, 0x80 },
+	{ 0x442B, 0x80 },
+	{ 0x442C, 0x80 },
+	{ 0x442D, 0x80 },
+	{ 0x442E, 0x80 },
+	{ 0x442F, 0x80 },
+	{ 0x4430, 0x80 },
+	{ 0x4431, 0x80 },
+	{ 0x4432, 0x80 },
+	{ 0x4433, 0x80 },
+	{ 0x4434, 0x80 },
+	{ 0x4435, 0x80 },
+	{ 0x4436, 0x80 },
+	{ 0x4437, 0x80 },
+	{ 0x4438, 0x80 },
+	{ 0x4439, 0x80 },
+	{ 0x443A, 0x80 },
+	{ 0x443B, 0x80 },
+	{ 0x443C, 0x80 },
+	{ 0x443D, 0x80 },
+	{ 0x443E, 0x80 },
+	{ 0x443F, 0x80 },
+	{ 0x4440, 0x80 },
+	{ 0x4441, 0x80 },
+	{ 0x4442, 0x80 },
+	{ 0x4443, 0x80 },
+	{ 0x4444, 0x80 },
+	{ 0x4445, 0x80 },
+	{ 0x4446, 0x80 },
+	{ 0x4447, 0x80 },
+	{ 0x4448, 0x80 },
+	{ 0x4449, 0x80 },
+	{ 0x444A, 0x80 },
+	{ 0x444B, 0x80 },
+	{ 0x444C, 0x80 },
+	{ 0x444D, 0x80 },
+	{ 0x444E, 0x80 },
+	{ 0x444F, 0x80 },
+	{ 0x4450, 0x80 },
+	{ 0x4451, 0x80 },
+	{ 0x4452, 0x80 },
+	{ 0x4453, 0x80 },
+	{ 0x4454, 0x80 },
+	{ 0x4455, 0x80 },
+	{ 0x4456, 0x80 },
+	{ 0x4457, 0x80 },
+	{ 0x4458, 0x80 },
+	{ 0x4459, 0x80 },
+	{ 0x445A, 0x80 },
+	{ 0x445B, 0x80 },
+	{ 0x445C, 0x80 },
+	{ 0x445D, 0x80 },
+	{ 0x445E, 0x80 },
+	{ 0x445F, 0x80 },
+	{ 0x4460, 0x80 },
+	{ 0x4461, 0x80 },
+	{ 0x4462, 0x80 },
+	{ 0x4463, 0x80 },
+	{ 0x4464, 0x80 },
+	{ 0x4465, 0x80 },
+	{ 0x4466, 0x80 },
+	{ 0x4467, 0x80 },
+	{ 0x4468, 0x80 },
+	{ 0x4469, 0x80 },
+	{ 0x446A, 0x80 },
+	{ 0x446B, 0x80 },
+	{ 0x446C, 0x80 },
+	{ 0x446D, 0x80 },
+	{ 0x446E, 0x80 },
+	{ 0x446F, 0x80 },
+	{ 0x4470, 0x80 },
+	{ 0x4471, 0x80 },
+	{ 0x4472, 0x80 },
+	{ 0x4473, 0x80 },
+	{ 0x4474, 0x80 },
+	{ 0x4475, 0x80 },
+	{ 0x4476, 0x80 },
+	{ 0x4477, 0x80 },
+	{ 0x4478, 0x80 },
+	{ 0x4479, 0x80 },
+	{ 0x447A, 0x80 },
+	{ 0x447B, 0x80 },
+	{ 0x447C, 0x80 },
+	{ 0x447D, 0x80 },
+	{ 0x447E, 0x80 },
+	{ 0x447F, 0x80 },
+	{ 0x4480, 0x80 },
+	{ 0x4481, 0x80 },
+	{ 0x4482, 0x80 },
+	{ 0x4483, 0x80 },
+	{ 0x4484, 0x80 },
+	{ 0x4485, 0x80 },
+	{ 0x4486, 0x80 },
+	{ 0x4487, 0x80 },
+	{ 0x4488, 0x80 },
+	{ 0x4489, 0x80 },
+	{ 0x448A, 0x80 },
+	{ 0x448B, 0x80 },
+	{ 0x448C, 0x80 },
+	{ 0x448D, 0x80 },
+	{ 0x448E, 0x80 },
+	{ 0x448F, 0x80 },
+	{ 0x4490, 0x80 },
+	{ 0x4491, 0x80 },
+	{ 0x4492, 0x80 },
+	{ 0x4493, 0x80 },
+	{ 0x4494, 0x80 },
+	{ 0x4495, 0x80 },
+	{ 0x4496, 0x80 },
+	{ 0x4497, 0x80 },
+	{ 0x4498, 0x80 },
+	{ 0x4499, 0x80 },
+	{ 0x449A, 0x80 },
+	{ 0x449B, 0x80 },
+	{ 0x449C, 0x80 },
+	{ 0x449D, 0x80 },
+	{ 0x449E, 0x80 },
+	{ 0x449F, 0x80 },
+	{ 0x44A0, 0x80 },
+	{ 0x44A1, 0x80 },
+	{ 0x44A2, 0x80 },
+	{ 0x44A3, 0x80 },
+	{ 0x44A4, 0x80 },
+	{ 0x44A5, 0x80 },
+	{ 0x44A6, 0x80 },
+	{ 0x44A7, 0x80 },
+	{ 0x44A8, 0x80 },
+	{ 0x44A9, 0x80 },
+	{ 0x44AA, 0x80 },
+	{ 0x44AB, 0x80 },
+	{ 0x44AC, 0x80 },
+	{ 0x44AD, 0x80 },
+	{ 0x44AE, 0x80 },
+	{ 0x44AF, 0x80 },
+	{ 0x44B0, 0x80 },
+	{ 0x44B1, 0x80 },
+	{ 0x44B2, 0x80 },
+	{ 0x44B3, 0x80 },
+	{ 0x44B4, 0x80 },
+	{ 0x44B5, 0x80 },
+	{ 0x44B6, 0x80 },
+	{ 0x44B7, 0x80 },
+	{ 0x44B8, 0x80 },
+	{ 0x44B9, 0x80 },
+	{ 0x44BA, 0x80 },
+	{ 0x44BB, 0x80 },
+	{ 0x44BC, 0x80 },
+	{ 0x44BD, 0x80 },
+	{ 0x44BE, 0x80 },
+	{ 0x44BF, 0x80 },
+	{ 0x44C0, 0x80 },
+	{ 0x44C1, 0x80 },
+	{ 0x44C2, 0x80 },
+	{ 0x44C3, 0x80 },
+	{ 0x44C4, 0x80 },
+	{ 0x44C5, 0x80 },
+	{ 0x44C6, 0x80 },
+	{ 0x44C7, 0x80 },
+	{ 0x44C8, 0x80 },
+	{ 0x44C9, 0x80 },
+	{ 0x44CA, 0x80 },
+	{ 0x44CB, 0x80 },
+	{ 0x44CC, 0x80 },
+	{ 0x44CD, 0x80 },
+	{ 0x44CE, 0x80 },
+	{ 0x44CF, 0x80 },
+	{ 0x44D0, 0x80 },
+	{ 0x44D1, 0x80 },
+	{ 0x44D2, 0x80 },
+	{ 0x44D3, 0x80 },
+	{ 0x44D4, 0x80 },
+	{ 0x44D5, 0x80 },
+	{ 0x44D6, 0x80 },
+	{ 0x44D7, 0x80 },
+	{ 0x4500, 0x80 },
+	{ 0x4501, 0x80 },
+	{ 0x4502, 0x80 },
+	{ 0x4503, 0x80 },
+	{ 0x4504, 0x80 },
+	{ 0x4505, 0x80 },
+	{ 0x4506, 0x80 },
+	{ 0x4507, 0x80 },
+	{ 0x4508, 0x80 },
+	{ 0x4509, 0x80 },
+	{ 0x450A, 0x80 },
+	{ 0x450B, 0x80 },
+	{ 0x450C, 0x80 },
+	{ 0x450D, 0x80 },
+	{ 0x450E, 0x80 },
+	{ 0x450F, 0x80 },
+	{ 0x4510, 0x80 },
+	{ 0x4511, 0x80 },
+	{ 0x4512, 0x80 },
+	{ 0x4513, 0x80 },
+	{ 0x4514, 0x80 },
+	{ 0x4515, 0x80 },
+	{ 0x4516, 0x80 },
+	{ 0x4517, 0x80 },
+	{ 0x4518, 0x80 },
+	{ 0x4519, 0x80 },
+	{ 0x451A, 0x80 },
+	{ 0x451B, 0x80 },
+	{ 0x451C, 0x80 },
+	{ 0x451D, 0x80 },
+	{ 0x451E, 0x80 },
+	{ 0x451F, 0x80 },
+	{ 0x4520, 0x80 },
+	{ 0x4521, 0x80 },
+	{ 0x4522, 0x80 },
+	{ 0x4523, 0x80 },
+	{ 0x4524, 0x80 },
+	{ 0x4525, 0x80 },
+	{ 0x4526, 0x80 },
+	{ 0x4527, 0x80 },
+	{ 0x4528, 0x80 },
+	{ 0x4529, 0x80 },
+	{ 0x452A, 0x80 },
+	{ 0x452B, 0x80 },
+	{ 0x452C, 0x80 },
+	{ 0x452D, 0x80 },
+	{ 0x452E, 0x80 },
+	{ 0x452F, 0x80 },
+	{ 0x4530, 0x80 },
+	{ 0x4531, 0x80 },
+	{ 0x4532, 0x80 },
+	{ 0x4533, 0x80 },
+	{ 0x4534, 0x80 },
+	{ 0x4535, 0x80 },
+	{ 0x4536, 0x80 },
+	{ 0x4537, 0x80 },
+	{ 0x4538, 0x80 },
+	{ 0x4539, 0x80 },
+	{ 0x453A, 0x80 },
+	{ 0x453B, 0x80 },
+	{ 0x453C, 0x80 },
+	{ 0x453D, 0x80 },
+	{ 0x453E, 0x80 },
+	{ 0x453F, 0x80 },
+	{ 0x4540, 0x80 },
+	{ 0x4541, 0x80 },
+	{ 0x4542, 0x80 },
+	{ 0x4543, 0x80 },
+	{ 0x4544, 0x80 },
+	{ 0x4545, 0x80 },
+	{ 0x4546, 0x80 },
+	{ 0x4547, 0x80 },
+	{ 0x4548, 0x80 },
+	{ 0x4549, 0x80 },
+	{ 0x454A, 0x80 },
+	{ 0x454B, 0x80 },
+	{ 0x454C, 0x80 },
+	{ 0x454D, 0x80 },
+	{ 0x454E, 0x80 },
+	{ 0x454F, 0x80 },
+	{ 0x4550, 0x80 },
+	{ 0x4551, 0x80 },
+	{ 0x4552, 0x80 },
+	{ 0x4553, 0x80 },
+	{ 0x4554, 0x80 },
+	{ 0x4555, 0x80 },
+	{ 0x4556, 0x80 },
+	{ 0x4557, 0x80 },
+	{ 0x4558, 0x80 },
+	{ 0x4559, 0x80 },
+	{ 0x455A, 0x80 },
+	{ 0x455B, 0x80 },
+	{ 0x455C, 0x80 },
+	{ 0x455D, 0x80 },
+	{ 0x455E, 0x80 },
+	{ 0x455F, 0x80 },
+	{ 0x4560, 0x80 },
+	{ 0x4561, 0x80 },
+	{ 0x4562, 0x80 },
+	{ 0x4563, 0x80 },
+	{ 0x4564, 0x80 },
+	{ 0x4565, 0x80 },
+	{ 0x4566, 0x80 },
+	{ 0x4567, 0x80 },
+	{ 0x4568, 0x80 },
+	{ 0x4569, 0x80 },
+	{ 0x456A, 0x80 },
+	{ 0x456B, 0x80 },
+	{ 0x456C, 0x80 },
+	{ 0x456D, 0x80 },
+	{ 0x456E, 0x80 },
+	{ 0x456F, 0x80 },
+	{ 0x4570, 0x80 },
+	{ 0x4571, 0x80 },
+	{ 0x4572, 0x80 },
+	{ 0x4573, 0x80 },
+	{ 0x4574, 0x80 },
+	{ 0x4575, 0x80 },
+	{ 0x4576, 0x80 },
+	{ 0x4577, 0x80 },
+	{ 0x4578, 0x80 },
+	{ 0x4579, 0x80 },
+	{ 0x457A, 0x80 },
+	{ 0x457B, 0x80 },
+	{ 0x457C, 0x80 },
+	{ 0x457D, 0x80 },
+	{ 0x457E, 0x80 },
+	{ 0x457F, 0x80 },
+	{ 0x4580, 0x80 },
+	{ 0x4581, 0x80 },
+	{ 0x4582, 0x80 },
+	{ 0x4583, 0x80 },
+	{ 0x4584, 0x80 },
+	{ 0x4585, 0x80 },
+	{ 0x4586, 0x80 },
+	{ 0x4587, 0x80 },
+	{ 0x4588, 0x80 },
+	{ 0x4589, 0x80 },
+	{ 0x458A, 0x80 },
+	{ 0x458B, 0x80 },
+	{ 0x458C, 0x80 },
+	{ 0x458D, 0x80 },
+	{ 0x458E, 0x80 },
+	{ 0x458F, 0x80 },
+	{ 0x4590, 0x80 },
+	{ 0x4591, 0x80 },
+	{ 0x4592, 0x80 },
+	{ 0x4593, 0x80 },
+	{ 0x4594, 0x80 },
+	{ 0x4595, 0x80 },
+	{ 0x4596, 0x80 },
+	{ 0x4597, 0x80 },
+	{ 0x4598, 0x80 },
+	{ 0x4599, 0x80 },
+	{ 0x459A, 0x80 },
+	{ 0x459B, 0x80 },
+	{ 0x459C, 0x80 },
+	{ 0x459D, 0x80 },
+	{ 0x459E, 0x80 },
+	{ 0x459F, 0x80 },
+	{ 0x45A0, 0x80 },
+	{ 0x45A1, 0x80 },
+	{ 0x45A2, 0x80 },
+	{ 0x45A3, 0x80 },
+	{ 0x45A4, 0x80 },
+	{ 0x45A5, 0x80 },
+	{ 0x45A6, 0x80 },
+	{ 0x45A7, 0x80 },
+	{ 0x45A8, 0x80 },
+	{ 0x45A9, 0x80 },
+	{ 0x45AA, 0x80 },
+	{ 0x45AB, 0x80 },
+	{ 0x45AC, 0x80 },
+	{ 0x45AD, 0x80 },
+	{ 0x45AE, 0x80 },
+	{ 0x45AF, 0x80 },
+	{ 0x45B0, 0x80 },
+	{ 0x45B1, 0x80 },
+	{ 0x45B2, 0x80 },
+	{ 0x45B3, 0x80 },
+	{ 0x45B4, 0x80 },
+	{ 0x45B5, 0x80 },
+	{ 0x45B6, 0x80 },
+	{ 0x45B7, 0x80 },
+	{ 0x45B8, 0x80 },
+	{ 0x45B9, 0x80 },
+	{ 0x45BA, 0x80 },
+	{ 0x45BB, 0x80 },
+	{ 0x45BC, 0x80 },
+	{ 0x45BD, 0x80 },
+	{ 0x45BE, 0x80 },
+	{ 0x45BF, 0x80 },
+	{ 0x45C0, 0x80 },
+	{ 0x45C1, 0x80 },
+	{ 0x45C2, 0x80 },
+	{ 0x45C3, 0x80 },
+	{ 0x45C4, 0x80 },
+	{ 0x45C5, 0x80 },
+	{ 0x45C6, 0x80 },
+	{ 0x45C7, 0x80 },
+	{ 0x45C8, 0x80 },
+	{ 0x45C9, 0x80 },
+	{ 0x45CA, 0x80 },
+	{ 0x45CB, 0x80 },
+	{ 0x45CC, 0x80 },
+	{ 0x45CD, 0x80 },
+	{ 0x45CE, 0x80 },
+	{ 0x45CF, 0x80 },
+	{ 0x45D0, 0x80 },
+	{ 0x45D1, 0x80 },
+	{ 0x45D2, 0x80 },
+	{ 0x45D3, 0x80 },
+	{ 0x45D4, 0x80 },
+	{ 0x45D5, 0x80 },
+	{ 0x45D6, 0x80 },
+	{ 0x45D7, 0x80 },
+	{ 0x7000, 0xAB },
+	{ 0x7001, 0xBA },
+	{ 0x7002, 0x40 },
+	{ 0x7003, 0x02 },
+	{ 0x7004, 0x00 },
+	{ 0x7005, 0x00 },
+	{ 0x7006, 0x00 },
+	{ 0x7007, 0x00 },
+	{ 0x7008, 0x00 },
+	{ 0x7009, 0x00 },
+	{ 0x700A, 0x00 },
+	{ 0x700B, 0x00 },
+	{ 0x700C, 0x00 },
+	{ 0x700D, 0x00 },
+	{ 0x700E, 0x00 },
+	{ 0x700F, 0x00 },
+	{ 0x7010, 0x55 },
+	{ 0x7011, 0x88 },
+	{ 0x7012, 0x40 },
+	{ 0x7013, 0x01 },
+	{ 0x7014, 0x72 },
+	{ 0x7015, 0xF1 },
+	{ 0x7016, 0x02 },
+	{ 0x7017, 0xF8 },
+	{ 0x7018, 0x00 },
+	{ 0x7019, 0x00 },
+	{ 0x701A, 0x00 },
+	{ 0x701B, 0x00 },
+	{ 0x701C, 0x00 },
+	{ 0x701D, 0x00 },
+	{ 0x701E, 0x00 },
+	{ 0x701F, 0x00 },
+	{ 0x7020, 0x00 },
+	{ 0x7021, 0x00 },
+	{ 0x7022, 0x00 },
+	{ 0x7023, 0x00 },
+	{ 0x7024, 0x00 },
+	{ 0x7025, 0x00 },
+	{ 0x7026, 0x00 },
+	{ 0x7027, 0x00 },
+	{ 0x7028, 0x00 },
+	{ 0x7029, 0x00 },
+	{ 0x702A, 0x00 },
+	{ 0x702B, 0x00 },
+	{ 0x702C, 0x00 },
+	{ 0x702D, 0x00 },
+	{ 0x702E, 0x00 },
+	{ 0x702F, 0x00 },
+	{ 0x7030, 0x00 },
+	{ 0x7031, 0x00 },
+	{ 0x7032, 0x00 },
+	{ 0x7033, 0x00 },
+	{ 0x7034, 0x00 },
+	{ 0x7035, 0x00 },
+	{ 0x7036, 0x00 },
+	{ 0x7037, 0x00 },
+	{ 0x7038, 0x00 },
+	{ 0x7039, 0x00 },
+	{ 0x703A, 0x00 },
+	{ 0x703B, 0x00 },
+	{ 0x703C, 0x00 },
+	{ 0x703D, 0x00 },
+	{ 0x703E, 0x00 },
+	{ 0x703F, 0x00 },
+	{ 0x7040, 0x00 },
+	{ 0x7041, 0x00 },
+	{ 0x7042, 0x00 },
+	{ 0x7043, 0x00 },
+	{ 0x7044, 0x00 },
+	{ 0x7045, 0x00 },
+	{ 0x7046, 0x00 },
+	{ 0x7047, 0x00 },
+	{ 0x7048, 0x00 },
+	{ 0x7049, 0x00 },
+	{ 0x704A, 0x00 },
+	{ 0x704B, 0x00 },
+	{ 0x704C, 0x00 },
+	{ 0x704D, 0x00 },
+	{ 0x704E, 0x00 },
+	{ 0x704F, 0x00 },
+	{ 0x7050, 0x00 },
+	{ 0x7051, 0x00 },
+	{ 0x7052, 0x00 },
+	{ 0x7053, 0x00 },
+	{ 0x7054, 0x00 },
+	{ 0x7055, 0x00 },
+	{ 0x7056, 0x00 },
+	{ 0x7057, 0x00 },
+	{ 0x7058, 0x00 },
+	{ 0x7059, 0x00 },
+	{ 0x705A, 0x00 },
+	{ 0x705B, 0x00 },
+	{ 0x705C, 0x00 },
+	{ 0x705D, 0x00 },
+	{ 0x705E, 0x00 },
+	{ 0x705F, 0x00 },
+	{ 0x7060, 0x00 },
+	{ 0x7061, 0x00 },
+	{ 0x7062, 0x00 },
+	{ 0x7063, 0x00 },
+	{ 0x7064, 0x00 },
+	{ 0x7065, 0x00 },
+	{ 0x7066, 0x00 },
+	{ 0x7067, 0x00 },
+	{ 0x7068, 0x00 },
+	{ 0x7069, 0x00 },
+	{ 0x706A, 0x00 },
+	{ 0x706B, 0x00 },
+	{ 0x706C, 0x00 },
+	{ 0x706D, 0x00 },
+	{ 0x706E, 0x00 },
+	{ 0x706F, 0x00 },
+	{ 0x7070, 0x00 },
+	{ 0x7071, 0x00 },
+	{ 0x7072, 0x00 },
+	{ 0x7073, 0x00 },
+	{ 0x7074, 0x00 },
+	{ 0x7075, 0x00 },
+	{ 0x7076, 0x00 },
+	{ 0x7077, 0x00 },
+	{ 0x7078, 0x00 },
+	{ 0x7079, 0x00 },
+	{ 0x707A, 0x00 },
+	{ 0x707B, 0x00 },
+	{ 0x707C, 0x00 },
+	{ 0x707D, 0x00 },
+	{ 0x707E, 0x00 },
+	{ 0x707F, 0x00 },
+	{ 0x7080, 0x00 },
+	{ 0x7081, 0x00 },
+	{ 0x7082, 0x00 },
+	{ 0x7083, 0x00 },
+	{ 0x7084, 0x00 },
+	{ 0x7085, 0x00 },
+	{ 0x7086, 0x00 },
+	{ 0x7087, 0x00 },
+	{ 0x7088, 0x00 },
+	{ 0x7089, 0x00 },
+	{ 0x708A, 0x00 },
+	{ 0x708B, 0x00 },
+	{ 0x708C, 0x00 },
+	{ 0x708D, 0x00 },
+	{ 0x708E, 0x00 },
+	{ 0x708F, 0x00 },
+	{ 0x7090, 0x00 },
+	{ 0x7091, 0xF0 },
+	{ 0x7092, 0x02 },
+	{ 0x7093, 0xF8 },
+	{ 0x7094, 0x8D },
+	{ 0x7095, 0xF6 },
+	{ 0x7096, 0xFA },
+	{ 0x7097, 0xFF },
+	{ 0x7098, 0xF0 },
+	{ 0x7099, 0xB5 },
+	{ 0x709A, 0x04 },
+	{ 0x709B, 0x46 },
+	{ 0x709C, 0x8F },
+	{ 0x709D, 0xB0 },
+	{ 0x709E, 0x5F },
+	{ 0x709F, 0x48 },
+	{ 0x70A0, 0x0C },
+	{ 0x70A1, 0x90 },
+	{ 0x70A2, 0x5F },
+	{ 0x70A3, 0x48 },
+	{ 0x70A4, 0x06 },
+	{ 0x70A5, 0x90 },
+	{ 0x70A6, 0x20 },
+	{ 0x70A7, 0x46 },
+	{ 0x70A8, 0x34 },
+	{ 0x70A9, 0x30 },
+	{ 0x70AA, 0x0B },
+	{ 0x70AB, 0x90 },
+	{ 0x70AC, 0x5B },
+	{ 0x70AD, 0x48 },
+	{ 0x70AE, 0x5A },
+	{ 0x70AF, 0x49 },
+	{ 0x70B0, 0x26 },
+	{ 0x70B1, 0x46 },
+	{ 0x70B2, 0x66 },
+	{ 0x70B3, 0x30 },
+	{ 0x70B4, 0x3A },
+	{ 0x70B5, 0x31 },
+	{ 0x70B6, 0x3C },
+	{ 0x70B7, 0x36 },
+	{ 0x70B8, 0x05 },
+	{ 0x70B9, 0x90 },
+	{ 0x70BA, 0x0A },
+	{ 0x70BB, 0x30 },
+	{ 0x70BC, 0x04 },
+	{ 0x70BD, 0x90 },
+	{ 0x70BE, 0x59 },
+	{ 0x70BF, 0x48 },
+	{ 0x70C0, 0x55 },
+	{ 0x70C1, 0x4A },
+	{ 0x70C2, 0x40 },
+	{ 0x70C3, 0x6E },
+	{ 0x70C4, 0xC0 },
+	{ 0x70C5, 0x07 },
+	{ 0x70C6, 0x7D },
+	{ 0x70C7, 0xD1 },
+	{ 0x70C8, 0x17 },
+	{ 0x70C9, 0x88 },
+	{ 0x70CA, 0x0A },
+	{ 0x70CB, 0x5E },
+	{ 0x70CC, 0x0D },
+	{ 0x70CD, 0x92 },
+	{ 0x70CE, 0x53 },
+	{ 0x70CF, 0x49 },
+	{ 0x70D0, 0x55 },
+	{ 0x70D1, 0x48 },
+	{ 0x70D2, 0x94 },
+	{ 0x70D3, 0x31 },
+	{ 0x70D4, 0x89 },
+	{ 0x70D5, 0x6B },
+	{ 0x70D6, 0x80 },
+	{ 0x70D7, 0x68 },
+	{ 0x70D8, 0x09 },
+	{ 0x70D9, 0x02 },
+	{ 0x70DA, 0x00 },
+	{ 0x70DB, 0x03 },
+	{ 0x70DC, 0x09 },
+	{ 0x70DD, 0x0E },
+	{ 0x70DE, 0x00 },
+	{ 0x70DF, 0x0B },
+	{ 0x70E0, 0x49 },
+	{ 0x70E1, 0x1C },
+	{ 0x70E2, 0x48 },
+	{ 0x70E3, 0x43 },
+	{ 0x70E4, 0x4D },
+	{ 0x70E5, 0x49 },
+	{ 0x70E6, 0x6C },
+	{ 0x70E7, 0x39 },
+	{ 0x70E8, 0x8A },
+	{ 0x70E9, 0x6A },
+	{ 0x70EA, 0x07 },
+	{ 0x70EB, 0x92 },
+	{ 0x70EC, 0xCA },
+	{ 0x70ED, 0x6A },
+	{ 0x70EE, 0x00 },
+	{ 0x70EF, 0x21 },
+	{ 0x70F0, 0xC9 },
+	{ 0x70F1, 0x43 },
+	{ 0x70F2, 0x03 },
+	{ 0x70F3, 0x92 },
+	{ 0x70F4, 0x00 },
+	{ 0x70F5, 0x22 },
+	{ 0x70F6, 0x00 },
+	{ 0x70F7, 0x91 },
+	{ 0x70F8, 0x01 },
+	{ 0x70F9, 0x92 },
+	{ 0x70FA, 0x39 },
+	{ 0x70FB, 0x46 },
+	{ 0x70FC, 0x8F },
+	{ 0x70FD, 0xF6 },
+	{ 0x70FE, 0xCE },
+	{ 0x70FF, 0xFB },
+	{ 0x7100, 0x01 },
+	{ 0x7101, 0x22 },
+	{ 0x7102, 0x00 },
+	{ 0x7103, 0x23 },
+	{ 0x7104, 0x8C },
+	{ 0x7105, 0xF6 },
+	{ 0x7106, 0x02 },
+	{ 0x7107, 0xFA },
+	{ 0x7108, 0x00 },
+	{ 0x7109, 0x21 },
+	{ 0x710A, 0x05 },
+	{ 0x710B, 0x46 },
+	{ 0x710C, 0x01 },
+	{ 0x710D, 0x91 },
+	{ 0x710E, 0x00 },
+	{ 0x710F, 0x90 },
+	{ 0x7110, 0x39 },
+	{ 0x7111, 0x46 },
+	{ 0x7112, 0x07 },
+	{ 0x7113, 0x98 },
+	{ 0x7114, 0x8F },
+	{ 0x7115, 0xF6 },
+	{ 0x7116, 0xC2 },
+	{ 0x7117, 0xFB },
+	{ 0x7118, 0x0D },
+	{ 0x7119, 0x9A },
+	{ 0x711A, 0xD3 },
+	{ 0x711B, 0x17 },
+	{ 0x711C, 0x80 },
+	{ 0x711D, 0x18 },
+	{ 0x711E, 0x59 },
+	{ 0x711F, 0x41 },
+	{ 0x7120, 0x01 },
+	{ 0x7121, 0x22 },
+	{ 0x7122, 0x00 },
+	{ 0x7123, 0x23 },
+	{ 0x7124, 0x8C },
+	{ 0x7125, 0xF6 },
+	{ 0x7126, 0xCD },
+	{ 0x7127, 0xF9 },
+	{ 0x7128, 0x07 },
+	{ 0x7129, 0x90 },
+	{ 0x712A, 0x00 },
+	{ 0x712B, 0x20 },
+	{ 0x712C, 0x01 },
+	{ 0x712D, 0x90 },
+	{ 0x712E, 0x00 },
+	{ 0x712F, 0x95 },
+	{ 0x7130, 0x39 },
+	{ 0x7131, 0x46 },
+	{ 0x7132, 0x03 },
+	{ 0x7133, 0x98 },
+	{ 0x7134, 0x8F },
+	{ 0x7135, 0xF6 },
+	{ 0x7136, 0xB2 },
+	{ 0x7137, 0xFB },
+	{ 0x7138, 0x01 },
+	{ 0x7139, 0x22 },
+	{ 0x713A, 0x00 },
+	{ 0x713B, 0x23 },
+	{ 0x713C, 0x8C },
+	{ 0x713D, 0xF6 },
+	{ 0x713E, 0xE6 },
+	{ 0x713F, 0xF9 },
+	{ 0x7140, 0x02 },
+	{ 0x7141, 0x46 },
+	{ 0x7142, 0x07 },
+	{ 0x7143, 0x98 },
+	{ 0x7144, 0x00 },
+	{ 0x7145, 0x23 },
+	{ 0x7146, 0x81 },
+	{ 0x7147, 0x0B },
+	{ 0x7148, 0x80 },
+	{ 0x7149, 0x04 },
+	{ 0x714A, 0x7A },
+	{ 0x714B, 0xF6 },
+	{ 0x714C, 0x54 },
+	{ 0x714D, 0xF8 },
+	{ 0x714E, 0x37 },
+	{ 0x714F, 0x4A },
+	{ 0x7150, 0x00 },
+	{ 0x7151, 0x23 },
+	{ 0x7152, 0x00 },
+	{ 0x7153, 0x92 },
+	{ 0x7154, 0x01 },
+	{ 0x7155, 0x93 },
+	{ 0x7156, 0x01 },
+	{ 0x7157, 0x22 },
+	{ 0x7158, 0x8C },
+	{ 0x7159, 0xF6 },
+	{ 0x715A, 0xD8 },
+	{ 0x715B, 0xF9 },
+	{ 0x715C, 0x05 },
+	{ 0x715D, 0x46 },
+	{ 0x715E, 0x60 },
+	{ 0x715F, 0x68 },
+	{ 0x7160, 0x00 },
+	{ 0x7161, 0x23 },
+	{ 0x7162, 0x01 },
+	{ 0x7163, 0x0C },
+	{ 0x7164, 0x00 },
+	{ 0x7165, 0x04 },
+	{ 0x7166, 0xE2 },
+	{ 0x7167, 0x68 },
+	{ 0x7168, 0x7A },
+	{ 0x7169, 0xF6 },
+	{ 0x716A, 0x45 },
+	{ 0x716B, 0xF8 },
+	{ 0x716C, 0x00 },
+	{ 0x716D, 0x22 },
+	{ 0x716E, 0xD2 },
+	{ 0x716F, 0x43 },
+	{ 0x7170, 0x00 },
+	{ 0x7171, 0x23 },
+	{ 0x7172, 0x00 },
+	{ 0x7173, 0x92 },
+	{ 0x7174, 0x01 },
+	{ 0x7175, 0x93 },
+	{ 0x7176, 0x1A },
+	{ 0x7177, 0x46 },
+	{ 0x7178, 0x8C },
+	{ 0x7179, 0xF6 },
+	{ 0x717A, 0xC8 },
+	{ 0x717B, 0xF9 },
+	{ 0x717C, 0x29 },
+	{ 0x717D, 0x46 },
+	{ 0x717E, 0x8F },
+	{ 0x717F, 0xF6 },
+	{ 0x7180, 0x8D },
+	{ 0x7181, 0xFB },
+	{ 0x7182, 0x8A },
+	{ 0x7183, 0x03 },
+	{ 0x7184, 0x80 },
+	{ 0x7185, 0x0C },
+	{ 0x7186, 0x10 },
+	{ 0x7187, 0x43 },
+	{ 0x7188, 0x00 },
+	{ 0x7189, 0x22 },
+	{ 0x718A, 0xD2 },
+	{ 0x718B, 0x43 },
+	{ 0x718C, 0x00 },
+	{ 0x718D, 0x23 },
+	{ 0x718E, 0x00 },
+	{ 0x718F, 0x92 },
+	{ 0x7190, 0x89 },
+	{ 0x7191, 0x0C },
+	{ 0x7192, 0x01 },
+	{ 0x7193, 0x93 },
+	{ 0x7194, 0x1A },
+	{ 0x7195, 0x46 },
+	{ 0x7196, 0x8C },
+	{ 0x7197, 0xF6 },
+	{ 0x7198, 0xB9 },
+	{ 0x7199, 0xF9 },
+	{ 0x719A, 0x00 },
+	{ 0x719B, 0x24 },
+	{ 0x719C, 0x03 },
+	{ 0x719D, 0x90 },
+	{ 0x719E, 0x0C },
+	{ 0x719F, 0x98 },
+	{ 0x71A0, 0x61 },
+	{ 0x71A1, 0x00 },
+	{ 0x71A2, 0x45 },
+	{ 0x71A3, 0x5A },
+	{ 0x71A4, 0x06 },
+	{ 0x71A5, 0x98 },
+	{ 0x71A6, 0x22 },
+	{ 0x71A7, 0x4A },
+	{ 0x71A8, 0x40 },
+	{ 0x71A9, 0x5A },
+	{ 0x71AA, 0x00 },
+	{ 0x71AB, 0x21 },
+	{ 0x71AC, 0x8C },
+	{ 0x71AD, 0xF6 },
+	{ 0x71AE, 0xBE },
+	{ 0x71AF, 0xF9 },
+	{ 0x71B0, 0x07 },
+	{ 0x71B1, 0x46 },
+	{ 0x71B2, 0x28 },
+	{ 0x71B3, 0x46 },
+	{ 0x71B4, 0x03 },
+	{ 0x71B5, 0x99 },
+	{ 0x71B6, 0x8F },
+	{ 0x71B7, 0xF6 },
+	{ 0x71B8, 0x71 },
+	{ 0x71B9, 0xFB },
+	{ 0x71BA, 0x3A },
+	{ 0x71BB, 0x46 },
+	{ 0x71BC, 0x00 },
+	{ 0x71BD, 0x23 },
+	{ 0x71BE, 0x79 },
+	{ 0x71BF, 0xF6 },
+	{ 0x71C0, 0xCA },
+	{ 0x71C1, 0xFF },
+	{ 0x71C2, 0x00 },
+	{ 0x71C3, 0xE0 },
+	{ 0x71C4, 0x0F },
+	{ 0x71C5, 0xE0 },
+	{ 0x71C6, 0x8A },
+	{ 0x71C7, 0x02 },
+	{ 0x71C8, 0x80 },
+	{ 0x71C9, 0x0D },
+	{ 0x71CA, 0x10 },
+	{ 0x71CB, 0x43 },
+	{ 0x71CC, 0x19 },
+	{ 0x71CD, 0x4A },
+	{ 0x71CE, 0x00 },
+	{ 0x71CF, 0x23 },
+	{ 0x71D0, 0x00 },
+	{ 0x71D1, 0x92 },
+	{ 0x71D2, 0x89 },
+	{ 0x71D3, 0x0D },
+	{ 0x71D4, 0x01 },
+	{ 0x71D5, 0x93 },
+	{ 0x71D6, 0x40 },
+	{ 0x71D7, 0x22 },
+	{ 0x71D8, 0x8C },
+	{ 0x71D9, 0xF6 },
+	{ 0x71DA, 0x98 },
+	{ 0x71DB, 0xF9 },
+	{ 0x71DC, 0xA1 },
+	{ 0x71DD, 0x00 },
+	{ 0x71DE, 0x64 },
+	{ 0x71DF, 0x1C },
+	{ 0x71E0, 0x70 },
+	{ 0x71E1, 0x50 },
+	{ 0x71E2, 0x04 },
+	{ 0x71E3, 0x2C },
+	{ 0x71E4, 0xDB },
+	{ 0x71E5, 0xD3 },
+	{ 0x71E6, 0x14 },
+	{ 0x71E7, 0x4D },
+	{ 0x71E8, 0x00 },
+	{ 0x71E9, 0x24 },
+	{ 0x71EA, 0x0B },
+	{ 0x71EB, 0x98 },
+	{ 0x71EC, 0x67 },
+	{ 0x71ED, 0x00 },
+	{ 0x71EE, 0xC0 },
+	{ 0x71EF, 0x5B },
+	{ 0x71F0, 0x2A },
+	{ 0x71F1, 0x46 },
+	{ 0x71F2, 0x40 },
+	{ 0x71F3, 0x21 },
+	{ 0x71F4, 0x8C },
+	{ 0x71F5, 0xF6 },
+	{ 0x71F6, 0x9A },
+	{ 0x71F7, 0xF9 },
+	{ 0x71F8, 0x05 },
+	{ 0x71F9, 0x99 },
+	{ 0x71FA, 0x0E },
+	{ 0x71FB, 0x4A },
+	{ 0x71FC, 0xC8 },
+	{ 0x71FD, 0x53 },
+	{ 0x71FE, 0xA7 },
+	{ 0x71FF, 0x00 },
+	{ 0x7200, 0xF0 },
+	{ 0x7201, 0x59 },
+	{ 0x7202, 0x40 },
+	{ 0x7203, 0x21 },
+	{ 0x7204, 0x8C },
+	{ 0x7205, 0xF6 },
+	{ 0x7206, 0x7B },
+	{ 0x7207, 0xF9 },
+	{ 0x7208, 0x04 },
+	{ 0x7209, 0x99 },
+	{ 0x720A, 0x64 },
+	{ 0x720B, 0x1C },
+	{ 0x720C, 0xC8 },
+	{ 0x720D, 0x51 },
+	{ 0x720E, 0x04 },
+	{ 0x720F, 0x2C },
+	{ 0x7210, 0xEB },
+	{ 0x7211, 0xD3 },
+	{ 0x7212, 0x0F },
+	{ 0x7213, 0xB0 },
+	{ 0x7214, 0xF0 },
+	{ 0x7215, 0xBD },
+	{ 0x7216, 0x00 },
+	{ 0x7217, 0x00 },
+	{ 0x7218, 0x76 },
+	{ 0x7219, 0x69 },
+	{ 0x721A, 0x18 },
+	{ 0x721B, 0x00 },
+	{ 0x721C, 0xEC },
+	{ 0x721D, 0x58 },
+	{ 0x721E, 0x18 },
+	{ 0x721F, 0x00 },
+	{ 0x7220, 0x38 },
+	{ 0x7221, 0x36 },
+	{ 0x7222, 0x18 },
+	{ 0x7223, 0x00 },
+	{ 0x7224, 0x00 },
+	{ 0x7225, 0x35 },
+	{ 0x7226, 0x18 },
+	{ 0x7227, 0x00 },
+	{ 0x7228, 0x00 },
+	{ 0x7229, 0x20 },
+	{ 0x722A, 0x18 },
+	{ 0x722B, 0x00 },
+	{ 0x722C, 0xFF },
+	{ 0x722D, 0xFF },
+	{ 0x722E, 0xFF },
+	{ 0x722F, 0x3F },
+	{ 0x7230, 0xFF },
+	{ 0x7231, 0x07 },
+	{ 0x7232, 0x00 },
+	{ 0x7233, 0x00 },
+	{ 0x7234, 0xFF },
+	{ 0x7235, 0xFF },
+	{ 0x7236, 0x07 },
+	{ 0x7237, 0x00 },
+	{ 0x7238, 0xFF },
+	{ 0x7239, 0x1F },
+	{ 0x723A, 0x00 },
+	{ 0x723B, 0x00 },
+	{ 0x723C, 0x01 },
+	{ 0x723D, 0xF6 },
+	{ 0x723E, 0x45 },
+	{ 0x723F, 0x12 },
+};
+
+static const struct reg_sequence imx390_linear_1936x1096[] = {
+	{ 0x000C, 0xF2 },
+	{ 0x000D, 0x02 },
+	{ 0x000E, 0x00 },
+	{ 0x0010, 0xF2 },
+	{ 0x0011, 0x02 },
+	{ 0x0012, 0x00 },
+	{ 0x0018, 0x0F },
+	{ 0x0019, 0x00 },
+	{ 0x001A, 0x0C },
+	{ 0x001B, 0x00 },
+	{ 0x0038, 0x00 },
+	{ 0x003C, 0x00 }, /* OBB_CLAMP_R_SP1H */
+	{ 0x003D, 0x00 }, /* OBB_CLAMP_R_SP1H */
+	{ 0x003E, 0x00 },
+	{ 0x0040, 0x00 }, /* OBB_CLAMP_GR_SP1H */
+	{ 0x0041, 0x00 }, /* OBB_CLAMP_GR_SP1H */
+	{ 0x0042, 0x00 },
+	{ 0x0044, 0x00 }, /* OBB_CLAMP_GB_SP1H */
+	{ 0x0045, 0x00 }, /* OBB_CLAMP_GB_SP1H */
+	{ 0x0046, 0x00 },
+	{ 0x0048, 0x00 },
+	{ 0x0049, 0x00 },
+	{ 0x004A, 0x00 },
+	{ 0x004C, 0x00 },
+	{ 0x004D, 0x00 },
+	{ 0x004E, 0x00 },
+	{ 0x0050, 0x00 },
+	{ 0x0051, 0x00 },
+	{ 0x0052, 0x00 },
+	{ 0x0054, 0x00 },
+	{ 0x0055, 0x00 },
+	{ 0x0056, 0x00 },
+	{ 0x0058, 0x00 },
+	{ 0x0059, 0x00 },
+	{ 0x005A, 0x00 },
+	{ 0x005C, 0x00 },
+	{ 0x005D, 0x00 },
+	{ 0x005E, 0x00 },
+	{ 0x0060, 0x00 },
+	{ 0x0061, 0x00 },
+	{ 0x0062, 0x00 },
+	{ 0x0064, 0x00 },
+	{ 0x0065, 0x00 },
+	{ 0x0066, 0x00 },
+	{ 0x0068, 0x00 },
+	{ 0x0069, 0x00 },
+	{ 0x006A, 0x00 },
+	{ 0x0074, 0x00 },
+	{ 0x0078, 0x00 },
+	{ 0x007C, 0x00 },
+	{ 0x007D, 0x00 },
+	{ 0x0080, 0x00 },
+	{ 0x0081, 0x00 },
+	{ 0x00F4, 0x1C },
+	{ 0x00F5, 0xF8 },
+	{ 0x00F6, 0x01 },
+	{ 0x00F8, 0x03 },
+	{ 0x00F9, 0x00 },
+	{ 0x00FA, 0x00 },
+	{ 0x00FB, 0x00 },
+	{ 0x0114, 0x00 },
+	{ 0x0115, 0x01 },
+	{ 0x0118, 0x20 },
+	{ 0x0119, 0x03 },
+	{ 0x011A, 0x00 },
+	{ 0x011B, 0x41 },
+	{ 0x011C, 0x80 },
+	{ 0x011D, 0x00 },
+	{ 0x0120, 0x20 },
+	{ 0x0121, 0x00 },
+	{ 0x0122, 0x00 },
+	{ 0x0123, 0x44 },
+	{ 0x0124, 0x00 },
+	{ 0x0125, 0x01 },
+	{ 0x0128, 0xAC },
+	{ 0x0129, 0x0D },
+	{ 0x012A, 0x00 },
+	{ 0x012B, 0xA4 },
+	{ 0x012C, 0x00 },
+	{ 0x012D, 0x01 },
+	{ 0x0130, 0xC4 },
+	{ 0x0131, 0x09 },
+	{ 0x0132, 0x00 },
+	{ 0x0133, 0xDA },
+	{ 0x013B, 0x01 },
+	{ 0x01C4, 0x00 },
+	{ 0x01C5, 0x00 },
+	{ 0x01CC, 0x01 },
+	{ 0x01D0, 0x09 },
+	{ 0x01D4, 0x01 },
+	{ 0x0232, 0x18 },
+	{ 0x0233, 0x00 },
+	{ 0x0390, 0x00 },
+	{ 0x0391, 0x00 },
+	{ 0x0392, 0x00 },
+	{ 0x03C0, 0x04 },
+	{ 0x2000, 0x55 },
+	{ 0x2001, 0x55 },
+	{ 0x2002, 0x55 },
+	{ 0x2003, 0x05 },
+	{ 0x2004, 0x02 },
+	{ 0x2008, 0x65 },
+	{ 0x2009, 0x04 },
+	{ 0x200A, 0x00 },
+	{ 0x200C, 0x30 },
+	{ 0x200D, 0x11 },
+	{ 0x2010, 0x04 },
+	{ 0x2014, 0x01 },
+	{ 0x2018, 0x02 },
+	{ 0x2019, 0x04 },
+	{ 0x201A, 0x00 },
+	{ 0x201C, 0x21 },
+	{ 0x201D, 0x11 },
+	{ 0x201E, 0x00 },
+	{ 0x201F, 0x00 },
+	{ 0x2020, 0xBC },
+	{ 0x2021, 0x00 },
+	{ 0x2022, 0x7F },
+	{ 0x2023, 0x00 },
+	{ 0x2024, 0xBA },
+	{ 0x2025, 0x00 },
+	{ 0x2026, 0x81 },
+	{ 0x2027, 0x00 },
+	{ 0x2028, 0x7D },
+	{ 0x2029, 0x90 },
+	{ 0x202A, 0x05 },
+	{ 0x202C, 0xFC },
+	{ 0x202D, 0x02 },
+	{ 0x202E, 0x25 },
+	{ 0x202F, 0x03 },
+	{ 0x2030, 0x05 },
+	{ 0x2031, 0x02 },
+	{ 0x2032, 0xCA },
+	{ 0x2033, 0x02 },
+	{ 0x2034, 0xFC },
+	{ 0x2035, 0x02 },
+	{ 0x2036, 0x25 },
+	{ 0x2037, 0x03 },
+	{ 0x2038, 0x25 },
+	{ 0x2039, 0x97 },
+	{ 0x203A, 0xEC },
+	{ 0x203B, 0x01 },
+	{ 0x203C, 0xF5 },
+	{ 0x203D, 0x8E },
+	{ 0x203E, 0x0C },
+	{ 0x203F, 0x2D },
+	{ 0x2040, 0x69 },
+	{ 0x2041, 0x01 },
+	{ 0x2042, 0x8E },
+	{ 0x2043, 0x01 },
+	{ 0x2044, 0x0C },
+	{ 0x2045, 0x02 },
+	{ 0x2046, 0x31 },
+	{ 0x2047, 0x02 },
+	{ 0x2048, 0x6A },
+	{ 0x2049, 0x01 },
+	{ 0x204A, 0x8E },
+	{ 0x204B, 0x01 },
+	{ 0x204C, 0x0D },
+	{ 0x204D, 0x02 },
+	{ 0x204E, 0x31 },
+	{ 0x204F, 0x02 },
+	{ 0x2050, 0x7B },
+	{ 0x2051, 0x00 },
+	{ 0x2052, 0x7D },
+	{ 0x2053, 0x00 },
+	{ 0x2054, 0x95 },
+	{ 0x2055, 0x00 },
+	{ 0x2056, 0x97 },
+	{ 0x2057, 0x00 },
+	{ 0x2058, 0xAD },
+	{ 0x2059, 0x00 },
+	{ 0x205A, 0xAF },
+	{ 0x205B, 0x00 },
+	{ 0x205C, 0x92 },
+	{ 0x205D, 0x00 },
+	{ 0x205E, 0x94 },
+	{ 0x205F, 0x00 },
+	{ 0x2060, 0x8E },
+	{ 0x2061, 0x00 },
+	{ 0x2062, 0x90 },
+	{ 0x2063, 0x00 },
+	{ 0x2064, 0xB1 },
+	{ 0x2065, 0x00 },
+	{ 0x2066, 0xB3 },
+	{ 0x2067, 0x00 },
+	{ 0x2068, 0x08 },
+	{ 0x2069, 0x00 },
+	{ 0x206A, 0x04 },
+	{ 0x206B, 0x00 },
+	{ 0x206C, 0x84 },
+	{ 0x206D, 0x00 },
+	{ 0x206E, 0x80 },
+	{ 0x206F, 0x00 },
+	{ 0x2070, 0x04 },
+	{ 0x2071, 0x00 },
+	{ 0x2072, 0x46 },
+	{ 0x2073, 0x00 },
+	{ 0x2074, 0xE9 },
+	{ 0x2075, 0x01 },
+	{ 0x2076, 0x74 },
+	{ 0x2077, 0x02 },
+	{ 0x2078, 0x80 },
+	{ 0x2079, 0x00 },
+	{ 0x207A, 0xC1 },
+	{ 0x207B, 0x00 },
+	{ 0x207C, 0xFF },
+	{ 0x207D, 0x03 },
+	{ 0x207E, 0xFF },
+	{ 0x207F, 0x03 },
+	{ 0x2080, 0x78 },
+	{ 0x2081, 0x00 },
+	{ 0x2082, 0x6A },
+	{ 0x2083, 0x01 },
+	{ 0x2084, 0xE4 },
+	{ 0x2085, 0x01 },
+	{ 0x2086, 0x2B },
+	{ 0x2087, 0x03 },
+	{ 0x2088, 0x00 },
+	{ 0x2089, 0x00 },
+	{ 0x208A, 0xFF },
+	{ 0x208B, 0x03 },
+	{ 0x208C, 0xFF },
+	{ 0x208D, 0x03 },
+	{ 0x208E, 0xFF },
+	{ 0x208F, 0x03 },
+	{ 0x2090, 0x7D },
+	{ 0x2091, 0x00 },
+	{ 0x2092, 0x62 },
+	{ 0x2093, 0x01 },
+	{ 0x2094, 0xE9 },
+	{ 0x2095, 0x01 },
+	{ 0x2096, 0x00 },
+	{ 0x2097, 0x00 },
+	{ 0x2098, 0x7C },
+	{ 0x2099, 0x00 },
+	{ 0x209A, 0x21 },
+	{ 0x209B, 0x03 },
+	{ 0x209C, 0xE9 },
+	{ 0x209D, 0x01 },
+	{ 0x209E, 0x21 },
+	{ 0x209F, 0x03 },
+	{ 0x20A0, 0xFF },
+	{ 0x20A1, 0x03 },
+	{ 0x20A2, 0xFF },
+	{ 0x20A3, 0x03 },
+	{ 0x20A4, 0xFF },
+	{ 0x20A5, 0x03 },
+	{ 0x20A6, 0xFF },
+	{ 0x20A7, 0x03 },
+	{ 0x20A8, 0xFF },
+	{ 0x20A9, 0x03 },
+	{ 0x20AA, 0xFF },
+	{ 0x20AB, 0x03 },
+	{ 0x20AC, 0xFF },
+	{ 0x20AD, 0x03 },
+	{ 0x20AE, 0xFF },
+	{ 0x20AF, 0x03 },
+	{ 0x20B0, 0xFF },
+	{ 0x20B1, 0x03 },
+	{ 0x20B2, 0xFF },
+	{ 0x20B3, 0x03 },
+	{ 0x20B4, 0x87 },
+	{ 0x20B5, 0xCC },
+	{ 0x20B6, 0x87 },
+	{ 0x20B7, 0x08 },
+	{ 0x20B8, 0xF4 },
+	{ 0x20B9, 0xA5 },
+	{ 0x20BA, 0x07 },
+	{ 0x20BC, 0x1F },
+	{ 0x20BD, 0x01 },
+	{ 0x20BE, 0xF6 },
+	{ 0x20BF, 0x00 },
+	{ 0x20C0, 0x90 },
+	{ 0x20C1, 0x01 },
+	{ 0x20C2, 0x67 },
+	{ 0x20C3, 0x01 },
+	{ 0x20C4, 0xFF },
+	{ 0x20C5, 0x03 },
+	{ 0x20C6, 0xFF },
+	{ 0x20C7, 0x03 },
+	{ 0x20C8, 0x33 },
+	{ 0x20C9, 0x02 },
+	{ 0x20CA, 0x0A },
+	{ 0x20CB, 0x02 },
+	{ 0x20CC, 0x7F },
+	{ 0x20CD, 0x00 },
+	{ 0x20CE, 0xD2 },
+	{ 0x20CF, 0x00 },
+	{ 0x20D0, 0x81 },
+	{ 0x20D1, 0x00 },
+	{ 0x20D2, 0x87 },
+	{ 0x20D3, 0x00 },
+	{ 0x20D4, 0x09 },
+	{ 0x20D5, 0x00 },
+	{ 0x20D8, 0x7F },
+	{ 0x20D9, 0x00 },
+	{ 0x20DA, 0x62 },
+	{ 0x20DB, 0x01 },
+	{ 0x20DC, 0x7F },
+	{ 0x20DD, 0x00 },
+	{ 0x20DE, 0x62 },
+	{ 0x20DF, 0x01 },
+	{ 0x20E0, 0x65 },
+	{ 0x20E1, 0x00 },
+	{ 0x20E2, 0x75 },
+	{ 0x20E3, 0x00 },
+	{ 0x20E4, 0xE0 },
+	{ 0x20E5, 0x00 },
+	{ 0x20E6, 0xF0 },
+	{ 0x20E7, 0x00 },
+	{ 0x20E8, 0x4C },
+	{ 0x20E9, 0x01 },
+	{ 0x20EA, 0x5C },
+	{ 0x20EB, 0x01 },
+	{ 0x20EC, 0xD1 },
+	{ 0x20ED, 0x01 },
+	{ 0x20EE, 0xE1 },
+	{ 0x20EF, 0x01 },
+	{ 0x20F0, 0x93 },
+	{ 0x20F1, 0x02 },
+	{ 0x20F2, 0xA3 },
+	{ 0x20F3, 0x02 },
+	{ 0x20F4, 0x0D },
+	{ 0x20F5, 0x03 },
+	{ 0x20F6, 0x1D },
+	{ 0x20F7, 0x03 },
+	{ 0x20F8, 0x57 },
+	{ 0x20F9, 0x00 },
+	{ 0x20FA, 0x7B },
+	{ 0x20FB, 0x00 },
+	{ 0x20FC, 0xD2 },
+	{ 0x20FD, 0x00 },
+	{ 0x20FE, 0xF6 },
+	{ 0x20FF, 0x00 },
+	{ 0x2100, 0x3E },
+	{ 0x2101, 0x01 },
+	{ 0x2102, 0x60 },
+	{ 0x2103, 0x01 },
+	{ 0x2104, 0xC3 },
+	{ 0x2105, 0x01 },
+	{ 0x2106, 0xE5 },
+	{ 0x2107, 0x01 },
+	{ 0x2108, 0x85 },
+	{ 0x2109, 0x02 },
+	{ 0x210A, 0xA9 },
+	{ 0x210B, 0x02 },
+	{ 0x210C, 0xFF },
+	{ 0x210D, 0x02 },
+	{ 0x210E, 0x21 },
+	{ 0x210F, 0x03 },
+	{ 0x2110, 0xFF },
+	{ 0x2111, 0x03 },
+	{ 0x2112, 0x00 },
+	{ 0x2113, 0x00 },
+	{ 0x2114, 0xFF },
+	{ 0x2115, 0x03 },
+	{ 0x2116, 0xFF },
+	{ 0x2117, 0x03 },
+	{ 0x2118, 0xFF },
+	{ 0x2119, 0x03 },
+	{ 0x211A, 0xFF },
+	{ 0x211B, 0x03 },
+	{ 0x211C, 0xFF },
+	{ 0x211D, 0x03 },
+	{ 0x211E, 0xFF },
+	{ 0x211F, 0x03 },
+	{ 0x2120, 0xFF },
+	{ 0x2121, 0x03 },
+	{ 0x2122, 0xFF },
+	{ 0x2123, 0x03 },
+	{ 0x2124, 0xFF },
+	{ 0x2125, 0x03 },
+	{ 0x2126, 0xFF },
+	{ 0x2127, 0x03 },
+	{ 0x2128, 0x7D },
+	{ 0x2129, 0x90 },
+	{ 0x212A, 0xD5 },
+	{ 0x212B, 0x07 },
+	{ 0x212C, 0x64 },
+	{ 0x212D, 0x01 },
+	{ 0x2130, 0x5F },
+	{ 0x2131, 0x7D },
+	{ 0x2132, 0x05 },
+	{ 0x2134, 0x78 },
+	{ 0x2135, 0x00 },
+	{ 0x2136, 0x76 },
+	{ 0x2137, 0x00 },
+	{ 0x2138, 0xF3 },
+	{ 0x2139, 0x00 },
+	{ 0x213A, 0xF1 },
+	{ 0x213B, 0x00 },
+	{ 0x213C, 0xA6 },
+	{ 0x213D, 0x02 },
+	{ 0x213E, 0xA4 },
+	{ 0x213F, 0x02 },
+	{ 0x2140, 0x7D },
+	{ 0x2141, 0x00 },
+	{ 0x2142, 0x8D },
+	{ 0x2143, 0x00 },
+	{ 0x2144, 0xA1 },
+	{ 0x2145, 0x01 },
+	{ 0x2146, 0xB1 },
+	{ 0x2147, 0x01 },
+	{ 0x2148, 0xAB },
+	{ 0x2149, 0x02 },
+	{ 0x214A, 0xBB },
+	{ 0x214B, 0x02 },
+	{ 0x214C, 0x17 },
+	{ 0x214D, 0x5C },
+	{ 0x214E, 0x00 },
+	{ 0x2150, 0x00 },
+	{ 0x2151, 0x00 },
+	{ 0x2152, 0xF8 },
+	{ 0x2153, 0x00 },
+	{ 0x2154, 0xBE },
+	{ 0x2155, 0x00 },
+	{ 0x2156, 0x7D },
+	{ 0x2157, 0x00 },
+	{ 0x2158, 0x25 },
+	{ 0x2159, 0x00 },
+	{ 0x215A, 0x7D },
+	{ 0x215B, 0x00 },
+	{ 0x215C, 0x62 },
+	{ 0x215D, 0x01 },
+	{ 0x215E, 0xFF },
+	{ 0x215F, 0x03 },
+	{ 0x2160, 0x26 },
+	{ 0x2161, 0x00 },
+	{ 0x2162, 0x7D },
+	{ 0x2163, 0x00 },
+	{ 0x2164, 0x63 },
+	{ 0x2165, 0x01 },
+	{ 0x2166, 0xFF },
+	{ 0x2167, 0x03 },
+	{ 0x2168, 0xCB },
+	{ 0x2169, 0x02 },
+	{ 0x216A, 0xCF },
+	{ 0x216B, 0x02 },
+	{ 0x216C, 0xFF },
+	{ 0x216D, 0x03 },
+	{ 0x216E, 0xFF },
+	{ 0x216F, 0x03 },
+	{ 0x2170, 0xFF },
+	{ 0x2171, 0x03 },
+	{ 0x2172, 0xFF },
+	{ 0x2173, 0x03 },
+	{ 0x2174, 0xFF },
+	{ 0x2175, 0x03 },
+	{ 0x2176, 0xFF },
+	{ 0x2177, 0x03 },
+	{ 0x2178, 0x7E },
+	{ 0x2179, 0x00 },
+	{ 0x217A, 0xBD },
+	{ 0x217B, 0x00 },
+	{ 0x217C, 0xEC },
+	{ 0x217D, 0x01 },
+	{ 0x217E, 0x7B },
+	{ 0x217F, 0x02 },
+	{ 0x2180, 0xD1 },
+	{ 0x2181, 0x02 },
+	{ 0x2182, 0x25 },
+	{ 0x2183, 0x03 },
+	{ 0x2184, 0x7F },
+	{ 0x2185, 0x00 },
+	{ 0x2186, 0xBD },
+	{ 0x2187, 0x00 },
+	{ 0x2188, 0xED },
+	{ 0x2189, 0x01 },
+	{ 0x218A, 0x7B },
+	{ 0x218B, 0x02 },
+	{ 0x218C, 0xD2 },
+	{ 0x218D, 0x02 },
+	{ 0x218E, 0x25 },
+	{ 0x218F, 0x03 },
+	{ 0x2190, 0xFF },
+	{ 0x2191, 0x03 },
+	{ 0x2192, 0xFF },
+	{ 0x2193, 0x03 },
+	{ 0x2194, 0xE9 },
+	{ 0x2195, 0x01 },
+	{ 0x2196, 0x21 },
+	{ 0x2197, 0x03 },
+	{ 0x2198, 0x17 },
+	{ 0x2199, 0xFC },
+	{ 0x219A, 0x7F },
+	{ 0x219B, 0x01 },
+	{ 0x219C, 0xFF },
+	{ 0x219D, 0x03 },
+	{ 0x21A0, 0x1B },
+	{ 0x21A1, 0x1B },
+	{ 0x21A2, 0x1B },
+	{ 0x21A3, 0x1B },
+	{ 0x21A4, 0x2E },
+	{ 0x21A5, 0x80 },
+	{ 0x21A6, 0x00 },
+	{ 0x21A8, 0x04 },
+	{ 0x21A9, 0x98 },
+	{ 0x21AA, 0x60 },
+	{ 0x21AB, 0x03 },
+	{ 0x21AC, 0x7F },
+	{ 0x21AD, 0x80 },
+	{ 0x21AE, 0x09 },
+	{ 0x21B0, 0x1C },
+	{ 0x21B1, 0x00 },
+	{ 0x21B2, 0xA0 },
+	{ 0x21B3, 0x00 },
+	{ 0x21B4, 0x0C },
+	{ 0x21B5, 0x00 },
+	{ 0x21B6, 0x2D },
+	{ 0x21B7, 0x00 },
+	{ 0x21B8, 0x20 },
+	{ 0x21B9, 0x00 },
+	{ 0x21BA, 0x02 },
+	{ 0x21BB, 0x00 },
+	{ 0x21BC, 0xCC },
+	{ 0x21BD, 0x00 },
+	{ 0x21BE, 0x4A },
+	{ 0x21BF, 0x00 },
+	{ 0x21C0, 0xD0 },
+	{ 0x21C1, 0x00 },
+	{ 0x21C2, 0x44 },
+	{ 0x21C3, 0x00 },
+	{ 0x21C4, 0x00 },
+	{ 0x21C5, 0xE0 },
+	{ 0x21C6, 0x00 },
+	{ 0x21C8, 0x11 },
+	{ 0x21C9, 0x00 },
+	{ 0x21CA, 0x02 },
+	{ 0x21CC, 0x08 },
+	{ 0x21CD, 0xC0 },
+	{ 0x21CE, 0x0C },
+	{ 0x21D0, 0x44 },
+	{ 0x21D1, 0x00 },
+	{ 0x21D2, 0x02 },
+	{ 0x21D4, 0x02 },
+	{ 0x21D5, 0x20 },
+	{ 0x21D6, 0x2C },
+	{ 0x21D8, 0xFE },
+	{ 0x21D9, 0x9D },
+	{ 0x21DA, 0xDF },
+	{ 0x21DB, 0x03 },
+	{ 0x21DC, 0x62 },
+	{ 0x21DD, 0x01 },
+	{ 0x21DE, 0x7F },
+	{ 0x21DF, 0x00 },
+	{ 0x21E0, 0xB7 },
+	{ 0x21E1, 0x01 },
+	{ 0x21E2, 0xB5 },
+	{ 0x21E3, 0x01 },
+	{ 0x21E4, 0xC1 },
+	{ 0x21E5, 0x02 },
+	{ 0x21E6, 0xBF },
+	{ 0x21E7, 0x02 },
+	{ 0x21E8, 0xB3 },
+	{ 0x21E9, 0x0D },
+	{ 0x21EA, 0x00 },
+	{ 0x21EB, 0x04 },
+	{ 0x21EC, 0x90 },
+	{ 0x21ED, 0x07 },
+	{ 0x21EE, 0x58 },
+	{ 0x21EF, 0x04 },
+	{ 0x21F0, 0x54 },
+	{ 0x21F1, 0x04 },
+	{ 0x21F4, 0x02 },
+	{ 0x21F5, 0x00 },
+	{ 0x21F6, 0x00 },
+	{ 0x21F8, 0x3C },
+	{ 0x21F9, 0x00 },
+	{ 0x21FC, 0x28 },
+	{ 0x21FD, 0x00 },
+	{ 0x21FE, 0x3C },
+	{ 0x21FF, 0x00 },
+	{ 0x2200, 0x00 },
+	{ 0x2204, 0x4C },
+	{ 0x2205, 0x04 },
+	{ 0x2206, 0x65 },
+	{ 0x2207, 0x04 },
+	{ 0x2208, 0x0A },
+	{ 0x2209, 0x00 },
+	{ 0x220C, 0x47 },
+	{ 0x220D, 0x00 },
+	{ 0x220E, 0x1F },
+	{ 0x220F, 0x00 },
+	{ 0x2210, 0x17 },
+	{ 0x2211, 0x00 },
+	{ 0x2212, 0x0F },
+	{ 0x2213, 0x00 },
+	{ 0x2214, 0x17 },
+	{ 0x2215, 0x00 },
+	{ 0x2216, 0x47 },
+	{ 0x2217, 0x00 },
+	{ 0x2218, 0x0F },
+	{ 0x2219, 0x00 },
+	{ 0x221A, 0x0F },
+	{ 0x221B, 0x00 },
+	{ 0x221C, 0x03 },
+	{ 0x2220, 0x20 },
+	{ 0x2221, 0x20 },
+	{ 0x2222, 0x22 },
+	{ 0x2223, 0x02 },
+	{ 0x2224, 0xA7 },
+	{ 0x2225, 0xAA },
+	{ 0x2226, 0x80 },
+	{ 0x2227, 0x08 },
+	{ 0x2228, 0x01 },
+	{ 0x22B2, 0x92 },
+	{ 0x22B4, 0x20 },
+	{ 0x22B5, 0x00 },
+	{ 0x22B6, 0x20 },
+	{ 0x22B7, 0x00 },
+	{ 0x22B8, 0x20 },
+	{ 0x22B9, 0x00 },
+	{ 0x22BA, 0x20 },
+	{ 0x22BB, 0x00 },
+	{ 0x22BC, 0x20 },
+	{ 0x22BD, 0x00 },
+	{ 0x22BE, 0x20 },
+	{ 0x22BF, 0x00 },
+	{ 0x22C0, 0x20 },
+	{ 0x22C1, 0x00 },
+	{ 0x22C2, 0x20 },
+	{ 0x22C3, 0x00 },
+	{ 0x22C4, 0x20 },
+	{ 0x22C5, 0x00 },
+	{ 0x22C6, 0x20 },
+	{ 0x22C7, 0x00 },
+	{ 0x22C8, 0x20 },
+	{ 0x22C9, 0x00 },
+	{ 0x22CA, 0x20 },
+	{ 0x22CB, 0x00 },
+	{ 0x22CC, 0x20 },
+	{ 0x22CD, 0x00 },
+	{ 0x22CE, 0x20 },
+	{ 0x22CF, 0x00 },
+	{ 0x22DA, 0x00 },
+	{ 0x2308, 0x01 },
+	{ 0x2311, 0x09 },
+	{ 0x2318, 0x40 },
+	{ 0x2319, 0xCD },
+	{ 0x231A, 0x54 },
+	{ 0x2324, 0x10 },
+	{ 0x2325, 0x00 },
+	{ 0x2328, 0x00 },
+	{ 0x2354, 0x0C },
+	{ 0x23C0, 0x5D },
+	{ 0x244C, 0x00 },
+	{ 0x244D, 0x02 },
+	{ 0x244E, 0x54 },
+	{ 0x244F, 0x02 },
+	{ 0x24A0, 0x00 },
+	{ 0x24DA, 0x6F },
+	{ 0x24DB, 0x00 },
+	{ 0x24DC, 0x62 },
+	{ 0x24DD, 0x01 },
+	{ 0x24EA, 0x32 },
+	{ 0x24EB, 0x00 },
+	{ 0x24EC, 0xDC },
+	{ 0x24ED, 0x00 },
+	{ 0x24FA, 0x32 },
+	{ 0x24FB, 0x00 },
+	{ 0x24FC, 0xDD },
+	{ 0x24FD, 0x00 },
+	{ 0x254A, 0x15 },
+	{ 0x254B, 0x01 },
+	{ 0x255A, 0x15 },
+	{ 0x255B, 0x01 },
+	{ 0x2560, 0x01 },
+	{ 0x2561, 0x00 },
+	{ 0x2562, 0x2A },
+	{ 0x2563, 0x00 },
+	{ 0x2564, 0xF8 },
+	{ 0x2565, 0x00 },
+	{ 0x2566, 0x15 },
+	{ 0x2567, 0x01 },
+	{ 0x2568, 0x0C },
+	{ 0x2569, 0x02 },
+	{ 0x256A, 0x31 },
+	{ 0x256B, 0x02 },
+	{ 0x2578, 0x90 },
+	{ 0x2579, 0x01 },
+	{ 0x257A, 0x92 },
+	{ 0x257B, 0x01 },
+	{ 0x257C, 0xB8 },
+	{ 0x257D, 0x02 },
+	{ 0x257E, 0xBA },
+	{ 0x257F, 0x02 },
+	{ 0x2584, 0x90 },
+	{ 0x2585, 0x01 },
+	{ 0x2586, 0x92 },
+	{ 0x2587, 0x01 },
+	{ 0x2588, 0xB8 },
+	{ 0x2589, 0x02 },
+	{ 0x258A, 0xBA },
+	{ 0x258B, 0x02 },
+	{ 0x26B8, 0x10 },
+	{ 0x26B9, 0x00 },
+	{ 0x26BA, 0x33 },
+	{ 0x26BB, 0x00 },
+	{ 0x26BC, 0x89 },
+	{ 0x26BD, 0x00 },
+	{ 0x26BE, 0xB0 },
+	{ 0x26BF, 0x00 },
+	{ 0x26C4, 0x4E },
+	{ 0x26C5, 0x00 },
+	{ 0x26C8, 0xC9 },
+	{ 0x26C9, 0x00 },
+	{ 0x26CC, 0x35 },
+	{ 0x26CD, 0x01 },
+	{ 0x26D0, 0xBA },
+	{ 0x26D1, 0x01 },
+	{ 0x26D4, 0x7C },
+	{ 0x26D5, 0x02 },
+	{ 0x26D8, 0xF6 },
+	{ 0x26D9, 0x02 },
+	{ 0x26DE, 0x51 },
+	{ 0x26DF, 0x00 },
+	{ 0x26E0, 0x7F },
+	{ 0x26E1, 0x00 },
+	{ 0x26E2, 0xCC },
+	{ 0x26E3, 0x00 },
+	{ 0x26E4, 0xF8 },
+	{ 0x26E5, 0x00 },
+	{ 0x26E6, 0x38 },
+	{ 0x26E7, 0x01 },
+	{ 0x26E8, 0x65 },
+	{ 0x26E9, 0x01 },
+	{ 0x26EA, 0xBD },
+	{ 0x26EB, 0x01 },
+	{ 0x26EE, 0x7F },
+	{ 0x26EF, 0x02 },
+	{ 0x26F0, 0xAB },
+	{ 0x26F1, 0x02 },
+	{ 0x26F2, 0xF9 },
+	{ 0x26F3, 0x02 },
+	{ 0x2722, 0x59 },
+	{ 0x2723, 0x02 },
+	{ 0x2938, 0x55 },
+	{ 0x2939, 0x00 },
+	{ 0x293A, 0x17 },
+	{ 0x293B, 0x00 },
+	{ 0x293C, 0xD0 },
+	{ 0x293D, 0x00 },
+	{ 0x293E, 0x91 },
+	{ 0x293F, 0x00 },
+	{ 0x2940, 0x3C },
+	{ 0x2941, 0x01 },
+	{ 0x2942, 0x0C },
+	{ 0x2943, 0x01 },
+	{ 0x2944, 0xC1 },
+	{ 0x2945, 0x01 },
+	{ 0x2946, 0x76 },
+	{ 0x2947, 0x01 },
+	{ 0x2948, 0x83 },
+	{ 0x2949, 0x02 },
+	{ 0x294A, 0xFB },
+	{ 0x294B, 0x01 },
+	{ 0x294C, 0xFD },
+	{ 0x294D, 0x02 },
+	{ 0x294E, 0xBF },
+	{ 0x294F, 0x02 },
+	{ 0x2A06, 0xFF },
+	{ 0x2A07, 0x03 },
+	{ 0x2A20, 0x00 },
+	{ 0x2A21, 0x00 },
+	{ 0x2A22, 0x7D },
+	{ 0x2A23, 0x00 },
+	{ 0x2B11, 0x19 },
+	{ 0x2B13, 0x15 },
+	{ 0x2B14, 0x14 },
+	{ 0x2B15, 0x13 },
+	{ 0x2B16, 0x12 },
+	{ 0x2B17, 0x11 },
+	{ 0x2B18, 0x10 },
+	{ 0x2B19, 0x0F },
+	{ 0x2B1A, 0x0E },
+	{ 0x2B1B, 0x0D },
+	{ 0x2B1C, 0x0C },
+	{ 0x2B1D, 0x0B },
+	{ 0x2B1E, 0x0A },
+	{ 0x2B1F, 0x09 },
+	{ 0x2B20, 0x08 },
+	{ 0x2B21, 0x07 },
+	{ 0x2B22, 0x06 },
+	{ 0x2B23, 0x05 },
+	{ 0x2B24, 0x04 },
+	{ 0x2B25, 0x03 },
+	{ 0x2B26, 0x03 },
+	{ 0x2B38, 0x01 },
+	{ 0x2B45, 0xE3 },
+	{ 0x2B50, 0x01 },
+	{ 0x2B51, 0x00 },
+	{ 0x2B6D, 0x47 },
+	{ 0x2B70, 0x02 },
+	{ 0x2B71, 0x02 },
+	{ 0x2B72, 0x02 },
+	{ 0x2B7F, 0x7F },
+	{ 0x2B80, 0x94 },
+	{ 0x2B81, 0x06 },
+	{ 0x2B87, 0x1B },
+	{ 0x2B88, 0x1B },
+	{ 0x2B89, 0x17 },
+	{ 0x2B8A, 0x12 },
+	{ 0x2B8B, 0x12 },
+	{ 0x2B8D, 0x2B },
+	{ 0x2B8E, 0x2B },
+	{ 0x2B8F, 0x2B },
+	{ 0x2B90, 0x7F },
+	{ 0x2B91, 0x1F },
+	{ 0x2B94, 0x7F },
+	{ 0x2B95, 0x27 },
+	{ 0x2B98, 0x7F },
+	{ 0x2B99, 0x57 },
+	{ 0x2BA8, 0xBC },
+	{ 0x2BA9, 0x62 },
+	{ 0x2BC1, 0x70 },
+	{ 0x2BC5, 0x80 },
+	{ 0x2BD5, 0x30 },
+	{ 0x2BD6, 0xF0 },
+	{ 0x2BD8, 0xDB },
+	{ 0x2BD9, 0xF6 },
+	{ 0x2BDA, 0x63 },
+	{ 0x2BDB, 0x0C },
+	{ 0x2BDC, 0x5C },
+	{ 0x2C98, 0xE1 },
+	{ 0x2C99, 0x2E },
+	{ 0x2C9B, 0x86 },
+	{ 0x2CA9, 0x80 },
+	{ 0x2CAA, 0x01 },
+	{ 0x2D39, 0x0E },
+	{ 0x2D54, 0x00 },
+	{ 0x2D5B, 0x58 },
+	{ 0x2D64, 0x64 },
+	{ 0x2D65, 0x80 },
+	{ 0x3000, 0x00 },
+	{ 0x3001, 0x00 },
+	{ 0x3002, 0x23 },
+	{ 0x3003, 0xA1 },
+	{ 0x3004, 0x00 },
+	{ 0x3005, 0x20 },
+	{ 0x3006, 0x84 },
+	{ 0x3007, 0x00 },
+	{ 0x3008, 0x06 },
+	{ 0x3009, 0xB4 },
+	{ 0x300A, 0x1F },
+	{ 0x300B, 0x00 },
+	{ 0x300C, 0x00 },
+	{ 0x300D, 0x1B },
+	{ 0x300E, 0x90 },
+	{ 0x300F, 0x97 },
+	{ 0x3010, 0x00 },
+	{ 0x3011, 0x00 },
+	{ 0x3012, 0x21 },
+	{ 0x3013, 0x21 },
+	{ 0x3014, 0x00 },
+	{ 0x3015, 0x20 },
+	{ 0x3016, 0x84 },
+	{ 0x3017, 0x00 },
+	{ 0x3018, 0x30 },
+	{ 0x3019, 0x09 },
+	{ 0x301A, 0x46 },
+	{ 0x301B, 0x00 },
+	{ 0x3070, 0xC1 },
+	{ 0x3071, 0x81 },
+	{ 0x3072, 0x29 },
+	{ 0x3073, 0x81 },
+	{ 0x3410, (IMX390_OUT_WIDTH & 0xFF) },
+	{ 0x3411, (IMX390_OUT_WIDTH >> 8) },
+	{ 0x3418, (IMX390_OUT_HEIGHT & 0xFF) },
+	{ 0x3419, (IMX390_OUT_HEIGHT >> 8) },
+	{ 0x34A0, 0x30 },
+	{ 0x34C0, 0xD3 },
+	{ 0x34C1, 0x00 },
+	{ 0x34C2, 0xD3 },
+	{ 0x34C3, 0x00 },
+	{ 0x34C4, 0xD3 },
+	{ 0x34C5, 0x00 },
+	{ 0x34C6, 0xD3 },
+	{ 0x34C7, 0x00 },
+	{ 0x34C8, 0xE2 },
+	{ 0x34C9, 0x21 },
+	{ 0x34CA, 0xE0 },
+	{ 0x34CB, 0x1F },
+	{ 0x34CC, 0x06 },
+	{ 0x34CD, 0x20 },
+	{ 0x34CE, 0x28 },
+	{ 0x34CF, 0x1F },
+	{ 0x3584, 0x00 },
+	{ 0x3586, 0x00 },
+	{ 0x3587, 0x01 },
+	{ 0x3588, 0xE6 },
+	{ 0x3589, 0x00 },
+	{ 0x3590, 0x00 },
+	{ 0x3591, 0x00 },
+	{ 0x3594, 0x40 },
+	{ 0x3598, 0x03 },
+	{ 0x3599, 0x00 },
+	{ 0x359A, 0x80 },
+	{ 0x359B, 0x00 },
+	{ 0x359C, 0x00 },
+	{ 0x359D, 0x01 },
+	{ 0x359E, 0x00 },
+	{ 0x359F, 0x02 },
+	{ 0x35A0, 0x00 },
+	{ 0x35A1, 0x04 },
+	{ 0x35A2, 0x20 },
+	{ 0x35A3, 0x00 },
+	{ 0x35A4, 0x40 },
+	{ 0x35A5, 0x00 },
+	{ 0x35A6, 0x80 },
+	{ 0x35A7, 0x00 },
+	{ 0x35A8, 0x00 },
+	{ 0x35A9, 0x01 },
+	{ 0x35AA, 0x3A },
+	{ 0x35AB, 0x00 },
+	{ 0x35AC, 0x80 },
+	{ 0x35AD, 0x00 },
+	{ 0x35AE, 0x00 },
+	{ 0x35AF, 0x01 },
+	{ 0x35B0, 0x00 },
+	{ 0x35B1, 0x02 },
+	{ 0x35B2, 0x00 },
+	{ 0x35B3, 0x04 },
+	{ 0x35B4, 0x02 },
+	{ 0x35B5, 0x00 },
+	{ 0x35B6, 0x04 },
+	{ 0x35B7, 0x00 },
+	{ 0x35B8, 0x08 },
+	{ 0x35B9, 0x00 },
+	{ 0x35BA, 0x10 },
+	{ 0x35BB, 0x00 },
+	{ 0x35BC, 0x03 },
+	{ 0x35BD, 0x00 },
+	{ 0x35C8, 0x00 },
+	{ 0x35C9, 0x01 },
+	{ 0x35CA, 0x00 },
+	{ 0x35CB, 0x04 },
+	{ 0x35CC, 0x00 },
+	{ 0x35CD, 0x10 },
+	{ 0x35CE, 0x00 },
+	{ 0x35CF, 0x40 },
+	{ 0x35D0, 0x00 },
+	{ 0x35D1, 0x0C },
+	{ 0x35D2, 0x00 },
+	{ 0x35D3, 0x0C },
+	{ 0x35D4, 0x00 },
+	{ 0x35D5, 0x0C },
+	{ 0x35D6, 0x00 },
+	{ 0x35D7, 0x0C },
+	{ 0x35D8, 0x00 },
+	{ 0x35D9, 0x00 },
+	{ 0x35DA, 0x08 },
+	{ 0x35DB, 0x00 },
+	{ 0x35DC, 0xD8 },
+	{ 0x35DD, 0x0E },
+	{ 0x35F0, 0x00 },
+	{ 0x35F1, 0x10 },
+	{ 0x35F2, 0x00 },
+	{ 0x35F3, 0x10 },
+	{ 0x35F4, 0x00 },
+	{ 0x35F5, 0x10 },
+	{ 0x35F6, 0x00 },
+	{ 0x35F7, 0x03 },
+	{ 0x35F8, 0x00 },
+	{ 0x35F9, 0x01 },
+	{ 0x35FA, 0x38 },
+	{ 0x35FB, 0x00 },
+	{ 0x35FC, 0xB3 },
+	{ 0x35FD, 0x01 },
+	{ 0x35FE, 0x00 },
+	{ 0x35FF, 0x00 },
+	{ 0x3600, 0x04 },
+	{ 0x3601, 0x06 },
+	{ 0x3604, 0x03 },
+	{ 0x3605, 0x00 },
+	{ 0x3608, 0x03 },
+	{ 0x3609, 0x00 },
+	{ 0x360C, 0x00 },
+	{ 0x360D, 0x00 },
+	{ 0x3610, 0x10 },
+	{ 0x3611, 0x01 },
+	{ 0x3612, 0x00 },
+	{ 0x3613, 0x00 },
+	{ 0x3614, 0x00 },
+	{ 0x3615, 0x00 },
+	{ 0x361C, 0x00 },
+	{ 0x361D, 0x01 },
+	{ 0x361E, 0x00 },
+	{ 0x361F, 0x01 },
+	{ 0x3620, 0x01 },
+	{ 0x3621, 0x00 },
+	{ 0x3622, 0xB0 },
+	{ 0x3623, 0x04 },
+	{ 0x3624, 0xDC },
+	{ 0x3625, 0x05 },
+	{ 0x3626, 0x00 },
+	{ 0x3627, 0x01 },
+	{ 0x3628, 0xFF },
+	{ 0x3629, 0x0F },
+	{ 0x362A, 0x00 },
+	{ 0x362B, 0x10 },
+	{ 0x362C, 0x00 },
+	{ 0x362D, 0x01 },
+	{ 0x3630, 0x40 },
+	{ 0x3631, 0x00 },
+	{ 0x3632, 0x40 },
+	{ 0x3633, 0x00 },
+	{ 0x3634, 0x40 },
+	{ 0x3635, 0x00 },
+	{ 0x3636, 0x40 },
+	{ 0x3637, 0x00 },
+	{ 0x3638, 0x40 },
+	{ 0x3639, 0x00 },
+	{ 0x363A, 0x40 },
+	{ 0x363B, 0x00 },
+	{ 0x363C, 0x40 },
+	{ 0x363D, 0x00 },
+	{ 0x363E, 0x40 },
+	{ 0x363F, 0x00 },
+	{ 0x36C4, 0x99 },
+	{ 0x36C5, 0x09 },
+	{ 0x36C6, 0x18 },
+	{ 0x36C7, 0x07 },
+	{ 0x36C8, 0x65 },
+	{ 0x36C9, 0x0E },
+	{ 0x36CC, 0x99 },
+	{ 0x36CD, 0x01 },
+	{ 0x36CE, 0x47 },
+	{ 0x36CF, 0x00 },
+	{ 0x36D0, 0x04 },
+	{ 0x36D1, 0x00 },
+	{ 0x36D4, 0x65 },
+	{ 0x36D5, 0x0E },
+	{ 0x36D6, 0xA4 },
+	{ 0x36D7, 0x0A },
+	{ 0x36D8, 0x65 },
+	{ 0x36D9, 0x0E },
+	{ 0x36DC, 0x65 },
+	{ 0x36DD, 0x0E },
+	{ 0x36DE, 0xA4 },
+	{ 0x36DF, 0x0A },
+	{ 0x36E0, 0x65 },
+	{ 0x36E1, 0x0E },
+	{ 0x36E4, 0x65 },
+	{ 0x36E5, 0x0E },
+	{ 0x36E6, 0xA4 },
+	{ 0x36E7, 0x0A },
+	{ 0x36E8, 0x65 },
+	{ 0x36E9, 0x0E },
+	{ 0x36EE, 0x00 },
+	{ 0x36EF, 0x00 },
+	{ 0x36F0, 0x00 },
+	{ 0x36F1, 0x80 },
+	{ 0x36F8, 0x00 },
+	{ 0x3702, 0x03 },
+	{ 0x3703, 0x04 },
+	{ 0x3704, 0x08 },
+	{ 0x370E, 0x0E },
+	{ 0x3718, 0x62 },
+	{ 0x3719, 0x4A },
+	{ 0x371A, 0x38 },
+	{ 0x371B, 0x20 },
+	{ 0x371C, 0x64 },
+	{ 0x371D, 0x42 },
+	{ 0x371E, 0x32 },
+	{ 0x371F, 0x1B },
+	{ 0x3720, 0x9C },
+	{ 0x3721, 0xA4 },
+	{ 0x3722, 0xAC },
+	{ 0x3723, 0xB4 },
+	{ 0x3748, 0xAA },
+	{ 0x3749, 0x96 },
+	{ 0x374A, 0x7D },
+	{ 0x374B, 0x69 },
+	{ 0x37C0, 0x00 },
+	{ 0x37C1, 0x00 },
+	{ 0x37C2, 0x00 },
+	{ 0x37C4, 0x00 },
+	{ 0x37C5, 0x00 },
+	{ 0x37C6, 0x00 },
+	{ 0x37C8, 0x00 },
+	{ 0x37C9, 0x00 },
+	{ 0x37CA, 0x00 },
+	{ 0x37CC, 0x00 },
+	{ 0x37CD, 0x00 },
+	{ 0x37CE, 0x00 },
+	{ 0x37D0, 0x00 },
+	{ 0x37D1, 0x00 },
+	{ 0x37D2, 0x00 },
+	{ 0x37D4, 0x00 },
+	{ 0x37D5, 0x00 },
+	{ 0x37D6, 0x00 },
+	{ 0x37D8, 0x00 },
+	{ 0x37D9, 0x00 },
+	{ 0x37DA, 0x00 },
+	{ 0x37DC, 0x00 },
+	{ 0x37DD, 0x00 },
+	{ 0x37DE, 0x00 },
+	{ 0x37E0, 0x00 },
+	{ 0x37E1, 0x00 },
+	{ 0x37E2, 0x00 },
+	{ 0x37E4, 0x00 },
+	{ 0x37E5, 0x00 },
+	{ 0x37E6, 0x00 },
+	{ 0x37E8, 0x00 },
+	{ 0x37E9, 0x00 },
+	{ 0x37EA, 0x00 },
+	{ 0x37EC, 0x00 },
+	{ 0x37ED, 0x00 },
+	{ 0x37EE, 0x00 },
+	{ 0x37F0, 0x00 },
+	{ 0x37F4, 0x00 },
+	{ 0x37F5, 0x1E },
+	{ 0x37F6, 0x34 },
+	{ 0x37F7, 0x00 },
+	{ 0x37F8, 0xFF },
+	{ 0x37F9, 0xFF },
+	{ 0x37FA, 0x03 },
+	{ 0x37FC, 0x00 },
+	{ 0x37FD, 0x00 },
+	{ 0x37FE, 0x04 },
+	{ 0x3800, 0xFF },
+	{ 0x3801, 0xFF },
+	{ 0x3802, 0x03 },
+	{ 0x3804, 0x00 },
+	{ 0x3805, 0x00 },
+	{ 0x3806, 0x04 },
+	{ 0x3808, 0x00 },
+	{ 0x3809, 0x00 },
+	{ 0x380A, 0x00 },
+	{ 0x380C, 0x00 },
+	{ 0x380D, 0x00 },
+	{ 0x380E, 0x00 },
+	{ 0x3810, 0x00 },
+	{ 0x3811, 0x00 },
+	{ 0x3812, 0x00 },
+	{ 0x3814, 0x00 },
+	{ 0x3815, 0x00 },
+	{ 0x3816, 0x00 },
+	{ 0x3818, 0x00 },
+	{ 0x3819, 0x00 },
+	{ 0x381A, 0x00 },
+	{ 0x381C, 0x00 },
+	{ 0x381D, 0x00 },
+	{ 0x381E, 0x00 },
+	{ 0x3820, 0x00 },
+	{ 0x3821, 0x00 },
+	{ 0x3822, 0x00 },
+	{ 0x3824, 0x00 },
+	{ 0x3825, 0x00 },
+	{ 0x3826, 0x00 },
+	{ 0x3828, 0x00 },
+	{ 0x3829, 0x00 },
+	{ 0x382A, 0x00 },
+	{ 0x382C, 0x00 },
+	{ 0x382D, 0x00 },
+	{ 0x382E, 0x00 },
+	{ 0x3830, 0x00 },
+	{ 0x3831, 0x00 },
+	{ 0x3832, 0x00 },
+	{ 0x3834, 0x00 },
+	{ 0x3835, 0x00 },
+	{ 0x3836, 0x00 },
+	{ 0x3838, 0x00 },
+	{ 0x3839, 0x00 },
+	{ 0x383A, 0x00 },
+	{ 0x383B, 0x00 },
+	{ 0x383C, 0x00 },
+	{ 0x383D, 0x00 },
+	{ 0x383E, 0x00 },
+	{ 0x383F, 0x00 },
+	{ 0x3840, 0x00 },
+	{ 0x3841, 0x00 },
+	{ 0x3842, 0x00 },
+	{ 0x3843, 0x00 },
+	{ 0x3844, 0x00 },
+	{ 0x3845, 0x00 },
+	{ 0x3846, 0x00 },
+	{ 0x3847, 0x00 },
+	{ 0x3848, 0x00 },
+	{ 0x3849, 0x00 },
+	{ 0x384A, 0x00 },
+	{ 0x384B, 0x00 },
+	{ 0x384C, 0x00 },
+	{ 0x384D, 0x00 },
+	{ 0x384E, 0x00 },
+	{ 0x384F, 0x00 },
+	{ 0x3850, 0xFF },
+	{ 0x3851, 0x0F },
+	{ 0x3852, 0x00 },
+	{ 0x3853, 0x10 },
+	{ 0x3854, 0xFF },
+	{ 0x3855, 0x0F },
+	{ 0x3856, 0x00 },
+	{ 0x3857, 0x10 },
+	{ 0x3858, 0xFF },
+	{ 0x3859, 0x0F },
+	{ 0x385A, 0x00 },
+	{ 0x385B, 0x10 },
+	{ 0x385C, 0x02 },
+	{ 0x385D, 0x00 },
+	{ 0x385E, 0x06 },
+	{ 0x385F, 0x00 },
+	{ 0x3860, 0x06 },
+	{ 0x3861, 0x00 },
+	{ 0x3862, 0x08 },
+	{ 0x3863, 0x00 },
+	{ 0x3864, 0x02 },
+	{ 0x3865, 0x00 },
+	{ 0x38A0, 0x01 },
+	{ 0x38A1, 0x01 },
+	{ 0x38A2, 0x00 },
+	{ 0x38A3, 0x01 },
+	{ 0x38A4, 0x07 },
+	{ 0x38A5, 0x00 },
+	{ 0x38A6, 0x04 },
+	{ 0x38A7, 0x05 },
+	{ 0x38A8, 0x00 },
+	{ 0x38A9, 0x00 },
+	{ 0x38AC, 0x00 },
+	{ 0x38AD, 0x00 },
+	{ 0x38AE, 0x01 },
+	{ 0x38B0, 0x02 },
+	{ 0x38B2, 0x22 },
+	{ 0x38B3, 0x00 },
+	{ 0x38B4, 0x17 },
+	{ 0x38B5, 0x00 },
+	{ 0x38B6, 0x11 },
+	{ 0x38B7, 0x00 },
+	{ 0x38B8, 0x0E },
+	{ 0x38B9, 0x00 },
+	{ 0x38BA, 0x2A },
+	{ 0x38BB, 0x00 },
+	{ 0x38BC, 0x1C },
+	{ 0x38BD, 0x00 },
+	{ 0x38BE, 0x14 },
+	{ 0x38BF, 0x00 },
+	{ 0x38C0, 0x10 },
+	{ 0x38C1, 0x00 },
+	{ 0x38C2, 0x31 },
+	{ 0x38C3, 0x00 },
+	{ 0x38C4, 0x21 },
+	{ 0x38C5, 0x00 },
+	{ 0x38C6, 0x18 },
+	{ 0x38C7, 0x00 },
+	{ 0x38C8, 0x12 },
+	{ 0x38C9, 0x00 },
+	{ 0x38CA, 0x3C },
+	{ 0x38CB, 0x00 },
+	{ 0x38CC, 0x29 },
+	{ 0x38CD, 0x00 },
+	{ 0x38CE, 0x1D },
+	{ 0x38CF, 0x00 },
+	{ 0x38D0, 0x15 },
+	{ 0x38D1, 0x00 },
+	{ 0x38D2, 0x4E },
+	{ 0x38D3, 0x00 },
+	{ 0x38D4, 0x35 },
+	{ 0x38D5, 0x00 },
+	{ 0x38D6, 0x26 },
+	{ 0x38D7, 0x00 },
+	{ 0x38D8, 0x1A },
+	{ 0x38D9, 0x00 },
+	{ 0x38DA, 0x69 },
+	{ 0x38DB, 0x00 },
+	{ 0x38DC, 0x48 },
+	{ 0x38DD, 0x00 },
+	{ 0x38DE, 0x33 },
+	{ 0x38DF, 0x00 },
+	{ 0x38E0, 0x22 },
+	{ 0x38E1, 0x00 },
+	{ 0x38E2, 0x93 },
+	{ 0x38E3, 0x00 },
+	{ 0x38E4, 0x64 },
+	{ 0x38E5, 0x00 },
+	{ 0x38E6, 0x48 },
+	{ 0x38E7, 0x00 },
+	{ 0x38E8, 0x30 },
+	{ 0x38E9, 0x00 },
+	{ 0x38EA, 0xD3 },
+	{ 0x38EB, 0x00 },
+	{ 0x38EC, 0x90 },
+	{ 0x38ED, 0x00 },
+	{ 0x38EE, 0x69 },
+	{ 0x38EF, 0x00 },
+	{ 0x38F0, 0x49 },
+	{ 0x38F1, 0x00 },
+	{ 0x38F2, 0x39 },
+	{ 0x38F3, 0x01 },
+	{ 0x38F4, 0xD5 },
+	{ 0x38F5, 0x00 },
+	{ 0x38F6, 0x9F },
+	{ 0x38F7, 0x00 },
+	{ 0x38F8, 0x75 },
+	{ 0x38F9, 0x00 },
+	{ 0x38FA, 0x00 },
+	{ 0x38FB, 0x01 },
+	{ 0x38FC, 0x00 },
+	{ 0x38FD, 0x01 },
+	{ 0x38FE, 0x00 },
+	{ 0x38FF, 0x01 },
+	{ 0x3900, 0x00 },
+	{ 0x3901, 0x01 },
+	{ 0x3902, 0x70 },
+	{ 0x3903, 0x00 },
+	{ 0x3904, 0x30 },
+	{ 0x3905, 0x00 },
+	{ 0x3906, 0x25 },
+	{ 0x3907, 0x00 },
+	{ 0x3908, 0x20 },
+	{ 0x3909, 0x00 },
+	{ 0x390A, 0xB2 },
+	{ 0x390B, 0x00 },
+	{ 0x390C, 0x80 },
+	{ 0x390D, 0x00 },
+	{ 0x390E, 0x70 },
+	{ 0x390F, 0x00 },
+	{ 0x3910, 0x50 },
+	{ 0x3911, 0x00 },
+	{ 0x3912, 0xB2 },
+	{ 0x3913, 0x00 },
+	{ 0x3914, 0x80 },
+	{ 0x3915, 0x00 },
+	{ 0x3916, 0x70 },
+	{ 0x3917, 0x00 },
+	{ 0x3918, 0x50 },
+	{ 0x3919, 0x00 },
+	{ 0x391A, 0xB2 },
+	{ 0x391B, 0x00 },
+	{ 0x391C, 0x80 },
+	{ 0x391D, 0x00 },
+	{ 0x391E, 0x70 },
+	{ 0x391F, 0x00 },
+	{ 0x3920, 0x50 },
+	{ 0x3921, 0x00 },
+	{ 0x3922, 0x40 },
+	{ 0x3923, 0x00 },
+	{ 0x3924, 0x40 },
+	{ 0x3925, 0x00 },
+	{ 0x3926, 0x40 },
+	{ 0x3927, 0x00 },
+	{ 0x3928, 0x40 },
+	{ 0x3929, 0x00 },
+	{ 0x392A, 0x80 },
+	{ 0x392B, 0x00 },
+	{ 0x392C, 0x80 },
+	{ 0x392D, 0x00 },
+	{ 0x392E, 0x80 },
+	{ 0x392F, 0x00 },
+	{ 0x3930, 0x80 },
+	{ 0x3931, 0x00 },
+	{ 0x3932, 0x80 },
+	{ 0x3933, 0x80 },
+	{ 0x3934, 0x80 },
+	{ 0x3940, 0x01 },
+	{ 0x3941, 0x01 },
+	{ 0x3942, 0x00 },
+	{ 0x3943, 0x01 },
+	{ 0x3944, 0x07 },
+	{ 0x3945, 0x00 },
+	{ 0x3946, 0x04 },
+	{ 0x3947, 0x05 },
+	{ 0x3948, 0x00 },
+	{ 0x3949, 0x00 },
+	{ 0x394C, 0x00 },
+	{ 0x394D, 0x00 },
+	{ 0x394E, 0x01 },
+	{ 0x3950, 0x03 },
+	{ 0x3952, 0x14 },
+	{ 0x3953, 0x00 },
+	{ 0x3954, 0x0F },
+	{ 0x3955, 0x00 },
+	{ 0x3956, 0x0E },
+	{ 0x3957, 0x00 },
+	{ 0x3958, 0x0E },
+	{ 0x3959, 0x00 },
+	{ 0x395A, 0x19 },
+	{ 0x395B, 0x00 },
+	{ 0x395C, 0x11 },
+	{ 0x395D, 0x00 },
+	{ 0x395E, 0x0F },
+	{ 0x395F, 0x00 },
+	{ 0x3960, 0x0E },
+	{ 0x3961, 0x00 },
+	{ 0x3962, 0x1C },
+	{ 0x3963, 0x00 },
+	{ 0x3964, 0x13 },
+	{ 0x3965, 0x00 },
+	{ 0x3966, 0x0F },
+	{ 0x3967, 0x00 },
+	{ 0x3968, 0x0E },
+	{ 0x3969, 0x00 },
+	{ 0x396A, 0x23 },
+	{ 0x396B, 0x00 },
+	{ 0x396C, 0x15 },
+	{ 0x396D, 0x00 },
+	{ 0x396E, 0x11 },
+	{ 0x396F, 0x00 },
+	{ 0x3970, 0x0E },
+	{ 0x3971, 0x00 },
+	{ 0x3972, 0x2E },
+	{ 0x3973, 0x00 },
+	{ 0x3974, 0x1A },
+	{ 0x3975, 0x00 },
+	{ 0x3976, 0x14 },
+	{ 0x3977, 0x00 },
+	{ 0x3978, 0x0F },
+	{ 0x3979, 0x00 },
+	{ 0x397A, 0x3E },
+	{ 0x397B, 0x00 },
+	{ 0x397C, 0x23 },
+	{ 0x397D, 0x00 },
+	{ 0x397E, 0x1A },
+	{ 0x397F, 0x00 },
+	{ 0x3980, 0x12 },
+	{ 0x3981, 0x00 },
+	{ 0x3982, 0x56 },
+	{ 0x3983, 0x00 },
+	{ 0x3984, 0x31 },
+	{ 0x3985, 0x00 },
+	{ 0x3986, 0x25 },
+	{ 0x3987, 0x00 },
+	{ 0x3988, 0x1A },
+	{ 0x3989, 0x00 },
+	{ 0x398A, 0x7B },
+	{ 0x398B, 0x00 },
+	{ 0x398C, 0x49 },
+	{ 0x398D, 0x00 },
+	{ 0x398E, 0x39 },
+	{ 0x398F, 0x00 },
+	{ 0x3990, 0x2C },
+	{ 0x3991, 0x00 },
+	{ 0x3992, 0xB4 },
+	{ 0x3993, 0x00 },
+	{ 0x3994, 0x75 },
+	{ 0x3995, 0x00 },
+	{ 0x3996, 0x61 },
+	{ 0x3997, 0x00 },
+	{ 0x3998, 0x53 },
+	{ 0x3999, 0x00 },
+	{ 0x399A, 0x00 },
+	{ 0x399B, 0x01 },
+	{ 0x399C, 0x00 },
+	{ 0x399D, 0x01 },
+	{ 0x399E, 0x00 },
+	{ 0x399F, 0x01 },
+	{ 0x39A0, 0x00 },
+	{ 0x39A1, 0x01 },
+	{ 0x39A2, 0x70 },
+	{ 0x39A3, 0x00 },
+	{ 0x39A4, 0x30 },
+	{ 0x39A5, 0x00 },
+	{ 0x39A6, 0x25 },
+	{ 0x39A7, 0x00 },
+	{ 0x39A8, 0x20 },
+	{ 0x39A9, 0x00 },
+	{ 0x39AA, 0xB2 },
+	{ 0x39AB, 0x00 },
+	{ 0x39AC, 0x80 },
+	{ 0x39AD, 0x00 },
+	{ 0x39AE, 0x70 },
+	{ 0x39AF, 0x00 },
+	{ 0x39B0, 0x80 },
+	{ 0x39B1, 0x00 },
+	{ 0x39B2, 0xB2 },
+	{ 0x39B3, 0x00 },
+	{ 0x39B4, 0x80 },
+	{ 0x39B5, 0x00 },
+	{ 0x39B6, 0x70 },
+	{ 0x39B7, 0x00 },
+	{ 0x39B8, 0x80 },
+	{ 0x39B9, 0x00 },
+	{ 0x39BA, 0xB2 },
+	{ 0x39BB, 0x00 },
+	{ 0x39BC, 0x80 },
+	{ 0x39BD, 0x00 },
+	{ 0x39BE, 0x70 },
+	{ 0x39BF, 0x00 },
+	{ 0x39C0, 0x80 },
+	{ 0x39C1, 0x00 },
+	{ 0x39C2, 0x40 },
+	{ 0x39C3, 0x00 },
+	{ 0x39C4, 0x40 },
+	{ 0x39C5, 0x00 },
+	{ 0x39C6, 0x40 },
+	{ 0x39C7, 0x00 },
+	{ 0x39C8, 0x40 },
+	{ 0x39C9, 0x00 },
+	{ 0x39CA, 0x80 },
+	{ 0x39CB, 0x00 },
+	{ 0x39CC, 0x80 },
+	{ 0x39CD, 0x00 },
+	{ 0x39CE, 0x80 },
+	{ 0x39CF, 0x00 },
+	{ 0x39D0, 0x80 },
+	{ 0x39D1, 0x00 },
+	{ 0x39D2, 0x80 },
+	{ 0x39D3, 0x80 },
+	{ 0x39D4, 0x80 },
+	{ 0x39E0, 0x01 },
+	{ 0x39E1, 0x00 },
+	{ 0x39E4, 0x40 },
+	{ 0x39E5, 0x01 },
+	{ 0x39E6, 0x01 },
+	{ 0x39E8, 0x00 },
+	{ 0x39E9, 0x01 },
+	{ 0x39EA, 0x00 },
+	{ 0x39EB, 0x00 },
+	{ 0x39EC, 0x01 },
+	{ 0x39ED, 0x00 },
+	{ 0x39EE, 0x01 },
+	{ 0x39F0, 0x03 },
+	{ 0x39F1, 0x04 },
+	{ 0x39F2, 0x0E },
+	{ 0x39F4, 0x1C },
+	{ 0x39F5, 0x00 },
+	{ 0x39F6, 0x13 },
+	{ 0x39F7, 0x00 },
+	{ 0x39F8, 0x0D },
+	{ 0x39F9, 0x00 },
+	{ 0x39FA, 0x07 },
+	{ 0x39FB, 0x00 },
+	{ 0x39FC, 0x38 },
+	{ 0x39FD, 0x00 },
+	{ 0x39FE, 0x1C },
+	{ 0x39FF, 0x00 },
+	{ 0x3A00, 0x11 },
+	{ 0x3A01, 0x00 },
+	{ 0x3A02, 0x08 },
+	{ 0x3A03, 0x00 },
+	{ 0x3A04, 0x4A },
+	{ 0x3A05, 0x00 },
+	{ 0x3A06, 0x23 },
+	{ 0x3A07, 0x00 },
+	{ 0x3A08, 0x15 },
+	{ 0x3A09, 0x00 },
+	{ 0x3A0A, 0x09 },
+	{ 0x3A0B, 0x00 },
+	{ 0x3A0C, 0x65 },
+	{ 0x3A0D, 0x00 },
+	{ 0x3A0E, 0x2D },
+	{ 0x3A0F, 0x00 },
+	{ 0x3A10, 0x1A },
+	{ 0x3A11, 0x00 },
+	{ 0x3A12, 0x0B },
+	{ 0x3A13, 0x00 },
+	{ 0x3A14, 0x8D },
+	{ 0x3A15, 0x00 },
+	{ 0x3A16, 0x3D },
+	{ 0x3A17, 0x00 },
+	{ 0x3A18, 0x23 },
+	{ 0x3A19, 0x00 },
+	{ 0x3A1A, 0x0E },
+	{ 0x3A1B, 0x00 },
+	{ 0x3A1C, 0xC5 },
+	{ 0x3A1D, 0x00 },
+	{ 0x3A1E, 0x55 },
+	{ 0x3A1F, 0x00 },
+	{ 0x3A20, 0x30 },
+	{ 0x3A21, 0x00 },
+	{ 0x3A22, 0x13 },
+	{ 0x3A23, 0x00 },
+	{ 0x3A24, 0x16 },
+	{ 0x3A25, 0x01 },
+	{ 0x3A26, 0x76 },
+	{ 0x3A27, 0x00 },
+	{ 0x3A28, 0x42 },
+	{ 0x3A29, 0x00 },
+	{ 0x3A2A, 0x1A },
+	{ 0x3A2B, 0x00 },
+	{ 0x3A2C, 0x88 },
+	{ 0x3A2D, 0x01 },
+	{ 0x3A2E, 0xA7 },
+	{ 0x3A2F, 0x00 },
+	{ 0x3A30, 0x5D },
+	{ 0x3A31, 0x00 },
+	{ 0x3A32, 0x24 },
+	{ 0x3A33, 0x00 },
+	{ 0x3A34, 0x2A },
+	{ 0x3A35, 0x02 },
+	{ 0x3A36, 0xEB },
+	{ 0x3A37, 0x00 },
+	{ 0x3A38, 0x83 },
+	{ 0x3A39, 0x00 },
+	{ 0x3A3A, 0x32 },
+	{ 0x3A3B, 0x00 },
+	{ 0x3A3C, 0x00 },
+	{ 0x3A3D, 0x01 },
+	{ 0x3A3E, 0x00 },
+	{ 0x3A3F, 0x01 },
+	{ 0x3A40, 0x00 },
+	{ 0x3A41, 0x01 },
+	{ 0x3A42, 0x00 },
+	{ 0x3A43, 0x01 },
+	{ 0x3A44, 0x80 },
+	{ 0x3A45, 0x00 },
+	{ 0x3A46, 0x50 },
+	{ 0x3A47, 0x00 },
+	{ 0x3A48, 0x30 },
+	{ 0x3A49, 0x00 },
+	{ 0x3A4A, 0x20 },
+	{ 0x3A4B, 0x00 },
+	{ 0x3A4C, 0x99 },
+	{ 0x3A4D, 0x00 },
+	{ 0x3A4E, 0x80 },
+	{ 0x3A4F, 0x00 },
+	{ 0x3A50, 0x80 },
+	{ 0x3A51, 0x00 },
+	{ 0x3A52, 0x80 },
+	{ 0x3A53, 0x00 },
+	{ 0x3A54, 0x99 },
+	{ 0x3A55, 0x00 },
+	{ 0x3A56, 0x80 },
+	{ 0x3A57, 0x00 },
+	{ 0x3A58, 0x80 },
+	{ 0x3A59, 0x00 },
+	{ 0x3A5A, 0x80 },
+	{ 0x3A5B, 0x00 },
+	{ 0x3A5C, 0x99 },
+	{ 0x3A5D, 0x00 },
+	{ 0x3A5E, 0x80 },
+	{ 0x3A5F, 0x00 },
+	{ 0x3A60, 0x80 },
+	{ 0x3A61, 0x00 },
+	{ 0x3A62, 0x80 },
+	{ 0x3A63, 0x00 },
+	{ 0x3A64, 0x1C },
+	{ 0x3A65, 0x00 },
+	{ 0x3A66, 0x13 },
+	{ 0x3A67, 0x00 },
+	{ 0x3A68, 0x0D },
+	{ 0x3A69, 0x00 },
+	{ 0x3A6A, 0x07 },
+	{ 0x3A6B, 0x00 },
+	{ 0x3A6C, 0x0C },
+	{ 0x3A6D, 0x00 },
+	{ 0x3A6E, 0x09 },
+	{ 0x3A6F, 0x00 },
+	{ 0x3A70, 0x06 },
+	{ 0x3A71, 0x00 },
+	{ 0x3A72, 0x03 },
+	{ 0x3A73, 0x00 },
+	{ 0x3A74, 0x1F },
+	{ 0x3A75, 0x00 },
+	{ 0x3A76, 0x1B },
+	{ 0x3A77, 0x00 },
+	{ 0x3A78, 0x0F },
+	{ 0x3A79, 0x00 },
+	{ 0x3A7A, 0x08 },
+	{ 0x3A7B, 0x00 },
+	{ 0x3A7C, 0x80 },
+	{ 0x3A7D, 0x00 },
+	{ 0x3A7E, 0x80 },
+	{ 0x3A7F, 0x00 },
+	{ 0x3A80, 0x80 },
+	{ 0x3A81, 0x00 },
+	{ 0x3A82, 0x80 },
+	{ 0x3A83, 0x00 },
+	{ 0x3A84, 0x09 },
+	{ 0x3A85, 0x00 },
+	{ 0x3A86, 0x04 },
+	{ 0x3A87, 0x00 },
+	{ 0x3A88, 0x03 },
+	{ 0x3A89, 0x00 },
+	{ 0x3A8A, 0x01 },
+	{ 0x3A8B, 0x00 },
+	{ 0x3A8C, 0x19 },
+	{ 0x3A8D, 0x01 },
+	{ 0x3A8E, 0xD2 },
+	{ 0x3A8F, 0x00 },
+	{ 0x3A90, 0x8C },
+	{ 0x3A91, 0x00 },
+	{ 0x3A92, 0x64 },
+	{ 0x3A93, 0x00 },
+	{ 0x3A94, 0xFF },
+	{ 0x3A95, 0x00 },
+	{ 0x3A96, 0xD2 },
+	{ 0x3A97, 0x00 },
+	{ 0x3A98, 0x8C },
+	{ 0x3A99, 0x00 },
+	{ 0x3A9A, 0x64 },
+	{ 0x3A9B, 0x00 },
+	{ 0x3A9C, 0x08 },
+	{ 0x3A9D, 0x10 },
+	{ 0x3A9E, 0x80 },
+	{ 0x3A9F, 0x80 },
+	{ 0x3AA0, 0x80 },
+	{ 0x3AA1, 0x04 },
+	{ 0x3AA2, 0x05 },
+	{ 0x3AC0, 0x01 },
+	{ 0x3AC4, 0x81 },
+	{ 0x3AC5, 0x00 },
+	{ 0x3AC6, 0x00 },
+	{ 0x3AC7, 0x00 },
+	{ 0x3AC8, 0x00 },
+	{ 0x3AC9, 0x00 },
+	{ 0x3ACA, 0x00 },
+	{ 0x3ACB, 0x00 },
+	{ 0x3ACC, 0x02 },
+	{ 0x3ACD, 0x00 },
+	{ 0x3ACE, 0x81 },
+	{ 0x3ACF, 0x00 },
+	{ 0x3AD0, 0x00 },
+	{ 0x3AD1, 0x00 },
+	{ 0x3AD2, 0xFD },
+	{ 0x3AD3, 0x03 },
+	{ 0x3AD4, 0x02 },
+	{ 0x3AD5, 0x00 },
+	{ 0x3AD6, 0x00 },
+	{ 0x3AD7, 0x00 },
+	{ 0x3AD8, 0x81 },
+	{ 0x3AD9, 0x00 },
+	{ 0x3ADA, 0xFD },
+	{ 0x3ADB, 0x03 },
+	{ 0x3ADC, 0xFF },
+	{ 0x3ADD, 0x03 },
+	{ 0x3ADE, 0x01 },
+	{ 0x3ADF, 0x00 },
+	{ 0x3AE0, 0x01 },
+	{ 0x3AE1, 0x00 },
+	{ 0x3AE2, 0x7E },
+	{ 0x3AE3, 0x00 },
+	{ 0x3AF4, 0x00 },
+	{ 0x3AF6, 0x40 },
+	{ 0x3AF7, 0x1E },
+	{ 0x3AF8, 0x01 },
+	{ 0x3AFA, 0x63 },
+	{ 0x3AFB, 0x09 },
+	{ 0x3AFC, 0x11 },
+	{ 0x3AFD, 0x09 },
+	{ 0x3AFE, 0x00 },
+	{ 0x3AFF, 0x00 },
+	{ 0x3B00, 0x00 },
+	{ 0x3B01, 0x00 },
+	{ 0x3B02, 0x84 },
+	{ 0x3B03, 0x06 },
+	{ 0x3B04, 0x30 },
+	{ 0x3B05, 0x06 },
+	{ 0x3B06, 0x00 },
+	{ 0x3B07, 0x00 },
+	{ 0x3B08, 0x00 },
+	{ 0x3B09, 0x00 },
+	{ 0x3B0A, 0x00 },
+	{ 0x3B0B, 0x00 },
+	{ 0x3B0C, 0x00 },
+	{ 0x3B0D, 0x00 },
+	{ 0x3B0E, 0x00 },
+	{ 0x3B0F, 0x00 },
+	{ 0x3B10, 0x00 },
+	{ 0x3B11, 0x00 },
+	{ 0x3B12, 0x00 },
+	{ 0x3B13, 0x00 },
+	{ 0x3B14, 0x00 },
+	{ 0x3B15, 0x00 },
+	{ 0x3B16, 0x00 },
+	{ 0x3B17, 0x00 },
+	{ 0x3B18, 0x00 },
+	{ 0x3B19, 0x00 },
+	{ 0x3B1A, 0x00 },
+	{ 0x3B1B, 0x00 },
+	{ 0x3B1C, 0x00 },
+	{ 0x3B1D, 0x00 },
+	{ 0x3B1E, 0x00 },
+	{ 0x3B1F, 0x00 },
+	{ 0x3B20, 0x00 },
+	{ 0x3B21, 0x00 },
+	{ 0x3B22, 0x00 },
+	{ 0x3B23, 0x00 },
+	{ 0x3B24, 0x00 },
+	{ 0x3B25, 0x00 },
+	{ 0x3B26, 0x00 },
+	{ 0x3B27, 0x00 },
+	{ 0x3B28, 0x00 },
+	{ 0x3B29, 0x00 },
+	{ 0x3B2A, 0x00 },
+	{ 0x3B2C, 0x00 },
+	{ 0x3B2E, 0x00 },
+	{ 0x3B30, 0x00 },
+	{ 0x3B32, 0x0C },
+	{ 0x4000, 0xD1 },
+	{ 0x4001, 0xC0 },
+	{ 0x4002, 0xC0 },
+	{ 0x4003, 0xB8 },
+	{ 0x4004, 0xC0 },
+	{ 0x4005, 0xB8 },
+	{ 0x4006, 0xB9 },
+	{ 0x4007, 0xB7 },
+	{ 0x4008, 0xB0 },
+	{ 0x4009, 0xAB },
+	{ 0x400A, 0xAC },
+	{ 0x400B, 0xAB },
+	{ 0x400C, 0xA8 },
+	{ 0x400D, 0xA6 },
+	{ 0x400E, 0xA6 },
+	{ 0x400F, 0xA5 },
+	{ 0x4010, 0xA2 },
+	{ 0x4011, 0xA0 },
+	{ 0x4012, 0xA0 },
+	{ 0x4013, 0x9F },
+	{ 0x4014, 0xA4 },
+	{ 0x4015, 0xA2 },
+	{ 0x4016, 0xA2 },
+	{ 0x4017, 0x9C },
+	{ 0x4018, 0xA8 },
+	{ 0x4019, 0xA6 },
+	{ 0x401A, 0xA8 },
+	{ 0x401B, 0xAA },
+	{ 0x401C, 0xB0 },
+	{ 0x401D, 0xAE },
+	{ 0x401E, 0xAE },
+	{ 0x401F, 0xAE },
+	{ 0x4020, 0xBA },
+	{ 0x4021, 0xAE },
+	{ 0x4022, 0xAF },
+	{ 0x4023, 0xAE },
+	{ 0x4024, 0xC6 },
+	{ 0x4025, 0xBD },
+	{ 0x4026, 0xBD },
+	{ 0x4027, 0xBA },
+	{ 0x4028, 0xB0 },
+	{ 0x4029, 0xA9 },
+	{ 0x402A, 0xAA },
+	{ 0x402B, 0xA8 },
+	{ 0x402C, 0x9F },
+	{ 0x402D, 0x9C },
+	{ 0x402E, 0x9C },
+	{ 0x402F, 0x9B },
+	{ 0x4030, 0x93 },
+	{ 0x4031, 0x91 },
+	{ 0x4032, 0x92 },
+	{ 0x4033, 0x91 },
+	{ 0x4034, 0x8D },
+	{ 0x4035, 0x8C },
+	{ 0x4036, 0x8C },
+	{ 0x4037, 0x8C },
+	{ 0x4038, 0x8F },
+	{ 0x4039, 0x8E },
+	{ 0x403A, 0x8E },
+	{ 0x403B, 0x8E },
+	{ 0x403C, 0x98 },
+	{ 0x403D, 0x96 },
+	{ 0x403E, 0x96 },
+	{ 0x403F, 0x95 },
+	{ 0x4040, 0xA4 },
+	{ 0x4041, 0xA0 },
+	{ 0x4042, 0xA0 },
+	{ 0x4043, 0x9E },
+	{ 0x4044, 0xB3 },
+	{ 0x4045, 0xAE },
+	{ 0x4046, 0xAF },
+	{ 0x4047, 0xAB },
+	{ 0x4048, 0xC2 },
+	{ 0x4049, 0xB7 },
+	{ 0x404A, 0xB8 },
+	{ 0x404B, 0xB5 },
+	{ 0x404C, 0xAB },
+	{ 0x404D, 0xA4 },
+	{ 0x404E, 0xA5 },
+	{ 0x404F, 0xA3 },
+	{ 0x4050, 0x99 },
+	{ 0x4051, 0x96 },
+	{ 0x4052, 0x96 },
+	{ 0x4053, 0x96 },
+	{ 0x4054, 0x8B },
+	{ 0x4055, 0x8A },
+	{ 0x4056, 0x8A },
+	{ 0x4057, 0x8A },
+	{ 0x4058, 0x82 },
+	{ 0x4059, 0x81 },
+	{ 0x405A, 0x81 },
+	{ 0x405B, 0x81 },
+	{ 0x405C, 0x85 },
+	{ 0x405D, 0x86 },
+	{ 0x405E, 0x85 },
+	{ 0x405F, 0x85 },
+	{ 0x4060, 0x90 },
+	{ 0x4061, 0x90 },
+	{ 0x4062, 0x8F },
+	{ 0x4063, 0x8F },
+	{ 0x4064, 0x9D },
+	{ 0x4065, 0x9B },
+	{ 0x4066, 0x9B },
+	{ 0x4067, 0x9A },
+	{ 0x4068, 0xAF },
+	{ 0x4069, 0xAA },
+	{ 0x406A, 0xAC },
+	{ 0x406B, 0xAA },
+	{ 0x406C, 0xC2 },
+	{ 0x406D, 0xB7 },
+	{ 0x406E, 0xB8 },
+	{ 0x406F, 0xB5 },
+	{ 0x4070, 0xAB },
+	{ 0x4071, 0xA4 },
+	{ 0x4072, 0xA4 },
+	{ 0x4073, 0xA3 },
+	{ 0x4074, 0x99 },
+	{ 0x4075, 0x96 },
+	{ 0x4076, 0x96 },
+	{ 0x4077, 0x96 },
+	{ 0x4078, 0x8B },
+	{ 0x4079, 0x8A },
+	{ 0x407A, 0x8A },
+	{ 0x407B, 0x8A },
+	{ 0x407C, 0x82 },
+	{ 0x407D, 0x82 },
+	{ 0x407E, 0x82 },
+	{ 0x407F, 0x82 },
+	{ 0x4080, 0x85 },
+	{ 0x4081, 0x86 },
+	{ 0x4082, 0x86 },
+	{ 0x4083, 0x86 },
+	{ 0x4084, 0x90 },
+	{ 0x4085, 0x90 },
+	{ 0x4086, 0x8F },
+	{ 0x4087, 0x8F },
+	{ 0x4088, 0x9D },
+	{ 0x4089, 0x9B },
+	{ 0x408A, 0x9B },
+	{ 0x408B, 0x99 },
+	{ 0x408C, 0xAE },
+	{ 0x408D, 0xAA },
+	{ 0x408E, 0xAA },
+	{ 0x408F, 0xA7 },
+	{ 0x4090, 0xC7 },
+	{ 0x4091, 0xBA },
+	{ 0x4092, 0xBC },
+	{ 0x4093, 0xB9 },
+	{ 0x4094, 0xB1 },
+	{ 0x4095, 0xA8 },
+	{ 0x4096, 0xA8 },
+	{ 0x4097, 0xA7 },
+	{ 0x4098, 0x9F },
+	{ 0x4099, 0x9B },
+	{ 0x409A, 0x9B },
+	{ 0x409B, 0x9B },
+	{ 0x409C, 0x93 },
+	{ 0x409D, 0x91 },
+	{ 0x409E, 0x91 },
+	{ 0x409F, 0x91 },
+	{ 0x40A0, 0x8D },
+	{ 0x40A1, 0x8C },
+	{ 0x40A2, 0x8C },
+	{ 0x40A3, 0x8C },
+	{ 0x40A4, 0x8E },
+	{ 0x40A5, 0x8E },
+	{ 0x40A6, 0x8D },
+	{ 0x40A7, 0x8D },
+	{ 0x40A8, 0x96 },
+	{ 0x40A9, 0x95 },
+	{ 0x40AA, 0x95 },
+	{ 0x40AB, 0x94 },
+	{ 0x40AC, 0xA2 },
+	{ 0x40AD, 0x9F },
+	{ 0x40AE, 0x9F },
+	{ 0x40AF, 0x9D },
+	{ 0x40B0, 0xB1 },
+	{ 0x40B1, 0xAC },
+	{ 0x40B2, 0xAB },
+	{ 0x40B3, 0xAA },
+	{ 0x40B4, 0xD3 },
+	{ 0x40B5, 0xBC },
+	{ 0x40B6, 0xBD },
+	{ 0x40B7, 0xBC },
+	{ 0x40B8, 0xC1 },
+	{ 0x40B9, 0xB7 },
+	{ 0x40BA, 0xB7 },
+	{ 0x40BB, 0xB5 },
+	{ 0x40BC, 0xB0 },
+	{ 0x40BD, 0xAA },
+	{ 0x40BE, 0xAA },
+	{ 0x40BF, 0xAA },
+	{ 0x40C0, 0xA8 },
+	{ 0x40C1, 0xA4 },
+	{ 0x40C2, 0xA4 },
+	{ 0x40C3, 0xA4 },
+	{ 0x40C4, 0xA2 },
+	{ 0x40C5, 0x9F },
+	{ 0x40C6, 0x9F },
+	{ 0x40C7, 0x9F },
+	{ 0x40C8, 0xA3 },
+	{ 0x40C9, 0xA0 },
+	{ 0x40CA, 0xA0 },
+	{ 0x40CB, 0xA0 },
+	{ 0x40CC, 0xA6 },
+	{ 0x40CD, 0xA3 },
+	{ 0x40CE, 0xA3 },
+	{ 0x40CF, 0xA2 },
+	{ 0x40D0, 0xAF },
+	{ 0x40D1, 0xAB },
+	{ 0x40D2, 0xAA },
+	{ 0x40D3, 0xA8 },
+	{ 0x40D4, 0xBA },
+	{ 0x40D5, 0xAE },
+	{ 0x40D6, 0xAE },
+	{ 0x40D7, 0xAB },
+	{ 0x4100, 0xBD },
+	{ 0x4101, 0xBA },
+	{ 0x4102, 0xBD },
+	{ 0x4103, 0xB7 },
+	{ 0x4104, 0xB7 },
+	{ 0x4105, 0xB7 },
+	{ 0x4106, 0xB8 },
+	{ 0x4107, 0xB5 },
+	{ 0x4108, 0xAB },
+	{ 0x4109, 0xAA },
+	{ 0x410A, 0xAC },
+	{ 0x410B, 0xAB },
+	{ 0x410C, 0xA4 },
+	{ 0x410D, 0xA5 },
+	{ 0x410E, 0xA5 },
+	{ 0x410F, 0xA4 },
+	{ 0x4110, 0x9F },
+	{ 0x4111, 0xA0 },
+	{ 0x4112, 0xA0 },
+	{ 0x4113, 0x9F },
+	{ 0x4114, 0xA0 },
+	{ 0x4115, 0xA0 },
+	{ 0x4116, 0xA0 },
+	{ 0x4117, 0x9F },
+	{ 0x4118, 0xA1 },
+	{ 0x4119, 0xA1 },
+	{ 0x411A, 0xA1 },
+	{ 0x411B, 0xA0 },
+	{ 0x411C, 0xA7 },
+	{ 0x411D, 0xA6 },
+	{ 0x411E, 0xA6 },
+	{ 0x411F, 0xA6 },
+	{ 0x4120, 0xA7 },
+	{ 0x4121, 0xA6 },
+	{ 0x4122, 0xA6 },
+	{ 0x4123, 0xA3 },
+	{ 0x4124, 0xB9 },
+	{ 0x4125, 0xB9 },
+	{ 0x4126, 0xBA },
+	{ 0x4127, 0xB8 },
+	{ 0x4128, 0xA6 },
+	{ 0x4129, 0xA7 },
+	{ 0x412A, 0xA7 },
+	{ 0x412B, 0xA6 },
+	{ 0x412C, 0x9B },
+	{ 0x412D, 0x9B },
+	{ 0x412E, 0x9B },
+	{ 0x412F, 0x9B },
+	{ 0x4130, 0x91 },
+	{ 0x4131, 0x92 },
+	{ 0x4132, 0x92 },
+	{ 0x4133, 0x91 },
+	{ 0x4134, 0x8C },
+	{ 0x4135, 0x8C },
+	{ 0x4136, 0x8C },
+	{ 0x4137, 0x8C },
+	{ 0x4138, 0x8D },
+	{ 0x4139, 0x8D },
+	{ 0x413A, 0x8D },
+	{ 0x413B, 0x8D },
+	{ 0x413C, 0x93 },
+	{ 0x413D, 0x93 },
+	{ 0x413E, 0x93 },
+	{ 0x413F, 0x92 },
+	{ 0x4140, 0x9A },
+	{ 0x4141, 0x9A },
+	{ 0x4142, 0x9A },
+	{ 0x4143, 0x99 },
+	{ 0x4144, 0xA7 },
+	{ 0x4145, 0xA5 },
+	{ 0x4146, 0xA6 },
+	{ 0x4147, 0xA6 },
+	{ 0x4148, 0xB8 },
+	{ 0x4149, 0xB4 },
+	{ 0x414A, 0xB4 },
+	{ 0x414B, 0xB3 },
+	{ 0x414C, 0xA3 },
+	{ 0x414D, 0xA2 },
+	{ 0x414E, 0xA3 },
+	{ 0x414F, 0xA2 },
+	{ 0x4150, 0x96 },
+	{ 0x4151, 0x96 },
+	{ 0x4152, 0x96 },
+	{ 0x4153, 0x96 },
+	{ 0x4154, 0x8A },
+	{ 0x4155, 0x8A },
+	{ 0x4156, 0x8A },
+	{ 0x4157, 0x8A },
+	{ 0x4158, 0x82 },
+	{ 0x4159, 0x82 },
+	{ 0x415A, 0x82 },
+	{ 0x415B, 0x82 },
+	{ 0x415C, 0x84 },
+	{ 0x415D, 0x85 },
+	{ 0x415E, 0x84 },
+	{ 0x415F, 0x84 },
+	{ 0x4160, 0x8D },
+	{ 0x4161, 0x8D },
+	{ 0x4162, 0x8D },
+	{ 0x4163, 0x8D },
+	{ 0x4164, 0x96 },
+	{ 0x4165, 0x96 },
+	{ 0x4166, 0x96 },
+	{ 0x4167, 0x95 },
+	{ 0x4168, 0xA5 },
+	{ 0x4169, 0xA2 },
+	{ 0x416A, 0xA3 },
+	{ 0x416B, 0xA2 },
+	{ 0x416C, 0xB7 },
+	{ 0x416D, 0xB3 },
+	{ 0x416E, 0xB5 },
+	{ 0x416F, 0xB4 },
+	{ 0x4170, 0xA4 },
+	{ 0x4171, 0xA2 },
+	{ 0x4172, 0xA3 },
+	{ 0x4173, 0xA2 },
+	{ 0x4174, 0x97 },
+	{ 0x4175, 0x96 },
+	{ 0x4176, 0x96 },
+	{ 0x4177, 0x96 },
+	{ 0x4178, 0x8B },
+	{ 0x4179, 0x8A },
+	{ 0x417A, 0x8A },
+	{ 0x417B, 0x8A },
+	{ 0x417C, 0x81 },
+	{ 0x417D, 0x81 },
+	{ 0x417E, 0x81 },
+	{ 0x417F, 0x81 },
+	{ 0x4180, 0x84 },
+	{ 0x4181, 0x84 },
+	{ 0x4182, 0x84 },
+	{ 0x4183, 0x84 },
+	{ 0x4184, 0x8C },
+	{ 0x4185, 0x8D },
+	{ 0x4186, 0x8D },
+	{ 0x4187, 0x8D },
+	{ 0x4188, 0x95 },
+	{ 0x4189, 0x96 },
+	{ 0x418A, 0x96 },
+	{ 0x418B, 0x95 },
+	{ 0x418C, 0xA1 },
+	{ 0x418D, 0xA1 },
+	{ 0x418E, 0xA1 },
+	{ 0x418F, 0xA0 },
+	{ 0x4190, 0xBC },
+	{ 0x4191, 0xB8 },
+	{ 0x4192, 0xB8 },
+	{ 0x4193, 0xB9 },
+	{ 0x4194, 0xA8 },
+	{ 0x4195, 0xA5 },
+	{ 0x4196, 0xA6 },
+	{ 0x4197, 0xA5 },
+	{ 0x4198, 0x9C },
+	{ 0x4199, 0x9A },
+	{ 0x419A, 0x9A },
+	{ 0x419B, 0x9A },
+	{ 0x419C, 0x91 },
+	{ 0x419D, 0x91 },
+	{ 0x419E, 0x91 },
+	{ 0x419F, 0x91 },
+	{ 0x41A0, 0x8B },
+	{ 0x41A1, 0x8B },
+	{ 0x41A2, 0x8B },
+	{ 0x41A3, 0x8B },
+	{ 0x41A4, 0x8C },
+	{ 0x41A5, 0x8C },
+	{ 0x41A6, 0x8C },
+	{ 0x41A7, 0x8C },
+	{ 0x41A8, 0x91 },
+	{ 0x41A9, 0x92 },
+	{ 0x41AA, 0x91 },
+	{ 0x41AB, 0x91 },
+	{ 0x41AC, 0x98 },
+	{ 0x41AD, 0x99 },
+	{ 0x41AE, 0x99 },
+	{ 0x41AF, 0x98 },
+	{ 0x41B0, 0xA3 },
+	{ 0x41B1, 0xA3 },
+	{ 0x41B2, 0xA3 },
+	{ 0x41B3, 0xA2 },
+	{ 0x41B4, 0xC1 },
+	{ 0x41B5, 0xB8 },
+	{ 0x41B6, 0xB9 },
+	{ 0x41B7, 0xBA },
+	{ 0x41B8, 0xB8 },
+	{ 0x41B9, 0xB4 },
+	{ 0x41BA, 0xB4 },
+	{ 0x41BB, 0xB4 },
+	{ 0x41BC, 0xAA },
+	{ 0x41BD, 0xA7 },
+	{ 0x41BE, 0xA7 },
+	{ 0x41BF, 0xA8 },
+	{ 0x41C0, 0xA4 },
+	{ 0x41C1, 0xA2 },
+	{ 0x41C2, 0xA2 },
+	{ 0x41C3, 0xA3 },
+	{ 0x41C4, 0x9E },
+	{ 0x41C5, 0x9D },
+	{ 0x41C6, 0x9D },
+	{ 0x41C7, 0x9D },
+	{ 0x41C8, 0x9E },
+	{ 0x41C9, 0x9D },
+	{ 0x41CA, 0x9D },
+	{ 0x41CB, 0x9D },
+	{ 0x41CC, 0x9E },
+	{ 0x41CD, 0x9E },
+	{ 0x41CE, 0x9E },
+	{ 0x41CF, 0x9E },
+	{ 0x41D0, 0xA3 },
+	{ 0x41D1, 0xA3 },
+	{ 0x41D2, 0xA2 },
+	{ 0x41D3, 0xA1 },
+	{ 0x41D4, 0xA7 },
+	{ 0x41D5, 0xA7 },
+	{ 0x41D6, 0xA7 },
+	{ 0x41D7, 0xA3 },
+	{ 0x4200, 0xCE },
+	{ 0x4201, 0xC0 },
+	{ 0x4202, 0xC1 },
+	{ 0x4203, 0xB9 },
+	{ 0x4204, 0xC3 },
+	{ 0x4205, 0xB9 },
+	{ 0x4206, 0xBC },
+	{ 0x4207, 0xBD },
+	{ 0x4208, 0xB3 },
+	{ 0x4209, 0xAE },
+	{ 0x420A, 0xAF },
+	{ 0x420B, 0xAE },
+	{ 0x420C, 0xAA },
+	{ 0x420D, 0xA8 },
+	{ 0x420E, 0xA8 },
+	{ 0x420F, 0xA6 },
+	{ 0x4210, 0xA4 },
+	{ 0x4211, 0xA2 },
+	{ 0x4212, 0xA2 },
+	{ 0x4213, 0xA0 },
+	{ 0x4214, 0xA4 },
+	{ 0x4215, 0xA3 },
+	{ 0x4216, 0xA2 },
+	{ 0x4217, 0xA0 },
+	{ 0x4218, 0xA7 },
+	{ 0x4219, 0xA5 },
+	{ 0x421A, 0xA3 },
+	{ 0x421B, 0xA1 },
+	{ 0x421C, 0xB0 },
+	{ 0x421D, 0xA8 },
+	{ 0x421E, 0xA8 },
+	{ 0x421F, 0xA6 },
+	{ 0x4220, 0xB4 },
+	{ 0x4221, 0xAA },
+	{ 0x4222, 0xA5 },
+	{ 0x4223, 0xA3 },
+	{ 0x4224, 0xC7 },
+	{ 0x4225, 0xBC },
+	{ 0x4226, 0xBE },
+	{ 0x4227, 0xBC },
+	{ 0x4228, 0xB0 },
+	{ 0x4229, 0xA9 },
+	{ 0x422A, 0xA9 },
+	{ 0x422B, 0xA8 },
+	{ 0x422C, 0xA0 },
+	{ 0x422D, 0x9D },
+	{ 0x422E, 0x9D },
+	{ 0x422F, 0x9C },
+	{ 0x4230, 0x94 },
+	{ 0x4231, 0x93 },
+	{ 0x4232, 0x93 },
+	{ 0x4233, 0x92 },
+	{ 0x4234, 0x8E },
+	{ 0x4235, 0x8D },
+	{ 0x4236, 0x8D },
+	{ 0x4237, 0x8C },
+	{ 0x4238, 0x8F },
+	{ 0x4239, 0x8E },
+	{ 0x423A, 0x8E },
+	{ 0x423B, 0x8D },
+	{ 0x423C, 0x96 },
+	{ 0x423D, 0x94 },
+	{ 0x423E, 0x94 },
+	{ 0x423F, 0x92 },
+	{ 0x4240, 0xA1 },
+	{ 0x4241, 0x9C },
+	{ 0x4242, 0x9C },
+	{ 0x4243, 0x99 },
+	{ 0x4244, 0xB0 },
+	{ 0x4245, 0xA8 },
+	{ 0x4246, 0xAB },
+	{ 0x4247, 0xA7 },
+	{ 0x4248, 0xC3 },
+	{ 0x4249, 0xB7 },
+	{ 0x424A, 0xB7 },
+	{ 0x424B, 0xBC },
+	{ 0x424C, 0xAB },
+	{ 0x424D, 0xA4 },
+	{ 0x424E, 0xA5 },
+	{ 0x424F, 0xA5 },
+	{ 0x4250, 0x9A },
+	{ 0x4251, 0x97 },
+	{ 0x4252, 0x97 },
+	{ 0x4253, 0x98 },
+	{ 0x4254, 0x8C },
+	{ 0x4255, 0x8B },
+	{ 0x4256, 0x8B },
+	{ 0x4257, 0x8B },
+	{ 0x4258, 0x82 },
+	{ 0x4259, 0x82 },
+	{ 0x425A, 0x82 },
+	{ 0x425B, 0x82 },
+	{ 0x425C, 0x85 },
+	{ 0x425D, 0x85 },
+	{ 0x425E, 0x85 },
+	{ 0x425F, 0x84 },
+	{ 0x4260, 0x8F },
+	{ 0x4261, 0x8E },
+	{ 0x4262, 0x8E },
+	{ 0x4263, 0x8D },
+	{ 0x4264, 0x9B },
+	{ 0x4265, 0x98 },
+	{ 0x4266, 0x98 },
+	{ 0x4267, 0x95 },
+	{ 0x4268, 0xAE },
+	{ 0x4269, 0xA5 },
+	{ 0x426A, 0xA7 },
+	{ 0x426B, 0xA2 },
+	{ 0x426C, 0xC2 },
+	{ 0x426D, 0xB7 },
+	{ 0x426E, 0xB8 },
+	{ 0x426F, 0xB9 },
+	{ 0x4270, 0xAA },
+	{ 0x4271, 0xA4 },
+	{ 0x4272, 0xA4 },
+	{ 0x4273, 0xA5 },
+	{ 0x4274, 0x99 },
+	{ 0x4275, 0x96 },
+	{ 0x4276, 0x97 },
+	{ 0x4277, 0x98 },
+	{ 0x4278, 0x8B },
+	{ 0x4279, 0x8A },
+	{ 0x427A, 0x8A },
+	{ 0x427B, 0x8B },
+	{ 0x427C, 0x81 },
+	{ 0x427D, 0x81 },
+	{ 0x427E, 0x81 },
+	{ 0x427F, 0x82 },
+	{ 0x4280, 0x84 },
+	{ 0x4281, 0x84 },
+	{ 0x4282, 0x84 },
+	{ 0x4283, 0x84 },
+	{ 0x4284, 0x8E },
+	{ 0x4285, 0x8E },
+	{ 0x4286, 0x8D },
+	{ 0x4287, 0x8C },
+	{ 0x4288, 0x9A },
+	{ 0x4289, 0x97 },
+	{ 0x428A, 0x97 },
+	{ 0x428B, 0x95 },
+	{ 0x428C, 0xAA },
+	{ 0x428D, 0xA3 },
+	{ 0x428E, 0xA3 },
+	{ 0x428F, 0xA2 },
+	{ 0x4290, 0xC7 },
+	{ 0x4291, 0xBA },
+	{ 0x4292, 0xC0 },
+	{ 0x4293, 0xC3 },
+	{ 0x4294, 0xB0 },
+	{ 0x4295, 0xA7 },
+	{ 0x4296, 0xA7 },
+	{ 0x4297, 0xA9 },
+	{ 0x4298, 0x9F },
+	{ 0x4299, 0x9B },
+	{ 0x429A, 0x9B },
+	{ 0x429B, 0x9D },
+	{ 0x429C, 0x93 },
+	{ 0x429D, 0x91 },
+	{ 0x429E, 0x91 },
+	{ 0x429F, 0x92 },
+	{ 0x42A0, 0x8C },
+	{ 0x42A1, 0x8B },
+	{ 0x42A2, 0x8B },
+	{ 0x42A3, 0x8C },
+	{ 0x42A4, 0x8D },
+	{ 0x42A5, 0x8C },
+	{ 0x42A6, 0x8C },
+	{ 0x42A7, 0x8C },
+	{ 0x42A8, 0x94 },
+	{ 0x42A9, 0x93 },
+	{ 0x42AA, 0x92 },
+	{ 0x42AB, 0x91 },
+	{ 0x42AC, 0x9E },
+	{ 0x42AD, 0x9B },
+	{ 0x42AE, 0x9B },
+	{ 0x42AF, 0x98 },
+	{ 0x42B0, 0xAC },
+	{ 0x42B1, 0xA6 },
+	{ 0x42B2, 0xA6 },
+	{ 0x42B3, 0xA2 },
+	{ 0x42B4, 0xCE },
+	{ 0x42B5, 0xBA },
+	{ 0x42B6, 0xBC },
+	{ 0x42B7, 0xB7 },
+	{ 0x42B8, 0xC5 },
+	{ 0x42B9, 0xB5 },
+	{ 0x42BA, 0xBA },
+	{ 0x42BB, 0xC0 },
+	{ 0x42BC, 0xB1 },
+	{ 0x42BD, 0xA8 },
+	{ 0x42BE, 0xAE },
+	{ 0x42BF, 0xAF },
+	{ 0x42C0, 0xA7 },
+	{ 0x42C1, 0xA3 },
+	{ 0x42C2, 0xA3 },
+	{ 0x42C3, 0xA5 },
+	{ 0x42C4, 0xA0 },
+	{ 0x42C5, 0x9D },
+	{ 0x42C6, 0x9D },
+	{ 0x42C7, 0x9F },
+	{ 0x42C8, 0xA0 },
+	{ 0x42C9, 0x9E },
+	{ 0x42CA, 0x9E },
+	{ 0x42CB, 0x9F },
+	{ 0x42CC, 0xA2 },
+	{ 0x42CD, 0xA0 },
+	{ 0x42CE, 0xA0 },
+	{ 0x42CF, 0xA0 },
+	{ 0x42D0, 0xA8 },
+	{ 0x42D1, 0xA5 },
+	{ 0x42D2, 0xA5 },
+	{ 0x42D3, 0xA2 },
+	{ 0x42D4, 0xB3 },
+	{ 0x42D5, 0xAA },
+	{ 0x42D6, 0xAB },
+	{ 0x42D7, 0xA3 },
+	{ 0x42D8, 0x00 },
+	{ 0x42D9, 0x00 },
+	{ 0x4300, 0xA2 },
+	{ 0x4301, 0xAE },
+	{ 0x4302, 0xAD },
+	{ 0x4303, 0xB5 },
+	{ 0x4304, 0x95 },
+	{ 0x4305, 0x9A },
+	{ 0x4306, 0x98 },
+	{ 0x4307, 0x9B },
+	{ 0x4308, 0x8D },
+	{ 0x4309, 0x90 },
+	{ 0x430A, 0x8F },
+	{ 0x430B, 0x91 },
+	{ 0x430C, 0x86 },
+	{ 0x430D, 0x88 },
+	{ 0x430E, 0x87 },
+	{ 0x430F, 0x89 },
+	{ 0x4310, 0x86 },
+	{ 0x4311, 0x87 },
+	{ 0x4312, 0x86 },
+	{ 0x4313, 0x88 },
+	{ 0x4314, 0x89 },
+	{ 0x4315, 0x88 },
+	{ 0x4316, 0x88 },
+	{ 0x4317, 0x8E },
+	{ 0x4318, 0x90 },
+	{ 0x4319, 0x8F },
+	{ 0x431A, 0x8C },
+	{ 0x431B, 0x8C },
+	{ 0x431C, 0x9C },
+	{ 0x431D, 0x99 },
+	{ 0x431E, 0x98 },
+	{ 0x431F, 0x99 },
+	{ 0x4320, 0xAB },
+	{ 0x4321, 0xB0 },
+	{ 0x4322, 0xAD },
+	{ 0x4323, 0xAF },
+	{ 0x4324, 0x9B },
+	{ 0x4325, 0x9F },
+	{ 0x4326, 0x9E },
+	{ 0x4327, 0xA1 },
+	{ 0x4328, 0x8E },
+	{ 0x4329, 0x91 },
+	{ 0x432A, 0x90 },
+	{ 0x432B, 0x93 },
+	{ 0x432C, 0x86 },
+	{ 0x432D, 0x88 },
+	{ 0x432E, 0x87 },
+	{ 0x432F, 0x89 },
+	{ 0x4330, 0x82 },
+	{ 0x4331, 0x84 },
+	{ 0x4332, 0x83 },
+	{ 0x4333, 0x84 },
+	{ 0x4334, 0x82 },
+	{ 0x4335, 0x82 },
+	{ 0x4336, 0x82 },
+	{ 0x4337, 0x83 },
+	{ 0x4338, 0x85 },
+	{ 0x4339, 0x84 },
+	{ 0x433A, 0x84 },
+	{ 0x433B, 0x85 },
+	{ 0x433C, 0x8A },
+	{ 0x433D, 0x89 },
+	{ 0x433E, 0x88 },
+	{ 0x433F, 0x89 },
+	{ 0x4340, 0x93 },
+	{ 0x4341, 0x91 },
+	{ 0x4342, 0x91 },
+	{ 0x4343, 0x93 },
+	{ 0x4344, 0xA0 },
+	{ 0x4345, 0x9E },
+	{ 0x4346, 0x9D },
+	{ 0x4347, 0xA1 },
+	{ 0x4348, 0x95 },
+	{ 0x4349, 0x9B },
+	{ 0x434A, 0x9A },
+	{ 0x434B, 0x9C },
+	{ 0x434C, 0x8A },
+	{ 0x434D, 0x8D },
+	{ 0x434E, 0x8C },
+	{ 0x434F, 0x8D },
+	{ 0x4350, 0x83 },
+	{ 0x4351, 0x85 },
+	{ 0x4352, 0x84 },
+	{ 0x4353, 0x85 },
+	{ 0x4354, 0x80 },
+	{ 0x4355, 0x81 },
+	{ 0x4356, 0x81 },
+	{ 0x4357, 0x81 },
+	{ 0x4358, 0x80 },
+	{ 0x4359, 0x80 },
+	{ 0x435A, 0x80 },
+	{ 0x435B, 0x80 },
+	{ 0x435C, 0x82 },
+	{ 0x435D, 0x81 },
+	{ 0x435E, 0x81 },
+	{ 0x435F, 0x81 },
+	{ 0x4360, 0x85 },
+	{ 0x4361, 0x84 },
+	{ 0x4362, 0x84 },
+	{ 0x4363, 0x85 },
+	{ 0x4364, 0x8D },
+	{ 0x4365, 0x8B },
+	{ 0x4366, 0x8B },
+	{ 0x4367, 0x8D },
+	{ 0x4368, 0x98 },
+	{ 0x4369, 0x98 },
+	{ 0x436A, 0x95 },
+	{ 0x436B, 0x98 },
+	{ 0x436C, 0x95 },
+	{ 0x436D, 0x9A },
+	{ 0x436E, 0x99 },
+	{ 0x436F, 0x9A },
+	{ 0x4370, 0x8A },
+	{ 0x4371, 0x8D },
+	{ 0x4372, 0x8C },
+	{ 0x4373, 0x8C },
+	{ 0x4374, 0x83 },
+	{ 0x4375, 0x85 },
+	{ 0x4376, 0x84 },
+	{ 0x4377, 0x84 },
+	{ 0x4378, 0x80 },
+	{ 0x4379, 0x80 },
+	{ 0x437A, 0x80 },
+	{ 0x437B, 0x80 },
+	{ 0x437C, 0x7F },
+	{ 0x437D, 0x7F },
+	{ 0x437E, 0x7F },
+	{ 0x437F, 0x7F },
+	{ 0x4380, 0x81 },
+	{ 0x4381, 0x80 },
+	{ 0x4382, 0x80 },
+	{ 0x4383, 0x81 },
+	{ 0x4384, 0x84 },
+	{ 0x4385, 0x83 },
+	{ 0x4386, 0x83 },
+	{ 0x4387, 0x84 },
+	{ 0x4388, 0x8B },
+	{ 0x4389, 0x8A },
+	{ 0x438A, 0x8A },
+	{ 0x438B, 0x8C },
+	{ 0x438C, 0x97 },
+	{ 0x438D, 0x96 },
+	{ 0x438E, 0x96 },
+	{ 0x438F, 0x99 },
+	{ 0x4390, 0x99 },
+	{ 0x4391, 0x9F },
+	{ 0x4392, 0x9E },
+	{ 0x4393, 0x9D },
+	{ 0x4394, 0x8D },
+	{ 0x4395, 0x90 },
+	{ 0x4396, 0x90 },
+	{ 0x4397, 0x8F },
+	{ 0x4398, 0x85 },
+	{ 0x4399, 0x87 },
+	{ 0x439A, 0x87 },
+	{ 0x439B, 0x86 },
+	{ 0x439C, 0x81 },
+	{ 0x439D, 0x83 },
+	{ 0x439E, 0x82 },
+	{ 0x439F, 0x82 },
+	{ 0x43A0, 0x80 },
+	{ 0x43A1, 0x81 },
+	{ 0x43A2, 0x81 },
+	{ 0x43A3, 0x81 },
+	{ 0x43A4, 0x82 },
+	{ 0x43A5, 0x82 },
+	{ 0x43A6, 0x82 },
+	{ 0x43A7, 0x82 },
+	{ 0x43A8, 0x86 },
+	{ 0x43A9, 0x85 },
+	{ 0x43AA, 0x85 },
+	{ 0x43AB, 0x87 },
+	{ 0x43AC, 0x8D },
+	{ 0x43AD, 0x8D },
+	{ 0x43AE, 0x8D },
+	{ 0x43AF, 0x90 },
+	{ 0x43B0, 0x9A },
+	{ 0x43B1, 0x9A },
+	{ 0x43B2, 0x9B },
+	{ 0x43B3, 0x9D },
+	{ 0x43B4, 0xA0 },
+	{ 0x43B5, 0xAD },
+	{ 0x43B6, 0xAC },
+	{ 0x43B7, 0xAA },
+	{ 0x43B8, 0x93 },
+	{ 0x43B9, 0x97 },
+	{ 0x43BA, 0x97 },
+	{ 0x43BB, 0x96 },
+	{ 0x43BC, 0x8B },
+	{ 0x43BD, 0x8E },
+	{ 0x43BE, 0x8E },
+	{ 0x43BF, 0x8C },
+	{ 0x43C0, 0x83 },
+	{ 0x43C1, 0x85 },
+	{ 0x43C2, 0x85 },
+	{ 0x43C3, 0x84 },
+	{ 0x43C4, 0x82 },
+	{ 0x43C5, 0x84 },
+	{ 0x43C6, 0x83 },
+	{ 0x43C7, 0x83 },
+	{ 0x43C8, 0x83 },
+	{ 0x43C9, 0x84 },
+	{ 0x43CA, 0x84 },
+	{ 0x43CB, 0x85 },
+	{ 0x43CC, 0x8A },
+	{ 0x43CD, 0x8A },
+	{ 0x43CE, 0x8A },
+	{ 0x43CF, 0x8C },
+	{ 0x43D0, 0x92 },
+	{ 0x43D1, 0x93 },
+	{ 0x43D2, 0x93 },
+	{ 0x43D3, 0x96 },
+	{ 0x43D4, 0x9F },
+	{ 0x43D5, 0xA6 },
+	{ 0x43D6, 0xA5 },
+	{ 0x43D7, 0xAA },
+	{ 0x4400, 0xA1 },
+	{ 0x4401, 0xAB },
+	{ 0x4402, 0xA7 },
+	{ 0x4403, 0xB0 },
+	{ 0x4404, 0x91 },
+	{ 0x4405, 0x96 },
+	{ 0x4406, 0x94 },
+	{ 0x4407, 0x99 },
+	{ 0x4408, 0x8A },
+	{ 0x4409, 0x8E },
+	{ 0x440A, 0x8C },
+	{ 0x440B, 0x8F },
+	{ 0x440C, 0x85 },
+	{ 0x440D, 0x86 },
+	{ 0x440E, 0x86 },
+	{ 0x440F, 0x88 },
+	{ 0x4410, 0x85 },
+	{ 0x4411, 0x86 },
+	{ 0x4412, 0x85 },
+	{ 0x4413, 0x87 },
+	{ 0x4414, 0x88 },
+	{ 0x4415, 0x87 },
+	{ 0x4416, 0x87 },
+	{ 0x4417, 0x89 },
+	{ 0x4418, 0x91 },
+	{ 0x4419, 0x8F },
+	{ 0x441A, 0x8F },
+	{ 0x441B, 0x90 },
+	{ 0x441C, 0x9C },
+	{ 0x441D, 0x9B },
+	{ 0x441E, 0x9A },
+	{ 0x441F, 0x9A },
+	{ 0x4420, 0xB3 },
+	{ 0x4421, 0xB1 },
+	{ 0x4422, 0xB0 },
+	{ 0x4423, 0xB2 },
+	{ 0x4424, 0x96 },
+	{ 0x4425, 0x9C },
+	{ 0x4426, 0x9A },
+	{ 0x4427, 0x9E },
+	{ 0x4428, 0x8B },
+	{ 0x4429, 0x8F },
+	{ 0x442A, 0x8E },
+	{ 0x442B, 0x91 },
+	{ 0x442C, 0x84 },
+	{ 0x442D, 0x87 },
+	{ 0x442E, 0x86 },
+	{ 0x442F, 0x88 },
+	{ 0x4430, 0x82 },
+	{ 0x4431, 0x83 },
+	{ 0x4432, 0x82 },
+	{ 0x4433, 0x84 },
+	{ 0x4434, 0x82 },
+	{ 0x4435, 0x82 },
+	{ 0x4436, 0x82 },
+	{ 0x4437, 0x83 },
+	{ 0x4438, 0x84 },
+	{ 0x4439, 0x84 },
+	{ 0x443A, 0x84 },
+	{ 0x443B, 0x84 },
+	{ 0x443C, 0x8B },
+	{ 0x443D, 0x89 },
+	{ 0x443E, 0x89 },
+	{ 0x443F, 0x89 },
+	{ 0x4440, 0x95 },
+	{ 0x4441, 0x93 },
+	{ 0x4442, 0x93 },
+	{ 0x4443, 0x93 },
+	{ 0x4444, 0xA2 },
+	{ 0x4445, 0xA2 },
+	{ 0x4446, 0xA1 },
+	{ 0x4447, 0xA0 },
+	{ 0x4448, 0x8F },
+	{ 0x4449, 0x97 },
+	{ 0x444A, 0x97 },
+	{ 0x444B, 0x98 },
+	{ 0x444C, 0x87 },
+	{ 0x444D, 0x8B },
+	{ 0x444E, 0x8A },
+	{ 0x444F, 0x8B },
+	{ 0x4450, 0x81 },
+	{ 0x4451, 0x83 },
+	{ 0x4452, 0x83 },
+	{ 0x4453, 0x84 },
+	{ 0x4454, 0x7F },
+	{ 0x4455, 0x80 },
+	{ 0x4456, 0x80 },
+	{ 0x4457, 0x81 },
+	{ 0x4458, 0x80 },
+	{ 0x4459, 0x80 },
+	{ 0x445A, 0x80 },
+	{ 0x445B, 0x80 },
+	{ 0x445C, 0x82 },
+	{ 0x445D, 0x81 },
+	{ 0x445E, 0x81 },
+	{ 0x445F, 0x81 },
+	{ 0x4460, 0x87 },
+	{ 0x4461, 0x85 },
+	{ 0x4462, 0x85 },
+	{ 0x4463, 0x86 },
+	{ 0x4464, 0x90 },
+	{ 0x4465, 0x8E },
+	{ 0x4466, 0x8E },
+	{ 0x4467, 0x8E },
+	{ 0x4468, 0x9B },
+	{ 0x4469, 0x9C },
+	{ 0x446A, 0x9A },
+	{ 0x446B, 0x9A },
+	{ 0x446C, 0x91 },
+	{ 0x446D, 0x97 },
+	{ 0x446E, 0x95 },
+	{ 0x446F, 0x95 },
+	{ 0x4470, 0x87 },
+	{ 0x4471, 0x8A },
+	{ 0x4472, 0x8A },
+	{ 0x4473, 0x89 },
+	{ 0x4474, 0x81 },
+	{ 0x4475, 0x83 },
+	{ 0x4476, 0x83 },
+	{ 0x4477, 0x83 },
+	{ 0x4478, 0x7F },
+	{ 0x4479, 0x80 },
+	{ 0x447A, 0x80 },
+	{ 0x447B, 0x80 },
+	{ 0x447C, 0x80 },
+	{ 0x447D, 0x80 },
+	{ 0x447E, 0x80 },
+	{ 0x447F, 0x7F },
+	{ 0x4480, 0x81 },
+	{ 0x4481, 0x81 },
+	{ 0x4482, 0x81 },
+	{ 0x4483, 0x81 },
+	{ 0x4484, 0x85 },
+	{ 0x4485, 0x85 },
+	{ 0x4486, 0x85 },
+	{ 0x4487, 0x85 },
+	{ 0x4488, 0x8E },
+	{ 0x4489, 0x8D },
+	{ 0x448A, 0x8D },
+	{ 0x448B, 0x8E },
+	{ 0x448C, 0x9D },
+	{ 0x448D, 0x9C },
+	{ 0x448E, 0x9C },
+	{ 0x448F, 0x9C },
+	{ 0x4490, 0x94 },
+	{ 0x4491, 0x9B },
+	{ 0x4492, 0x9A },
+	{ 0x4493, 0x97 },
+	{ 0x4494, 0x8A },
+	{ 0x4495, 0x8E },
+	{ 0x4496, 0x8E },
+	{ 0x4497, 0x8C },
+	{ 0x4498, 0x84 },
+	{ 0x4499, 0x86 },
+	{ 0x449A, 0x86 },
+	{ 0x449B, 0x84 },
+	{ 0x449C, 0x81 },
+	{ 0x449D, 0x83 },
+	{ 0x449E, 0x83 },
+	{ 0x449F, 0x81 },
+	{ 0x44A0, 0x81 },
+	{ 0x44A1, 0x82 },
+	{ 0x44A2, 0x82 },
+	{ 0x44A3, 0x81 },
+	{ 0x44A4, 0x83 },
+	{ 0x44A5, 0x83 },
+	{ 0x44A6, 0x83 },
+	{ 0x44A7, 0x83 },
+	{ 0x44A8, 0x88 },
+	{ 0x44A9, 0x88 },
+	{ 0x44AA, 0x88 },
+	{ 0x44AB, 0x88 },
+	{ 0x44AC, 0x91 },
+	{ 0x44AD, 0x91 },
+	{ 0x44AE, 0x91 },
+	{ 0x44AF, 0x92 },
+	{ 0x44B0, 0xA0 },
+	{ 0x44B1, 0xA0 },
+	{ 0x44B2, 0xA0 },
+	{ 0x44B3, 0xA0 },
+	{ 0x44B4, 0x9E },
+	{ 0x44B5, 0xA9 },
+	{ 0x44B6, 0xA8 },
+	{ 0x44B7, 0xA3 },
+	{ 0x44B8, 0x90 },
+	{ 0x44B9, 0x95 },
+	{ 0x44BA, 0x95 },
+	{ 0x44BB, 0x92 },
+	{ 0x44BC, 0x8A },
+	{ 0x44BD, 0x8E },
+	{ 0x44BE, 0x8E },
+	{ 0x44BF, 0x8B },
+	{ 0x44C0, 0x84 },
+	{ 0x44C1, 0x86 },
+	{ 0x44C2, 0x86 },
+	{ 0x44C3, 0x84 },
+	{ 0x44C4, 0x84 },
+	{ 0x44C5, 0x85 },
+	{ 0x44C6, 0x85 },
+	{ 0x44C7, 0x84 },
+	{ 0x44C8, 0x86 },
+	{ 0x44C9, 0x87 },
+	{ 0x44CA, 0x87 },
+	{ 0x44CB, 0x86 },
+	{ 0x44CC, 0x8D },
+	{ 0x44CD, 0x8E },
+	{ 0x44CE, 0x8E },
+	{ 0x44CF, 0x8D },
+	{ 0x44D0, 0x98 },
+	{ 0x44D1, 0x98 },
+	{ 0x44D2, 0x99 },
+	{ 0x44D3, 0x9A },
+	{ 0x44D4, 0xA9 },
+	{ 0x44D5, 0xAA },
+	{ 0x44D6, 0xAA },
+	{ 0x44D7, 0xAD },
+	{ 0x4500, 0x9F },
+	{ 0x4501, 0xA8 },
+	{ 0x4502, 0xA5 },
+	{ 0x4503, 0xAF },
+	{ 0x4504, 0x8F },
+	{ 0x4505, 0x96 },
+	{ 0x4506, 0x92 },
+	{ 0x4507, 0x94 },
+	{ 0x4508, 0x89 },
+	{ 0x4509, 0x8D },
+	{ 0x450A, 0x8A },
+	{ 0x450B, 0x8E },
+	{ 0x450C, 0x84 },
+	{ 0x450D, 0x85 },
+	{ 0x450E, 0x84 },
+	{ 0x450F, 0x87 },
+	{ 0x4510, 0x84 },
+	{ 0x4511, 0x85 },
+	{ 0x4512, 0x84 },
+	{ 0x4513, 0x86 },
+	{ 0x4514, 0x87 },
+	{ 0x4515, 0x86 },
+	{ 0x4516, 0x86 },
+	{ 0x4517, 0x88 },
+	{ 0x4518, 0x8F },
+	{ 0x4519, 0x8D },
+	{ 0x451A, 0x8D },
+	{ 0x451B, 0x8F },
+	{ 0x451C, 0x9A },
+	{ 0x451D, 0x9A },
+	{ 0x451E, 0x98 },
+	{ 0x451F, 0x9A },
+	{ 0x4520, 0xAF },
+	{ 0x4521, 0xAF },
+	{ 0x4522, 0xB2 },
+	{ 0x4523, 0xB1 },
+	{ 0x4524, 0x95 },
+	{ 0x4525, 0x9B },
+	{ 0x4526, 0x97 },
+	{ 0x4527, 0x9C },
+	{ 0x4528, 0x8A },
+	{ 0x4529, 0x8E },
+	{ 0x452A, 0x8D },
+	{ 0x452B, 0x90 },
+	{ 0x452C, 0x84 },
+	{ 0x452D, 0x86 },
+	{ 0x452E, 0x85 },
+	{ 0x452F, 0x87 },
+	{ 0x4530, 0x81 },
+	{ 0x4531, 0x82 },
+	{ 0x4532, 0x82 },
+	{ 0x4533, 0x83 },
+	{ 0x4534, 0x81 },
+	{ 0x4535, 0x81 },
+	{ 0x4536, 0x81 },
+	{ 0x4537, 0x82 },
+	{ 0x4538, 0x84 },
+	{ 0x4539, 0x83 },
+	{ 0x453A, 0x83 },
+	{ 0x453B, 0x84 },
+	{ 0x453C, 0x8A },
+	{ 0x453D, 0x88 },
+	{ 0x453E, 0x88 },
+	{ 0x453F, 0x89 },
+	{ 0x4540, 0x94 },
+	{ 0x4541, 0x92 },
+	{ 0x4542, 0x91 },
+	{ 0x4543, 0x92 },
+	{ 0x4544, 0xA1 },
+	{ 0x4545, 0xA0 },
+	{ 0x4546, 0x9C },
+	{ 0x4547, 0x9D },
+	{ 0x4548, 0x8F },
+	{ 0x4549, 0x96 },
+	{ 0x454A, 0x95 },
+	{ 0x454B, 0x92 },
+	{ 0x454C, 0x87 },
+	{ 0x454D, 0x8A },
+	{ 0x454E, 0x89 },
+	{ 0x454F, 0x8A },
+	{ 0x4550, 0x81 },
+	{ 0x4551, 0x83 },
+	{ 0x4552, 0x82 },
+	{ 0x4553, 0x83 },
+	{ 0x4554, 0x7F },
+	{ 0x4555, 0x80 },
+	{ 0x4556, 0x80 },
+	{ 0x4557, 0x81 },
+	{ 0x4558, 0x7F },
+	{ 0x4559, 0x80 },
+	{ 0x455A, 0x7F },
+	{ 0x455B, 0x80 },
+	{ 0x455C, 0x81 },
+	{ 0x455D, 0x81 },
+	{ 0x455E, 0x81 },
+	{ 0x455F, 0x81 },
+	{ 0x4560, 0x86 },
+	{ 0x4561, 0x85 },
+	{ 0x4562, 0x85 },
+	{ 0x4563, 0x85 },
+	{ 0x4564, 0x8F },
+	{ 0x4565, 0x8D },
+	{ 0x4566, 0x8D },
+	{ 0x4567, 0x8D },
+	{ 0x4568, 0x99 },
+	{ 0x4569, 0x9A },
+	{ 0x456A, 0x97 },
+	{ 0x456B, 0x99 },
+	{ 0x456C, 0x90 },
+	{ 0x456D, 0x95 },
+	{ 0x456E, 0x93 },
+	{ 0x456F, 0x92 },
+	{ 0x4570, 0x87 },
+	{ 0x4571, 0x8A },
+	{ 0x4572, 0x88 },
+	{ 0x4573, 0x87 },
+	{ 0x4574, 0x81 },
+	{ 0x4575, 0x83 },
+	{ 0x4576, 0x82 },
+	{ 0x4577, 0x82 },
+	{ 0x4578, 0x7F },
+	{ 0x4579, 0x80 },
+	{ 0x457A, 0x80 },
+	{ 0x457B, 0x80 },
+	{ 0x457C, 0x80 },
+	{ 0x457D, 0x80 },
+	{ 0x457E, 0x80 },
+	{ 0x457F, 0x80 },
+	{ 0x4580, 0x81 },
+	{ 0x4581, 0x81 },
+	{ 0x4582, 0x81 },
+	{ 0x4583, 0x81 },
+	{ 0x4584, 0x85 },
+	{ 0x4585, 0x85 },
+	{ 0x4586, 0x84 },
+	{ 0x4587, 0x85 },
+	{ 0x4588, 0x8E },
+	{ 0x4589, 0x8D },
+	{ 0x458A, 0x8C },
+	{ 0x458B, 0x8D },
+	{ 0x458C, 0x9B },
+	{ 0x458D, 0x9B },
+	{ 0x458E, 0x9A },
+	{ 0x458F, 0x98 },
+	{ 0x4590, 0x94 },
+	{ 0x4591, 0x9A },
+	{ 0x4592, 0x94 },
+	{ 0x4593, 0x90 },
+	{ 0x4594, 0x8A },
+	{ 0x4595, 0x8D },
+	{ 0x4596, 0x8C },
+	{ 0x4597, 0x89 },
+	{ 0x4598, 0x84 },
+	{ 0x4599, 0x86 },
+	{ 0x459A, 0x85 },
+	{ 0x459B, 0x83 },
+	{ 0x459C, 0x82 },
+	{ 0x459D, 0x83 },
+	{ 0x459E, 0x82 },
+	{ 0x459F, 0x80 },
+	{ 0x45A0, 0x81 },
+	{ 0x45A1, 0x82 },
+	{ 0x45A2, 0x81 },
+	{ 0x45A3, 0x80 },
+	{ 0x45A4, 0x83 },
+	{ 0x45A5, 0x83 },
+	{ 0x45A6, 0x83 },
+	{ 0x45A7, 0x83 },
+	{ 0x45A8, 0x88 },
+	{ 0x45A9, 0x87 },
+	{ 0x45AA, 0x87 },
+	{ 0x45AB, 0x88 },
+	{ 0x45AC, 0x91 },
+	{ 0x45AD, 0x90 },
+	{ 0x45AE, 0x90 },
+	{ 0x45AF, 0x91 },
+	{ 0x45B0, 0x9F },
+	{ 0x45B1, 0x9F },
+	{ 0x45B2, 0x9E },
+	{ 0x45B3, 0x9F },
+	{ 0x45B4, 0x9F },
+	{ 0x45B5, 0xA8 },
+	{ 0x45B6, 0xA6 },
+	{ 0x45B7, 0xA7 },
+	{ 0x45B8, 0x8D },
+	{ 0x45B9, 0x95 },
+	{ 0x45BA, 0x90 },
+	{ 0x45BB, 0x8A },
+	{ 0x45BC, 0x89 },
+	{ 0x45BD, 0x8D },
+	{ 0x45BE, 0x88 },
+	{ 0x45BF, 0x86 },
+	{ 0x45C0, 0x84 },
+	{ 0x45C1, 0x86 },
+	{ 0x45C2, 0x85 },
+	{ 0x45C3, 0x82 },
+	{ 0x45C4, 0x84 },
+	{ 0x45C5, 0x85 },
+	{ 0x45C6, 0x85 },
+	{ 0x45C7, 0x83 },
+	{ 0x45C8, 0x86 },
+	{ 0x45C9, 0x86 },
+	{ 0x45CA, 0x86 },
+	{ 0x45CB, 0x85 },
+	{ 0x45CC, 0x8E },
+	{ 0x45CD, 0x8D },
+	{ 0x45CE, 0x8D },
+	{ 0x45CF, 0x8C },
+	{ 0x45D0, 0x99 },
+	{ 0x45D1, 0x98 },
+	{ 0x45D2, 0x98 },
+	{ 0x45D3, 0x98 },
+	{ 0x45D4, 0xA6 },
+	{ 0x45D5, 0xA9 },
+	{ 0x45D6, 0xA7 },
+	{ 0x45D7, 0xAC },
+};
diff -Naur --no-dereference a/drivers/media/i2c/imx728.c b/drivers/media/i2c/imx728.c
--- a/drivers/media/i2c/imx728.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/media/i2c/imx728.c	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,9655 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Sony IMX728 CMOS Image Sensor Driver
+ *
+ * Copyright (c) 2024-2025 Define Design Deploy Corp
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm_runtime.h>
+#include <linux/types.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-subdev.h>
+
+#define IMX728_FRAMERATE_MAX           30
+#define IMX728_FRAMERATE_DEFAULT       30
+#define IMX728_FRAMERATE_MIN           10
+
+#define IMX728_PIXEL_ARRAY_WIDTH       3857
+#define IMX728_PIXEL_ARRAY_HEIGHT      2177
+#define IMX728_PIXEL_ARRAY_MARGIN_TOP  1
+#define IMX728_PIXEL_ARRAY_MARGIN_LEFT 1
+#define IMX728_PIXEL_ARRAY_RECORDING_WIDTH     3856
+#define IMX728_PIXEL_ARRAY_RECORDING_HEIGHT    2176
+
+#define IMX728_PIXEL_RATE              248832000
+#define IMX728_LINK_FREQ               800000000
+
+#define IMX728_EXPOSURE_DEFAULT        1440
+#define IMX728_AGAIN_DEFAULT           240
+
+#define IMX728_PM_IDLE_TIMEOUT         1000
+
+#define IMX728_REG_STATE              CCI_REG8(0x2cac)
+#define IMX728_REG_EXPOSURE_SP1       CCI_REG32_LE(0x98dc)
+#define IMX728_REG_EXPOSURE_SP2       CCI_REG32_LE(0x98e4)
+#define IMX728_REG_EXPOSURE_SP1VS     CCI_REG32_LE(0x98ec)
+#define IMX728_REG_FME_ISP_GAIN_FID0  CCI_REG16_LE(0x9918)
+#define IMX728_REG_FLIP               CCI_REG8(0x9651)
+#define IMX728_REG_HFLIP              CCI_REG8(0xb67c)
+#define IMX728_REG_VFLIP              CCI_REG8(0xb67d)
+#define IMX728_REG_VMINOR             CCI_REG8(0x6000)
+#define IMX728_REG_VMAJOR             CCI_REG8(0x6002)
+#define IMX728_REG_RESET_0            CCI_REG8(0xb661)
+#define IMX728_REG_RESET_1            CCI_REG8(0x95c5)
+#define IMX728_REG_INCK_0             CCI_REG8(0x1b20)
+#define IMX728_REG_INCK_1             CCI_REG8(0x1b1c)
+#define IMX728_REG_SLEEP              CCI_REG8(0x1b05)
+#define IMX728_REG_REGMAP             CCI_REG8(0xffff)
+#define IMX728_REG_UNIT_00            CCI_REG8(0x98e0)
+#define IMX728_REG_UNIT_01            CCI_REG8(0x98e8)
+#define IMX728_REG_UNIT_02            CCI_REG8(0x98f0)
+#define IMX728_REG_OB_0               CCI_REG16_LE(0xec12)
+#define IMX728_REG_OB_1               CCI_REG8(0xec14)
+#define IMX728_REG_SKEW               CCI_REG8(0x1761)
+#define IMX728_REG_SUBP_0             CCI_REG8(0x9714)
+#define IMX728_REG_SUBP_1             CCI_REG8(0xb684)
+#define IMX728_REG_STREAM_02          CCI_REG8(0x1b04)
+
+enum imx728_sensor_state {
+	IMX728_SENSOR_STATE_SLEEP      = 0x02,
+	IMX728_SENSOR_STATE_STANDBY    = 0x04,
+	IMX728_SENSOR_STATE_STREAMING  = 0x10,
+	IMX728_SENSOR_STATE_SAFE       = 0x20,
+};
+
+enum imx728_remap_mode_id {
+	IMX728_REMAP_MODE_STANDBY                              = 0x00,
+	IMX728_REMAP_MODE_STANDBY_PIXEL_SHADING_COMPENSATION   = 0x01,
+	IMX728_REMAP_MODE_STANDBY_SPOT_PIXEL_COMPENSATION      = 0x02,
+	IMX728_REMAP_MODE_STREAMING                            = 0x04,
+	IMX728_REMAP_MODE_STREAMING_PIXEL_SHADING_COMPENSATION = 0x05,
+	IMX728_REMAP_MODE_STREAMING_SPOT_PIXEL_COMPENSATION    = 0x06,
+	IMX728_REMAP_MODE_SLEEP                                = 0x20,
+};
+
+enum imx728_drive_mode {
+	IMX728_MODE_3856x2176_45_4LANE_RAW10 = 0x01,
+	IMX728_MODE_3856x2176_45_4LANE_RAW12 = 0x02,
+	IMX728_MODE_3856x2176_45_4LANE_RAW16 = 0x03,
+	IMX728_MODE_3856x2176_45_4LANE_RAW20 = 0x04,
+	IMX728_MODE_3856x2176_45_4LANE_RAW12_HDR = 0x05,
+	IMX728_MODE_3856x2176_40_4LANE_RAW10 = 0x11,
+	IMX728_MODE_3856x2176_40_4LANE_RAW12 = 0x12,
+	IMX728_MODE_3856x2176_40_4LANE_RAW16 = 0x13,
+	IMX728_MODE_3856x2176_40_4LANE_RAW20 = 0x14,
+	IMX728_MODE_3856x2176_40_4LANE_RAW12_HDR = 0x16,
+};
+
+enum imx728_awbmode {
+	IMX728_AWBMODE_ATW = 0,
+	IMX728_AWBMODE_ALL_PULL_IN = 1,
+	IMX728_AWBMODE_USER_PRESET = 2,
+	IMX728_AWBMODE_FULL_MWB = 3,
+	IMX728_AWBMODE_HOLD = 4,
+};
+
+enum imx728_img_raw_mode {
+	IMX728_IMG_MODE_LINEAR = 0x0,
+	IMX728_IMG_MODE_LI = 0x1,
+	IMX728_IMG_MODE_HDR = 0x2,
+	IMX728_IMG_MODE_LI_HDR = 0x3,
+};
+
+enum imx728_aemode {
+	IMX728_AEMODE_AE_AUTO  = 0,
+	IMX728_AEMODE_AE_HOLD  = 1,
+	IMX728_AEMODE_SCALE_ME = 2,
+	IMX728_AEMODE_FULL_ME  = 3,
+};
+
+enum imx728_fme_shtval_unit {
+	IMX728_FME_SHTVAL_UNIT_LINES        = 1,
+	IMX728_FME_SHTVAL_UNIT_MICROSECONDS = 3,
+	IMX728_FME_SHTVAL_UNIT_FRAMES       = 4,
+};
+
+enum imx728_linear_raw_sel {
+	IMX728_RAW_SEL_SP1H = 0x0,
+	IMX728_RAW_SEL_SP1L = 0x1,
+	IMX728_RAW_SEL_SP1EC = 0x2,
+	IMX728_RAW_SEL_SP2 = 0x3,
+	IMX728_RAW_SEL_SP1VS = 0x4
+};
+
+struct imx728_ctrl {
+	struct v4l2_ctrl_handler handler;
+	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *again;
+	struct v4l2_ctrl *h_flip;
+	struct v4l2_ctrl *v_flip;
+	struct v4l2_ctrl *pixel_rate;
+	struct v4l2_ctrl *link_freq;
+};
+
+/*
+ * struct imx728 - imx728 device structure
+ * @dev: Device handle
+ * @clk: Pointer to imx728 clock
+ * @client: Pointer to I2C client
+ * @regmap: Pointer to regmap structure
+ * @reset_gpio: Pointer to XCLR gpio
+ * @subdev: V4L2 subdevice structure
+ * @format: V4L2 media bus frame format structure
+ *              (width and height are in sync with the compose rect)
+ * @pad: Media pad structure
+ * @ctrl: imx728 control structure
+ * @clk_rate: Frequency of imx728 clock
+ * @fps: Current frame rate of the sensor.
+ * @lock: Mutex structure for V4L2 ctrl handler
+ * @streaming: Flag to store streaming on/off status
+ */
+struct imx728 {
+	struct device *dev;
+
+	struct clk *clk;
+	struct i2c_client *client;
+	struct regmap *regmap;
+	struct gpio_desc *reset_gpio;
+
+	struct v4l2_subdev subdev;
+	struct v4l2_mbus_framefmt format;
+	struct media_pad pad;
+
+	struct imx728_ctrl ctrl;
+
+	unsigned long clk_rate;
+	u32 fps;
+
+	struct mutex lock;
+	bool streaming;
+};
+
+static const struct v4l2_area imx728_framesizes[] = {
+	{
+		.width = 3856,
+		.height = 2176,
+	},
+};
+
+static const u32 imx728_mbus_formats[] = {
+	MEDIA_BUS_FMT_SRGGB12_1X12,
+};
+
+static const s64 imx728_link_freq_menu[] = {
+	IMX728_LINK_FREQ,
+};
+
+static const struct cci_reg_sequence imx728_wdr_12bit_3856x2176[] = {
+	{CCI_REG8(0xffff), 0x00},
+	{CCI_REG8(0x1749), 0x01},
+	{CCI_REG8(0x174b), 0x01},
+	{CCI_REG8(0x2dcc), 0x69},
+	{CCI_REG8(0x2dcd), 0x04},
+	{CCI_REG8(0x2dce), 0x68},
+	{CCI_REG8(0x2dcf), 0x04},
+	{CCI_REG8(0x2dd4), 0x00},
+	{CCI_REG8(0x2dd5), 0x00},
+	{CCI_REG8(0x2dd6), 0x00},
+	{CCI_REG8(0x2dd7), 0x00},
+	{CCI_REG8(0x2dd8), 0x00},
+	{CCI_REG8(0x2dd9), 0x00},
+	{CCI_REG8(0x2ddc), 0x00},
+	{CCI_REG8(0x2ddd), 0x00},
+	{CCI_REG8(0x2dde), 0x63},
+	{CCI_REG8(0x2ddf), 0x04},
+	{CCI_REG8(0x2de0), 0x62},
+	{CCI_REG8(0x2de1), 0x04},
+	{CCI_REG8(0x2de6), 0x00},
+	{CCI_REG8(0x2de7), 0x00},
+	{CCI_REG8(0x2de8), 0x00},
+	{CCI_REG8(0x2de9), 0x00},
+	{CCI_REG8(0x2dea), 0x00},
+	{CCI_REG8(0x2deb), 0x00},
+	{CCI_REG8(0x2dee), 0x00},
+	{CCI_REG8(0x2def), 0x00},
+	{CCI_REG8(0x2df8), 0x00},
+	{CCI_REG8(0x2df9), 0x00},
+	{CCI_REG8(0x2dfa), 0x00},
+	{CCI_REG8(0x2dfb), 0x00},
+	{CCI_REG8(0x2dfc), 0x00},
+	{CCI_REG8(0x2dfd), 0x00},
+	{CCI_REG8(0x2e00), 0x00},
+	{CCI_REG8(0x2e01), 0x00},
+	{CCI_REG8(0x2e02), 0x68},
+	{CCI_REG8(0x2e03), 0x04},
+	{CCI_REG8(0x2e04), 0x69},
+	{CCI_REG8(0x2e05), 0x04},
+	{CCI_REG8(0x2e06), 0x62},
+	{CCI_REG8(0x2e07), 0x04},
+	{CCI_REG8(0x2e08), 0x63},
+	{CCI_REG8(0x2e09), 0x04},
+	{CCI_REG8(0x2e0e), 0x6c},
+	{CCI_REG8(0x2e0f), 0x04},
+	{CCI_REG8(0x2e10), 0x66},
+	{CCI_REG8(0x2e11), 0x04},
+	{CCI_REG8(0x2e12), 0x67},
+	{CCI_REG8(0x2e13), 0x04},
+	{CCI_REG8(0x2e28), 0x78},
+	{CCI_REG8(0x2e29), 0x05},
+	{CCI_REG8(0x2e2a), 0x00},
+	{CCI_REG8(0x2e2c), 0x78},
+	{CCI_REG8(0x2e2d), 0x05},
+	{CCI_REG8(0x2e2e), 0x00},
+	{CCI_REG8(0x2e3a), 0x05},
+	{CCI_REG8(0x2e3b), 0x00},
+	{CCI_REG8(0x2e40), 0x5a},
+	{CCI_REG8(0x2e60), 0x7f},
+	{CCI_REG8(0x2e61), 0x00},
+	{CCI_REG8(0x2e64), 0x37},
+	{CCI_REG8(0x2e65), 0x00},
+	{CCI_REG8(0x2e66), 0x37},
+	{CCI_REG8(0x2e67), 0x00},
+	{CCI_REG8(0x2e68), 0xf7},
+	{CCI_REG8(0x2e69), 0x00},
+	{CCI_REG8(0x2e6a), 0x5f},
+	{CCI_REG8(0x2e6b), 0x00},
+	{CCI_REG8(0x2e6c), 0x3f},
+	{CCI_REG8(0x2e6d), 0x00},
+	{CCI_REG8(0x2e6e), 0x6f},
+	{CCI_REG8(0x2e6f), 0x00},
+	{CCI_REG8(0x2e70), 0x3f},
+	{CCI_REG8(0x2e71), 0x00},
+	{CCI_REG8(0x2e72), 0x2f},
+	{CCI_REG8(0x2e73), 0x00},
+	{CCI_REG8(0x2ea0), 0x64},
+	{CCI_REG8(0x2ea1), 0xca},
+	{CCI_REG8(0x2ea2), 0x19},
+	{CCI_REG8(0x2ea3), 0x2d},
+	{CCI_REG8(0x2edd), 0x01},
+	{CCI_REG8(0x2f26), 0x0b},
+	{CCI_REG8(0x2f27), 0x00},
+	{CCI_REG8(0x2f4a), 0x20},
+	{CCI_REG8(0x2f4b), 0x00},
+	{CCI_REG8(0x2f56), 0x00},
+	{CCI_REG8(0x2f57), 0x00},
+	{CCI_REG8(0x2f68), 0x78},
+	{CCI_REG8(0x2f69), 0x00},
+	{CCI_REG8(0x2f6a), 0x04},
+	{CCI_REG8(0x2f6b), 0x00},
+	{CCI_REG8(0x2f76), 0x16},
+	{CCI_REG8(0x2f77), 0x00},
+	{CCI_REG8(0x2f98), 0x8d},
+	{CCI_REG8(0x2f99), 0x00},
+	{CCI_REG8(0x2f9a), 0x0a},
+	{CCI_REG8(0x2f9b), 0x00},
+	{CCI_REG8(0x2fa6), 0x10},
+	{CCI_REG8(0x2fa7), 0x00},
+	{CCI_REG8(0x2fc2), 0x0b},
+	{CCI_REG8(0x2fc3), 0x00},
+	{CCI_REG8(0x2fe2), 0x0b},
+	{CCI_REG8(0x2fe3), 0x00},
+	{CCI_REG8(0x300c), 0x78},
+	{CCI_REG8(0x300d), 0x00},
+	{CCI_REG8(0x300e), 0x05},
+	{CCI_REG8(0x300f), 0x00},
+	{CCI_REG8(0x3018), 0x8d},
+	{CCI_REG8(0x3019), 0x00},
+	{CCI_REG8(0x301a), 0x0a},
+	{CCI_REG8(0x301b), 0x00},
+	{CCI_REG8(0x301c), 0x7d},
+	{CCI_REG8(0x301d), 0x00},
+	{CCI_REG8(0x301e), 0x04},
+	{CCI_REG8(0x301f), 0x00},
+	{CCI_REG8(0x306a), 0x00},
+	{CCI_REG8(0x306b), 0x00},
+	{CCI_REG8(0x306c), 0x00},
+	{CCI_REG8(0x306d), 0x00},
+	{CCI_REG8(0x306e), 0x01},
+	{CCI_REG8(0x306f), 0x00},
+	{CCI_REG8(0x3070), 0x06},
+	{CCI_REG8(0x3071), 0x00},
+	{CCI_REG8(0x3072), 0x07},
+	{CCI_REG8(0x3073), 0x00},
+	{CCI_REG8(0x3074), 0xc9},
+	{CCI_REG8(0x3075), 0x08},
+	{CCI_REG8(0x3082), 0xcc},
+	{CCI_REG8(0x3083), 0x08},
+	{CCI_REG8(0x3084), 0xcd},
+	{CCI_REG8(0x3085), 0x08},
+	{CCI_REG8(0x30ed), 0x11},
+	{CCI_REG8(0x30ee), 0x1f},
+	{CCI_REG8(0x30ef), 0x11},
+	{CCI_REG8(0x30f0), 0x0d},
+	{CCI_REG8(0x30f1), 0x1f},
+	{CCI_REG8(0x30f2), 0x1f},
+	{CCI_REG8(0x3142), 0x00},
+	{CCI_REG8(0x315e), 0xd4},
+	{CCI_REG8(0x315f), 0x01},
+	{CCI_REG8(0x3162), 0x47},
+	{CCI_REG8(0x3163), 0x02},
+	{CCI_REG8(0x3176), 0xe0},
+	{CCI_REG8(0x3177), 0x01},
+	{CCI_REG8(0x317a), 0x41},
+	{CCI_REG8(0x317b), 0x02},
+	{CCI_REG8(0x31c2), 0x88},
+	{CCI_REG8(0x31c3), 0x01},
+	{CCI_REG8(0x31d4), 0xd5},
+	{CCI_REG8(0x31d5), 0x01},
+	{CCI_REG8(0x31d8), 0x48},
+	{CCI_REG8(0x31d9), 0x02},
+	{CCI_REG8(0x31ec), 0xe1},
+	{CCI_REG8(0x31ed), 0x01},
+	{CCI_REG8(0x31f0), 0x42},
+	{CCI_REG8(0x31f1), 0x02},
+	{CCI_REG8(0x3238), 0x89},
+	{CCI_REG8(0x3239), 0x01},
+	{CCI_REG8(0x3256), 0xff},
+	{CCI_REG8(0x3257), 0x07},
+	{CCI_REG8(0x326e), 0x05},
+	{CCI_REG8(0x326f), 0x03},
+	{CCI_REG8(0x32ba), 0xff},
+	{CCI_REG8(0x32bb), 0x07},
+	{CCI_REG8(0x32d0), 0xff},
+	{CCI_REG8(0x32d1), 0x07},
+	{CCI_REG8(0x32d2), 0xff},
+	{CCI_REG8(0x32d3), 0x07},
+	{CCI_REG8(0x32e8), 0xff},
+	{CCI_REG8(0x32e9), 0x07},
+	{CCI_REG8(0x32ea), 0xff},
+	{CCI_REG8(0x32eb), 0x07},
+	{CCI_REG8(0x3334), 0xff},
+	{CCI_REG8(0x3335), 0x07},
+	{CCI_REG8(0x3336), 0xff},
+	{CCI_REG8(0x3337), 0x07},
+	{CCI_REG8(0x334c), 0xff},
+	{CCI_REG8(0x334d), 0x07},
+	{CCI_REG8(0x33b0), 0xff},
+	{CCI_REG8(0x33b1), 0x07},
+	{CCI_REG8(0x33c6), 0xff},
+	{CCI_REG8(0x33c7), 0x07},
+	{CCI_REG8(0x33d2), 0x00},
+	{CCI_REG8(0x33d3), 0x03},
+	{CCI_REG8(0x3412), 0xff},
+	{CCI_REG8(0x3413), 0x07},
+	{CCI_REG8(0x3420), 0xff},
+	{CCI_REG8(0x3421), 0x07},
+	{CCI_REG8(0x3422), 0xff},
+	{CCI_REG8(0x3423), 0x07},
+	{CCI_REG8(0x346c), 0x28},
+	{CCI_REG8(0x346d), 0x01},
+	{CCI_REG8(0x3470), 0xff},
+	{CCI_REG8(0x3471), 0x07},
+	{CCI_REG8(0x347c), 0x01},
+	{CCI_REG8(0x347d), 0x03},
+	{CCI_REG8(0x34bc), 0xff},
+	{CCI_REG8(0x34bd), 0x07},
+	{CCI_REG8(0x3556), 0x03},
+	{CCI_REG8(0x3557), 0x03},
+	{CCI_REG8(0x3562), 0xfb},
+	{CCI_REG8(0x3563), 0x02},
+	{CCI_REG8(0x3586), 0x44},
+	{CCI_REG8(0x3587), 0x02},
+	{CCI_REG8(0x35b8), 0x04},
+	{CCI_REG8(0x35b9), 0x03},
+	{CCI_REG8(0x35c4), 0xfc},
+	{CCI_REG8(0x35c5), 0x02},
+	{CCI_REG8(0x35e8), 0x45},
+	{CCI_REG8(0x35e9), 0x02},
+	{CCI_REG8(0x35f4), 0xd6},
+	{CCI_REG8(0x35f5), 0x01},
+	{CCI_REG8(0x3636), 0xd5},
+	{CCI_REG8(0x3637), 0x01},
+	{CCI_REG8(0x3750), 0xc1},
+	{CCI_REG8(0x3751), 0x00},
+	{CCI_REG8(0x3752), 0xff},
+	{CCI_REG8(0x3753), 0x07},
+	{CCI_REG8(0x3754), 0xff},
+	{CCI_REG8(0x3755), 0x07},
+	{CCI_REG8(0x3760), 0xff},
+	{CCI_REG8(0x3761), 0x07},
+	{CCI_REG8(0x37b0), 0xc1},
+	{CCI_REG8(0x37b1), 0x00},
+	{CCI_REG8(0x37b2), 0xdc},
+	{CCI_REG8(0x37b3), 0x01},
+	{CCI_REG8(0x37b4), 0x03},
+	{CCI_REG8(0x37b5), 0x02},
+	{CCI_REG8(0x37b6), 0x33},
+	{CCI_REG8(0x37b7), 0x02},
+	{CCI_REG8(0x37f0), 0xff},
+	{CCI_REG8(0x37f1), 0x07},
+	{CCI_REG8(0x37f2), 0xc0},
+	{CCI_REG8(0x37f3), 0x00},
+	{CCI_REG8(0x37f6), 0xff},
+	{CCI_REG8(0x37f7), 0x07},
+	{CCI_REG8(0x3800), 0xdd},
+	{CCI_REG8(0x3801), 0x01},
+	{CCI_REG8(0x3802), 0xc0},
+	{CCI_REG8(0x3803), 0x00},
+	{CCI_REG8(0x3804), 0x34},
+	{CCI_REG8(0x3805), 0x02},
+	{CCI_REG8(0x3806), 0x02},
+	{CCI_REG8(0x3807), 0x02},
+	{CCI_REG8(0x3b10), 0xff},
+	{CCI_REG8(0x3b11), 0x07},
+	{CCI_REG8(0x3b12), 0x00},
+	{CCI_REG8(0x3b13), 0x00},
+	{CCI_REG8(0x3b18), 0xff},
+	{CCI_REG8(0x3b19), 0x07},
+	{CCI_REG8(0x3b1a), 0x00},
+	{CCI_REG8(0x3b1b), 0x00},
+	{CCI_REG8(0x3b20), 0xff},
+	{CCI_REG8(0x3b21), 0x07},
+	{CCI_REG8(0x3b22), 0x00},
+	{CCI_REG8(0x3b23), 0x00},
+	{CCI_REG8(0x3b40), 0x00},
+	{CCI_REG8(0x3b41), 0x00},
+	{CCI_REG8(0x3b42), 0xff},
+	{CCI_REG8(0x3b43), 0x07},
+	{CCI_REG8(0x3b48), 0x00},
+	{CCI_REG8(0x3b49), 0x00},
+	{CCI_REG8(0x3b4a), 0xff},
+	{CCI_REG8(0x3b4b), 0x07},
+	{CCI_REG8(0x3b50), 0x00},
+	{CCI_REG8(0x3b51), 0x00},
+	{CCI_REG8(0x3b52), 0xff},
+	{CCI_REG8(0x3b53), 0x07},
+	{CCI_REG8(0x3b66), 0xd4},
+	{CCI_REG8(0x3b67), 0x01},
+	{CCI_REG8(0x3bf4), 0xd5},
+	{CCI_REG8(0x3bf5), 0x01},
+	{CCI_REG8(0x3d7c), 0xce},
+	{CCI_REG8(0x3d7d), 0x01},
+	{CCI_REG8(0x3dfc), 0x2c},
+	{CCI_REG8(0x3dfd), 0x01},
+	{CCI_REG8(0x3eba), 0xd7},
+	{CCI_REG8(0x3ebb), 0x00},
+	{CCI_REG8(0x3ebe), 0xff},
+	{CCI_REG8(0x3ebf), 0x07},
+	{CCI_REG8(0x3ec2), 0xff},
+	{CCI_REG8(0x3ec3), 0x07},
+	{CCI_REG8(0x3efa), 0xd7},
+	{CCI_REG8(0x3efb), 0x00},
+	{CCI_REG8(0x3efe), 0xff},
+	{CCI_REG8(0x3eff), 0x07},
+	{CCI_REG8(0x3f02), 0xff},
+	{CCI_REG8(0x3f03), 0x07},
+	{CCI_REG8(0x3f08), 0xd8},
+	{CCI_REG8(0x3f09), 0x00},
+	{CCI_REG8(0x3f0a), 0xdc},
+	{CCI_REG8(0x3f0b), 0x00},
+	{CCI_REG8(0x3f0c), 0xff},
+	{CCI_REG8(0x3f0d), 0x07},
+	{CCI_REG8(0x3f0e), 0xff},
+	{CCI_REG8(0x3f0f), 0x07},
+	{CCI_REG8(0x3f10), 0xff},
+	{CCI_REG8(0x3f11), 0x07},
+	{CCI_REG8(0x3f12), 0xff},
+	{CCI_REG8(0x3f13), 0x07},
+	{CCI_REG8(0x3f48), 0xd8},
+	{CCI_REG8(0x3f49), 0x00},
+	{CCI_REG8(0x3f4a), 0xdc},
+	{CCI_REG8(0x3f4b), 0x00},
+	{CCI_REG8(0x3f4c), 0xff},
+	{CCI_REG8(0x3f4d), 0x07},
+	{CCI_REG8(0x3f4e), 0xff},
+	{CCI_REG8(0x3f4f), 0x07},
+	{CCI_REG8(0x3f50), 0xff},
+	{CCI_REG8(0x3f51), 0x07},
+	{CCI_REG8(0x3f52), 0xff},
+	{CCI_REG8(0x3f53), 0x07},
+	{CCI_REG8(0x3f58), 0xdd},
+	{CCI_REG8(0x3f59), 0x00},
+	{CCI_REG8(0x3f5c), 0xff},
+	{CCI_REG8(0x3f5d), 0x07},
+	{CCI_REG8(0x3f60), 0xff},
+	{CCI_REG8(0x3f61), 0x07},
+	{CCI_REG8(0x3f98), 0xdd},
+	{CCI_REG8(0x3f99), 0x00},
+	{CCI_REG8(0x3f9c), 0xff},
+	{CCI_REG8(0x3f9d), 0x07},
+	{CCI_REG8(0x3fa0), 0xff},
+	{CCI_REG8(0x3fa1), 0x07},
+	{CCI_REG8(0x3faa), 0xc7},
+	{CCI_REG8(0x3fab), 0x00},
+	{CCI_REG8(0x3fac), 0xe0},
+	{CCI_REG8(0x3fad), 0x00},
+	{CCI_REG8(0x3fea), 0xc7},
+	{CCI_REG8(0x3feb), 0x00},
+	{CCI_REG8(0x3fec), 0xe0},
+	{CCI_REG8(0x3fed), 0x00},
+	{CCI_REG8(0x3ff8), 0xc8},
+	{CCI_REG8(0x3ff9), 0x00},
+	{CCI_REG8(0x3ffa), 0xcc},
+	{CCI_REG8(0x3ffb), 0x00},
+	{CCI_REG8(0x4038), 0xc8},
+	{CCI_REG8(0x4039), 0x00},
+	{CCI_REG8(0x403a), 0xcc},
+	{CCI_REG8(0x403b), 0x00},
+	{CCI_REG8(0x4048), 0xcd},
+	{CCI_REG8(0x4049), 0x00},
+	{CCI_REG8(0x404e), 0xdf},
+	{CCI_REG8(0x404f), 0x00},
+	{CCI_REG8(0x4088), 0xcd},
+	{CCI_REG8(0x4089), 0x00},
+	{CCI_REG8(0x408e), 0xdf},
+	{CCI_REG8(0x408f), 0x00},
+	{CCI_REG8(0x420c), 0xff},
+	{CCI_REG8(0x420d), 0x07},
+	{CCI_REG8(0x4210), 0xff},
+	{CCI_REG8(0x4211), 0x07},
+	{CCI_REG8(0x4286), 0xff},
+	{CCI_REG8(0x4287), 0x07},
+	{CCI_REG8(0x428a), 0xff},
+	{CCI_REG8(0x428b), 0x07},
+	{CCI_REG8(0x4408), 0xff},
+	{CCI_REG8(0x4409), 0x07},
+	{CCI_REG8(0x4410), 0xff},
+	{CCI_REG8(0x4411), 0x07},
+	{CCI_REG8(0x4418), 0xff},
+	{CCI_REG8(0x4419), 0x07},
+	{CCI_REG8(0x4420), 0xff},
+	{CCI_REG8(0x4421), 0x07},
+	{CCI_REG8(0x4428), 0xff},
+	{CCI_REG8(0x4429), 0x07},
+	{CCI_REG8(0x4430), 0xff},
+	{CCI_REG8(0x4431), 0x07},
+	{CCI_REG8(0x4436), 0xff},
+	{CCI_REG8(0x4437), 0x07},
+	{CCI_REG8(0x443c), 0xff},
+	{CCI_REG8(0x443d), 0x07},
+	{CCI_REG8(0x4444), 0xff},
+	{CCI_REG8(0x4445), 0x07},
+	{CCI_REG8(0x4464), 0xff},
+	{CCI_REG8(0x4465), 0x07},
+	{CCI_REG8(0x446c), 0xff},
+	{CCI_REG8(0x446d), 0x07},
+	{CCI_REG8(0x4474), 0xff},
+	{CCI_REG8(0x4475), 0x07},
+	{CCI_REG8(0x4485), 0x28},
+	{CCI_REG8(0x44a7), 0x2e},
+	{CCI_REG8(0x44a8), 0x2c},
+	{CCI_REG8(0x4594), 0x1b},
+	{CCI_REG8(0x4596), 0x1f},
+	{CCI_REG8(0x459b), 0x1b},
+	{CCI_REG8(0x459d), 0x1f},
+	{CCI_REG8(0x45a1), 0x14},
+	{CCI_REG8(0x45a4), 0x16},
+	{CCI_REG8(0x45a6), 0x14},
+	{CCI_REG8(0x45ab), 0x16},
+	{CCI_REG8(0x45ac), 0x11},
+	{CCI_REG8(0x45ad), 0x11},
+	{CCI_REG8(0x45ae), 0x0b},
+	{CCI_REG8(0x45af), 0x0b},
+	{CCI_REG8(0x45b0), 0x0b},
+	{CCI_REG8(0x45b1), 0x0b},
+	{CCI_REG8(0x45b2), 0x1f},
+	{CCI_REG8(0x45b3), 0x0b},
+	{CCI_REG8(0x45b4), 0x0b},
+	{CCI_REG8(0x45b5), 0x1f},
+	{CCI_REG8(0x45b6), 0x1f},
+	{CCI_REG8(0x45b7), 0x1f},
+	{CCI_REG8(0x45b8), 0x1f},
+	{CCI_REG8(0x45b9), 0x1f},
+	{CCI_REG8(0x45ba), 0x1f},
+	{CCI_REG8(0x45bb), 0x1f},
+	{CCI_REG8(0x45bc), 0x1f},
+	{CCI_REG8(0x45bd), 0x1f},
+	{CCI_REG8(0x45be), 0x0d},
+	{CCI_REG8(0x45bf), 0x0d},
+	{CCI_REG8(0x45c0), 0x0b},
+	{CCI_REG8(0x45c1), 0x0b},
+	{CCI_REG8(0x45c2), 0x0b},
+	{CCI_REG8(0x45c3), 0x0b},
+	{CCI_REG8(0x45c4), 0x1f},
+	{CCI_REG8(0x45c5), 0x0b},
+	{CCI_REG8(0x45c6), 0x0b},
+	{CCI_REG8(0x460b), 0x01},
+	{CCI_REG8(0x462e), 0x1c},
+	{CCI_REG8(0x4631), 0x01},
+	{CCI_REG8(0x465a), 0x08},
+	{CCI_REG8(0x465b), 0x00},
+	{CCI_REG8(0x465c), 0x00},
+	{CCI_REG8(0x465d), 0x00},
+	{CCI_REG8(0x465e), 0x06},
+	{CCI_REG8(0x4660), 0x00},
+	{CCI_REG8(0x4661), 0x00},
+	{CCI_REG8(0x4662), 0x00},
+	{CCI_REG8(0x4663), 0x00},
+	{CCI_REG8(0x4664), 0x00},
+	{CCI_REG8(0x4665), 0x00},
+	{CCI_REG8(0x4666), 0x00},
+	{CCI_REG8(0x4667), 0x00},
+	{CCI_REG8(0x4668), 0x00},
+	{CCI_REG8(0x4669), 0x00},
+	{CCI_REG8(0x466a), 0x04},
+	{CCI_REG8(0x466c), 0x00},
+	{CCI_REG8(0x466d), 0x00},
+	{CCI_REG8(0x466e), 0x06},
+	{CCI_REG8(0x4670), 0x00},
+	{CCI_REG8(0x4671), 0x00},
+	{CCI_REG8(0x4672), 0x00},
+	{CCI_REG8(0x4673), 0x00},
+	{CCI_REG8(0x4674), 0x00},
+	{CCI_REG8(0x4675), 0x00},
+	{CCI_REG8(0x4676), 0x00},
+	{CCI_REG8(0x4677), 0x00},
+	{CCI_REG8(0x4678), 0x00},
+	{CCI_REG8(0x4679), 0x00},
+	{CCI_REG8(0x46ae), 0xca},
+	{CCI_REG8(0x46af), 0x00},
+	{CCI_REG8(0x46b0), 0xb8},
+	{CCI_REG8(0x46b1), 0x01},
+	{CCI_REG8(0x46b6), 0x34},
+	{CCI_REG8(0x46b7), 0x02},
+	{CCI_REG8(0x46b8), 0x87},
+	{CCI_REG8(0x46b9), 0x02},
+	{CCI_REG8(0x46ba), 0x94},
+	{CCI_REG8(0x46bb), 0x06},
+	{CCI_REG8(0x46d2), 0xa0},
+	{CCI_REG8(0x46d3), 0x04},
+	{CCI_REG8(0x4778), 0x02},
+	{CCI_REG8(0x4779), 0x02},
+	{CCI_REG8(0x477a), 0x02},
+	{CCI_REG8(0x477b), 0x02},
+	{CCI_REG8(0x477c), 0x02},
+	{CCI_REG8(0x477d), 0x02},
+	{CCI_REG8(0x477e), 0x02},
+	{CCI_REG8(0x477f), 0x02},
+	{CCI_REG8(0x4782), 0x03},
+	{CCI_REG8(0x4786), 0x03},
+	{CCI_REG8(0x4788), 0x03},
+	{CCI_REG8(0x4789), 0x03},
+	{CCI_REG8(0x478a), 0x03},
+	{CCI_REG8(0x478c), 0x03},
+	{CCI_REG8(0x478d), 0x03},
+	{CCI_REG8(0x478e), 0x03},
+	{CCI_REG8(0x4792), 0x03},
+	{CCI_REG8(0x4796), 0x03},
+	{CCI_REG8(0x4798), 0x01},
+	{CCI_REG8(0x4799), 0x02},
+	{CCI_REG8(0x479a), 0x03},
+	{CCI_REG8(0x479c), 0x03},
+	{CCI_REG8(0x479d), 0x03},
+	{CCI_REG8(0x479e), 0x03},
+	{CCI_REG8(0x47a3), 0x01},
+	{CCI_REG8(0x47ab), 0x00},
+	{CCI_REG8(0x47ad), 0x00},
+	{CCI_REG8(0x47b0), 0x03},
+	{CCI_REG8(0x47b1), 0x03},
+	{CCI_REG8(0x47b2), 0x03},
+	{CCI_REG8(0x47b3), 0x03},
+	{CCI_REG8(0x47b4), 0x03},
+	{CCI_REG8(0x47b5), 0x03},
+	{CCI_REG8(0x47b6), 0x03},
+	{CCI_REG8(0x47b7), 0x03},
+	{CCI_REG8(0x47f4), 0x12},
+	{CCI_REG8(0x47f6), 0x0c},
+	{CCI_REG8(0x47fa), 0x09},
+	{CCI_REG8(0x47fb), 0x0b},
+	{CCI_REG8(0x47fc), 0x0a},
+	{CCI_REG8(0x4801), 0x05},
+	{CCI_REG8(0x4802), 0x04},
+	{CCI_REG8(0x4803), 0x06},
+	{CCI_REG8(0x4804), 0x05},
+	{CCI_REG8(0x4805), 0x04},
+	{CCI_REG8(0x480a), 0x0d},
+	{CCI_REG8(0x480b), 0x14},
+	{CCI_REG8(0x480c), 0x10},
+	{CCI_REG8(0x480d), 0x12},
+	{CCI_REG8(0x480e), 0x16},
+	{CCI_REG8(0x4815), 0x09},
+	{CCI_REG8(0x4816), 0x05},
+	{CCI_REG8(0x4817), 0x08},
+	{CCI_REG8(0x481e), 0x09},
+	{CCI_REG8(0x481f), 0x09},
+	{CCI_REG8(0x4820), 0x0d},
+	{CCI_REG8(0x4827), 0x09},
+	{CCI_REG8(0x4828), 0x07},
+	{CCI_REG8(0x4829), 0x0b},
+	{CCI_REG8(0x482e), 0x0f},
+	{CCI_REG8(0x482f), 0x0f},
+	{CCI_REG8(0x4830), 0x0a},
+	{CCI_REG8(0x4831), 0x0a},
+	{CCI_REG8(0x48f2), 0x04},
+	{CCI_REG8(0x48f6), 0xe2},
+	{CCI_REG8(0x48f7), 0x00},
+	{CCI_REG8(0x48f8), 0x84},
+	{CCI_REG8(0x48f9), 0x00},
+	{CCI_REG8(0x48fa), 0x80},
+	{CCI_REG8(0x48fb), 0x00},
+	{CCI_REG8(0x48fc), 0x45},
+	{CCI_REG8(0x48fd), 0x00},
+	{CCI_REG8(0x48fe), 0x70},
+	{CCI_REG8(0x48ff), 0x00},
+	{CCI_REG8(0x48f6), 0xe2},
+	{CCI_REG8(0x48f7), 0x00},
+	{CCI_REG8(0x48f8), 0x84},
+	{CCI_REG8(0x48f9), 0x00},
+	{CCI_REG8(0x48fa), 0x80},
+	{CCI_REG8(0x48fb), 0x00},
+	{CCI_REG8(0x48fc), 0x45},
+	{CCI_REG8(0x48fd), 0x00},
+	{CCI_REG8(0x48fe), 0x70},
+	{CCI_REG8(0x48ff), 0x00},
+	{CCI_REG8(0x4902), 0xb9},
+	{CCI_REG8(0x4903), 0x00},
+	{CCI_REG8(0x4904), 0x45},
+	{CCI_REG8(0x4905), 0x00},
+	{CCI_REG8(0x4906), 0x1f},
+	{CCI_REG8(0x4907), 0x1f},
+	{CCI_REG8(0x4908), 0x18},
+	{CCI_REG8(0x4909), 0x1f},
+	{CCI_REG8(0x490a), 0x1e},
+	{CCI_REG8(0x490c), 0x0a},
+	{CCI_REG8(0x490d), 0x1f},
+	{CCI_REG8(0x490e), 0x00},
+	{CCI_REG8(0x490f), 0x00},
+	{CCI_REG8(0x4910), 0x06},
+	{CCI_REG8(0x4911), 0x00},
+	{CCI_REG8(0x4912), 0x00},
+	{CCI_REG8(0x4915), 0x00},
+	{CCI_REG8(0x491c), 0x78},
+	{CCI_REG8(0x491d), 0x78},
+	{CCI_REG8(0x491e), 0x78},
+	{CCI_REG8(0x491f), 0x78},
+	{CCI_REG8(0x4924), 0x61},
+	{CCI_REG8(0x4925), 0x61},
+	{CCI_REG8(0x4926), 0x61},
+	{CCI_REG8(0x4927), 0x61},
+	{CCI_REG8(0x4928), 0x5f},
+	{CCI_REG8(0x4929), 0x5f},
+	{CCI_REG8(0x492a), 0x5f},
+	{CCI_REG8(0x492b), 0x5f},
+	{CCI_REG8(0x492c), 0x78},
+	{CCI_REG8(0x492d), 0x78},
+	{CCI_REG8(0x492e), 0x78},
+	{CCI_REG8(0x492f), 0x78},
+	{CCI_REG8(0x4930), 0x78},
+	{CCI_REG8(0x4931), 0x78},
+	{CCI_REG8(0x4932), 0x78},
+	{CCI_REG8(0x4933), 0x78},
+	{CCI_REG8(0x4934), 0x78},
+	{CCI_REG8(0x4935), 0x78},
+	{CCI_REG8(0x4936), 0x78},
+	{CCI_REG8(0x4937), 0x78},
+	{CCI_REG8(0x4938), 0x5f},
+	{CCI_REG8(0x4939), 0x5f},
+	{CCI_REG8(0x493a), 0x5f},
+	{CCI_REG8(0x493b), 0x5f},
+	{CCI_REG8(0x4942), 0x0a},
+	{CCI_REG8(0x4943), 0x0a},
+	{CCI_REG8(0x4944), 0x0a},
+	{CCI_REG8(0x4945), 0x0a},
+	{CCI_REG8(0x4947), 0x1f},
+	{CCI_REG8(0x4948), 0x1f},
+	{CCI_REG8(0x4949), 0x1f},
+	{CCI_REG8(0x494a), 0x0c},
+	{CCI_REG8(0x494b), 0x0c},
+	{CCI_REG8(0x494c), 0x0c},
+	{CCI_REG8(0x494d), 0x0c},
+	{CCI_REG8(0x494e), 0x0e},
+	{CCI_REG8(0x494f), 0x0e},
+	{CCI_REG8(0x4950), 0x0e},
+	{CCI_REG8(0x4951), 0x0e},
+	{CCI_REG8(0x4952), 0x11},
+	{CCI_REG8(0x4953), 0x11},
+	{CCI_REG8(0x4954), 0x11},
+	{CCI_REG8(0x4955), 0x11},
+	{CCI_REG8(0x4956), 0x0e},
+	{CCI_REG8(0x4957), 0x0e},
+	{CCI_REG8(0x4958), 0x0e},
+	{CCI_REG8(0x4959), 0x0e},
+	{CCI_REG8(0x495a), 0x10},
+	{CCI_REG8(0x495b), 0x10},
+	{CCI_REG8(0x495c), 0x10},
+	{CCI_REG8(0x495d), 0x10},
+	{CCI_REG8(0x495e), 0x0e},
+	{CCI_REG8(0x495f), 0x0e},
+	{CCI_REG8(0x4960), 0x0e},
+	{CCI_REG8(0x4961), 0x0e},
+	{CCI_REG8(0x4970), 0x00},
+	{CCI_REG8(0x4971), 0x00},
+	{CCI_REG8(0x4972), 0x00},
+	{CCI_REG8(0x4973), 0x00},
+	{CCI_REG8(0x4974), 0x00},
+	{CCI_REG8(0x4975), 0x00},
+	{CCI_REG8(0x4976), 0x00},
+	{CCI_REG8(0x4977), 0x00},
+	{CCI_REG8(0x4978), 0x04},
+	{CCI_REG8(0x4979), 0x04},
+	{CCI_REG8(0x497a), 0x04},
+	{CCI_REG8(0x497b), 0x04},
+	{CCI_REG8(0x497c), 0x03},
+	{CCI_REG8(0x497d), 0x03},
+	{CCI_REG8(0x497e), 0x03},
+	{CCI_REG8(0x497f), 0x03},
+	{CCI_REG8(0x4980), 0x05},
+	{CCI_REG8(0x4981), 0x05},
+	{CCI_REG8(0x4982), 0x05},
+	{CCI_REG8(0x4983), 0x05},
+	{CCI_REG8(0x4984), 0x00},
+	{CCI_REG8(0x4985), 0x00},
+	{CCI_REG8(0x4986), 0x00},
+	{CCI_REG8(0x4987), 0x00},
+	{CCI_REG8(0x49e0), 0xc3},
+	{CCI_REG8(0x49e1), 0x00},
+	{CCI_REG8(0x49e2), 0xea},
+	{CCI_REG8(0x49e3), 0x01},
+	{CCI_REG8(0x49e4), 0xd7},
+	{CCI_REG8(0x49e5), 0x02},
+	{CCI_REG8(0x49e8), 0xc3},
+	{CCI_REG8(0x49e9), 0x00},
+	{CCI_REG8(0x49ea), 0xd6},
+	{CCI_REG8(0x49eb), 0x01},
+	{CCI_REG8(0x4a68), 0x72},
+	{CCI_REG8(0x4a69), 0x00},
+	{CCI_REG8(0x4a6a), 0x6e},
+	{CCI_REG8(0x4a6b), 0x00},
+	{CCI_REG8(0x4a9c), 0x6e},
+	{CCI_REG8(0x4a9d), 0x00},
+	{CCI_REG8(0x4bb8), 0x00},
+	{CCI_REG8(0x4bb9), 0x00},
+	{CCI_REG8(0x4bba), 0xff},
+	{CCI_REG8(0x4bbb), 0x03},
+	{CCI_REG8(0x4bc0), 0x00},
+	{CCI_REG8(0x4bc1), 0x00},
+	{CCI_REG8(0x4bc2), 0xff},
+	{CCI_REG8(0x4bc3), 0x03},
+	{CCI_REG8(0x4c46), 0x6e},
+	{CCI_REG8(0x4c47), 0x00},
+	{CCI_REG8(0x4cda), 0x28},
+	{CCI_REG8(0x4cdb), 0x00},
+	{CCI_REG8(0x4cde), 0x7b},
+	{CCI_REG8(0x4cdf), 0x00},
+	{CCI_REG8(0x4ce2), 0x28},
+	{CCI_REG8(0x4ce3), 0x00},
+	{CCI_REG8(0x4eea), 0x70},
+	{CCI_REG8(0x4eeb), 0x00},
+	{CCI_REG8(0x4f00), 0x6c},
+	{CCI_REG8(0x4f01), 0x00},
+	{CCI_REG8(0x5072), 0x6c},
+	{CCI_REG8(0x5073), 0x00},
+	{CCI_REG8(0x5086), 0x6c},
+	{CCI_REG8(0x5087), 0x00},
+	{CCI_REG8(0x55a0), 0x3a},
+	{CCI_REG8(0x55a1), 0x00},
+	{CCI_REG8(0x55a6), 0x7a},
+	{CCI_REG8(0x55a7), 0x01},
+	{CCI_REG8(0x55a8), 0x3a},
+	{CCI_REG8(0x55a9), 0x00},
+	{CCI_REG8(0x55ae), 0xbb},
+	{CCI_REG8(0x55af), 0x00},
+	{CCI_REG8(0x55b2), 0x60},
+	{CCI_REG8(0x55b3), 0x00},
+	{CCI_REG8(0x55b4), 0x86},
+	{CCI_REG8(0x55b5), 0x00},
+	{CCI_REG8(0x55b6), 0xb7},
+	{CCI_REG8(0x55b7), 0x00},
+	{CCI_REG8(0x55b8), 0x17},
+	{CCI_REG8(0x55b9), 0x00},
+	{CCI_REG8(0x55ba), 0x5f},
+	{CCI_REG8(0x55bb), 0x00},
+	{CCI_REG8(0x55bc), 0x8d},
+	{CCI_REG8(0x55bd), 0x00},
+	{CCI_REG8(0x55be), 0xbb},
+	{CCI_REG8(0x55bf), 0x00},
+	{CCI_REG8(0x594c), 0xff},
+	{CCI_REG8(0x594d), 0x03},
+	{CCI_REG8(0x594e), 0xff},
+	{CCI_REG8(0x594f), 0x03},
+	{CCI_REG8(0x5950), 0xff},
+	{CCI_REG8(0x5951), 0x03},
+	{CCI_REG8(0x5952), 0xff},
+	{CCI_REG8(0x5953), 0x03},
+	{CCI_REG8(0x5b24), 0x20},
+	{CCI_REG8(0x5b25), 0x0d},
+	{CCI_REG8(0x5b28), 0x88},
+	{CCI_REG8(0x5b29), 0x04},
+	{CCI_REG8(0x961c), 0x00},
+	{CCI_REG8(0x961d), 0x03},
+	{CCI_REG8(0x9722), 0x09},
+	{CCI_REG8(0x9788), 0x01},
+	{CCI_REG8(0x9796), 0xd0},
+	{CCI_REG8(0x9797), 0x0a},
+	{CCI_REG8(0x9798), 0xf0},
+	{CCI_REG8(0x9799), 0x00},
+	{CCI_REG8(0x979c), 0xd0},
+	{CCI_REG8(0x979d), 0x0a},
+	{CCI_REG8(0x979e), 0xf0},
+	{CCI_REG8(0x979f), 0x00},
+	{CCI_REG8(0x97a0), 0xc0},
+	{CCI_REG8(0x97a1), 0xdf},
+	{CCI_REG8(0x97a4), 0x80},
+	{CCI_REG8(0x97a5), 0x7a},
+	{CCI_REG8(0x97a8), 0x00},
+	{CCI_REG8(0x97a9), 0x50},
+	{CCI_REG8(0x97aa), 0xc0},
+	{CCI_REG8(0x97ab), 0x35},
+	{CCI_REG8(0x97c4), 0xc5},
+	{CCI_REG8(0x97c5), 0x02},
+	{CCI_REG8(0xb51d), 0x01},
+	{CCI_REG8(0xb526), 0x00},
+	{CCI_REG8(0xcf61), 0x00},
+	{CCI_REG8(0xcfaf), 0x00},
+	{CCI_REG8(0xcffd), 0x00},
+	{CCI_REG8(0xd04b), 0x00},
+	{CCI_REG8(0xd099), 0x00},
+	{CCI_REG8(0xd0e7), 0x00},
+	{CCI_REG8(0xb527), 0x05},
+	{CCI_REG8(0xcf62), 0x05},
+	{CCI_REG8(0xcfb0), 0x05},
+	{CCI_REG8(0xcffe), 0x05},
+	{CCI_REG8(0xd04c), 0x05},
+	{CCI_REG8(0xd09a), 0x05},
+	{CCI_REG8(0xd0e8), 0x05},
+	{CCI_REG8(0xb52a), 0xc0},
+	{CCI_REG8(0xcf65), 0xc0},
+	{CCI_REG8(0xcfb3), 0xc0},
+	{CCI_REG8(0xd001), 0xc0},
+	{CCI_REG8(0xd04f), 0xc0},
+	{CCI_REG8(0xd09d), 0xc0},
+	{CCI_REG8(0xd0eb), 0xc0},
+	{CCI_REG8(0xb52b), 0x03},
+	{CCI_REG8(0xcf66), 0x03},
+	{CCI_REG8(0xcfb4), 0x03},
+	{CCI_REG8(0xd002), 0x03},
+	{CCI_REG8(0xd050), 0x03},
+	{CCI_REG8(0xd09e), 0x03},
+	{CCI_REG8(0xd0ec), 0x03},
+	{CCI_REG8(0xb530), 0x00},
+	{CCI_REG8(0xcf6a), 0x00},
+	{CCI_REG8(0xcfb8), 0x00},
+	{CCI_REG8(0xd006), 0x00},
+	{CCI_REG8(0xd054), 0x00},
+	{CCI_REG8(0xd0a2), 0x00},
+	{CCI_REG8(0xd0f0), 0x00},
+	{CCI_REG8(0xb531), 0x05},
+	{CCI_REG8(0xcf6b), 0x05},
+	{CCI_REG8(0xcfb9), 0x05},
+	{CCI_REG8(0xd007), 0x05},
+	{CCI_REG8(0xd055), 0x05},
+	{CCI_REG8(0xd0a3), 0x05},
+	{CCI_REG8(0xd0f1), 0x05},
+	{CCI_REG8(0xb534), 0xc0},
+	{CCI_REG8(0xcf6e), 0xc0},
+	{CCI_REG8(0xcfbc), 0xc0},
+	{CCI_REG8(0xd00a), 0xc0},
+	{CCI_REG8(0xd058), 0xc0},
+	{CCI_REG8(0xd0a6), 0xc0},
+	{CCI_REG8(0xd0f4), 0xc0},
+	{CCI_REG8(0xb535), 0x03},
+	{CCI_REG8(0xcf6f), 0x03},
+	{CCI_REG8(0xcfbd), 0x03},
+	{CCI_REG8(0xd00b), 0x03},
+	{CCI_REG8(0xd059), 0x03},
+	{CCI_REG8(0xd0a7), 0x03},
+	{CCI_REG8(0xd0f5), 0x03},
+	{CCI_REG8(0xb644), 0x70},
+	{CCI_REG8(0xb645), 0x03},
+	{CCI_REG8(0xb646), 0x00},
+	{CCI_REG8(0xb647), 0x00},
+	{CCI_REG8(0xb68a), 0x00},
+	{CCI_REG8(0xb68b), 0x03},
+	{CCI_REG8(0xb6bc), 0x00},
+	{CCI_REG8(0xcf84), 0x00},
+	{CCI_REG8(0xcfd2), 0x00},
+	{CCI_REG8(0xd020), 0x00},
+	{CCI_REG8(0xd06e), 0x00},
+	{CCI_REG8(0xd0bc), 0x00},
+	{CCI_REG8(0xd10a), 0x00},
+	{CCI_REG8(0xb6bd), 0x05},
+	{CCI_REG8(0xcf85), 0x05},
+	{CCI_REG8(0xcfd3), 0x05},
+	{CCI_REG8(0xd021), 0x05},
+	{CCI_REG8(0xd06f), 0x05},
+	{CCI_REG8(0xd0bd), 0x05},
+	{CCI_REG8(0xd10b), 0x05},
+	{CCI_REG8(0xb6c0), 0xc0},
+	{CCI_REG8(0xcf88), 0xc0},
+	{CCI_REG8(0xcfd6), 0xc0},
+	{CCI_REG8(0xd024), 0xc0},
+	{CCI_REG8(0xd072), 0xc0},
+	{CCI_REG8(0xd0c0), 0xc0},
+	{CCI_REG8(0xd10e), 0xc0},
+	{CCI_REG8(0xb6c1), 0x03},
+	{CCI_REG8(0xcf89), 0x03},
+	{CCI_REG8(0xcfd7), 0x03},
+	{CCI_REG8(0xd025), 0x03},
+	{CCI_REG8(0xd073), 0x03},
+	{CCI_REG8(0xd0c1), 0x03},
+	{CCI_REG8(0xd10f), 0x03},
+	{CCI_REG8(0xb6cc), 0x00},
+	{CCI_REG8(0xcf8d), 0x00},
+	{CCI_REG8(0xcfdb), 0x00},
+	{CCI_REG8(0xd029), 0x00},
+	{CCI_REG8(0xd077), 0x00},
+	{CCI_REG8(0xd0c5), 0x00},
+	{CCI_REG8(0xd113), 0x00},
+	{CCI_REG8(0xb6cd), 0x05},
+	{CCI_REG8(0xcf8e), 0x05},
+	{CCI_REG8(0xcfdc), 0x05},
+	{CCI_REG8(0xd02a), 0x05},
+	{CCI_REG8(0xd078), 0x05},
+	{CCI_REG8(0xd0c6), 0x05},
+	{CCI_REG8(0xd114), 0x05},
+	{CCI_REG8(0xb6d0), 0xc0},
+	{CCI_REG8(0xcf91), 0xc0},
+	{CCI_REG8(0xcfdf), 0xc0},
+	{CCI_REG8(0xd02d), 0xc0},
+	{CCI_REG8(0xd07b), 0xc0},
+	{CCI_REG8(0xd0c9), 0xc0},
+	{CCI_REG8(0xd117), 0xc0},
+	{CCI_REG8(0xb6d1), 0x03},
+	{CCI_REG8(0xcf92), 0x03},
+	{CCI_REG8(0xcfe0), 0x03},
+	{CCI_REG8(0xd02e), 0x03},
+	{CCI_REG8(0xd07c), 0x03},
+	{CCI_REG8(0xd0ca), 0x03},
+	{CCI_REG8(0xd118), 0x03},
+	{CCI_REG8(0xb6e8), 0x51},
+	{CCI_REG8(0xb6e9), 0x05},
+	{CCI_REG8(0xb6ea), 0x55},
+	{CCI_REG8(0xb6ec), 0x40},
+	{CCI_REG8(0xb6ed), 0x05},
+	{CCI_REG8(0xb6ee), 0x55},
+	{CCI_REG8(0xb6ef), 0x55},
+	{CCI_REG8(0xb6f0), 0x55},
+	{CCI_REG8(0xb6f1), 0x55},
+	{CCI_REG8(0xb6f2), 0x55},
+	{CCI_REG8(0xb6f3), 0x01},
+	{CCI_REG8(0xec40), 0x70},
+	{CCI_REG8(0xec41), 0x03},
+	{CCI_REG8(0xec42), 0x00},
+	{CCI_REG8(0xec43), 0x00},
+	{CCI_REG8(0xec68), 0x88},
+	{CCI_REG8(0xec69), 0x07},
+	{CCI_REG8(0xec6a), 0x40},
+	{CCI_REG8(0xec6b), 0x04},
+	{CCI_REG8(0xec81), 0x01},
+	{CCI_REG8(0xec9e), 0x2c},
+	{CCI_REG8(0xec9f), 0x01},
+	{CCI_REG8(0xec80), 0x01},
+	{CCI_REG8(0x2dc0), 0xbb},
+	{CCI_REG8(0x2dc1), 0x08},
+	{CCI_REG8(0xb7dc), 0x01},
+	{CCI_REG8(0xb7dd), 0x01},
+	{CCI_REG8(0xb7de), 0x01},
+	{CCI_REG8(0x97a2), 0x80},
+	{CCI_REG8(0x97a3), 0xac},
+	{CCI_REG8(0x97a6), 0x00},
+	{CCI_REG8(0x97a7), 0x4b},
+	{CCI_REG8(0x97ae), 0x20},
+	{CCI_REG8(0x97af), 0x35},
+	{CCI_REG8(0x95c1), 0x01},
+	{CCI_REG8(0xfff0), 0x01},
+	{CCI_REG8(0x98ac), 0x03},
+	{CCI_REG8(0xa248), 0x03},
+	{CCI_REG8(0xffff), 0x00},
+	{CCI_REG8(0x9782), 0x00},
+	{CCI_REG8(0xb708), 0x00},
+	{CCI_REG8(0x9783), 0x00},
+	{CCI_REG8(0xffff), 0x00},
+	{CCI_REG8(0x1981), 0x01},
+	{CCI_REG8(0x1982), 0x01},
+	{CCI_REG8(0x1983), 0x01},
+	{CCI_REG8(0x1984), 0x01},
+	{CCI_REG8(0x1985), 0x01},
+	{CCI_REG8(0x56a5), 0x01},
+	{CCI_REG8(0x571c), 0x01},
+	{CCI_REG8(0x571d), 0x00},
+	{CCI_REG8(0x9782), 0x98},
+	{CCI_REG8(0xb708), 0x98},
+	{CCI_REG8(0x9783), 0x09},
+	{CCI_REG8(0x1708), 0x00},
+	{CCI_REG8(0x1709), 0x00},
+	{CCI_REG8(0x170a), 0x00},
+	{CCI_REG8(0x1b40), 0x00},
+	{CCI_REG8(0x1808), 0x01},
+	{CCI_REG8(0xffff), 0x00},
+	{CCI_REG8(0x98b5), 0x00},
+	{CCI_REG8(0x98b6), 0xd8},
+	{CCI_REG8(0x98b7), 0xd8},
+	{CCI_REG8(0x98b8), 0xec},
+	{CCI_REG8(0x98ca), 0x0f},
+	{CCI_REG8(0x98cb), 0x55},
+	{CCI_REG8(0x98cc), 0x0b},
+	{CCI_REG8(0x98d2), 0xa0},
+	{CCI_REG8(0x98d3), 0x28},
+	{CCI_REG8(0x98ec), 0x38},
+	{CCI_REG8(0xc1a8), 0x38},
+	{CCI_REG8(0xc2bc), 0x38},
+	{CCI_REG8(0xc3d0), 0x38},
+	{CCI_REG8(0xc4e4), 0x38},
+	{CCI_REG8(0xc5f8), 0x38},
+	{CCI_REG8(0xc70c), 0x38},
+	{CCI_REG8(0x98ed), 0x00},
+	{CCI_REG8(0xc1a9), 0x00},
+	{CCI_REG8(0xc2bd), 0x00},
+	{CCI_REG8(0xc3d1), 0x00},
+	{CCI_REG8(0xc4e5), 0x00},
+	{CCI_REG8(0xc5f9), 0x00},
+	{CCI_REG8(0xc70d), 0x00},
+	{CCI_REG8(0x98ee), 0x00},
+	{CCI_REG8(0xc1aa), 0x00},
+	{CCI_REG8(0xc2be), 0x00},
+	{CCI_REG8(0xc3d2), 0x00},
+	{CCI_REG8(0xc4e6), 0x00},
+	{CCI_REG8(0xc5fa), 0x00},
+	{CCI_REG8(0xc70e), 0x00},
+	{CCI_REG8(0x98ef), 0x00},
+	{CCI_REG8(0xc1ab), 0x00},
+	{CCI_REG8(0xc2bf), 0x00},
+	{CCI_REG8(0xc3d3), 0x00},
+	{CCI_REG8(0xc4e7), 0x00},
+	{CCI_REG8(0xc5fb), 0x00},
+	{CCI_REG8(0xc70f), 0x00},
+	{CCI_REG8(0x98f0), 0x03},
+	{CCI_REG8(0xc1ac), 0x03},
+	{CCI_REG8(0xc2c0), 0x03},
+	{CCI_REG8(0xc3d4), 0x03},
+	{CCI_REG8(0xc4e8), 0x03},
+	{CCI_REG8(0xc5fc), 0x03},
+	{CCI_REG8(0xc710), 0x03},
+	{CCI_REG8(0x98fc), 0x4b},
+	{CCI_REG8(0xc1b8), 0x4b},
+	{CCI_REG8(0xc2cc), 0x4b},
+	{CCI_REG8(0xc3e0), 0x4b},
+	{CCI_REG8(0xc4f4), 0x4b},
+	{CCI_REG8(0xc608), 0x4b},
+	{CCI_REG8(0xc71c), 0x4b},
+	{CCI_REG8(0x98fd), 0x00},
+	{CCI_REG8(0xc1b9), 0x00},
+	{CCI_REG8(0xc2cd), 0x00},
+	{CCI_REG8(0xc3e1), 0x00},
+	{CCI_REG8(0xc4f5), 0x00},
+	{CCI_REG8(0xc609), 0x00},
+	{CCI_REG8(0xc71d), 0x00},
+	{CCI_REG8(0x98fe), 0x00},
+	{CCI_REG8(0xc1ba), 0x00},
+	{CCI_REG8(0xc2ce), 0x00},
+	{CCI_REG8(0xc3e2), 0x00},
+	{CCI_REG8(0xc4f6), 0x00},
+	{CCI_REG8(0xc60a), 0x00},
+	{CCI_REG8(0xc71e), 0x00},
+	{CCI_REG8(0x9900), 0x15},
+	{CCI_REG8(0xc1bc), 0x15},
+	{CCI_REG8(0xc2d0), 0x15},
+	{CCI_REG8(0xc3e4), 0x15},
+	{CCI_REG8(0xc4f8), 0x15},
+	{CCI_REG8(0xc60c), 0x15},
+	{CCI_REG8(0xc720), 0x15},
+	{CCI_REG8(0x9901), 0x00},
+	{CCI_REG8(0xc1bd), 0x00},
+	{CCI_REG8(0xc2d1), 0x00},
+	{CCI_REG8(0xc3e5), 0x00},
+	{CCI_REG8(0xc4f9), 0x00},
+	{CCI_REG8(0xc60d), 0x00},
+	{CCI_REG8(0xc721), 0x00},
+	{CCI_REG8(0x9902), 0x00},
+	{CCI_REG8(0xc1be), 0x00},
+	{CCI_REG8(0xc2d2), 0x00},
+	{CCI_REG8(0xc3e6), 0x00},
+	{CCI_REG8(0xc4fa), 0x00},
+	{CCI_REG8(0xc60e), 0x00},
+	{CCI_REG8(0xc722), 0x00},
+	{CCI_REG8(0x9904), 0x21},
+	{CCI_REG8(0xc1c0), 0x21},
+	{CCI_REG8(0xc2d4), 0x21},
+	{CCI_REG8(0xc3e8), 0x21},
+	{CCI_REG8(0xc4fc), 0x21},
+	{CCI_REG8(0xc610), 0x21},
+	{CCI_REG8(0xc724), 0x21},
+	{CCI_REG8(0x9905), 0x00},
+	{CCI_REG8(0xc1c1), 0x00},
+	{CCI_REG8(0xc2d5), 0x00},
+	{CCI_REG8(0xc3e9), 0x00},
+	{CCI_REG8(0xc4fd), 0x00},
+	{CCI_REG8(0xc611), 0x00},
+	{CCI_REG8(0xc725), 0x00},
+	{CCI_REG8(0x9906), 0x00},
+	{CCI_REG8(0xc1c2), 0x00},
+	{CCI_REG8(0xc2d6), 0x00},
+	{CCI_REG8(0xc3ea), 0x00},
+	{CCI_REG8(0xc4fe), 0x00},
+	{CCI_REG8(0xc612), 0x00},
+	{CCI_REG8(0xc726), 0x00},
+	{CCI_REG8(0x9908), 0x54},
+	{CCI_REG8(0xc1c4), 0x54},
+	{CCI_REG8(0xc2d8), 0x54},
+	{CCI_REG8(0xc3ec), 0x54},
+	{CCI_REG8(0xc500), 0x54},
+	{CCI_REG8(0xc614), 0x54},
+	{CCI_REG8(0xc728), 0x54},
+	{CCI_REG8(0x9909), 0x00},
+	{CCI_REG8(0xc1c5), 0x00},
+	{CCI_REG8(0xc2d9), 0x00},
+	{CCI_REG8(0xc3ed), 0x00},
+	{CCI_REG8(0xc501), 0x00},
+	{CCI_REG8(0xc615), 0x00},
+	{CCI_REG8(0xc729), 0x00},
+	{CCI_REG8(0x990a), 0x00},
+	{CCI_REG8(0xc1c6), 0x00},
+	{CCI_REG8(0xc2da), 0x00},
+	{CCI_REG8(0xc3ee), 0x00},
+	{CCI_REG8(0xc502), 0x00},
+	{CCI_REG8(0xc616), 0x00},
+	{CCI_REG8(0xc72a), 0x00},
+	{CCI_REG8(0x9921), 0x04},
+	{CCI_REG8(0x9923), 0x02},
+	{CCI_REG8(0x9925), 0x28},
+	{CCI_REG8(0x9926), 0x14},
+	{CCI_REG8(0x9938), 0x4b},
+	{CCI_REG8(0x993e), 0x15},
+	{CCI_REG8(0x9960), 0x01},
+	{CCI_REG8(0x9961), 0x03},
+	{CCI_REG8(0x9963), 0x02},
+	{CCI_REG8(0x9968), 0xb6},
+	{CCI_REG8(0x9969), 0x26},
+	{CCI_REG8(0x996a), 0x00},
+	{CCI_REG8(0x996b), 0x00},
+	{CCI_REG8(0x996c), 0xf8},
+	{CCI_REG8(0x996d), 0x2a},
+	{CCI_REG8(0x996e), 0x00},
+	{CCI_REG8(0x996f), 0x00},
+	{CCI_REG8(0x9970), 0x01},
+	{CCI_REG8(0x9971), 0x00},
+	{CCI_REG8(0x9972), 0x00},
+	{CCI_REG8(0x9973), 0x00},
+	{CCI_REG8(0x9975), 0x03},
+	{CCI_REG8(0x9976), 0x04},
+	{CCI_REG8(0x9982), 0xb4},
+	{CCI_REG8(0x9983), 0x00},
+	{CCI_REG8(0x99c8), 0xb0},
+	{CCI_REG8(0x99c9), 0x04},
+	{CCI_REG8(0x99ca), 0xb0},
+	{CCI_REG8(0x99cb), 0x04},
+	{CCI_REG8(0x99de), 0x64},
+	{CCI_REG8(0x99df), 0x64},
+	{CCI_REG8(0x99e0), 0x64},
+	{CCI_REG8(0x99e1), 0x64},
+	{CCI_REG8(0x99e2), 0x64},
+	{CCI_REG8(0x99e3), 0x64},
+	{CCI_REG8(0x99e4), 0x64},
+	{CCI_REG8(0x99e5), 0x64},
+	{CCI_REG8(0x99e6), 0x64},
+	{CCI_REG8(0x99e7), 0x64},
+	{CCI_REG8(0x99e8), 0x64},
+	{CCI_REG8(0x99e9), 0x64},
+	{CCI_REG8(0x99ea), 0x64},
+	{CCI_REG8(0x99eb), 0x64},
+	{CCI_REG8(0x99ec), 0x64},
+	{CCI_REG8(0x99ed), 0x64},
+	{CCI_REG8(0x99ee), 0x64},
+	{CCI_REG8(0x99ef), 0x64},
+	{CCI_REG8(0x99f0), 0x64},
+	{CCI_REG8(0x99f1), 0x64},
+	{CCI_REG8(0x99f2), 0x64},
+	{CCI_REG8(0x99f3), 0x64},
+	{CCI_REG8(0x99f4), 0x64},
+	{CCI_REG8(0x99f5), 0x64},
+	{CCI_REG8(0x99f6), 0x64},
+	{CCI_REG8(0x99f7), 0x64},
+	{CCI_REG8(0x99f8), 0x64},
+	{CCI_REG8(0x99f9), 0x64},
+	{CCI_REG8(0x99fa), 0x64},
+	{CCI_REG8(0x99fb), 0x64},
+	{CCI_REG8(0x99fc), 0x64},
+	{CCI_REG8(0x99fd), 0x64},
+	{CCI_REG8(0x99fe), 0x64},
+	{CCI_REG8(0x99ff), 0x64},
+	{CCI_REG8(0x9a00), 0x64},
+	{CCI_REG8(0x9a01), 0x64},
+	{CCI_REG8(0x9a02), 0x64},
+	{CCI_REG8(0x9a03), 0x64},
+	{CCI_REG8(0x9a04), 0x64},
+	{CCI_REG8(0x9a05), 0x64},
+	{CCI_REG8(0x9a07), 0x64},
+	{CCI_REG8(0x9a08), 0x64},
+	{CCI_REG8(0x9a09), 0x64},
+	{CCI_REG8(0x9a0a), 0x64},
+	{CCI_REG8(0x9a0b), 0x64},
+	{CCI_REG8(0x9a0c), 0x64},
+	{CCI_REG8(0x9a0d), 0x64},
+	{CCI_REG8(0x9a0e), 0x64},
+	{CCI_REG8(0x9a0f), 0x64},
+	{CCI_REG8(0x9a10), 0x64},
+	{CCI_REG8(0x9a11), 0x64},
+	{CCI_REG8(0x9a12), 0x64},
+	{CCI_REG8(0x9a13), 0x64},
+	{CCI_REG8(0x9a14), 0x64},
+	{CCI_REG8(0x9a15), 0x64},
+	{CCI_REG8(0x9a16), 0x64},
+	{CCI_REG8(0x9a17), 0x64},
+	{CCI_REG8(0x9a18), 0x64},
+	{CCI_REG8(0x9a19), 0x64},
+	{CCI_REG8(0x9a1a), 0x64},
+	{CCI_REG8(0x9a1b), 0x64},
+	{CCI_REG8(0x9a1c), 0x64},
+	{CCI_REG8(0x9a3a), 0x20},
+	{CCI_REG8(0x9a3b), 0x00},
+	{CCI_REG8(0x9a3c), 0x20},
+	{CCI_REG8(0x9a3d), 0x00},
+	{CCI_REG8(0x9a3e), 0x20},
+	{CCI_REG8(0x9a3f), 0x00},
+	{CCI_REG8(0x9a40), 0x20},
+	{CCI_REG8(0x9a41), 0x00},
+	{CCI_REG8(0x9a42), 0x20},
+	{CCI_REG8(0x9a43), 0x00},
+	{CCI_REG8(0x9a44), 0x20},
+	{CCI_REG8(0x9a45), 0x00},
+	{CCI_REG8(0x9a46), 0x20},
+	{CCI_REG8(0x9a47), 0x00},
+	{CCI_REG8(0x9a48), 0x30},
+	{CCI_REG8(0x9a49), 0x00},
+	{CCI_REG8(0x9a4a), 0x40},
+	{CCI_REG8(0x9a4b), 0x00},
+	{CCI_REG8(0x9a4c), 0x50},
+	{CCI_REG8(0x9a4d), 0x00},
+	{CCI_REG8(0x9a4e), 0x60},
+	{CCI_REG8(0x9a4f), 0x00},
+	{CCI_REG8(0x9a50), 0x70},
+	{CCI_REG8(0x9a51), 0x00},
+	{CCI_REG8(0x9a52), 0x80},
+	{CCI_REG8(0x9a53), 0x00},
+	{CCI_REG8(0x9a54), 0x90},
+	{CCI_REG8(0x9a55), 0x00},
+	{CCI_REG8(0x9a56), 0xa0},
+	{CCI_REG8(0x9a57), 0x00},
+	{CCI_REG8(0x9a58), 0xb0},
+	{CCI_REG8(0x9a59), 0x00},
+	{CCI_REG8(0x9a5a), 0xc0},
+	{CCI_REG8(0x9a5b), 0x00},
+	{CCI_REG8(0x9a5c), 0xc0},
+	{CCI_REG8(0x9a5d), 0x00},
+	{CCI_REG8(0x9a5f), 0x10},
+	{CCI_REG8(0x9a64), 0xff},
+	{CCI_REG8(0x9a65), 0xff},
+	{CCI_REG8(0x9a66), 0xff},
+	{CCI_REG8(0x9a67), 0xff},
+	{CCI_REG8(0x9be4), 0x02},
+	{CCI_REG8(0x9be5), 0x00},
+	{CCI_REG8(0x9be6), 0x00},
+	{CCI_REG8(0x9be7), 0x00},
+	{CCI_REG8(0x9bea), 0x54},
+	{CCI_REG8(0x9beb), 0x00},
+	{CCI_REG8(0x9bec), 0x54},
+	{CCI_REG8(0x9bed), 0x00},
+	{CCI_REG8(0x9bfa), 0x01},
+	{CCI_REG8(0x9bfc), 0x00},
+	{CCI_REG8(0x9bfd), 0x10},
+	{CCI_REG8(0x9bfe), 0x00},
+	{CCI_REG8(0x9c00), 0x00},
+	{CCI_REG8(0x9c01), 0x10},
+	{CCI_REG8(0x9c02), 0x00},
+	{CCI_REG8(0x9c04), 0x00},
+	{CCI_REG8(0x9c05), 0x10},
+	{CCI_REG8(0x9c06), 0x00},
+	{CCI_REG8(0x9c08), 0x00},
+	{CCI_REG8(0x9c09), 0x10},
+	{CCI_REG8(0x9c0a), 0x00},
+	{CCI_REG8(0x9c0c), 0x00},
+	{CCI_REG8(0x9c0d), 0x10},
+	{CCI_REG8(0x9c0e), 0x00},
+	{CCI_REG8(0x9c10), 0x00},
+	{CCI_REG8(0x9c11), 0x10},
+	{CCI_REG8(0x9c12), 0x00},
+	{CCI_REG8(0x9c14), 0x00},
+	{CCI_REG8(0x9c15), 0x10},
+	{CCI_REG8(0x9c16), 0x00},
+	{CCI_REG8(0x9c18), 0x00},
+	{CCI_REG8(0x9c19), 0x10},
+	{CCI_REG8(0x9c1a), 0x00},
+	{CCI_REG8(0x9c1c), 0x00},
+	{CCI_REG8(0x9c1d), 0x10},
+	{CCI_REG8(0x9c1e), 0x00},
+	{CCI_REG8(0x9c20), 0x00},
+	{CCI_REG8(0x9c21), 0x10},
+	{CCI_REG8(0x9c22), 0x00},
+	{CCI_REG8(0x9c24), 0x00},
+	{CCI_REG8(0x9c25), 0x10},
+	{CCI_REG8(0x9c26), 0x00},
+	{CCI_REG8(0x9c28), 0x00},
+	{CCI_REG8(0x9c29), 0x10},
+	{CCI_REG8(0x9c2a), 0x00},
+	{CCI_REG8(0x9c58), 0x21},
+	{CCI_REG8(0x9c5a), 0xc0},
+	{CCI_REG8(0xc1cc), 0xc0},
+	{CCI_REG8(0xc2e0), 0xc0},
+	{CCI_REG8(0xc3f4), 0xc0},
+	{CCI_REG8(0xc508), 0xc0},
+	{CCI_REG8(0xc61c), 0xc0},
+	{CCI_REG8(0xc730), 0xc0},
+	{CCI_REG8(0x9c5b), 0x5d},
+	{CCI_REG8(0xc1cd), 0x5d},
+	{CCI_REG8(0xc2e1), 0x5d},
+	{CCI_REG8(0xc3f5), 0x5d},
+	{CCI_REG8(0xc509), 0x5d},
+	{CCI_REG8(0xc61d), 0x5d},
+	{CCI_REG8(0xc731), 0x5d},
+	{CCI_REG8(0x9c5c), 0x80},
+	{CCI_REG8(0xc1ce), 0x80},
+	{CCI_REG8(0xc2e2), 0x80},
+	{CCI_REG8(0xc3f6), 0x80},
+	{CCI_REG8(0xc50a), 0x80},
+	{CCI_REG8(0xc61e), 0x80},
+	{CCI_REG8(0xc732), 0x80},
+	{CCI_REG8(0x9c5d), 0x57},
+	{CCI_REG8(0xc1cf), 0x57},
+	{CCI_REG8(0xc2e3), 0x57},
+	{CCI_REG8(0xc3f7), 0x57},
+	{CCI_REG8(0xc50b), 0x57},
+	{CCI_REG8(0xc61f), 0x57},
+	{CCI_REG8(0xc733), 0x57},
+	{CCI_REG8(0x9c60), 0x00},
+	{CCI_REG8(0xc1d2), 0x00},
+	{CCI_REG8(0xc2e6), 0x00},
+	{CCI_REG8(0xc3fa), 0x00},
+	{CCI_REG8(0xc50e), 0x00},
+	{CCI_REG8(0xc622), 0x00},
+	{CCI_REG8(0xc736), 0x00},
+	{CCI_REG8(0x9c61), 0x30},
+	{CCI_REG8(0xc1d3), 0x30},
+	{CCI_REG8(0xc2e7), 0x30},
+	{CCI_REG8(0xc3fb), 0x30},
+	{CCI_REG8(0xc50f), 0x30},
+	{CCI_REG8(0xc623), 0x30},
+	{CCI_REG8(0xc737), 0x30},
+	{CCI_REG8(0x9c62), 0x00},
+	{CCI_REG8(0xc1d4), 0x00},
+	{CCI_REG8(0xc2e8), 0x00},
+	{CCI_REG8(0xc3fc), 0x00},
+	{CCI_REG8(0xc510), 0x00},
+	{CCI_REG8(0xc624), 0x00},
+	{CCI_REG8(0xc738), 0x00},
+	{CCI_REG8(0x9c63), 0x00},
+	{CCI_REG8(0xc1d5), 0x00},
+	{CCI_REG8(0xc2e9), 0x00},
+	{CCI_REG8(0xc3fd), 0x00},
+	{CCI_REG8(0xc511), 0x00},
+	{CCI_REG8(0xc625), 0x00},
+	{CCI_REG8(0xc739), 0x00},
+	{CCI_REG8(0x9c64), 0x00},
+	{CCI_REG8(0xc1d6), 0x00},
+	{CCI_REG8(0xc2ea), 0x00},
+	{CCI_REG8(0xc3fe), 0x00},
+	{CCI_REG8(0xc512), 0x00},
+	{CCI_REG8(0xc626), 0x00},
+	{CCI_REG8(0xc73a), 0x00},
+	{CCI_REG8(0x9c65), 0x50},
+	{CCI_REG8(0xc1d7), 0x50},
+	{CCI_REG8(0xc2eb), 0x50},
+	{CCI_REG8(0xc3ff), 0x50},
+	{CCI_REG8(0xc513), 0x50},
+	{CCI_REG8(0xc627), 0x50},
+	{CCI_REG8(0xc73b), 0x50},
+	{CCI_REG8(0x9c66), 0x00},
+	{CCI_REG8(0xc1d8), 0x00},
+	{CCI_REG8(0xc2ec), 0x00},
+	{CCI_REG8(0xc400), 0x00},
+	{CCI_REG8(0xc514), 0x00},
+	{CCI_REG8(0xc628), 0x00},
+	{CCI_REG8(0xc73c), 0x00},
+	{CCI_REG8(0x9c67), 0x00},
+	{CCI_REG8(0xc1d9), 0x00},
+	{CCI_REG8(0xc2ed), 0x00},
+	{CCI_REG8(0xc401), 0x00},
+	{CCI_REG8(0xc515), 0x00},
+	{CCI_REG8(0xc629), 0x00},
+	{CCI_REG8(0xc73d), 0x00},
+	{CCI_REG8(0x9c6a), 0x00},
+	{CCI_REG8(0xc1dc), 0x00},
+	{CCI_REG8(0xc2f0), 0x00},
+	{CCI_REG8(0xc404), 0x00},
+	{CCI_REG8(0xc518), 0x00},
+	{CCI_REG8(0xc62c), 0x00},
+	{CCI_REG8(0xc740), 0x00},
+	{CCI_REG8(0x9c6b), 0xe0},
+	{CCI_REG8(0xc1dd), 0xe0},
+	{CCI_REG8(0xc2f1), 0xe0},
+	{CCI_REG8(0xc405), 0xe0},
+	{CCI_REG8(0xc519), 0xe0},
+	{CCI_REG8(0xc62d), 0xe0},
+	{CCI_REG8(0xc741), 0xe0},
+	{CCI_REG8(0x9c6c), 0x00},
+	{CCI_REG8(0xc1de), 0x00},
+	{CCI_REG8(0xc2f2), 0x00},
+	{CCI_REG8(0xc406), 0x00},
+	{CCI_REG8(0xc51a), 0x00},
+	{CCI_REG8(0xc62e), 0x00},
+	{CCI_REG8(0xc742), 0x00},
+	{CCI_REG8(0x9c6d), 0x30},
+	{CCI_REG8(0xc1df), 0x30},
+	{CCI_REG8(0xc2f3), 0x30},
+	{CCI_REG8(0xc407), 0x30},
+	{CCI_REG8(0xc51b), 0x30},
+	{CCI_REG8(0xc62f), 0x30},
+	{CCI_REG8(0xc743), 0x30},
+	{CCI_REG8(0x9c6e), 0x00},
+	{CCI_REG8(0xc1e0), 0x00},
+	{CCI_REG8(0xc2f4), 0x00},
+	{CCI_REG8(0xc408), 0x00},
+	{CCI_REG8(0xc51c), 0x00},
+	{CCI_REG8(0xc630), 0x00},
+	{CCI_REG8(0xc744), 0x00},
+	{CCI_REG8(0x9c6f), 0x00},
+	{CCI_REG8(0xc1e1), 0x00},
+	{CCI_REG8(0xc2f5), 0x00},
+	{CCI_REG8(0xc409), 0x00},
+	{CCI_REG8(0xc51d), 0x00},
+	{CCI_REG8(0xc631), 0x00},
+	{CCI_REG8(0xc745), 0x00},
+	{CCI_REG8(0x9c70), 0x00},
+	{CCI_REG8(0xc1e2), 0x00},
+	{CCI_REG8(0xc2f6), 0x00},
+	{CCI_REG8(0xc40a), 0x00},
+	{CCI_REG8(0xc51e), 0x00},
+	{CCI_REG8(0xc632), 0x00},
+	{CCI_REG8(0xc746), 0x00},
+	{CCI_REG8(0x9c71), 0x50},
+	{CCI_REG8(0xc1e3), 0x50},
+	{CCI_REG8(0xc2f7), 0x50},
+	{CCI_REG8(0xc40b), 0x50},
+	{CCI_REG8(0xc51f), 0x50},
+	{CCI_REG8(0xc633), 0x50},
+	{CCI_REG8(0xc747), 0x50},
+	{CCI_REG8(0x9c72), 0x00},
+	{CCI_REG8(0xc1e4), 0x00},
+	{CCI_REG8(0xc2f8), 0x00},
+	{CCI_REG8(0xc40c), 0x00},
+	{CCI_REG8(0xc520), 0x00},
+	{CCI_REG8(0xc634), 0x00},
+	{CCI_REG8(0xc748), 0x00},
+	{CCI_REG8(0x9c73), 0x00},
+	{CCI_REG8(0xc1e5), 0x00},
+	{CCI_REG8(0xc2f9), 0x00},
+	{CCI_REG8(0xc40d), 0x00},
+	{CCI_REG8(0xc521), 0x00},
+	{CCI_REG8(0xc635), 0x00},
+	{CCI_REG8(0xc749), 0x00},
+	{CCI_REG8(0x9c76), 0x00},
+	{CCI_REG8(0xc1e8), 0x00},
+	{CCI_REG8(0xc2fc), 0x00},
+	{CCI_REG8(0xc410), 0x00},
+	{CCI_REG8(0xc524), 0x00},
+	{CCI_REG8(0xc638), 0x00},
+	{CCI_REG8(0xc74c), 0x00},
+	{CCI_REG8(0x9c77), 0xe0},
+	{CCI_REG8(0xc1e9), 0xe0},
+	{CCI_REG8(0xc2fd), 0xe0},
+	{CCI_REG8(0xc411), 0xe0},
+	{CCI_REG8(0xc525), 0xe0},
+	{CCI_REG8(0xc639), 0xe0},
+	{CCI_REG8(0xc74d), 0xe0},
+	{CCI_REG8(0x9d00), 0x00},
+	{CCI_REG8(0x9d01), 0x10},
+	{CCI_REG8(0x9d02), 0x00},
+	{CCI_REG8(0x9d04), 0x00},
+	{CCI_REG8(0x9d05), 0x10},
+	{CCI_REG8(0x9d06), 0x00},
+	{CCI_REG8(0x9d08), 0x00},
+	{CCI_REG8(0x9d09), 0x10},
+	{CCI_REG8(0x9d0a), 0x00},
+	{CCI_REG8(0x9d0c), 0x00},
+	{CCI_REG8(0x9d0d), 0x10},
+	{CCI_REG8(0x9d0e), 0x00},
+	{CCI_REG8(0x9d10), 0x00},
+	{CCI_REG8(0x9d11), 0x10},
+	{CCI_REG8(0x9d12), 0x00},
+	{CCI_REG8(0x9d14), 0x00},
+	{CCI_REG8(0x9d15), 0x10},
+	{CCI_REG8(0x9d16), 0x00},
+	{CCI_REG8(0x9d18), 0x00},
+	{CCI_REG8(0x9d19), 0x10},
+	{CCI_REG8(0x9d1a), 0x00},
+	{CCI_REG8(0x9d1c), 0x00},
+	{CCI_REG8(0x9d1d), 0x10},
+	{CCI_REG8(0x9d1e), 0x00},
+	{CCI_REG8(0x9d20), 0x00},
+	{CCI_REG8(0x9d21), 0x10},
+	{CCI_REG8(0x9d22), 0x00},
+	{CCI_REG8(0x9d23), 0x00},
+	{CCI_REG8(0x9d24), 0x00},
+	{CCI_REG8(0x9d25), 0x10},
+	{CCI_REG8(0x9d26), 0x00},
+	{CCI_REG8(0x9d27), 0x00},
+	{CCI_REG8(0x9d28), 0x00},
+	{CCI_REG8(0x9d29), 0x10},
+	{CCI_REG8(0x9d2a), 0x00},
+	{CCI_REG8(0x9d2b), 0x00},
+	{CCI_REG8(0x9d2c), 0x00},
+	{CCI_REG8(0x9d2d), 0x10},
+	{CCI_REG8(0x9d2e), 0x00},
+	{CCI_REG8(0x9d2f), 0x00},
+	{CCI_REG8(0x9d30), 0x01},
+	{CCI_REG8(0x9d31), 0x00},
+	{CCI_REG8(0x9d32), 0x00},
+	{CCI_REG8(0x9d33), 0x00},
+	{CCI_REG8(0x9d34), 0x00},
+	{CCI_REG8(0x9d35), 0x00},
+	{CCI_REG8(0x9d38), 0x01},
+	{CCI_REG8(0x9d39), 0x00},
+	{CCI_REG8(0x9d3a), 0x00},
+	{CCI_REG8(0x9d3b), 0x00},
+	{CCI_REG8(0x9d3c), 0x00},
+	{CCI_REG8(0x9d3d), 0x00},
+	{CCI_REG8(0x9d40), 0x01},
+	{CCI_REG8(0x9d41), 0x00},
+	{CCI_REG8(0x9d42), 0x00},
+	{CCI_REG8(0x9d43), 0x00},
+	{CCI_REG8(0x9d44), 0x00},
+	{CCI_REG8(0x9d45), 0x00},
+	{CCI_REG8(0x9d48), 0x01},
+	{CCI_REG8(0x9d49), 0x00},
+	{CCI_REG8(0x9d4a), 0x00},
+	{CCI_REG8(0x9d4b), 0x00},
+	{CCI_REG8(0x9d4c), 0x00},
+	{CCI_REG8(0x9d4d), 0x00},
+	{CCI_REG8(0xa2e4), 0x23},
+	{CCI_REG8(0xa2e7), 0x01},
+	{CCI_REG8(0xa3cc), 0xaa},
+	{CCI_REG8(0xa3cd), 0x0f},
+	{CCI_REG8(0xa3ce), 0x81},
+	{CCI_REG8(0xa3cf), 0x0d},
+	{CCI_REG8(0xa3d0), 0xfc},
+	{CCI_REG8(0xa3d1), 0x00},
+	{CCI_REG8(0xa3d2), 0xc5},
+	{CCI_REG8(0xa3d3), 0x02},
+	{CCI_REG8(0xa3b0), 0xe6},
+	{CCI_REG8(0xc204), 0xe6},
+	{CCI_REG8(0xc318), 0xe6},
+	{CCI_REG8(0xc42c), 0xe6},
+	{CCI_REG8(0xc540), 0xe6},
+	{CCI_REG8(0xc654), 0xe6},
+	{CCI_REG8(0xc768), 0xe6},
+	{CCI_REG8(0xa3b1), 0x00},
+	{CCI_REG8(0xc205), 0x00},
+	{CCI_REG8(0xc319), 0x00},
+	{CCI_REG8(0xc42d), 0x00},
+	{CCI_REG8(0xc541), 0x00},
+	{CCI_REG8(0xc655), 0x00},
+	{CCI_REG8(0xc769), 0x00},
+	{CCI_REG8(0xa3b2), 0xe6},
+	{CCI_REG8(0xc206), 0xe6},
+	{CCI_REG8(0xc31a), 0xe6},
+	{CCI_REG8(0xc42e), 0xe6},
+	{CCI_REG8(0xc542), 0xe6},
+	{CCI_REG8(0xc656), 0xe6},
+	{CCI_REG8(0xc76a), 0xe6},
+	{CCI_REG8(0xa3b3), 0x00},
+	{CCI_REG8(0xc207), 0x00},
+	{CCI_REG8(0xc31b), 0x00},
+	{CCI_REG8(0xc42f), 0x00},
+	{CCI_REG8(0xc543), 0x00},
+	{CCI_REG8(0xc657), 0x00},
+	{CCI_REG8(0xc76b), 0x00},
+	{CCI_REG8(0x9e7c), 0x87},
+	{CCI_REG8(0x9e88), 0x6e},
+	{CCI_REG8(0x9e89), 0x87},
+	{CCI_REG8(0x9e8a), 0x9b},
+	{CCI_REG8(0x9e8b), 0xaf},
+	{CCI_REG8(0x9e8c), 0x6e},
+	{CCI_REG8(0x9e8d), 0x87},
+	{CCI_REG8(0x9e8e), 0x9b},
+	{CCI_REG8(0x9e8f), 0xaf},
+	{CCI_REG8(0x9e90), 0x28},
+	{CCI_REG8(0x9e91), 0x00},
+	{CCI_REG8(0x9e92), 0x50},
+	{CCI_REG8(0x9e93), 0x00},
+	{CCI_REG8(0x9e94), 0xb2},
+	{CCI_REG8(0x9e95), 0x0c},
+	{CCI_REG8(0x9e96), 0xa6},
+	{CCI_REG8(0x9e97), 0x0e},
+	{CCI_REG8(0x9e98), 0x28},
+	{CCI_REG8(0x9e99), 0x00},
+	{CCI_REG8(0x9e9a), 0x50},
+	{CCI_REG8(0x9e9b), 0x00},
+	{CCI_REG8(0x9e9c), 0xb2},
+	{CCI_REG8(0x9e9d), 0x0c},
+	{CCI_REG8(0x9e9e), 0xa6},
+	{CCI_REG8(0x9e9f), 0x0e},
+	{CCI_REG8(0x9ea0), 0x28},
+	{CCI_REG8(0x9ea1), 0x00},
+	{CCI_REG8(0x9ea2), 0x50},
+	{CCI_REG8(0x9ea3), 0x00},
+	{CCI_REG8(0x9ea4), 0xb2},
+	{CCI_REG8(0x9ea5), 0x0c},
+	{CCI_REG8(0x9ea6), 0xa6},
+	{CCI_REG8(0x9ea7), 0x0e},
+	{CCI_REG8(0x9ea8), 0x28},
+	{CCI_REG8(0x9ea9), 0x00},
+	{CCI_REG8(0x9eaa), 0x50},
+	{CCI_REG8(0x9eab), 0x00},
+	{CCI_REG8(0x9eac), 0xb2},
+	{CCI_REG8(0x9ead), 0x0c},
+	{CCI_REG8(0x9eae), 0xa6},
+	{CCI_REG8(0x9eaf), 0x0e},
+	{CCI_REG8(0x9eb0), 0x28},
+	{CCI_REG8(0x9eb1), 0x00},
+	{CCI_REG8(0x9eb2), 0x50},
+	{CCI_REG8(0x9eb3), 0x00},
+	{CCI_REG8(0x9eb4), 0xb2},
+	{CCI_REG8(0x9eb5), 0x0c},
+	{CCI_REG8(0x9eb6), 0xa6},
+	{CCI_REG8(0x9eb7), 0x0e},
+	{CCI_REG8(0x9eb8), 0x28},
+	{CCI_REG8(0x9eb9), 0x00},
+	{CCI_REG8(0x9eba), 0x50},
+	{CCI_REG8(0x9ebb), 0x00},
+	{CCI_REG8(0x9ebc), 0xb2},
+	{CCI_REG8(0x9ebd), 0x0c},
+	{CCI_REG8(0x9ebe), 0xa6},
+	{CCI_REG8(0x9ebf), 0x0e},
+	{CCI_REG8(0x9ec0), 0x28},
+	{CCI_REG8(0x9ec1), 0x00},
+	{CCI_REG8(0x9ec2), 0x50},
+	{CCI_REG8(0x9ec3), 0x00},
+	{CCI_REG8(0x9ec4), 0xb2},
+	{CCI_REG8(0x9ec5), 0x0c},
+	{CCI_REG8(0x9ec6), 0xa6},
+	{CCI_REG8(0x9ec7), 0x0e},
+	{CCI_REG8(0x9ed2), 0x01},
+	{CCI_REG8(0x9ed3), 0x01},
+	{CCI_REG8(0x9ed4), 0x01},
+	{CCI_REG8(0x9ed5), 0x01},
+	{CCI_REG8(0x9ed6), 0x01},
+	{CCI_REG8(0x9ed7), 0x01},
+	{CCI_REG8(0x9ed8), 0x01},
+	{CCI_REG8(0x9eda), 0xb2},
+	{CCI_REG8(0x9edb), 0x0c},
+	{CCI_REG8(0x9edc), 0xb2},
+	{CCI_REG8(0x9edd), 0x0c},
+	{CCI_REG8(0x9ede), 0xb2},
+	{CCI_REG8(0x9edf), 0x0c},
+	{CCI_REG8(0x9ee0), 0xb2},
+	{CCI_REG8(0x9ee1), 0x0c},
+	{CCI_REG8(0x9ee2), 0xa6},
+	{CCI_REG8(0x9ee3), 0x0e},
+	{CCI_REG8(0x9ee4), 0xa6},
+	{CCI_REG8(0x9ee5), 0x0e},
+	{CCI_REG8(0x9ee6), 0xa6},
+	{CCI_REG8(0x9ee7), 0x0e},
+	{CCI_REG8(0x9ee8), 0xa6},
+	{CCI_REG8(0x9ee9), 0x0e},
+	{CCI_REG8(0x9eea), 0xb2},
+	{CCI_REG8(0x9eeb), 0x0c},
+	{CCI_REG8(0x9eec), 0xb2},
+	{CCI_REG8(0x9eed), 0x0c},
+	{CCI_REG8(0x9eee), 0xb2},
+	{CCI_REG8(0x9eef), 0x0c},
+	{CCI_REG8(0x9ef0), 0xb2},
+	{CCI_REG8(0x9ef1), 0x0c},
+	{CCI_REG8(0x9ef2), 0xa6},
+	{CCI_REG8(0x9ef3), 0x0e},
+	{CCI_REG8(0x9ef4), 0xa6},
+	{CCI_REG8(0x9ef5), 0x0e},
+	{CCI_REG8(0x9ef6), 0xa6},
+	{CCI_REG8(0x9ef7), 0x0e},
+	{CCI_REG8(0x9ef8), 0xa6},
+	{CCI_REG8(0x9ef9), 0x0e},
+	{CCI_REG8(0x9efa), 0xb2},
+	{CCI_REG8(0x9efb), 0x0c},
+	{CCI_REG8(0x9efc), 0xb2},
+	{CCI_REG8(0x9efd), 0x0c},
+	{CCI_REG8(0x9efe), 0xb2},
+	{CCI_REG8(0x9eff), 0x0c},
+	{CCI_REG8(0x9f00), 0xb2},
+	{CCI_REG8(0x9f01), 0x0c},
+	{CCI_REG8(0x9f02), 0xa6},
+	{CCI_REG8(0x9f03), 0x0e},
+	{CCI_REG8(0x9f04), 0xa6},
+	{CCI_REG8(0x9f05), 0x0e},
+	{CCI_REG8(0x9f06), 0xa6},
+	{CCI_REG8(0x9f07), 0x0e},
+	{CCI_REG8(0x9f08), 0xa6},
+	{CCI_REG8(0x9f09), 0x0e},
+	{CCI_REG8(0x9f0a), 0xb2},
+	{CCI_REG8(0x9f0b), 0x0c},
+	{CCI_REG8(0x9f0c), 0xb2},
+	{CCI_REG8(0x9f0d), 0x0c},
+	{CCI_REG8(0x9f0e), 0xb2},
+	{CCI_REG8(0x9f0f), 0x0c},
+	{CCI_REG8(0x9f10), 0xb2},
+	{CCI_REG8(0x9f11), 0x0c},
+	{CCI_REG8(0x9f12), 0xa6},
+	{CCI_REG8(0x9f13), 0x0e},
+	{CCI_REG8(0x9f14), 0xa6},
+	{CCI_REG8(0x9f15), 0x0e},
+	{CCI_REG8(0x9f16), 0xa6},
+	{CCI_REG8(0x9f17), 0x0e},
+	{CCI_REG8(0x9f18), 0xa6},
+	{CCI_REG8(0x9f19), 0x0e},
+	{CCI_REG8(0x9f1a), 0xb2},
+	{CCI_REG8(0x9f1b), 0x0c},
+	{CCI_REG8(0x9f1c), 0xb2},
+	{CCI_REG8(0x9f1d), 0x0c},
+	{CCI_REG8(0x9f1e), 0xb2},
+	{CCI_REG8(0x9f1f), 0x0c},
+	{CCI_REG8(0x9f20), 0xb2},
+	{CCI_REG8(0x9f21), 0x0c},
+	{CCI_REG8(0x9f22), 0xa6},
+	{CCI_REG8(0x9f23), 0x0e},
+	{CCI_REG8(0x9f24), 0xa6},
+	{CCI_REG8(0x9f25), 0x0e},
+	{CCI_REG8(0x9f26), 0xa6},
+	{CCI_REG8(0x9f27), 0x0e},
+	{CCI_REG8(0x9f28), 0xa6},
+	{CCI_REG8(0x9f29), 0x0e},
+	{CCI_REG8(0x9f2a), 0xb2},
+	{CCI_REG8(0x9f2b), 0x0c},
+	{CCI_REG8(0x9f2c), 0xb2},
+	{CCI_REG8(0x9f2d), 0x0c},
+	{CCI_REG8(0x9f2e), 0xb2},
+	{CCI_REG8(0x9f2f), 0x0c},
+	{CCI_REG8(0x9f30), 0xb2},
+	{CCI_REG8(0x9f31), 0x0c},
+	{CCI_REG8(0x9f32), 0xa6},
+	{CCI_REG8(0x9f33), 0x0e},
+	{CCI_REG8(0x9f34), 0xa6},
+	{CCI_REG8(0x9f35), 0x0e},
+	{CCI_REG8(0x9f36), 0xa6},
+	{CCI_REG8(0x9f37), 0x0e},
+	{CCI_REG8(0x9f38), 0xa6},
+	{CCI_REG8(0x9f39), 0x0e},
+	{CCI_REG8(0x9f3a), 0xb2},
+	{CCI_REG8(0x9f3b), 0x0c},
+	{CCI_REG8(0x9f3c), 0xb2},
+	{CCI_REG8(0x9f3d), 0x0c},
+	{CCI_REG8(0x9f3e), 0xb2},
+	{CCI_REG8(0x9f3f), 0x0c},
+	{CCI_REG8(0x9f40), 0xb2},
+	{CCI_REG8(0x9f41), 0x0c},
+	{CCI_REG8(0x9f42), 0xa6},
+	{CCI_REG8(0x9f43), 0x0e},
+	{CCI_REG8(0x9f44), 0xa6},
+	{CCI_REG8(0x9f45), 0x0e},
+	{CCI_REG8(0x9f46), 0xa6},
+	{CCI_REG8(0x9f47), 0x0e},
+	{CCI_REG8(0x9f48), 0xa6},
+	{CCI_REG8(0x9f49), 0x0e},
+	{CCI_REG8(0x9f4a), 0xb2},
+	{CCI_REG8(0x9f4b), 0x0c},
+	{CCI_REG8(0x9f4c), 0xb2},
+	{CCI_REG8(0x9f4d), 0x0c},
+	{CCI_REG8(0x9f4e), 0xb2},
+	{CCI_REG8(0x9f4f), 0x0c},
+	{CCI_REG8(0x9f50), 0xb2},
+	{CCI_REG8(0x9f51), 0x0c},
+	{CCI_REG8(0x9f52), 0xa6},
+	{CCI_REG8(0x9f53), 0x0e},
+	{CCI_REG8(0x9f54), 0xa6},
+	{CCI_REG8(0x9f55), 0x0e},
+	{CCI_REG8(0x9f56), 0xa6},
+	{CCI_REG8(0x9f57), 0x0e},
+	{CCI_REG8(0x9f58), 0xa6},
+	{CCI_REG8(0x9f59), 0x0e},
+	{CCI_REG8(0x9f5a), 0xd0},
+	{CCI_REG8(0x9f5b), 0x07},
+	{CCI_REG8(0x9f5c), 0xd0},
+	{CCI_REG8(0x9f5d), 0x07},
+	{CCI_REG8(0x9f5e), 0xd0},
+	{CCI_REG8(0x9f5f), 0x07},
+	{CCI_REG8(0x9f60), 0xd0},
+	{CCI_REG8(0x9f61), 0x07},
+	{CCI_REG8(0x9f62), 0xc4},
+	{CCI_REG8(0x9f63), 0x09},
+	{CCI_REG8(0x9f64), 0xc4},
+	{CCI_REG8(0x9f65), 0x09},
+	{CCI_REG8(0x9f66), 0xc4},
+	{CCI_REG8(0x9f67), 0x09},
+	{CCI_REG8(0x9f68), 0xc4},
+	{CCI_REG8(0x9f69), 0x09},
+	{CCI_REG8(0x9f6a), 0xd0},
+	{CCI_REG8(0x9f6b), 0x07},
+	{CCI_REG8(0x9f6c), 0xd0},
+	{CCI_REG8(0x9f6d), 0x07},
+	{CCI_REG8(0x9f6e), 0xd0},
+	{CCI_REG8(0x9f6f), 0x07},
+	{CCI_REG8(0x9f70), 0xd0},
+	{CCI_REG8(0x9f71), 0x07},
+	{CCI_REG8(0x9f72), 0xc4},
+	{CCI_REG8(0x9f73), 0x09},
+	{CCI_REG8(0x9f74), 0xc4},
+	{CCI_REG8(0x9f75), 0x09},
+	{CCI_REG8(0x9f76), 0xc4},
+	{CCI_REG8(0x9f77), 0x09},
+	{CCI_REG8(0x9f78), 0xc4},
+	{CCI_REG8(0x9f79), 0x09},
+	{CCI_REG8(0x9f7a), 0xd0},
+	{CCI_REG8(0x9f7b), 0x07},
+	{CCI_REG8(0x9f7c), 0xd0},
+	{CCI_REG8(0x9f7d), 0x07},
+	{CCI_REG8(0x9f7e), 0xd0},
+	{CCI_REG8(0x9f7f), 0x07},
+	{CCI_REG8(0x9f80), 0xd0},
+	{CCI_REG8(0x9f81), 0x07},
+	{CCI_REG8(0x9f82), 0xc4},
+	{CCI_REG8(0x9f83), 0x09},
+	{CCI_REG8(0x9f84), 0xc4},
+	{CCI_REG8(0x9f85), 0x09},
+	{CCI_REG8(0x9f86), 0xc4},
+	{CCI_REG8(0x9f87), 0x09},
+	{CCI_REG8(0x9f88), 0xc4},
+	{CCI_REG8(0x9f89), 0x09},
+	{CCI_REG8(0x9f8a), 0xd0},
+	{CCI_REG8(0x9f8b), 0x07},
+	{CCI_REG8(0x9f8c), 0xd0},
+	{CCI_REG8(0x9f8d), 0x07},
+	{CCI_REG8(0x9f8e), 0xd0},
+	{CCI_REG8(0x9f8f), 0x07},
+	{CCI_REG8(0x9f90), 0xd0},
+	{CCI_REG8(0x9f91), 0x07},
+	{CCI_REG8(0x9f92), 0xc4},
+	{CCI_REG8(0x9f93), 0x09},
+	{CCI_REG8(0x9f94), 0xc4},
+	{CCI_REG8(0x9f95), 0x09},
+	{CCI_REG8(0x9f96), 0xc4},
+	{CCI_REG8(0x9f97), 0x09},
+	{CCI_REG8(0x9f98), 0xc4},
+	{CCI_REG8(0x9f99), 0x09},
+	{CCI_REG8(0x9f9a), 0xd0},
+	{CCI_REG8(0x9f9b), 0x07},
+	{CCI_REG8(0x9f9c), 0xd0},
+	{CCI_REG8(0x9f9d), 0x07},
+	{CCI_REG8(0x9f9e), 0xd0},
+	{CCI_REG8(0x9f9f), 0x07},
+	{CCI_REG8(0x9fa0), 0xd0},
+	{CCI_REG8(0x9fa1), 0x07},
+	{CCI_REG8(0x9fa2), 0xc4},
+	{CCI_REG8(0x9fa3), 0x09},
+	{CCI_REG8(0x9fa4), 0xc4},
+	{CCI_REG8(0x9fa5), 0x09},
+	{CCI_REG8(0x9fa6), 0xc4},
+	{CCI_REG8(0x9fa7), 0x09},
+	{CCI_REG8(0x9fa8), 0xc4},
+	{CCI_REG8(0x9fa9), 0x09},
+	{CCI_REG8(0x9faa), 0xd0},
+	{CCI_REG8(0x9fab), 0x07},
+	{CCI_REG8(0x9fac), 0xd0},
+	{CCI_REG8(0x9fad), 0x07},
+	{CCI_REG8(0x9fae), 0xd0},
+	{CCI_REG8(0x9faf), 0x07},
+	{CCI_REG8(0x9fb0), 0xd0},
+	{CCI_REG8(0x9fb1), 0x07},
+	{CCI_REG8(0x9fb2), 0xc4},
+	{CCI_REG8(0x9fb3), 0x09},
+	{CCI_REG8(0x9fb4), 0xc4},
+	{CCI_REG8(0x9fb5), 0x09},
+	{CCI_REG8(0x9fb6), 0xc4},
+	{CCI_REG8(0x9fb7), 0x09},
+	{CCI_REG8(0x9fb8), 0xc4},
+	{CCI_REG8(0x9fb9), 0x09},
+	{CCI_REG8(0x9fba), 0xd0},
+	{CCI_REG8(0x9fbb), 0x07},
+	{CCI_REG8(0x9fbc), 0xd0},
+	{CCI_REG8(0x9fbd), 0x07},
+	{CCI_REG8(0x9fbe), 0xd0},
+	{CCI_REG8(0x9fbf), 0x07},
+	{CCI_REG8(0x9fc0), 0xd0},
+	{CCI_REG8(0x9fc1), 0x07},
+	{CCI_REG8(0x9fc2), 0xc4},
+	{CCI_REG8(0x9fc3), 0x09},
+	{CCI_REG8(0x9fc4), 0xc4},
+	{CCI_REG8(0x9fc5), 0x09},
+	{CCI_REG8(0x9fc6), 0xc4},
+	{CCI_REG8(0x9fc7), 0x09},
+	{CCI_REG8(0x9fc8), 0xc4},
+	{CCI_REG8(0x9fc9), 0x09},
+	{CCI_REG8(0x9fca), 0xd0},
+	{CCI_REG8(0x9fcb), 0x07},
+	{CCI_REG8(0x9fcc), 0xd0},
+	{CCI_REG8(0x9fcd), 0x07},
+	{CCI_REG8(0x9fce), 0xd0},
+	{CCI_REG8(0x9fcf), 0x07},
+	{CCI_REG8(0x9fd0), 0xd0},
+	{CCI_REG8(0x9fd1), 0x07},
+	{CCI_REG8(0x9fd2), 0xc4},
+	{CCI_REG8(0x9fd3), 0x09},
+	{CCI_REG8(0x9fd4), 0xc4},
+	{CCI_REG8(0x9fd5), 0x09},
+	{CCI_REG8(0x9fd6), 0xc4},
+	{CCI_REG8(0x9fd7), 0x09},
+	{CCI_REG8(0x9fd8), 0xc4},
+	{CCI_REG8(0x9fd9), 0x09},
+	{CCI_REG8(0x9fda), 0xd0},
+	{CCI_REG8(0x9fdb), 0x07},
+	{CCI_REG8(0x9fdc), 0xd0},
+	{CCI_REG8(0x9fdd), 0x07},
+	{CCI_REG8(0x9fde), 0xd0},
+	{CCI_REG8(0x9fdf), 0x07},
+	{CCI_REG8(0x9fe0), 0xd0},
+	{CCI_REG8(0x9fe1), 0x07},
+	{CCI_REG8(0x9fe2), 0xc4},
+	{CCI_REG8(0x9fe3), 0x09},
+	{CCI_REG8(0x9fe4), 0xc4},
+	{CCI_REG8(0x9fe5), 0x09},
+	{CCI_REG8(0x9fe6), 0xc4},
+	{CCI_REG8(0x9fe7), 0x09},
+	{CCI_REG8(0x9fe8), 0xc4},
+	{CCI_REG8(0x9fe9), 0x09},
+	{CCI_REG8(0x9fea), 0xd0},
+	{CCI_REG8(0x9feb), 0x07},
+	{CCI_REG8(0x9fec), 0xd0},
+	{CCI_REG8(0x9fed), 0x07},
+	{CCI_REG8(0x9fee), 0xd0},
+	{CCI_REG8(0x9fef), 0x07},
+	{CCI_REG8(0x9ff0), 0xd0},
+	{CCI_REG8(0x9ff1), 0x07},
+	{CCI_REG8(0x9ff2), 0xc4},
+	{CCI_REG8(0x9ff3), 0x09},
+	{CCI_REG8(0x9ff4), 0xc4},
+	{CCI_REG8(0x9ff5), 0x09},
+	{CCI_REG8(0x9ff6), 0xc4},
+	{CCI_REG8(0x9ff7), 0x09},
+	{CCI_REG8(0x9ff8), 0xc4},
+	{CCI_REG8(0x9ff9), 0x09},
+	{CCI_REG8(0x9ffa), 0xd0},
+	{CCI_REG8(0x9ffb), 0x07},
+	{CCI_REG8(0x9ffc), 0xd0},
+	{CCI_REG8(0x9ffd), 0x07},
+	{CCI_REG8(0x9ffe), 0xd0},
+	{CCI_REG8(0x9fff), 0x07},
+	{CCI_REG8(0xa000), 0xd0},
+	{CCI_REG8(0xa001), 0x07},
+	{CCI_REG8(0xa002), 0xc4},
+	{CCI_REG8(0xa003), 0x09},
+	{CCI_REG8(0xa004), 0xc4},
+	{CCI_REG8(0xa005), 0x09},
+	{CCI_REG8(0xa006), 0xc4},
+	{CCI_REG8(0xa007), 0x09},
+	{CCI_REG8(0xa008), 0xc4},
+	{CCI_REG8(0xa009), 0x09},
+	{CCI_REG8(0xa00a), 0xd0},
+	{CCI_REG8(0xa00b), 0x07},
+	{CCI_REG8(0xa00c), 0xd0},
+	{CCI_REG8(0xa00d), 0x07},
+	{CCI_REG8(0xa00e), 0xd0},
+	{CCI_REG8(0xa00f), 0x07},
+	{CCI_REG8(0xa010), 0xd0},
+	{CCI_REG8(0xa011), 0x07},
+	{CCI_REG8(0xa012), 0xc4},
+	{CCI_REG8(0xa013), 0x09},
+	{CCI_REG8(0xa014), 0xc4},
+	{CCI_REG8(0xa015), 0x09},
+	{CCI_REG8(0xa016), 0xc4},
+	{CCI_REG8(0xa017), 0x09},
+	{CCI_REG8(0xa018), 0xc4},
+	{CCI_REG8(0xa019), 0x09},
+	{CCI_REG8(0xa044), 0x4b},
+	{CCI_REG8(0xa045), 0x00},
+	{CCI_REG8(0xa046), 0x4b},
+	{CCI_REG8(0xa047), 0x00},
+	{CCI_REG8(0xa048), 0x4b},
+	{CCI_REG8(0xa049), 0x00},
+	{CCI_REG8(0xa04a), 0x4b},
+	{CCI_REG8(0xa04b), 0x00},
+	{CCI_REG8(0xa04c), 0x15},
+	{CCI_REG8(0xa04d), 0x00},
+	{CCI_REG8(0xa04e), 0x15},
+	{CCI_REG8(0xa04f), 0x00},
+	{CCI_REG8(0xa050), 0x15},
+	{CCI_REG8(0xa051), 0x00},
+	{CCI_REG8(0xa052), 0x15},
+	{CCI_REG8(0xa053), 0x00},
+	{CCI_REG8(0xa054), 0x28},
+	{CCI_REG8(0xa055), 0x00},
+	{CCI_REG8(0xa056), 0x28},
+	{CCI_REG8(0xa057), 0x00},
+	{CCI_REG8(0xa058), 0x28},
+	{CCI_REG8(0xa059), 0x00},
+	{CCI_REG8(0xa05a), 0x28},
+	{CCI_REG8(0xa05b), 0x00},
+	{CCI_REG8(0xa05c), 0x28},
+	{CCI_REG8(0xa05d), 0x00},
+	{CCI_REG8(0xa05e), 0x28},
+	{CCI_REG8(0xa05f), 0x00},
+	{CCI_REG8(0xa060), 0x28},
+	{CCI_REG8(0xa061), 0x00},
+	{CCI_REG8(0xa062), 0x28},
+	{CCI_REG8(0xa063), 0x00},
+	{CCI_REG8(0xa064), 0x21},
+	{CCI_REG8(0xa065), 0x00},
+	{CCI_REG8(0xa066), 0x21},
+	{CCI_REG8(0xa067), 0x00},
+	{CCI_REG8(0xa068), 0x21},
+	{CCI_REG8(0xa069), 0x00},
+	{CCI_REG8(0xa06a), 0x21},
+	{CCI_REG8(0xa06b), 0x00},
+	{CCI_REG8(0xa076), 0x21},
+	{CCI_REG8(0xa077), 0x00},
+	{CCI_REG8(0xa078), 0x21},
+	{CCI_REG8(0xa079), 0x00},
+	{CCI_REG8(0xa07a), 0x21},
+	{CCI_REG8(0xa07b), 0x00},
+	{CCI_REG8(0xa07c), 0x21},
+	{CCI_REG8(0xa07d), 0x00},
+	{CCI_REG8(0xa07e), 0x28},
+	{CCI_REG8(0xa07f), 0x00},
+	{CCI_REG8(0xa080), 0x28},
+	{CCI_REG8(0xa081), 0x00},
+	{CCI_REG8(0xa082), 0x28},
+	{CCI_REG8(0xa083), 0x00},
+	{CCI_REG8(0xa084), 0x28},
+	{CCI_REG8(0xa085), 0x00},
+	{CCI_REG8(0xa086), 0x54},
+	{CCI_REG8(0xa087), 0x00},
+	{CCI_REG8(0xa088), 0x54},
+	{CCI_REG8(0xa089), 0x00},
+	{CCI_REG8(0xa08a), 0x54},
+	{CCI_REG8(0xa08b), 0x00},
+	{CCI_REG8(0xa08c), 0x54},
+	{CCI_REG8(0xa08d), 0x00},
+	{CCI_REG8(0xa09a), 0xa6},
+	{CCI_REG8(0xa09b), 0x0e},
+	{CCI_REG8(0xa09c), 0xa6},
+	{CCI_REG8(0xa09d), 0x0e},
+	{CCI_REG8(0xa09e), 0xa6},
+	{CCI_REG8(0xa09f), 0x0e},
+	{CCI_REG8(0xa0a0), 0xa6},
+	{CCI_REG8(0xa0a1), 0x0e},
+	{CCI_REG8(0xa0a2), 0xa6},
+	{CCI_REG8(0xa0a3), 0x0e},
+	{CCI_REG8(0xa0a4), 0xa6},
+	{CCI_REG8(0xa0a5), 0x0e},
+	{CCI_REG8(0xa0a6), 0xa6},
+	{CCI_REG8(0xa0a7), 0x0e},
+	{CCI_REG8(0xa0a8), 0xa6},
+	{CCI_REG8(0xa0a9), 0x0e},
+	{CCI_REG8(0xa0aa), 0xa6},
+	{CCI_REG8(0xa0ab), 0x0e},
+	{CCI_REG8(0xa0ac), 0xa6},
+	{CCI_REG8(0xa0ad), 0x0e},
+	{CCI_REG8(0xa0ae), 0xa6},
+	{CCI_REG8(0xa0af), 0x0e},
+	{CCI_REG8(0xa0b0), 0xa6},
+	{CCI_REG8(0xa0b1), 0x0e},
+	{CCI_REG8(0xa0bc), 0xfe},
+	{CCI_REG8(0xa0bd), 0x01},
+	{CCI_REG8(0xa0be), 0xfe},
+	{CCI_REG8(0xa0bf), 0x01},
+	{CCI_REG8(0xa0c0), 0xfe},
+	{CCI_REG8(0xa0c1), 0x01},
+	{CCI_REG8(0xa0c2), 0xfe},
+	{CCI_REG8(0xa0c3), 0x01},
+	{CCI_REG8(0xa0c4), 0xfc},
+	{CCI_REG8(0xa0c5), 0x03},
+	{CCI_REG8(0xa0c6), 0xfc},
+	{CCI_REG8(0xa0c7), 0x03},
+	{CCI_REG8(0xa0c8), 0xfc},
+	{CCI_REG8(0xa0c9), 0x03},
+	{CCI_REG8(0xa0ca), 0xfc},
+	{CCI_REG8(0xa0cb), 0x03},
+	{CCI_REG8(0xa0cc), 0xfe},
+	{CCI_REG8(0xa0cd), 0x01},
+	{CCI_REG8(0xa0ce), 0xfe},
+	{CCI_REG8(0xa0cf), 0x01},
+	{CCI_REG8(0xa0d0), 0xfe},
+	{CCI_REG8(0xa0d1), 0x01},
+	{CCI_REG8(0xa0d2), 0xfe},
+	{CCI_REG8(0xa0d3), 0x01},
+	{CCI_REG8(0xa0d4), 0xfc},
+	{CCI_REG8(0xa0d5), 0x03},
+	{CCI_REG8(0xa0d6), 0xfc},
+	{CCI_REG8(0xa0d7), 0x03},
+	{CCI_REG8(0xa0d8), 0xfc},
+	{CCI_REG8(0xa0d9), 0x03},
+	{CCI_REG8(0xa0da), 0xfc},
+	{CCI_REG8(0xa0db), 0x03},
+	{CCI_REG8(0xa0dc), 0xfe},
+	{CCI_REG8(0xa0dd), 0x01},
+	{CCI_REG8(0xa0de), 0xfe},
+	{CCI_REG8(0xa0df), 0x01},
+	{CCI_REG8(0xa0e0), 0xfe},
+	{CCI_REG8(0xa0e1), 0x01},
+	{CCI_REG8(0xa0e2), 0xfe},
+	{CCI_REG8(0xa0e3), 0x01},
+	{CCI_REG8(0xa0e4), 0xfc},
+	{CCI_REG8(0xa0e5), 0x03},
+	{CCI_REG8(0xa0e6), 0xfc},
+	{CCI_REG8(0xa0e7), 0x03},
+	{CCI_REG8(0xa0e8), 0xfc},
+	{CCI_REG8(0xa0e9), 0x03},
+	{CCI_REG8(0xa0ea), 0xfc},
+	{CCI_REG8(0xa0eb), 0x03},
+	{CCI_REG8(0xa0ec), 0xfe},
+	{CCI_REG8(0xa0ed), 0x01},
+	{CCI_REG8(0xa0ee), 0xfe},
+	{CCI_REG8(0xa0ef), 0x01},
+	{CCI_REG8(0xa0f0), 0xfe},
+	{CCI_REG8(0xa0f1), 0x01},
+	{CCI_REG8(0xa0f2), 0xfe},
+	{CCI_REG8(0xa0f3), 0x01},
+	{CCI_REG8(0xa0f4), 0xfc},
+	{CCI_REG8(0xa0f5), 0x03},
+	{CCI_REG8(0xa0f6), 0xfc},
+	{CCI_REG8(0xa0f7), 0x03},
+	{CCI_REG8(0xa0f8), 0xfc},
+	{CCI_REG8(0xa0f9), 0x03},
+	{CCI_REG8(0xa0fa), 0xfc},
+	{CCI_REG8(0xa0fb), 0x03},
+	{CCI_REG8(0xa11c), 0x01},
+	{CCI_REG8(0xa126), 0x00},
+	{CCI_REG8(0xa127), 0x04},
+	{CCI_REG8(0xa128), 0x00},
+	{CCI_REG8(0xa129), 0x02},
+	{CCI_REG8(0xa12a), 0x00},
+	{CCI_REG8(0xa12b), 0x02},
+	{CCI_REG8(0xa12c), 0x00},
+	{CCI_REG8(0xa12d), 0x02},
+	{CCI_REG8(0xa12e), 0x00},
+	{CCI_REG8(0xa12f), 0x02},
+	{CCI_REG8(0xa130), 0x00},
+	{CCI_REG8(0xa131), 0x02},
+	{CCI_REG8(0xa132), 0x00},
+	{CCI_REG8(0xa133), 0x02},
+	{CCI_REG8(0xa134), 0x00},
+	{CCI_REG8(0xa135), 0x02},
+	{CCI_REG8(0xa136), 0x00},
+	{CCI_REG8(0xa137), 0x02},
+	{CCI_REG8(0xa138), 0xa6},
+	{CCI_REG8(0xa139), 0x0e},
+	{CCI_REG8(0xa13a), 0xa6},
+	{CCI_REG8(0xa13b), 0x0e},
+	{CCI_REG8(0xa13c), 0xa6},
+	{CCI_REG8(0xa13d), 0x0e},
+	{CCI_REG8(0xa13e), 0xa6},
+	{CCI_REG8(0xa13f), 0x0e},
+	{CCI_REG8(0xa140), 0xa6},
+	{CCI_REG8(0xa141), 0x0e},
+	{CCI_REG8(0xa142), 0xa6},
+	{CCI_REG8(0xa143), 0x0e},
+	{CCI_REG8(0xa144), 0xa6},
+	{CCI_REG8(0xa145), 0x0e},
+	{CCI_REG8(0xa146), 0xa6},
+	{CCI_REG8(0xa147), 0x0e},
+	{CCI_REG8(0xa148), 0xa6},
+	{CCI_REG8(0xa149), 0x0e},
+	{CCI_REG8(0xa14a), 0xa6},
+	{CCI_REG8(0xa14b), 0x0e},
+	{CCI_REG8(0xa14c), 0xa6},
+	{CCI_REG8(0xa14d), 0x0e},
+	{CCI_REG8(0xa14e), 0xa6},
+	{CCI_REG8(0xa14f), 0x0e},
+	{CCI_REG8(0xa150), 0xa6},
+	{CCI_REG8(0xa151), 0x0e},
+	{CCI_REG8(0xa152), 0xa6},
+	{CCI_REG8(0xa153), 0x0e},
+	{CCI_REG8(0xa154), 0xa6},
+	{CCI_REG8(0xa155), 0x0e},
+	{CCI_REG8(0xa156), 0xa6},
+	{CCI_REG8(0xa157), 0x0e},
+	{CCI_REG8(0xa15e), 0x09},
+	{CCI_REG8(0xa15f), 0x08},
+	{CCI_REG8(0xa160), 0x10},
+	{CCI_REG8(0xa161), 0x09},
+	{CCI_REG8(0xa162), 0x01},
+	{CCI_REG8(0xa163), 0x00},
+	{CCI_REG8(0xa166), 0x2f},
+	{CCI_REG8(0xa167), 0x00},
+	{CCI_REG8(0xa168), 0x01},
+	{CCI_REG8(0xa169), 0x00},
+	{CCI_REG8(0xa16a), 0x00},
+	{CCI_REG8(0xa16b), 0x00},
+	{CCI_REG8(0xa16c), 0x00},
+	{CCI_REG8(0xa16d), 0x00},
+	{CCI_REG8(0xa16e), 0x00},
+	{CCI_REG8(0xa16f), 0x00},
+	{CCI_REG8(0xa170), 0x00},
+	{CCI_REG8(0xa171), 0x00},
+	{CCI_REG8(0xa172), 0x33},
+	{CCI_REG8(0xa173), 0x00},
+	{CCI_REG8(0xa174), 0x33},
+	{CCI_REG8(0xa175), 0x00},
+	{CCI_REG8(0xa176), 0x33},
+	{CCI_REG8(0xa177), 0x00},
+	{CCI_REG8(0xa178), 0x33},
+	{CCI_REG8(0xa179), 0x00},
+	{CCI_REG8(0xa17c), 0xde},
+	{CCI_REG8(0xa17d), 0x00},
+	{CCI_REG8(0xa17e), 0xea},
+	{CCI_REG8(0xa17f), 0x00},
+	{CCI_REG8(0xa180), 0xde},
+	{CCI_REG8(0xa181), 0x00},
+	{CCI_REG8(0xa182), 0xea},
+	{CCI_REG8(0xa183), 0x00},
+	{CCI_REG8(0xa184), 0xde},
+	{CCI_REG8(0xa185), 0x00},
+	{CCI_REG8(0xa186), 0xea},
+	{CCI_REG8(0xa187), 0x00},
+	{CCI_REG8(0xa18a), 0x87},
+	{CCI_REG8(0xa18b), 0x87},
+	{CCI_REG8(0xa414), 0x67},
+	{CCI_REG8(0xa415), 0x09},
+	{CCI_REG8(0xa416), 0xd8},
+	{CCI_REG8(0xa417), 0x1a},
+	{CCI_REG8(0xa418), 0xb4},
+	{CCI_REG8(0xa419), 0x0c},
+	{CCI_REG8(0xa41a), 0x7e},
+	{CCI_REG8(0xa41b), 0x15},
+	{CCI_REG8(0xa41c), 0x01},
+	{CCI_REG8(0xa41d), 0x10},
+	{CCI_REG8(0xa41e), 0x24},
+	{CCI_REG8(0xa41f), 0x10},
+	{CCI_REG8(0xa420), 0x1a},
+	{CCI_REG8(0xa421), 0x14},
+	{CCI_REG8(0xa422), 0x6a},
+	{CCI_REG8(0xa423), 0x0e},
+	{CCI_REG8(0xa424), 0xd5},
+	{CCI_REG8(0xa425), 0x19},
+	{CCI_REG8(0xa426), 0xd5},
+	{CCI_REG8(0xa427), 0x0c},
+	{CCI_REG8(0xa428), 0xa9},
+	{CCI_REG8(0xa429), 0x0d},
+	{CCI_REG8(0xa42a), 0xe1},
+	{CCI_REG8(0xa42b), 0x13},
+	{CCI_REG8(0xa42c), 0x10},
+	{CCI_REG8(0xa42d), 0x0e},
+	{CCI_REG8(0xa42e), 0x47},
+	{CCI_REG8(0xa42f), 0x0f},
+	{CCI_REG8(0xa6b1), 0x01},
+	{CCI_REG8(0xa6da), 0x23},
+	{CCI_REG8(0xa6db), 0x00},
+	{CCI_REG8(0xa6dc), 0x20},
+	{CCI_REG8(0xa6dd), 0x00},
+	{CCI_REG8(0xa6de), 0x1c},
+	{CCI_REG8(0xa6df), 0x00},
+	{CCI_REG8(0xa6e0), 0x18},
+	{CCI_REG8(0xa6e1), 0x00},
+	{CCI_REG8(0xa6e2), 0x46},
+	{CCI_REG8(0xa6e3), 0x00},
+	{CCI_REG8(0xa6e4), 0x40},
+	{CCI_REG8(0xa6e5), 0x00},
+	{CCI_REG8(0xa6e6), 0x39},
+	{CCI_REG8(0xa6e7), 0x00},
+	{CCI_REG8(0xa6e8), 0x31},
+	{CCI_REG8(0xa6e9), 0x00},
+	{CCI_REG8(0xa6ea), 0x8c},
+	{CCI_REG8(0xa6eb), 0x00},
+	{CCI_REG8(0xa6ec), 0x7f},
+	{CCI_REG8(0xa6ed), 0x00},
+	{CCI_REG8(0xa6ee), 0x71},
+	{CCI_REG8(0xa6ef), 0x00},
+	{CCI_REG8(0xa6f0), 0x61},
+	{CCI_REG8(0xa6f1), 0x00},
+	{CCI_REG8(0xa6f2), 0x18},
+	{CCI_REG8(0xa6f3), 0x01},
+	{CCI_REG8(0xa6f4), 0xff},
+	{CCI_REG8(0xa6f5), 0x00},
+	{CCI_REG8(0xa6f6), 0xe2},
+	{CCI_REG8(0xa6f7), 0x00},
+	{CCI_REG8(0xa6f8), 0xc2},
+	{CCI_REG8(0xa6f9), 0x00},
+	{CCI_REG8(0xa702), 0x02},
+	{CCI_REG8(0xa703), 0x00},
+	{CCI_REG8(0xa704), 0x02},
+	{CCI_REG8(0xa705), 0x00},
+	{CCI_REG8(0xa706), 0x02},
+	{CCI_REG8(0xa707), 0x00},
+	{CCI_REG8(0xa708), 0x02},
+	{CCI_REG8(0xa709), 0x00},
+	{CCI_REG8(0xa72e), 0x40},
+	{CCI_REG8(0xa72f), 0x40},
+	{CCI_REG8(0xa730), 0x40},
+	{CCI_REG8(0xa731), 0x40},
+	{CCI_REG8(0xa732), 0x05},
+	{CCI_REG8(0xa733), 0x00},
+	{CCI_REG8(0xa734), 0x05},
+	{CCI_REG8(0xa735), 0x00},
+	{CCI_REG8(0xa736), 0x05},
+	{CCI_REG8(0xa737), 0x00},
+	{CCI_REG8(0xa738), 0x05},
+	{CCI_REG8(0xa739), 0x00},
+	{CCI_REG8(0xa73a), 0x09},
+	{CCI_REG8(0xa73b), 0x00},
+	{CCI_REG8(0xa73c), 0x09},
+	{CCI_REG8(0xa73d), 0x00},
+	{CCI_REG8(0xa73e), 0x09},
+	{CCI_REG8(0xa73f), 0x00},
+	{CCI_REG8(0xa740), 0x09},
+	{CCI_REG8(0xa741), 0x00},
+	{CCI_REG8(0xa742), 0x13},
+	{CCI_REG8(0xa743), 0x00},
+	{CCI_REG8(0xa744), 0x13},
+	{CCI_REG8(0xa745), 0x00},
+	{CCI_REG8(0xa746), 0x13},
+	{CCI_REG8(0xa747), 0x00},
+	{CCI_REG8(0xa748), 0x13},
+	{CCI_REG8(0xa749), 0x00},
+	{CCI_REG8(0xa74a), 0x25},
+	{CCI_REG8(0xa74b), 0x00},
+	{CCI_REG8(0xa74c), 0x25},
+	{CCI_REG8(0xa74d), 0x00},
+	{CCI_REG8(0xa74e), 0x25},
+	{CCI_REG8(0xa74f), 0x00},
+	{CCI_REG8(0xa750), 0x25},
+	{CCI_REG8(0xa751), 0x00},
+	{CCI_REG8(0xa75a), 0x02},
+	{CCI_REG8(0xa75b), 0x00},
+	{CCI_REG8(0xa75c), 0x02},
+	{CCI_REG8(0xa75d), 0x00},
+	{CCI_REG8(0xa75e), 0x02},
+	{CCI_REG8(0xa75f), 0x00},
+	{CCI_REG8(0xa760), 0x02},
+	{CCI_REG8(0xa761), 0x00},
+	{CCI_REG8(0xa782), 0x40},
+	{CCI_REG8(0xa783), 0x40},
+	{CCI_REG8(0xa784), 0x40},
+	{CCI_REG8(0xa785), 0x40},
+	{CCI_REG8(0xa786), 0x40},
+	{CCI_REG8(0xa787), 0x40},
+	{CCI_REG8(0xa788), 0x40},
+	{CCI_REG8(0xa789), 0x40},
+	{CCI_REG8(0xa78a), 0x03},
+	{CCI_REG8(0xa78b), 0x00},
+	{CCI_REG8(0xa78c), 0x03},
+	{CCI_REG8(0xa78d), 0x00},
+	{CCI_REG8(0xa78e), 0x03},
+	{CCI_REG8(0xa78f), 0x00},
+	{CCI_REG8(0xa790), 0x03},
+	{CCI_REG8(0xa791), 0x00},
+	{CCI_REG8(0xa792), 0x06},
+	{CCI_REG8(0xa793), 0x00},
+	{CCI_REG8(0xa794), 0x06},
+	{CCI_REG8(0xa795), 0x00},
+	{CCI_REG8(0xa796), 0x06},
+	{CCI_REG8(0xa797), 0x00},
+	{CCI_REG8(0xa798), 0x06},
+	{CCI_REG8(0xa799), 0x00},
+	{CCI_REG8(0xa79a), 0x0c},
+	{CCI_REG8(0xa79b), 0x00},
+	{CCI_REG8(0xa79c), 0x0c},
+	{CCI_REG8(0xa79d), 0x00},
+	{CCI_REG8(0xa79e), 0x0c},
+	{CCI_REG8(0xa79f), 0x00},
+	{CCI_REG8(0xa7a0), 0x0c},
+	{CCI_REG8(0xa7a1), 0x00},
+	{CCI_REG8(0xa7a2), 0x19},
+	{CCI_REG8(0xa7a3), 0x00},
+	{CCI_REG8(0xa7a4), 0x19},
+	{CCI_REG8(0xa7a5), 0x00},
+	{CCI_REG8(0xa7a6), 0x19},
+	{CCI_REG8(0xa7a7), 0x00},
+	{CCI_REG8(0xa7a8), 0x19},
+	{CCI_REG8(0xa7a9), 0x00},
+	{CCI_REG8(0xa7b2), 0x02},
+	{CCI_REG8(0xa7b3), 0x00},
+	{CCI_REG8(0xa7b4), 0x02},
+	{CCI_REG8(0xa7b5), 0x00},
+	{CCI_REG8(0xa7b6), 0x02},
+	{CCI_REG8(0xa7b7), 0x00},
+	{CCI_REG8(0xa7b8), 0x02},
+	{CCI_REG8(0xa7b9), 0x00},
+	{CCI_REG8(0xa7e2), 0x01},
+	{CCI_REG8(0xa7e3), 0x00},
+	{CCI_REG8(0xa7e4), 0x01},
+	{CCI_REG8(0xa7e5), 0x00},
+	{CCI_REG8(0xa7e6), 0x01},
+	{CCI_REG8(0xa7e7), 0x00},
+	{CCI_REG8(0xa7e8), 0x01},
+	{CCI_REG8(0xa7e9), 0x00},
+	{CCI_REG8(0xa7ea), 0x03},
+	{CCI_REG8(0xa7eb), 0x00},
+	{CCI_REG8(0xa7ec), 0x03},
+	{CCI_REG8(0xa7ed), 0x00},
+	{CCI_REG8(0xa7ee), 0x03},
+	{CCI_REG8(0xa7ef), 0x00},
+	{CCI_REG8(0xa7f0), 0x03},
+	{CCI_REG8(0xa7f1), 0x00},
+	{CCI_REG8(0xa7f2), 0x0b},
+	{CCI_REG8(0xa7f3), 0x00},
+	{CCI_REG8(0xa7f4), 0x0b},
+	{CCI_REG8(0xa7f5), 0x00},
+	{CCI_REG8(0xa7f6), 0x0b},
+	{CCI_REG8(0xa7f7), 0x00},
+	{CCI_REG8(0xa7f8), 0x0b},
+	{CCI_REG8(0xa7f9), 0x00},
+	{CCI_REG8(0xa7fa), 0x2e},
+	{CCI_REG8(0xa7fb), 0x00},
+	{CCI_REG8(0xa7fc), 0x2e},
+	{CCI_REG8(0xa7fd), 0x00},
+	{CCI_REG8(0xa7fe), 0x2e},
+	{CCI_REG8(0xa7ff), 0x00},
+	{CCI_REG8(0xa800), 0x2e},
+	{CCI_REG8(0xa801), 0x00},
+	{CCI_REG8(0xa80a), 0x0a},
+	{CCI_REG8(0xa80b), 0x00},
+	{CCI_REG8(0xa80c), 0x0a},
+	{CCI_REG8(0xa80d), 0x00},
+	{CCI_REG8(0xa80e), 0x0a},
+	{CCI_REG8(0xa80f), 0x00},
+	{CCI_REG8(0xa810), 0x0a},
+	{CCI_REG8(0xa811), 0x00},
+	{CCI_REG8(0xa832), 0x40},
+	{CCI_REG8(0xa833), 0x40},
+	{CCI_REG8(0xa834), 0x40},
+	{CCI_REG8(0xa835), 0x40},
+	{CCI_REG8(0xa836), 0x40},
+	{CCI_REG8(0xa837), 0x40},
+	{CCI_REG8(0xa838), 0x40},
+	{CCI_REG8(0xa839), 0x40},
+	{CCI_REG8(0xa83a), 0x05},
+	{CCI_REG8(0xa83b), 0x00},
+	{CCI_REG8(0xa83c), 0x05},
+	{CCI_REG8(0xa83d), 0x00},
+	{CCI_REG8(0xa83e), 0x05},
+	{CCI_REG8(0xa83f), 0x00},
+	{CCI_REG8(0xa840), 0x05},
+	{CCI_REG8(0xa841), 0x00},
+	{CCI_REG8(0xa842), 0x0a},
+	{CCI_REG8(0xa843), 0x00},
+	{CCI_REG8(0xa844), 0x0a},
+	{CCI_REG8(0xa845), 0x00},
+	{CCI_REG8(0xa846), 0x0a},
+	{CCI_REG8(0xa847), 0x00},
+	{CCI_REG8(0xa848), 0x0a},
+	{CCI_REG8(0xa849), 0x00},
+	{CCI_REG8(0xa84a), 0x13},
+	{CCI_REG8(0xa84b), 0x00},
+	{CCI_REG8(0xa84c), 0x13},
+	{CCI_REG8(0xa84d), 0x00},
+	{CCI_REG8(0xa84e), 0x13},
+	{CCI_REG8(0xa84f), 0x00},
+	{CCI_REG8(0xa850), 0x13},
+	{CCI_REG8(0xa851), 0x00},
+	{CCI_REG8(0xa852), 0x26},
+	{CCI_REG8(0xa853), 0x00},
+	{CCI_REG8(0xa854), 0x26},
+	{CCI_REG8(0xa855), 0x00},
+	{CCI_REG8(0xa856), 0x26},
+	{CCI_REG8(0xa857), 0x00},
+	{CCI_REG8(0xa858), 0x26},
+	{CCI_REG8(0xa859), 0x00},
+	{CCI_REG8(0xa862), 0x02},
+	{CCI_REG8(0xa863), 0x00},
+	{CCI_REG8(0xa864), 0x02},
+	{CCI_REG8(0xa865), 0x00},
+	{CCI_REG8(0xa866), 0x02},
+	{CCI_REG8(0xa867), 0x00},
+	{CCI_REG8(0xa868), 0x02},
+	{CCI_REG8(0xa869), 0x00},
+	{CCI_REG8(0xa455), 0x00},
+	{CCI_REG8(0xa456), 0x01},
+	{CCI_REG8(0xa470), 0xaf},
+	{CCI_REG8(0xa471), 0x9b},
+	{CCI_REG8(0xa472), 0x87},
+	{CCI_REG8(0xa473), 0x6e},
+	{CCI_REG8(0xa474), 0xaf},
+	{CCI_REG8(0xa475), 0x9b},
+	{CCI_REG8(0xa476), 0x87},
+	{CCI_REG8(0xa477), 0x6e},
+	{CCI_REG8(0xa478), 0xaf},
+	{CCI_REG8(0xa479), 0x9b},
+	{CCI_REG8(0xa47a), 0x87},
+	{CCI_REG8(0xa47b), 0x6e},
+	{CCI_REG8(0xa4b4), 0x70},
+	{CCI_REG8(0xa4b5), 0x70},
+	{CCI_REG8(0xa4b6), 0x70},
+	{CCI_REG8(0xa4b7), 0x70},
+	{CCI_REG8(0xa4b9), 0x4a},
+	{CCI_REG8(0xa4ba), 0x44},
+	{CCI_REG8(0xa4bb), 0x3c},
+	{CCI_REG8(0xa4bc), 0x19},
+	{CCI_REG8(0xa4bd), 0x19},
+	{CCI_REG8(0xa4be), 0x19},
+	{CCI_REG8(0xa4bf), 0x19},
+	{CCI_REG8(0xa4c0), 0x07},
+	{CCI_REG8(0xa4c1), 0x07},
+	{CCI_REG8(0xa4c2), 0x07},
+	{CCI_REG8(0xa4c3), 0x07},
+	{CCI_REG8(0xa4c4), 0x0b},
+	{CCI_REG8(0xa4c5), 0x0b},
+	{CCI_REG8(0xa4c6), 0x0b},
+	{CCI_REG8(0xa4c7), 0x0b},
+	{CCI_REG8(0xa4c8), 0x1c},
+	{CCI_REG8(0xa4c9), 0x1c},
+	{CCI_REG8(0xa4ca), 0x1c},
+	{CCI_REG8(0xa4cb), 0x1c},
+	{CCI_REG8(0xb220), 0x00},
+	{CCI_REG8(0xb221), 0x01},
+	{CCI_REG8(0xb222), 0x00},
+	{CCI_REG8(0xb223), 0x01},
+	{CCI_REG8(0xb224), 0x00},
+	{CCI_REG8(0xb225), 0x01},
+	{CCI_REG8(0xb226), 0x00},
+	{CCI_REG8(0xb227), 0x01},
+	{CCI_REG8(0xb228), 0x00},
+	{CCI_REG8(0xb229), 0x01},
+	{CCI_REG8(0xb22a), 0x00},
+	{CCI_REG8(0xb22b), 0x01},
+	{CCI_REG8(0xb22c), 0x00},
+	{CCI_REG8(0xb22d), 0x01},
+	{CCI_REG8(0xb22e), 0x00},
+	{CCI_REG8(0xb22f), 0x01},
+	{CCI_REG8(0xb230), 0x00},
+	{CCI_REG8(0xb231), 0x01},
+	{CCI_REG8(0xb232), 0x00},
+	{CCI_REG8(0xb233), 0x01},
+	{CCI_REG8(0xb234), 0x00},
+	{CCI_REG8(0xb235), 0x01},
+	{CCI_REG8(0xb236), 0x00},
+	{CCI_REG8(0xb237), 0x01},
+	{CCI_REG8(0xb238), 0x00},
+	{CCI_REG8(0xb239), 0x01},
+	{CCI_REG8(0xb23a), 0x00},
+	{CCI_REG8(0xb23b), 0x01},
+	{CCI_REG8(0xb23c), 0x00},
+	{CCI_REG8(0xb23d), 0x01},
+	{CCI_REG8(0xb23e), 0x00},
+	{CCI_REG8(0xb23f), 0x01},
+	{CCI_REG8(0xb240), 0x80},
+	{CCI_REG8(0xb241), 0x00},
+	{CCI_REG8(0xb242), 0x80},
+	{CCI_REG8(0xb243), 0x00},
+	{CCI_REG8(0xb244), 0x80},
+	{CCI_REG8(0xb245), 0x00},
+	{CCI_REG8(0xb246), 0x80},
+	{CCI_REG8(0xb247), 0x00},
+	{CCI_REG8(0xb248), 0x80},
+	{CCI_REG8(0xb249), 0x00},
+	{CCI_REG8(0xb24a), 0x80},
+	{CCI_REG8(0xb24b), 0x00},
+	{CCI_REG8(0xb24c), 0x80},
+	{CCI_REG8(0xb24d), 0x00},
+	{CCI_REG8(0xb24e), 0x80},
+	{CCI_REG8(0xb24f), 0x00},
+	{CCI_REG8(0xb250), 0x80},
+	{CCI_REG8(0xb251), 0x00},
+	{CCI_REG8(0xb252), 0x80},
+	{CCI_REG8(0xb253), 0x00},
+	{CCI_REG8(0xb254), 0x80},
+	{CCI_REG8(0xb255), 0x00},
+	{CCI_REG8(0xb256), 0x80},
+	{CCI_REG8(0xb257), 0x00},
+	{CCI_REG8(0xb258), 0x80},
+	{CCI_REG8(0xb259), 0x00},
+	{CCI_REG8(0xb25a), 0x80},
+	{CCI_REG8(0xb25b), 0x00},
+	{CCI_REG8(0xb25c), 0x80},
+	{CCI_REG8(0xb25d), 0x00},
+	{CCI_REG8(0xb25e), 0x80},
+	{CCI_REG8(0xb25f), 0x00},
+	{CCI_REG8(0xb260), 0x00},
+	{CCI_REG8(0xb261), 0x01},
+	{CCI_REG8(0xb262), 0x00},
+	{CCI_REG8(0xb263), 0x01},
+	{CCI_REG8(0xb264), 0x00},
+	{CCI_REG8(0xb265), 0x01},
+	{CCI_REG8(0xb266), 0x00},
+	{CCI_REG8(0xb267), 0x01},
+	{CCI_REG8(0xb268), 0x00},
+	{CCI_REG8(0xb269), 0x01},
+	{CCI_REG8(0xb26a), 0x00},
+	{CCI_REG8(0xb26b), 0x01},
+	{CCI_REG8(0xb26c), 0x00},
+	{CCI_REG8(0xb26d), 0x01},
+	{CCI_REG8(0xb26e), 0x00},
+	{CCI_REG8(0xb26f), 0x01},
+	{CCI_REG8(0xb270), 0x00},
+	{CCI_REG8(0xb271), 0x01},
+	{CCI_REG8(0xb272), 0x00},
+	{CCI_REG8(0xb273), 0x01},
+	{CCI_REG8(0xb274), 0x00},
+	{CCI_REG8(0xb275), 0x01},
+	{CCI_REG8(0xb276), 0x00},
+	{CCI_REG8(0xb277), 0x01},
+	{CCI_REG8(0xb278), 0x00},
+	{CCI_REG8(0xb279), 0x01},
+	{CCI_REG8(0xb27a), 0x00},
+	{CCI_REG8(0xb27b), 0x01},
+	{CCI_REG8(0xb27c), 0x00},
+	{CCI_REG8(0xb27d), 0x01},
+	{CCI_REG8(0xb27e), 0x00},
+	{CCI_REG8(0xb27f), 0x01},
+	{CCI_REG8(0xb280), 0x80},
+	{CCI_REG8(0xb281), 0x00},
+	{CCI_REG8(0xb282), 0x80},
+	{CCI_REG8(0xb283), 0x00},
+	{CCI_REG8(0xb284), 0x80},
+	{CCI_REG8(0xb285), 0x00},
+	{CCI_REG8(0xb286), 0x80},
+	{CCI_REG8(0xb287), 0x00},
+	{CCI_REG8(0xb288), 0x80},
+	{CCI_REG8(0xb289), 0x00},
+	{CCI_REG8(0xb28a), 0x80},
+	{CCI_REG8(0xb28b), 0x00},
+	{CCI_REG8(0xb28c), 0x80},
+	{CCI_REG8(0xb28d), 0x00},
+	{CCI_REG8(0xb28e), 0x80},
+	{CCI_REG8(0xb28f), 0x00},
+	{CCI_REG8(0xb290), 0x80},
+	{CCI_REG8(0xb291), 0x00},
+	{CCI_REG8(0xb292), 0x80},
+	{CCI_REG8(0xb293), 0x00},
+	{CCI_REG8(0xb294), 0x80},
+	{CCI_REG8(0xb295), 0x00},
+	{CCI_REG8(0xb296), 0x80},
+	{CCI_REG8(0xb297), 0x00},
+	{CCI_REG8(0xb298), 0x80},
+	{CCI_REG8(0xb299), 0x00},
+	{CCI_REG8(0xb29a), 0x80},
+	{CCI_REG8(0xb29b), 0x00},
+	{CCI_REG8(0xb29c), 0x80},
+	{CCI_REG8(0xb29d), 0x00},
+	{CCI_REG8(0xb29e), 0x80},
+	{CCI_REG8(0xb29f), 0x00},
+	{CCI_REG8(0xb2a0), 0x00},
+	{CCI_REG8(0xb2a1), 0x01},
+	{CCI_REG8(0xb2a2), 0x00},
+	{CCI_REG8(0xb2a3), 0x01},
+	{CCI_REG8(0xb2a4), 0x00},
+	{CCI_REG8(0xb2a5), 0x01},
+	{CCI_REG8(0xb2a6), 0x00},
+	{CCI_REG8(0xb2a7), 0x01},
+	{CCI_REG8(0xb2a8), 0x00},
+	{CCI_REG8(0xb2a9), 0x01},
+	{CCI_REG8(0xb2aa), 0x00},
+	{CCI_REG8(0xb2ab), 0x01},
+	{CCI_REG8(0xb2ac), 0x00},
+	{CCI_REG8(0xb2ad), 0x01},
+	{CCI_REG8(0xb2ae), 0x00},
+	{CCI_REG8(0xb2af), 0x01},
+	{CCI_REG8(0xb2b0), 0x00},
+	{CCI_REG8(0xb2b1), 0x01},
+	{CCI_REG8(0xb2b2), 0x00},
+	{CCI_REG8(0xb2b3), 0x01},
+	{CCI_REG8(0xb2b4), 0x00},
+	{CCI_REG8(0xb2b5), 0x01},
+	{CCI_REG8(0xb2b6), 0x00},
+	{CCI_REG8(0xb2b7), 0x01},
+	{CCI_REG8(0xb2b8), 0x00},
+	{CCI_REG8(0xb2b9), 0x01},
+	{CCI_REG8(0xb2ba), 0x00},
+	{CCI_REG8(0xb2bb), 0x01},
+	{CCI_REG8(0xb2bc), 0x00},
+	{CCI_REG8(0xb2bd), 0x01},
+	{CCI_REG8(0xb2be), 0x00},
+	{CCI_REG8(0xb2bf), 0x01},
+	{CCI_REG8(0xb2c0), 0x80},
+	{CCI_REG8(0xb2c1), 0x00},
+	{CCI_REG8(0xb2c2), 0x80},
+	{CCI_REG8(0xb2c3), 0x00},
+	{CCI_REG8(0xb2c4), 0x80},
+	{CCI_REG8(0xb2c5), 0x00},
+	{CCI_REG8(0xb2c6), 0x80},
+	{CCI_REG8(0xb2c7), 0x00},
+	{CCI_REG8(0xb2c8), 0x80},
+	{CCI_REG8(0xb2c9), 0x00},
+	{CCI_REG8(0xb2ca), 0x80},
+	{CCI_REG8(0xb2cb), 0x00},
+	{CCI_REG8(0xb2cc), 0x80},
+	{CCI_REG8(0xb2cd), 0x00},
+	{CCI_REG8(0xb2ce), 0x80},
+	{CCI_REG8(0xb2cf), 0x00},
+	{CCI_REG8(0xb2d0), 0x80},
+	{CCI_REG8(0xb2d1), 0x00},
+	{CCI_REG8(0xb2d2), 0x80},
+	{CCI_REG8(0xb2d3), 0x00},
+	{CCI_REG8(0xb2d4), 0x80},
+	{CCI_REG8(0xb2d5), 0x00},
+	{CCI_REG8(0xb2d6), 0x80},
+	{CCI_REG8(0xb2d7), 0x00},
+	{CCI_REG8(0xb2d8), 0x80},
+	{CCI_REG8(0xb2d9), 0x00},
+	{CCI_REG8(0xb2da), 0x80},
+	{CCI_REG8(0xb2db), 0x00},
+	{CCI_REG8(0xb2dc), 0x80},
+	{CCI_REG8(0xb2dd), 0x00},
+	{CCI_REG8(0xb2de), 0x80},
+	{CCI_REG8(0xb2df), 0x00},
+	{CCI_REG8(0xb2e0), 0x00},
+	{CCI_REG8(0xb2e1), 0x01},
+	{CCI_REG8(0xb2e2), 0x00},
+	{CCI_REG8(0xb2e3), 0x01},
+	{CCI_REG8(0xb2e4), 0x00},
+	{CCI_REG8(0xb2e5), 0x01},
+	{CCI_REG8(0xb2e6), 0x00},
+	{CCI_REG8(0xb2e7), 0x01},
+	{CCI_REG8(0xb2e8), 0x00},
+	{CCI_REG8(0xb2e9), 0x01},
+	{CCI_REG8(0xb2ea), 0x00},
+	{CCI_REG8(0xb2eb), 0x01},
+	{CCI_REG8(0xb2ec), 0x00},
+	{CCI_REG8(0xb2ed), 0x01},
+	{CCI_REG8(0xb2ee), 0x00},
+	{CCI_REG8(0xb2ef), 0x01},
+	{CCI_REG8(0xb2f0), 0x00},
+	{CCI_REG8(0xb2f1), 0x01},
+	{CCI_REG8(0xb2f2), 0x00},
+	{CCI_REG8(0xb2f3), 0x01},
+	{CCI_REG8(0xb2f4), 0x00},
+	{CCI_REG8(0xb2f5), 0x01},
+	{CCI_REG8(0xb2f6), 0x00},
+	{CCI_REG8(0xb2f7), 0x01},
+	{CCI_REG8(0xb2f8), 0x00},
+	{CCI_REG8(0xb2f9), 0x01},
+	{CCI_REG8(0xb2fa), 0x00},
+	{CCI_REG8(0xb2fb), 0x01},
+	{CCI_REG8(0xb2fc), 0x00},
+	{CCI_REG8(0xb2fd), 0x01},
+	{CCI_REG8(0xb2fe), 0x00},
+	{CCI_REG8(0xb2ff), 0x01},
+	{CCI_REG8(0xb300), 0x80},
+	{CCI_REG8(0xb301), 0x00},
+	{CCI_REG8(0xb302), 0x80},
+	{CCI_REG8(0xb303), 0x00},
+	{CCI_REG8(0xb304), 0x80},
+	{CCI_REG8(0xb305), 0x00},
+	{CCI_REG8(0xb306), 0x80},
+	{CCI_REG8(0xb307), 0x00},
+	{CCI_REG8(0xb308), 0x80},
+	{CCI_REG8(0xb309), 0x00},
+	{CCI_REG8(0xb30a), 0x80},
+	{CCI_REG8(0xb30b), 0x00},
+	{CCI_REG8(0xb30c), 0x80},
+	{CCI_REG8(0xb30d), 0x00},
+	{CCI_REG8(0xb30e), 0x80},
+	{CCI_REG8(0xb30f), 0x00},
+	{CCI_REG8(0xb310), 0x80},
+	{CCI_REG8(0xb311), 0x00},
+	{CCI_REG8(0xb312), 0x80},
+	{CCI_REG8(0xb313), 0x00},
+	{CCI_REG8(0xb314), 0x80},
+	{CCI_REG8(0xb315), 0x00},
+	{CCI_REG8(0xb316), 0x80},
+	{CCI_REG8(0xb317), 0x00},
+	{CCI_REG8(0xb318), 0x80},
+	{CCI_REG8(0xb319), 0x00},
+	{CCI_REG8(0xb31a), 0x80},
+	{CCI_REG8(0xb31b), 0x00},
+	{CCI_REG8(0xb31c), 0x80},
+	{CCI_REG8(0xb31d), 0x00},
+	{CCI_REG8(0xb31e), 0x80},
+	{CCI_REG8(0xb31f), 0x00},
+	{CCI_REG8(0xb320), 0x40},
+	{CCI_REG8(0xb321), 0x40},
+	{CCI_REG8(0xb322), 0x40},
+	{CCI_REG8(0xb323), 0x40},
+	{CCI_REG8(0xb324), 0x40},
+	{CCI_REG8(0xb325), 0x40},
+	{CCI_REG8(0xb326), 0x40},
+	{CCI_REG8(0xb327), 0x40},
+	{CCI_REG8(0xb328), 0x40},
+	{CCI_REG8(0xb329), 0x40},
+	{CCI_REG8(0xb32a), 0x40},
+	{CCI_REG8(0xb32b), 0x40},
+	{CCI_REG8(0xb32c), 0x40},
+	{CCI_REG8(0xb32d), 0x40},
+	{CCI_REG8(0xb32e), 0x40},
+	{CCI_REG8(0xb32f), 0x40},
+	{CCI_REG8(0xb34c), 0x40},
+	{CCI_REG8(0xb34d), 0x40},
+	{CCI_REG8(0xb34e), 0x40},
+	{CCI_REG8(0xb34f), 0x40},
+	{CCI_REG8(0xb350), 0x40},
+	{CCI_REG8(0xb351), 0x40},
+	{CCI_REG8(0xb352), 0x40},
+	{CCI_REG8(0xb353), 0x40},
+	{CCI_REG8(0xb354), 0x40},
+	{CCI_REG8(0xb355), 0x40},
+	{CCI_REG8(0xb356), 0x40},
+	{CCI_REG8(0xb357), 0x40},
+	{CCI_REG8(0xb358), 0x40},
+	{CCI_REG8(0xb359), 0x40},
+	{CCI_REG8(0xb35a), 0x40},
+	{CCI_REG8(0xb35b), 0x40},
+	{CCI_REG8(0xb378), 0x40},
+	{CCI_REG8(0xb379), 0x40},
+	{CCI_REG8(0xb37a), 0x40},
+	{CCI_REG8(0xb37b), 0x40},
+	{CCI_REG8(0xb37c), 0x40},
+	{CCI_REG8(0xb37d), 0x40},
+	{CCI_REG8(0xb37e), 0x40},
+	{CCI_REG8(0xb37f), 0x40},
+	{CCI_REG8(0xb380), 0x40},
+	{CCI_REG8(0xb381), 0x40},
+	{CCI_REG8(0xb382), 0x40},
+	{CCI_REG8(0xb383), 0x40},
+	{CCI_REG8(0xb384), 0x40},
+	{CCI_REG8(0xb385), 0x40},
+	{CCI_REG8(0xb386), 0x40},
+	{CCI_REG8(0xb387), 0x40},
+	{CCI_REG8(0xb3a4), 0x40},
+	{CCI_REG8(0xb3a5), 0x40},
+	{CCI_REG8(0xb3a6), 0x40},
+	{CCI_REG8(0xb3a7), 0x40},
+	{CCI_REG8(0xb3a8), 0x40},
+	{CCI_REG8(0xb3a9), 0x40},
+	{CCI_REG8(0xb3aa), 0x40},
+	{CCI_REG8(0xb3ab), 0x40},
+	{CCI_REG8(0xb3ac), 0x40},
+	{CCI_REG8(0xb3ad), 0x40},
+	{CCI_REG8(0xb3ae), 0x40},
+	{CCI_REG8(0xb3af), 0x40},
+	{CCI_REG8(0xb3b0), 0x40},
+	{CCI_REG8(0xb3b1), 0x40},
+	{CCI_REG8(0xb3b2), 0x40},
+	{CCI_REG8(0xb3b3), 0x40},
+	{CCI_REG8(0xb3d0), 0x40},
+	{CCI_REG8(0xb3d1), 0x40},
+	{CCI_REG8(0xb3d2), 0x40},
+	{CCI_REG8(0xb3d3), 0x40},
+	{CCI_REG8(0xb3d4), 0x40},
+	{CCI_REG8(0xb3d5), 0x40},
+	{CCI_REG8(0xb3d6), 0x40},
+	{CCI_REG8(0xb3d7), 0x40},
+	{CCI_REG8(0xb3d8), 0x40},
+	{CCI_REG8(0xb3d9), 0x40},
+	{CCI_REG8(0xb3da), 0x40},
+	{CCI_REG8(0xb3db), 0x40},
+	{CCI_REG8(0xb3dc), 0x40},
+	{CCI_REG8(0xb3dd), 0x40},
+	{CCI_REG8(0xb3de), 0x40},
+	{CCI_REG8(0xb3df), 0x40},
+	{CCI_REG8(0xa4dc), 0x02},
+	{CCI_REG8(0xa4dd), 0x12},
+	{CCI_REG8(0xa690), 0x02},
+	{CCI_REG8(0xa694), 0x01},
+	{CCI_REG8(0xa695), 0x01},
+	{CCI_REG8(0xa696), 0x01},
+	{CCI_REG8(0xa8c8), 0x19},
+	{CCI_REG8(0xa8c9), 0x00},
+	{CCI_REG8(0xa8ca), 0x17},
+	{CCI_REG8(0xa8cb), 0x00},
+	{CCI_REG8(0xa8cc), 0x14},
+	{CCI_REG8(0xa8cd), 0x00},
+	{CCI_REG8(0xa8ce), 0x11},
+	{CCI_REG8(0xa8cf), 0x00},
+	{CCI_REG8(0xa8d0), 0x23},
+	{CCI_REG8(0xa8d1), 0x00},
+	{CCI_REG8(0xa8d2), 0x20},
+	{CCI_REG8(0xa8d3), 0x00},
+	{CCI_REG8(0xa8d4), 0x1c},
+	{CCI_REG8(0xa8d5), 0x00},
+	{CCI_REG8(0xa8d6), 0x18},
+	{CCI_REG8(0xa8d7), 0x00},
+	{CCI_REG8(0xa8d8), 0x31},
+	{CCI_REG8(0xa8d9), 0x00},
+	{CCI_REG8(0xa8da), 0x2d},
+	{CCI_REG8(0xa8db), 0x00},
+	{CCI_REG8(0xa8dc), 0x28},
+	{CCI_REG8(0xa8dd), 0x00},
+	{CCI_REG8(0xa8de), 0x22},
+	{CCI_REG8(0xa8df), 0x00},
+	{CCI_REG8(0xa8e0), 0x46},
+	{CCI_REG8(0xa8e1), 0x00},
+	{CCI_REG8(0xa8e2), 0x40},
+	{CCI_REG8(0xa8e3), 0x00},
+	{CCI_REG8(0xa8e4), 0x39},
+	{CCI_REG8(0xa8e5), 0x00},
+	{CCI_REG8(0xa8e6), 0x31},
+	{CCI_REG8(0xa8e7), 0x00},
+	{CCI_REG8(0xa8e8), 0x63},
+	{CCI_REG8(0xa8e9), 0x00},
+	{CCI_REG8(0xa8ea), 0x5a},
+	{CCI_REG8(0xa8eb), 0x00},
+	{CCI_REG8(0xa8ec), 0x50},
+	{CCI_REG8(0xa8ed), 0x00},
+	{CCI_REG8(0xa8ee), 0x45},
+	{CCI_REG8(0xa8ef), 0x00},
+	{CCI_REG8(0xa8f0), 0x8c},
+	{CCI_REG8(0xa8f1), 0x00},
+	{CCI_REG8(0xa8f2), 0x7f},
+	{CCI_REG8(0xa8f3), 0x00},
+	{CCI_REG8(0xa8f4), 0x71},
+	{CCI_REG8(0xa8f5), 0x00},
+	{CCI_REG8(0xa8f6), 0x61},
+	{CCI_REG8(0xa8f7), 0x00},
+	{CCI_REG8(0xa8f8), 0xc6},
+	{CCI_REG8(0xa8f9), 0x00},
+	{CCI_REG8(0xa8fa), 0xb4},
+	{CCI_REG8(0xa8fb), 0x00},
+	{CCI_REG8(0xa8fc), 0xa0},
+	{CCI_REG8(0xa8fd), 0x00},
+	{CCI_REG8(0xa8fe), 0x89},
+	{CCI_REG8(0xa8ff), 0x00},
+	{CCI_REG8(0xa900), 0x18},
+	{CCI_REG8(0xa901), 0x01},
+	{CCI_REG8(0xa902), 0xff},
+	{CCI_REG8(0xa903), 0x00},
+	{CCI_REG8(0xa904), 0xe2},
+	{CCI_REG8(0xa905), 0x00},
+	{CCI_REG8(0xa906), 0xc2},
+	{CCI_REG8(0xa907), 0x00},
+	{CCI_REG8(0xa928), 0x02},
+	{CCI_REG8(0xa929), 0x00},
+	{CCI_REG8(0xa92a), 0x02},
+	{CCI_REG8(0xa92b), 0x00},
+	{CCI_REG8(0xa92c), 0x02},
+	{CCI_REG8(0xa92d), 0x00},
+	{CCI_REG8(0xa92e), 0x02},
+	{CCI_REG8(0xa92f), 0x00},
+	{CCI_REG8(0xa930), 0x02},
+	{CCI_REG8(0xa931), 0x00},
+	{CCI_REG8(0xa932), 0x02},
+	{CCI_REG8(0xa933), 0x00},
+	{CCI_REG8(0xa934), 0x02},
+	{CCI_REG8(0xa935), 0x00},
+	{CCI_REG8(0xa936), 0x02},
+	{CCI_REG8(0xa937), 0x00},
+	{CCI_REG8(0xa938), 0x02},
+	{CCI_REG8(0xa939), 0x00},
+	{CCI_REG8(0xa93a), 0x02},
+	{CCI_REG8(0xa93b), 0x00},
+	{CCI_REG8(0xa93c), 0x02},
+	{CCI_REG8(0xa93d), 0x00},
+	{CCI_REG8(0xa93e), 0x02},
+	{CCI_REG8(0xa93f), 0x00},
+	{CCI_REG8(0xa940), 0x02},
+	{CCI_REG8(0xa941), 0x00},
+	{CCI_REG8(0xa942), 0x02},
+	{CCI_REG8(0xa943), 0x00},
+	{CCI_REG8(0xa944), 0x02},
+	{CCI_REG8(0xa945), 0x00},
+	{CCI_REG8(0xa946), 0x02},
+	{CCI_REG8(0xa947), 0x00},
+	{CCI_REG8(0xa948), 0x40},
+	{CCI_REG8(0xa949), 0x40},
+	{CCI_REG8(0xa94a), 0x40},
+	{CCI_REG8(0xa94b), 0x40},
+	{CCI_REG8(0xa94c), 0x40},
+	{CCI_REG8(0xa94d), 0x40},
+	{CCI_REG8(0xa94e), 0x40},
+	{CCI_REG8(0xa94f), 0x40},
+	{CCI_REG8(0xa950), 0x40},
+	{CCI_REG8(0xa951), 0x40},
+	{CCI_REG8(0xa952), 0x40},
+	{CCI_REG8(0xa953), 0x40},
+	{CCI_REG8(0xa954), 0x40},
+	{CCI_REG8(0xa955), 0x40},
+	{CCI_REG8(0xa956), 0x40},
+	{CCI_REG8(0xa957), 0x40},
+	{CCI_REG8(0xa960), 0x03},
+	{CCI_REG8(0xa961), 0x00},
+	{CCI_REG8(0xa962), 0x03},
+	{CCI_REG8(0xa963), 0x00},
+	{CCI_REG8(0xa964), 0x03},
+	{CCI_REG8(0xa965), 0x00},
+	{CCI_REG8(0xa966), 0x03},
+	{CCI_REG8(0xa967), 0x00},
+	{CCI_REG8(0xa968), 0x05},
+	{CCI_REG8(0xa969), 0x00},
+	{CCI_REG8(0xa96a), 0x05},
+	{CCI_REG8(0xa96b), 0x00},
+	{CCI_REG8(0xa96c), 0x05},
+	{CCI_REG8(0xa96d), 0x00},
+	{CCI_REG8(0xa96e), 0x05},
+	{CCI_REG8(0xa96f), 0x00},
+	{CCI_REG8(0xa970), 0x07},
+	{CCI_REG8(0xa971), 0x00},
+	{CCI_REG8(0xa972), 0x07},
+	{CCI_REG8(0xa973), 0x00},
+	{CCI_REG8(0xa974), 0x07},
+	{CCI_REG8(0xa975), 0x00},
+	{CCI_REG8(0xa976), 0x07},
+	{CCI_REG8(0xa977), 0x00},
+	{CCI_REG8(0xa978), 0x09},
+	{CCI_REG8(0xa979), 0x00},
+	{CCI_REG8(0xa97a), 0x09},
+	{CCI_REG8(0xa97b), 0x00},
+	{CCI_REG8(0xa97c), 0x09},
+	{CCI_REG8(0xa97d), 0x00},
+	{CCI_REG8(0xa97e), 0x09},
+	{CCI_REG8(0xa97f), 0x00},
+	{CCI_REG8(0xa980), 0x0d},
+	{CCI_REG8(0xa981), 0x00},
+	{CCI_REG8(0xa982), 0x0d},
+	{CCI_REG8(0xa983), 0x00},
+	{CCI_REG8(0xa984), 0x0d},
+	{CCI_REG8(0xa985), 0x00},
+	{CCI_REG8(0xa986), 0x0d},
+	{CCI_REG8(0xa987), 0x00},
+	{CCI_REG8(0xa988), 0x13},
+	{CCI_REG8(0xa989), 0x00},
+	{CCI_REG8(0xa98a), 0x13},
+	{CCI_REG8(0xa98b), 0x00},
+	{CCI_REG8(0xa98c), 0x13},
+	{CCI_REG8(0xa98d), 0x00},
+	{CCI_REG8(0xa98e), 0x13},
+	{CCI_REG8(0xa98f), 0x00},
+	{CCI_REG8(0xa990), 0x1a},
+	{CCI_REG8(0xa991), 0x00},
+	{CCI_REG8(0xa992), 0x1a},
+	{CCI_REG8(0xa993), 0x00},
+	{CCI_REG8(0xa994), 0x1a},
+	{CCI_REG8(0xa995), 0x00},
+	{CCI_REG8(0xa996), 0x1a},
+	{CCI_REG8(0xa997), 0x00},
+	{CCI_REG8(0xa998), 0x25},
+	{CCI_REG8(0xa999), 0x00},
+	{CCI_REG8(0xa99a), 0x25},
+	{CCI_REG8(0xa99b), 0x00},
+	{CCI_REG8(0xa99c), 0x25},
+	{CCI_REG8(0xa99d), 0x00},
+	{CCI_REG8(0xa99e), 0x25},
+	{CCI_REG8(0xa99f), 0x00},
+	{CCI_REG8(0xa9c0), 0x02},
+	{CCI_REG8(0xa9c1), 0x00},
+	{CCI_REG8(0xa9c2), 0x02},
+	{CCI_REG8(0xa9c3), 0x00},
+	{CCI_REG8(0xa9c4), 0x02},
+	{CCI_REG8(0xa9c5), 0x00},
+	{CCI_REG8(0xa9c6), 0x02},
+	{CCI_REG8(0xa9c7), 0x00},
+	{CCI_REG8(0xa9c8), 0x02},
+	{CCI_REG8(0xa9c9), 0x00},
+	{CCI_REG8(0xa9ca), 0x02},
+	{CCI_REG8(0xa9cb), 0x00},
+	{CCI_REG8(0xa9cc), 0x02},
+	{CCI_REG8(0xa9cd), 0x00},
+	{CCI_REG8(0xa9ce), 0x02},
+	{CCI_REG8(0xa9cf), 0x00},
+	{CCI_REG8(0xa9d0), 0x02},
+	{CCI_REG8(0xa9d1), 0x00},
+	{CCI_REG8(0xa9d2), 0x02},
+	{CCI_REG8(0xa9d3), 0x00},
+	{CCI_REG8(0xa9d4), 0x02},
+	{CCI_REG8(0xa9d5), 0x00},
+	{CCI_REG8(0xa9d6), 0x02},
+	{CCI_REG8(0xa9d7), 0x00},
+	{CCI_REG8(0xa9d8), 0x02},
+	{CCI_REG8(0xa9d9), 0x00},
+	{CCI_REG8(0xa9da), 0x02},
+	{CCI_REG8(0xa9db), 0x00},
+	{CCI_REG8(0xa9dc), 0x02},
+	{CCI_REG8(0xa9dd), 0x00},
+	{CCI_REG8(0xa9de), 0x02},
+	{CCI_REG8(0xa9df), 0x00},
+	{CCI_REG8(0xa9e0), 0x40},
+	{CCI_REG8(0xa9e1), 0x40},
+	{CCI_REG8(0xa9e2), 0x40},
+	{CCI_REG8(0xa9e3), 0x40},
+	{CCI_REG8(0xa9e4), 0x40},
+	{CCI_REG8(0xa9e5), 0x40},
+	{CCI_REG8(0xa9e6), 0x40},
+	{CCI_REG8(0xa9e7), 0x40},
+	{CCI_REG8(0xa9e8), 0x40},
+	{CCI_REG8(0xa9e9), 0x40},
+	{CCI_REG8(0xa9ea), 0x40},
+	{CCI_REG8(0xa9eb), 0x40},
+	{CCI_REG8(0xa9ec), 0x40},
+	{CCI_REG8(0xa9ed), 0x40},
+	{CCI_REG8(0xa9ee), 0x40},
+	{CCI_REG8(0xa9ef), 0x40},
+	{CCI_REG8(0xa9f8), 0x02},
+	{CCI_REG8(0xa9f9), 0x00},
+	{CCI_REG8(0xa9fa), 0x02},
+	{CCI_REG8(0xa9fb), 0x00},
+	{CCI_REG8(0xa9fc), 0x02},
+	{CCI_REG8(0xa9fd), 0x00},
+	{CCI_REG8(0xa9fe), 0x02},
+	{CCI_REG8(0xa9ff), 0x00},
+	{CCI_REG8(0xaa00), 0x03},
+	{CCI_REG8(0xaa01), 0x00},
+	{CCI_REG8(0xaa02), 0x03},
+	{CCI_REG8(0xaa03), 0x00},
+	{CCI_REG8(0xaa04), 0x03},
+	{CCI_REG8(0xaa05), 0x00},
+	{CCI_REG8(0xaa06), 0x03},
+	{CCI_REG8(0xaa07), 0x00},
+	{CCI_REG8(0xaa08), 0x04},
+	{CCI_REG8(0xaa09), 0x00},
+	{CCI_REG8(0xaa0a), 0x04},
+	{CCI_REG8(0xaa0b), 0x00},
+	{CCI_REG8(0xaa0c), 0x04},
+	{CCI_REG8(0xaa0d), 0x00},
+	{CCI_REG8(0xaa0e), 0x04},
+	{CCI_REG8(0xaa0f), 0x00},
+	{CCI_REG8(0xaa10), 0x06},
+	{CCI_REG8(0xaa11), 0x00},
+	{CCI_REG8(0xaa12), 0x06},
+	{CCI_REG8(0xaa13), 0x00},
+	{CCI_REG8(0xaa14), 0x06},
+	{CCI_REG8(0xaa15), 0x00},
+	{CCI_REG8(0xaa16), 0x06},
+	{CCI_REG8(0xaa17), 0x00},
+	{CCI_REG8(0xaa18), 0x09},
+	{CCI_REG8(0xaa19), 0x00},
+	{CCI_REG8(0xaa1a), 0x09},
+	{CCI_REG8(0xaa1b), 0x00},
+	{CCI_REG8(0xaa1c), 0x09},
+	{CCI_REG8(0xaa1d), 0x00},
+	{CCI_REG8(0xaa1e), 0x09},
+	{CCI_REG8(0xaa1f), 0x00},
+	{CCI_REG8(0xaa20), 0x0c},
+	{CCI_REG8(0xaa21), 0x00},
+	{CCI_REG8(0xaa22), 0x0c},
+	{CCI_REG8(0xaa23), 0x00},
+	{CCI_REG8(0xaa24), 0x0c},
+	{CCI_REG8(0xaa25), 0x00},
+	{CCI_REG8(0xaa26), 0x0c},
+	{CCI_REG8(0xaa27), 0x00},
+	{CCI_REG8(0xaa28), 0x12},
+	{CCI_REG8(0xaa29), 0x00},
+	{CCI_REG8(0xaa2a), 0x12},
+	{CCI_REG8(0xaa2b), 0x00},
+	{CCI_REG8(0xaa2c), 0x12},
+	{CCI_REG8(0xaa2d), 0x00},
+	{CCI_REG8(0xaa2e), 0x12},
+	{CCI_REG8(0xaa2f), 0x00},
+	{CCI_REG8(0xaa30), 0x19},
+	{CCI_REG8(0xaa31), 0x00},
+	{CCI_REG8(0xaa32), 0x19},
+	{CCI_REG8(0xaa33), 0x00},
+	{CCI_REG8(0xaa34), 0x19},
+	{CCI_REG8(0xaa35), 0x00},
+	{CCI_REG8(0xaa36), 0x19},
+	{CCI_REG8(0xaa37), 0x00},
+	{CCI_REG8(0xaa58), 0x02},
+	{CCI_REG8(0xaa59), 0x00},
+	{CCI_REG8(0xaa5a), 0x02},
+	{CCI_REG8(0xaa5b), 0x00},
+	{CCI_REG8(0xaa5c), 0x02},
+	{CCI_REG8(0xaa5d), 0x00},
+	{CCI_REG8(0xaa5e), 0x02},
+	{CCI_REG8(0xaa5f), 0x00},
+	{CCI_REG8(0xaa60), 0x02},
+	{CCI_REG8(0xaa61), 0x00},
+	{CCI_REG8(0xaa62), 0x02},
+	{CCI_REG8(0xaa63), 0x00},
+	{CCI_REG8(0xaa64), 0x02},
+	{CCI_REG8(0xaa65), 0x00},
+	{CCI_REG8(0xaa66), 0x02},
+	{CCI_REG8(0xaa67), 0x00},
+	{CCI_REG8(0xaa68), 0x02},
+	{CCI_REG8(0xaa69), 0x00},
+	{CCI_REG8(0xaa6a), 0x02},
+	{CCI_REG8(0xaa6b), 0x00},
+	{CCI_REG8(0xaa6c), 0x02},
+	{CCI_REG8(0xaa6d), 0x00},
+	{CCI_REG8(0xaa6e), 0x02},
+	{CCI_REG8(0xaa6f), 0x00},
+	{CCI_REG8(0xaa70), 0x02},
+	{CCI_REG8(0xaa71), 0x00},
+	{CCI_REG8(0xaa72), 0x02},
+	{CCI_REG8(0xaa73), 0x00},
+	{CCI_REG8(0xaa74), 0x02},
+	{CCI_REG8(0xaa75), 0x00},
+	{CCI_REG8(0xaa76), 0x02},
+	{CCI_REG8(0xaa77), 0x00},
+	{CCI_REG8(0xaa78), 0x40},
+	{CCI_REG8(0xaa79), 0x40},
+	{CCI_REG8(0xaa7a), 0x40},
+	{CCI_REG8(0xaa7b), 0x40},
+	{CCI_REG8(0xaa7c), 0x40},
+	{CCI_REG8(0xaa7d), 0x40},
+	{CCI_REG8(0xaa7e), 0x40},
+	{CCI_REG8(0xaa7f), 0x40},
+	{CCI_REG8(0xaa80), 0x40},
+	{CCI_REG8(0xaa81), 0x40},
+	{CCI_REG8(0xaa82), 0x40},
+	{CCI_REG8(0xaa83), 0x40},
+	{CCI_REG8(0xaa84), 0x40},
+	{CCI_REG8(0xaa85), 0x40},
+	{CCI_REG8(0xaa86), 0x40},
+	{CCI_REG8(0xaa87), 0x40},
+	{CCI_REG8(0xaa90), 0x00},
+	{CCI_REG8(0xaa91), 0x00},
+	{CCI_REG8(0xaa92), 0x00},
+	{CCI_REG8(0xaa93), 0x00},
+	{CCI_REG8(0xaa94), 0x00},
+	{CCI_REG8(0xaa95), 0x00},
+	{CCI_REG8(0xaa96), 0x00},
+	{CCI_REG8(0xaa97), 0x00},
+	{CCI_REG8(0xaa98), 0x01},
+	{CCI_REG8(0xaa99), 0x00},
+	{CCI_REG8(0xaa9a), 0x01},
+	{CCI_REG8(0xaa9b), 0x00},
+	{CCI_REG8(0xaa9c), 0x01},
+	{CCI_REG8(0xaa9d), 0x00},
+	{CCI_REG8(0xaa9e), 0x01},
+	{CCI_REG8(0xaa9f), 0x00},
+	{CCI_REG8(0xaaa0), 0x01},
+	{CCI_REG8(0xaaa1), 0x00},
+	{CCI_REG8(0xaaa2), 0x01},
+	{CCI_REG8(0xaaa3), 0x00},
+	{CCI_REG8(0xaaa4), 0x01},
+	{CCI_REG8(0xaaa5), 0x00},
+	{CCI_REG8(0xaaa6), 0x01},
+	{CCI_REG8(0xaaa7), 0x00},
+	{CCI_REG8(0xaaa8), 0x03},
+	{CCI_REG8(0xaaa9), 0x00},
+	{CCI_REG8(0xaaaa), 0x03},
+	{CCI_REG8(0xaaab), 0x00},
+	{CCI_REG8(0xaaac), 0x03},
+	{CCI_REG8(0xaaad), 0x00},
+	{CCI_REG8(0xaaae), 0x03},
+	{CCI_REG8(0xaaaf), 0x00},
+	{CCI_REG8(0xaab0), 0x06},
+	{CCI_REG8(0xaab1), 0x00},
+	{CCI_REG8(0xaab2), 0x06},
+	{CCI_REG8(0xaab3), 0x00},
+	{CCI_REG8(0xaab4), 0x06},
+	{CCI_REG8(0xaab5), 0x00},
+	{CCI_REG8(0xaab6), 0x06},
+	{CCI_REG8(0xaab7), 0x00},
+	{CCI_REG8(0xaab8), 0x0b},
+	{CCI_REG8(0xaab9), 0x00},
+	{CCI_REG8(0xaaba), 0x0b},
+	{CCI_REG8(0xaabb), 0x00},
+	{CCI_REG8(0xaabc), 0x0b},
+	{CCI_REG8(0xaabd), 0x00},
+	{CCI_REG8(0xaabe), 0x0b},
+	{CCI_REG8(0xaabf), 0x00},
+	{CCI_REG8(0xaac0), 0x17},
+	{CCI_REG8(0xaac1), 0x00},
+	{CCI_REG8(0xaac2), 0x17},
+	{CCI_REG8(0xaac3), 0x00},
+	{CCI_REG8(0xaac4), 0x17},
+	{CCI_REG8(0xaac5), 0x00},
+	{CCI_REG8(0xaac6), 0x17},
+	{CCI_REG8(0xaac7), 0x00},
+	{CCI_REG8(0xaac8), 0x2e},
+	{CCI_REG8(0xaac9), 0x00},
+	{CCI_REG8(0xaaca), 0x2e},
+	{CCI_REG8(0xaacb), 0x00},
+	{CCI_REG8(0xaacc), 0x2e},
+	{CCI_REG8(0xaacd), 0x00},
+	{CCI_REG8(0xaace), 0x2e},
+	{CCI_REG8(0xaacf), 0x00},
+	{CCI_REG8(0xaaf0), 0x0a},
+	{CCI_REG8(0xaaf1), 0x00},
+	{CCI_REG8(0xaaf2), 0x0a},
+	{CCI_REG8(0xaaf3), 0x00},
+	{CCI_REG8(0xaaf4), 0x0a},
+	{CCI_REG8(0xaaf5), 0x00},
+	{CCI_REG8(0xaaf6), 0x0a},
+	{CCI_REG8(0xaaf7), 0x00},
+	{CCI_REG8(0xaaf8), 0x0a},
+	{CCI_REG8(0xaaf9), 0x00},
+	{CCI_REG8(0xaafa), 0x0a},
+	{CCI_REG8(0xaafb), 0x00},
+	{CCI_REG8(0xaafc), 0x0a},
+	{CCI_REG8(0xaafd), 0x00},
+	{CCI_REG8(0xaafe), 0x0a},
+	{CCI_REG8(0xaaff), 0x00},
+	{CCI_REG8(0xab00), 0x0a},
+	{CCI_REG8(0xab01), 0x00},
+	{CCI_REG8(0xab02), 0x0a},
+	{CCI_REG8(0xab03), 0x00},
+	{CCI_REG8(0xab04), 0x0a},
+	{CCI_REG8(0xab05), 0x00},
+	{CCI_REG8(0xab06), 0x0a},
+	{CCI_REG8(0xab07), 0x00},
+	{CCI_REG8(0xab08), 0x0a},
+	{CCI_REG8(0xab09), 0x00},
+	{CCI_REG8(0xab0a), 0x0a},
+	{CCI_REG8(0xab0b), 0x00},
+	{CCI_REG8(0xab0c), 0x0a},
+	{CCI_REG8(0xab0d), 0x00},
+	{CCI_REG8(0xab0e), 0x0a},
+	{CCI_REG8(0xab0f), 0x00},
+	{CCI_REG8(0xab10), 0x40},
+	{CCI_REG8(0xab11), 0x40},
+	{CCI_REG8(0xab12), 0x40},
+	{CCI_REG8(0xab13), 0x40},
+	{CCI_REG8(0xab14), 0x40},
+	{CCI_REG8(0xab15), 0x40},
+	{CCI_REG8(0xab16), 0x40},
+	{CCI_REG8(0xab17), 0x40},
+	{CCI_REG8(0xab18), 0x40},
+	{CCI_REG8(0xab19), 0x40},
+	{CCI_REG8(0xab1a), 0x40},
+	{CCI_REG8(0xab1b), 0x40},
+	{CCI_REG8(0xab1c), 0x40},
+	{CCI_REG8(0xab1d), 0x40},
+	{CCI_REG8(0xab1e), 0x40},
+	{CCI_REG8(0xab1f), 0x40},
+	{CCI_REG8(0xab28), 0x03},
+	{CCI_REG8(0xab29), 0x00},
+	{CCI_REG8(0xab2a), 0x03},
+	{CCI_REG8(0xab2b), 0x00},
+	{CCI_REG8(0xab2c), 0x03},
+	{CCI_REG8(0xab2d), 0x00},
+	{CCI_REG8(0xab2e), 0x03},
+	{CCI_REG8(0xab2f), 0x00},
+	{CCI_REG8(0xab30), 0x05},
+	{CCI_REG8(0xab31), 0x00},
+	{CCI_REG8(0xab32), 0x05},
+	{CCI_REG8(0xab33), 0x00},
+	{CCI_REG8(0xab34), 0x05},
+	{CCI_REG8(0xab35), 0x00},
+	{CCI_REG8(0xab36), 0x05},
+	{CCI_REG8(0xab37), 0x00},
+	{CCI_REG8(0xab38), 0x07},
+	{CCI_REG8(0xab39), 0x00},
+	{CCI_REG8(0xab3a), 0x07},
+	{CCI_REG8(0xab3b), 0x00},
+	{CCI_REG8(0xab3c), 0x07},
+	{CCI_REG8(0xab3d), 0x00},
+	{CCI_REG8(0xab3e), 0x07},
+	{CCI_REG8(0xab3f), 0x00},
+	{CCI_REG8(0xab40), 0x0a},
+	{CCI_REG8(0xab41), 0x00},
+	{CCI_REG8(0xab42), 0x0a},
+	{CCI_REG8(0xab43), 0x00},
+	{CCI_REG8(0xab44), 0x0a},
+	{CCI_REG8(0xab45), 0x00},
+	{CCI_REG8(0xab46), 0x0a},
+	{CCI_REG8(0xab47), 0x00},
+	{CCI_REG8(0xab48), 0x0e},
+	{CCI_REG8(0xab49), 0x00},
+	{CCI_REG8(0xab4a), 0x0e},
+	{CCI_REG8(0xab4b), 0x00},
+	{CCI_REG8(0xab4c), 0x0e},
+	{CCI_REG8(0xab4d), 0x00},
+	{CCI_REG8(0xab4e), 0x0e},
+	{CCI_REG8(0xab4f), 0x00},
+	{CCI_REG8(0xab50), 0x13},
+	{CCI_REG8(0xab51), 0x00},
+	{CCI_REG8(0xab52), 0x13},
+	{CCI_REG8(0xab53), 0x00},
+	{CCI_REG8(0xab54), 0x13},
+	{CCI_REG8(0xab55), 0x00},
+	{CCI_REG8(0xab56), 0x13},
+	{CCI_REG8(0xab57), 0x00},
+	{CCI_REG8(0xab58), 0x1b},
+	{CCI_REG8(0xab59), 0x00},
+	{CCI_REG8(0xab5a), 0x1b},
+	{CCI_REG8(0xab5b), 0x00},
+	{CCI_REG8(0xab5c), 0x1b},
+	{CCI_REG8(0xab5d), 0x00},
+	{CCI_REG8(0xab5e), 0x1b},
+	{CCI_REG8(0xab5f), 0x00},
+	{CCI_REG8(0xab60), 0x26},
+	{CCI_REG8(0xab61), 0x00},
+	{CCI_REG8(0xab62), 0x26},
+	{CCI_REG8(0xab63), 0x00},
+	{CCI_REG8(0xab64), 0x26},
+	{CCI_REG8(0xab65), 0x00},
+	{CCI_REG8(0xab66), 0x26},
+	{CCI_REG8(0xab67), 0x00},
+	{CCI_REG8(0xab88), 0x02},
+	{CCI_REG8(0xab89), 0x00},
+	{CCI_REG8(0xab8a), 0x02},
+	{CCI_REG8(0xab8b), 0x00},
+	{CCI_REG8(0xab8c), 0x02},
+	{CCI_REG8(0xab8d), 0x00},
+	{CCI_REG8(0xab8e), 0x02},
+	{CCI_REG8(0xab8f), 0x00},
+	{CCI_REG8(0xab90), 0x02},
+	{CCI_REG8(0xab91), 0x00},
+	{CCI_REG8(0xab92), 0x02},
+	{CCI_REG8(0xab93), 0x00},
+	{CCI_REG8(0xab94), 0x02},
+	{CCI_REG8(0xab95), 0x00},
+	{CCI_REG8(0xab96), 0x02},
+	{CCI_REG8(0xab97), 0x00},
+	{CCI_REG8(0xab98), 0x02},
+	{CCI_REG8(0xab99), 0x00},
+	{CCI_REG8(0xab9a), 0x02},
+	{CCI_REG8(0xab9b), 0x00},
+	{CCI_REG8(0xab9c), 0x02},
+	{CCI_REG8(0xab9d), 0x00},
+	{CCI_REG8(0xab9e), 0x02},
+	{CCI_REG8(0xab9f), 0x00},
+	{CCI_REG8(0xaba0), 0x02},
+	{CCI_REG8(0xaba1), 0x00},
+	{CCI_REG8(0xaba2), 0x02},
+	{CCI_REG8(0xaba3), 0x00},
+	{CCI_REG8(0xaba4), 0x02},
+	{CCI_REG8(0xaba5), 0x00},
+	{CCI_REG8(0xaba6), 0x02},
+	{CCI_REG8(0xaba7), 0x00},
+	{CCI_REG8(0xaba8), 0x40},
+	{CCI_REG8(0xaba9), 0x40},
+	{CCI_REG8(0xabaa), 0x40},
+	{CCI_REG8(0xabab), 0x40},
+	{CCI_REG8(0xabac), 0x40},
+	{CCI_REG8(0xabad), 0x40},
+	{CCI_REG8(0xabae), 0x40},
+	{CCI_REG8(0xabaf), 0x40},
+	{CCI_REG8(0xabb0), 0x40},
+	{CCI_REG8(0xabb1), 0x40},
+	{CCI_REG8(0xabb2), 0x40},
+	{CCI_REG8(0xabb3), 0x40},
+	{CCI_REG8(0xabb4), 0x40},
+	{CCI_REG8(0xabb5), 0x40},
+	{CCI_REG8(0xabb6), 0x40},
+	{CCI_REG8(0xabb7), 0x40},
+	{CCI_REG8(0xa69c), 0x01},
+	{CCI_REG8(0xa69d), 0x01},
+	{CCI_REG8(0xa69e), 0x01},
+	{CCI_REG8(0xa69f), 0x01},
+	{CCI_REG8(0xa6a0), 0x01},
+	{CCI_REG8(0xa6a1), 0x01},
+	{CCI_REG8(0xb1b0), 0x00},
+	{CCI_REG8(0xb1b1), 0xf0},
+	{CCI_REG8(0xa198), 0x64},
+	{CCI_REG8(0xa199), 0x00},
+	{CCI_REG8(0xa19a), 0x00},
+	{CCI_REG8(0xa19c), 0x64},
+	{CCI_REG8(0xa19d), 0x00},
+	{CCI_REG8(0xa19e), 0x00},
+	{CCI_REG8(0xa1a0), 0xd4},
+	{CCI_REG8(0xa1a1), 0x00},
+	{CCI_REG8(0xa1a2), 0x00},
+	{CCI_REG8(0xa1a4), 0xaf},
+	{CCI_REG8(0xa1a5), 0x00},
+	{CCI_REG8(0xa1a6), 0x00},
+	{CCI_REG8(0xa1a8), 0xc2},
+	{CCI_REG8(0xa1a9), 0x01},
+	{CCI_REG8(0xa1aa), 0x00},
+	{CCI_REG8(0xa1ac), 0x34},
+	{CCI_REG8(0xa1ad), 0x01},
+	{CCI_REG8(0xa1ae), 0x00},
+	{CCI_REG8(0xa1b0), 0xba},
+	{CCI_REG8(0xa1b1), 0x03},
+	{CCI_REG8(0xa1b2), 0x00},
+	{CCI_REG8(0xa1b4), 0xa7},
+	{CCI_REG8(0xa1b5), 0x01},
+	{CCI_REG8(0xa1b6), 0x00},
+	{CCI_REG8(0xa1b8), 0xe8},
+	{CCI_REG8(0xa1b9), 0x07},
+	{CCI_REG8(0xa1ba), 0x00},
+	{CCI_REG8(0xa1bc), 0x70},
+	{CCI_REG8(0xa1bd), 0x02},
+	{CCI_REG8(0xa1be), 0x00},
+	{CCI_REG8(0xa1c0), 0xc5},
+	{CCI_REG8(0xa1c1), 0x10},
+	{CCI_REG8(0xa1c2), 0x00},
+	{CCI_REG8(0xa1c4), 0xfa},
+	{CCI_REG8(0xa1c5), 0x02},
+	{CCI_REG8(0xa1c6), 0x00},
+	{CCI_REG8(0xa1c8), 0x92},
+	{CCI_REG8(0xa1c9), 0x23},
+	{CCI_REG8(0xa1ca), 0x00},
+	{CCI_REG8(0xa1cc), 0xeb},
+	{CCI_REG8(0xa1cd), 0x03},
+	{CCI_REG8(0xa1ce), 0x00},
+	{CCI_REG8(0xa1d0), 0x71},
+	{CCI_REG8(0xa1d1), 0x4b},
+	{CCI_REG8(0xa1d2), 0x00},
+	{CCI_REG8(0xa1d4), 0x8f},
+	{CCI_REG8(0xa1d5), 0x04},
+	{CCI_REG8(0xa1d6), 0x00},
+	{CCI_REG8(0xa1d8), 0x03},
+	{CCI_REG8(0xa1d9), 0xa0},
+	{CCI_REG8(0xa1da), 0x00},
+	{CCI_REG8(0xa1dc), 0xb0},
+	{CCI_REG8(0xa1dd), 0x05},
+	{CCI_REG8(0xa1de), 0x00},
+	{CCI_REG8(0xa1e0), 0x63},
+	{CCI_REG8(0xa1e1), 0x53},
+	{CCI_REG8(0xa1e2), 0x01},
+	{CCI_REG8(0xa1e4), 0x74},
+	{CCI_REG8(0xa1e5), 0x06},
+	{CCI_REG8(0xa1e6), 0x00},
+	{CCI_REG8(0xa1e8), 0xd7},
+	{CCI_REG8(0xa1e9), 0xcf},
+	{CCI_REG8(0xa1ea), 0x02},
+	{CCI_REG8(0xa1ec), 0xce},
+	{CCI_REG8(0xa1ed), 0x07},
+	{CCI_REG8(0xa1ee), 0x00},
+	{CCI_REG8(0xa1f0), 0xc8},
+	{CCI_REG8(0xa1f1), 0xf6},
+	{CCI_REG8(0xa1f2), 0x05},
+	{CCI_REG8(0xa1f4), 0xb9},
+	{CCI_REG8(0xa1f5), 0x08},
+	{CCI_REG8(0xa1f6), 0x00},
+	{CCI_REG8(0xa1f8), 0x4d},
+	{CCI_REG8(0xa1f9), 0xa6},
+	{CCI_REG8(0xa1fa), 0x0c},
+	{CCI_REG8(0xa1fc), 0x56},
+	{CCI_REG8(0xa1fd), 0x0a},
+	{CCI_REG8(0xa1fe), 0x00},
+	{CCI_REG8(0xa200), 0x70},
+	{CCI_REG8(0xa201), 0xd4},
+	{CCI_REG8(0xa202), 0x1a},
+	{CCI_REG8(0xa204), 0x70},
+	{CCI_REG8(0xa205), 0x0b},
+	{CCI_REG8(0xa206), 0x00},
+	{CCI_REG8(0xa208), 0xf4},
+	{CCI_REG8(0xa209), 0xe7},
+	{CCI_REG8(0xa20a), 0x38},
+	{CCI_REG8(0xa20c), 0x5f},
+	{CCI_REG8(0xa20d), 0x0d},
+	{CCI_REG8(0xa20e), 0x00},
+	{CCI_REG8(0xa210), 0xa2},
+	{CCI_REG8(0xa211), 0xb2},
+	{CCI_REG8(0xa212), 0x78},
+	{CCI_REG8(0xa214), 0xaf},
+	{CCI_REG8(0xa215), 0x0e},
+	{CCI_REG8(0xa216), 0x00},
+	{CCI_REG8(0xa21c), 0xff},
+	{CCI_REG8(0xa21d), 0x0f},
+	{CCI_REG8(0xa21e), 0x00},
+	{CCI_REG8(0x179c), 0x02},
+	{CCI_REG8(0x179d), 0x03},
+	{CCI_REG8(0x179e), 0x01},
+	{CCI_REG8(0x179f), 0x03},
+	{CCI_REG8(0x17a0), 0x03},
+	{CCI_REG8(0x17a1), 0x01},
+	{CCI_REG8(0x17a2), 0x03},
+	{CCI_REG8(0x17a3), 0x03},
+	{CCI_REG8(0x17a4), 0x01},
+	{CCI_REG8(0x17a5), 0x03},
+	{CCI_REG8(0x17a6), 0x03},
+	{CCI_REG8(0x17a7), 0x01},
+	{CCI_REG8(0x17a8), 0x03},
+	{CCI_REG8(0x17a9), 0x03},
+	{CCI_REG8(0x17aa), 0x01},
+	{CCI_REG8(0x17ab), 0x03},
+	{CCI_REG8(0x17f2), 0x01},
+	{CCI_REG8(0x17f4), 0x01},
+	{CCI_REG8(0x17f6), 0xff},
+	{CCI_REG8(0x17f7), 0x0f},
+	{CCI_REG8(0x1792), 0x01},
+	{CCI_REG8(0x1794), 0x01},
+	{CCI_REG8(0x1796), 0x01},
+	{CCI_REG8(0x1798), 0x01},
+	{CCI_REG8(0x179a), 0x01},
+	{CCI_REG8(0x1808), 0x00},
+	{CCI_REG8(0x16dd), 0x01},
+	{CCI_REG8(0xa198), 0x80},
+	{CCI_REG8(0xa199), 0x01},
+	{CCI_REG8(0xa19a), 0x00},
+	{CCI_REG8(0xa1a0), 0x5a},
+	{CCI_REG8(0xa1a1), 0x03},
+	{CCI_REG8(0xa1a2), 0x00},
+	{CCI_REG8(0xa1a8), 0xb2},
+	{CCI_REG8(0xa1a9), 0x0c},
+	{CCI_REG8(0xa1aa), 0x00},
+	{CCI_REG8(0xa1b0), 0x6d},
+	{CCI_REG8(0xa1b1), 0x38},
+	{CCI_REG8(0xa1b2), 0x00},
+	{CCI_REG8(0xa1b8), 0x71},
+	{CCI_REG8(0xa1b9), 0x88},
+	{CCI_REG8(0xa1ba), 0x00},
+	{CCI_REG8(0xa1c0), 0x77},
+	{CCI_REG8(0xa1c1), 0xe7},
+	{CCI_REG8(0xa1c2), 0x00},
+	{CCI_REG8(0xa1c8), 0x7b},
+	{CCI_REG8(0xa1c9), 0xb5},
+	{CCI_REG8(0xa1ca), 0x03},
+	{CCI_REG8(0xa1d0), 0xa4},
+	{CCI_REG8(0xa1d1), 0x7d},
+	{CCI_REG8(0xa1d2), 0x07},
+	{CCI_REG8(0xa1d8), 0xcb},
+	{CCI_REG8(0xa1d9), 0x36},
+	{CCI_REG8(0xa1da), 0x0f},
+	{CCI_REG8(0xa1e0), 0x86},
+	{CCI_REG8(0xa1e1), 0x68},
+	{CCI_REG8(0xa1e2), 0x3e},
+	{CCI_REG8(0xa1e8), 0xff},
+	{CCI_REG8(0xa1e9), 0xff},
+	{CCI_REG8(0xa1ea), 0xff},
+	{CCI_REG8(0xa1f0), 0xff},
+	{CCI_REG8(0xa1f1), 0xff},
+	{CCI_REG8(0xa1f2), 0xff},
+	{CCI_REG8(0xa1f8), 0xff},
+	{CCI_REG8(0xa1f9), 0xff},
+	{CCI_REG8(0xa1fa), 0xff},
+	{CCI_REG8(0xa200), 0xff},
+	{CCI_REG8(0xa201), 0xff},
+	{CCI_REG8(0xa202), 0xff},
+	{CCI_REG8(0xa208), 0xff},
+	{CCI_REG8(0xa209), 0xff},
+	{CCI_REG8(0xa20a), 0xff},
+	{CCI_REG8(0xa210), 0xff},
+	{CCI_REG8(0xa211), 0xff},
+	{CCI_REG8(0xa212), 0xff},
+	{CCI_REG8(0xa218), 0xff},
+	{CCI_REG8(0xa219), 0xff},
+	{CCI_REG8(0xa21a), 0xff},
+	{CCI_REG8(0xa19c), 0x80},
+	{CCI_REG8(0xa19d), 0x01},
+	{CCI_REG8(0xa19e), 0x00},
+	{CCI_REG8(0xa1a4), 0x00},
+	{CCI_REG8(0xa1a5), 0x02},
+	{CCI_REG8(0xa1a6), 0x00},
+	{CCI_REG8(0xa1ac), 0x40},
+	{CCI_REG8(0xa1ad), 0x04},
+	{CCI_REG8(0xa1ae), 0x00},
+	{CCI_REG8(0xa1b4), 0x80},
+	{CCI_REG8(0xa1b5), 0x05},
+	{CCI_REG8(0xa1b6), 0x00},
+	{CCI_REG8(0xa1bc), 0xa0},
+	{CCI_REG8(0xa1bd), 0x07},
+	{CCI_REG8(0xa1be), 0x00},
+	{CCI_REG8(0xa1c4), 0xe0},
+	{CCI_REG8(0xa1c5), 0x07},
+	{CCI_REG8(0xa1c6), 0x00},
+	{CCI_REG8(0xa1cc), 0x00},
+	{CCI_REG8(0xa1cd), 0x0a},
+	{CCI_REG8(0xa1ce), 0x00},
+	{CCI_REG8(0xa1d4), 0xa0},
+	{CCI_REG8(0xa1d5), 0x0b},
+	{CCI_REG8(0xa1d6), 0x00},
+	{CCI_REG8(0xa1dc), 0xe0},
+	{CCI_REG8(0xa1dd), 0x0b},
+	{CCI_REG8(0xa1de), 0x00},
+	{CCI_REG8(0xa1e4), 0xc0},
+	{CCI_REG8(0xa1e5), 0x0c},
+	{CCI_REG8(0xa1e6), 0x00},
+	{CCI_REG8(0xa1ec), 0xff},
+	{CCI_REG8(0xa1ed), 0x0f},
+	{CCI_REG8(0xa1ee), 0x00},
+	{CCI_REG8(0xa1f4), 0xff},
+	{CCI_REG8(0xa1f5), 0x0f},
+	{CCI_REG8(0xa1f6), 0x00},
+	{CCI_REG8(0xa1fc), 0xff},
+	{CCI_REG8(0xa1fd), 0x0f},
+	{CCI_REG8(0xa1fe), 0x00},
+	{CCI_REG8(0xa204), 0xff},
+	{CCI_REG8(0xa205), 0x0f},
+	{CCI_REG8(0xa206), 0x00},
+	{CCI_REG8(0xa20c), 0xff},
+	{CCI_REG8(0xa20d), 0x0f},
+	{CCI_REG8(0xa20e), 0x00},
+	{CCI_REG8(0xa214), 0xff},
+	{CCI_REG8(0xa215), 0x0f},
+	{CCI_REG8(0xa216), 0x00},
+	{CCI_REG8(0xa21c), 0xff},
+	{CCI_REG8(0xa21d), 0x0f},
+	{CCI_REG8(0xa21e), 0x00},
+	{CCI_REG8(0xffff), 0x00},
+	{CCI_REG8(0xac4d), 0x02},
+	{CCI_REG8(0xffff), 0x01},
+	{CCI_REG8(0x0070), 0x61},
+	{CCI_REG8(0x0071), 0x40},
+	{CCI_REG8(0x0072), 0xb4},
+	{CCI_REG8(0x0073), 0x40},
+	{CCI_REG8(0x0074), 0xf6},
+	{CCI_REG8(0x0075), 0x40},
+	{CCI_REG8(0x0076), 0x45},
+	{CCI_REG8(0x0077), 0x40},
+	{CCI_REG8(0x0078), 0x07},
+	{CCI_REG8(0x0079), 0x40},
+	{CCI_REG8(0x007a), 0x04},
+	{CCI_REG8(0x007b), 0x00},
+	{CCI_REG8(0x007c), 0x1c},
+	{CCI_REG8(0x007d), 0x40},
+	{CCI_REG8(0x007e), 0x32},
+	{CCI_REG8(0x007f), 0x40},
+	{CCI_REG8(0x0080), 0x05},
+	{CCI_REG8(0x0081), 0x40},
+	{CCI_REG8(0x0082), 0x4c},
+	{CCI_REG8(0x0083), 0x40},
+	{CCI_REG8(0x0084), 0x64},
+	{CCI_REG8(0x0085), 0x40},
+	{CCI_REG8(0x0086), 0x40},
+	{CCI_REG8(0x0087), 0x40},
+	{CCI_REG8(0x0088), 0x10},
+	{CCI_REG8(0x0089), 0x40},
+	{CCI_REG8(0x008a), 0x2d},
+	{CCI_REG8(0x008b), 0x40},
+	{CCI_REG8(0x008c), 0x39},
+	{CCI_REG8(0x008d), 0x40},
+	{CCI_REG8(0x008e), 0x47},
+	{CCI_REG8(0x008f), 0x40},
+	{CCI_REG8(0x0090), 0x30},
+	{CCI_REG8(0x0091), 0x40},
+	{CCI_REG8(0x0092), 0x45},
+	{CCI_REG8(0x0093), 0x40},
+	{CCI_REG8(0x0094), 0x7f},
+	{CCI_REG8(0x0095), 0x40},
+	{CCI_REG8(0x0096), 0x63},
+	{CCI_REG8(0x0097), 0x40},
+	{CCI_REG8(0x0098), 0x1b},
+	{CCI_REG8(0x0099), 0x40},
+	{CCI_REG8(0x009a), 0x4e},
+	{CCI_REG8(0x009b), 0x40},
+	{CCI_REG8(0x009c), 0x4f},
+	{CCI_REG8(0x009d), 0x40},
+	{CCI_REG8(0x009e), 0x45},
+	{CCI_REG8(0x009f), 0x40},
+	{CCI_REG8(0x00a0), 0x2c},
+	{CCI_REG8(0x00a1), 0x00},
+	{CCI_REG8(0x00a2), 0x0d},
+	{CCI_REG8(0x00a3), 0x00},
+	{CCI_REG8(0x00a4), 0x35},
+	{CCI_REG8(0x00a5), 0x40},
+	{CCI_REG8(0x00a6), 0x01},
+	{CCI_REG8(0x00a7), 0x00},
+	{CCI_REG8(0x00a8), 0x23},
+	{CCI_REG8(0x00a9), 0x00},
+	{CCI_REG8(0x00aa), 0x10},
+	{CCI_REG8(0x00ab), 0x40},
+	{CCI_REG8(0x00ac), 0x1a},
+	{CCI_REG8(0x00ad), 0x40},
+	{CCI_REG8(0x00ae), 0x15},
+	{CCI_REG8(0x00af), 0x40},
+	{CCI_REG8(0x00b0), 0x28},
+	{CCI_REG8(0x00b1), 0x00},
+	{CCI_REG8(0x00b2), 0x01},
+	{CCI_REG8(0x00b3), 0x40},
+	{CCI_REG8(0x00b4), 0x1b},
+	{CCI_REG8(0x00b5), 0x40},
+	{CCI_REG8(0x00b6), 0x0e},
+	{CCI_REG8(0x00b7), 0x00},
+	{CCI_REG8(0x00b8), 0x1d},
+	{CCI_REG8(0x00b9), 0x00},
+	{CCI_REG8(0x00ba), 0x2d},
+	{CCI_REG8(0x00bb), 0x00},
+	{CCI_REG8(0x00bc), 0x10},
+	{CCI_REG8(0x00bd), 0x40},
+	{CCI_REG8(0x00be), 0x3a},
+	{CCI_REG8(0x00bf), 0x40},
+	{CCI_REG8(0x00c0), 0x3e},
+	{CCI_REG8(0x00c1), 0x00},
+	{CCI_REG8(0x00c2), 0x4f},
+	{CCI_REG8(0x00c3), 0x00},
+	{CCI_REG8(0x00c4), 0x48},
+	{CCI_REG8(0x00c5), 0x00},
+	{CCI_REG8(0x00c6), 0x1b},
+	{CCI_REG8(0x00c7), 0x00},
+	{CCI_REG8(0x00c8), 0x1b},
+	{CCI_REG8(0x00c9), 0x40},
+	{CCI_REG8(0x00ca), 0x51},
+	{CCI_REG8(0x00cb), 0x40},
+	{CCI_REG8(0x00cc), 0x4a},
+	{CCI_REG8(0x00cd), 0x40},
+	{CCI_REG8(0x00ce), 0x27},
+	{CCI_REG8(0x00cf), 0x40},
+	{CCI_REG8(0x00d0), 0x7a},
+	{CCI_REG8(0x00d1), 0x40},
+	{CCI_REG8(0x00d2), 0x8c},
+	{CCI_REG8(0x00d3), 0x40},
+	{CCI_REG8(0x00d4), 0x91},
+	{CCI_REG8(0x00d5), 0x40},
+	{CCI_REG8(0x00d6), 0x7c},
+	{CCI_REG8(0x00d7), 0x40},
+	{CCI_REG8(0x00d8), 0xab},
+	{CCI_REG8(0x00d9), 0x40},
+	{CCI_REG8(0x00da), 0xc7},
+	{CCI_REG8(0x00db), 0x40},
+	{CCI_REG8(0x00dc), 0xce},
+	{CCI_REG8(0x00dd), 0x40},
+	{CCI_REG8(0x00de), 0xb9},
+	{CCI_REG8(0x00df), 0x40},
+	{CCI_REG8(0x00e0), 0xe0},
+	{CCI_REG8(0x00e1), 0x40},
+	{CCI_REG8(0x00e2), 0xfd},
+	{CCI_REG8(0x00e3), 0x40},
+	{CCI_REG8(0x00e4), 0xfe},
+	{CCI_REG8(0x00e5), 0x40},
+	{CCI_REG8(0x00e6), 0xea},
+	{CCI_REG8(0x00e7), 0x40},
+	{CCI_REG8(0x00e8), 0xbf},
+	{CCI_REG8(0x00e9), 0x40},
+	{CCI_REG8(0x00ea), 0xe1},
+	{CCI_REG8(0x00eb), 0x40},
+	{CCI_REG8(0x00ec), 0xea},
+	{CCI_REG8(0x00ed), 0x40},
+	{CCI_REG8(0x00ee), 0xce},
+	{CCI_REG8(0x00ef), 0x40},
+	{CCI_REG8(0x00f0), 0x8d},
+	{CCI_REG8(0x00f1), 0x40},
+	{CCI_REG8(0x00f2), 0xae},
+	{CCI_REG8(0x00f3), 0x40},
+	{CCI_REG8(0x00f4), 0xae},
+	{CCI_REG8(0x00f5), 0x40},
+	{CCI_REG8(0x00f6), 0xa7},
+	{CCI_REG8(0x00f7), 0x40},
+	{CCI_REG8(0x00f8), 0x58},
+	{CCI_REG8(0x00f9), 0x40},
+	{CCI_REG8(0x00fa), 0x81},
+	{CCI_REG8(0x00fb), 0x40},
+	{CCI_REG8(0x00fc), 0x8c},
+	{CCI_REG8(0x00fd), 0x40},
+	{CCI_REG8(0x00fe), 0x69},
+	{CCI_REG8(0x00ff), 0x40},
+	{CCI_REG8(0x0100), 0x25},
+	{CCI_REG8(0x0101), 0x00},
+	{CCI_REG8(0x0102), 0x12},
+	{CCI_REG8(0x0103), 0x00},
+	{CCI_REG8(0x0104), 0x0a},
+	{CCI_REG8(0x0105), 0x00},
+	{CCI_REG8(0x0106), 0x06},
+	{CCI_REG8(0x0107), 0x00},
+	{CCI_REG8(0x0108), 0x5c},
+	{CCI_REG8(0x0109), 0x40},
+	{CCI_REG8(0x010a), 0x80},
+	{CCI_REG8(0x010b), 0x40},
+	{CCI_REG8(0x010c), 0x86},
+	{CCI_REG8(0x010d), 0x40},
+	{CCI_REG8(0x010e), 0x5f},
+	{CCI_REG8(0x010f), 0x40},
+	{CCI_REG8(0x0110), 0x84},
+	{CCI_REG8(0x0111), 0x00},
+	{CCI_REG8(0x0112), 0x7c},
+	{CCI_REG8(0x0113), 0x00},
+	{CCI_REG8(0x0114), 0x73},
+	{CCI_REG8(0x0115), 0x00},
+	{CCI_REG8(0x0116), 0x80},
+	{CCI_REG8(0x0117), 0x00},
+	{CCI_REG8(0x0118), 0x23},
+	{CCI_REG8(0x0119), 0x00},
+	{CCI_REG8(0x011a), 0x0e},
+	{CCI_REG8(0x011b), 0x00},
+	{CCI_REG8(0x011c), 0x14},
+	{CCI_REG8(0x011d), 0x00},
+	{CCI_REG8(0x011e), 0x1d},
+	{CCI_REG8(0x011f), 0x00},
+	{CCI_REG8(0x0120), 0x32},
+	{CCI_REG8(0x0121), 0x40},
+	{CCI_REG8(0x0122), 0x5a},
+	{CCI_REG8(0x0123), 0x40},
+	{CCI_REG8(0x0124), 0x67},
+	{CCI_REG8(0x0125), 0x40},
+	{CCI_REG8(0x0126), 0x4f},
+	{CCI_REG8(0x0127), 0x40},
+	{CCI_REG8(0x0128), 0x9e},
+	{CCI_REG8(0x0129), 0x40},
+	{CCI_REG8(0x012a), 0xb3},
+	{CCI_REG8(0x012b), 0x40},
+	{CCI_REG8(0x012c), 0xb7},
+	{CCI_REG8(0x012d), 0x40},
+	{CCI_REG8(0x012e), 0xb4},
+	{CCI_REG8(0x012f), 0x40},
+	{CCI_REG8(0x0130), 0xd1},
+	{CCI_REG8(0x0131), 0x40},
+	{CCI_REG8(0x0132), 0xe7},
+	{CCI_REG8(0x0133), 0x40},
+	{CCI_REG8(0x0134), 0xef},
+	{CCI_REG8(0x0135), 0x40},
+	{CCI_REG8(0x0136), 0xe2},
+	{CCI_REG8(0x0137), 0x40},
+	{CCI_REG8(0x0138), 0xc2},
+	{CCI_REG8(0x0139), 0x40},
+	{CCI_REG8(0x013a), 0xe6},
+	{CCI_REG8(0x013b), 0x40},
+	{CCI_REG8(0x013c), 0xec},
+	{CCI_REG8(0x013d), 0x40},
+	{CCI_REG8(0x013e), 0xdb},
+	{CCI_REG8(0x013f), 0x40},
+	{CCI_REG8(0x0140), 0x84},
+	{CCI_REG8(0x0141), 0x40},
+	{CCI_REG8(0x0142), 0x9e},
+	{CCI_REG8(0x0143), 0x40},
+	{CCI_REG8(0x0144), 0xad},
+	{CCI_REG8(0x0145), 0x40},
+	{CCI_REG8(0x0146), 0x95},
+	{CCI_REG8(0x0147), 0x40},
+	{CCI_REG8(0x0148), 0x3c},
+	{CCI_REG8(0x0149), 0x40},
+	{CCI_REG8(0x014a), 0x5f},
+	{CCI_REG8(0x014b), 0x40},
+	{CCI_REG8(0x014c), 0x64},
+	{CCI_REG8(0x014d), 0x40},
+	{CCI_REG8(0x014e), 0x55},
+	{CCI_REG8(0x014f), 0x40},
+	{CCI_REG8(0x0150), 0x8e},
+	{CCI_REG8(0x0151), 0x00},
+	{CCI_REG8(0x0152), 0x75},
+	{CCI_REG8(0x0153), 0x00},
+	{CCI_REG8(0x0154), 0x6f},
+	{CCI_REG8(0x0155), 0x00},
+	{CCI_REG8(0x0156), 0x7b},
+	{CCI_REG8(0x0157), 0x00},
+	{CCI_REG8(0x0158), 0x3c},
+	{CCI_REG8(0x0159), 0x40},
+	{CCI_REG8(0x015a), 0x49},
+	{CCI_REG8(0x015b), 0x40},
+	{CCI_REG8(0x015c), 0x4c},
+	{CCI_REG8(0x015d), 0x40},
+	{CCI_REG8(0x015e), 0x5b},
+	{CCI_REG8(0x015f), 0x40},
+	{CCI_REG8(0x0160), 0xca},
+	{CCI_REG8(0x0161), 0x00},
+	{CCI_REG8(0x0162), 0xca},
+	{CCI_REG8(0x0163), 0x00},
+	{CCI_REG8(0x0164), 0xdc},
+	{CCI_REG8(0x0165), 0x00},
+	{CCI_REG8(0x0166), 0xb8},
+	{CCI_REG8(0x0167), 0x00},
+	{CCI_REG8(0x0168), 0x50},
+	{CCI_REG8(0x0169), 0x00},
+	{CCI_REG8(0x016a), 0x29},
+	{CCI_REG8(0x016b), 0x00},
+	{CCI_REG8(0x016c), 0x19},
+	{CCI_REG8(0x016d), 0x00},
+	{CCI_REG8(0x016e), 0x3d},
+	{CCI_REG8(0x016f), 0x00},
+	{CCI_REG8(0x0170), 0x2f},
+	{CCI_REG8(0x0171), 0x40},
+	{CCI_REG8(0x0172), 0x4e},
+	{CCI_REG8(0x0173), 0x40},
+	{CCI_REG8(0x0174), 0x51},
+	{CCI_REG8(0x0175), 0x40},
+	{CCI_REG8(0x0176), 0x3d},
+	{CCI_REG8(0x0177), 0x40},
+	{CCI_REG8(0x0178), 0x99},
+	{CCI_REG8(0x0179), 0x40},
+	{CCI_REG8(0x017a), 0xb0},
+	{CCI_REG8(0x017b), 0x40},
+	{CCI_REG8(0x017c), 0xb9},
+	{CCI_REG8(0x017d), 0x40},
+	{CCI_REG8(0x017e), 0xaf},
+	{CCI_REG8(0x017f), 0x40},
+	{CCI_REG8(0x0180), 0xec},
+	{CCI_REG8(0x0181), 0x40},
+	{CCI_REG8(0x0182), 0xfe},
+	{CCI_REG8(0x0183), 0x40},
+	{CCI_REG8(0x0184), 0x02},
+	{CCI_REG8(0x0185), 0x41},
+	{CCI_REG8(0x0186), 0xff},
+	{CCI_REG8(0x0187), 0x40},
+	{CCI_REG8(0x0188), 0xd8},
+	{CCI_REG8(0x0189), 0x40},
+	{CCI_REG8(0x018a), 0xf8},
+	{CCI_REG8(0x018b), 0x40},
+	{CCI_REG8(0x018c), 0x02},
+	{CCI_REG8(0x018d), 0x41},
+	{CCI_REG8(0x018e), 0xed},
+	{CCI_REG8(0x018f), 0x40},
+	{CCI_REG8(0x0190), 0x93},
+	{CCI_REG8(0x0191), 0x40},
+	{CCI_REG8(0x0192), 0xb1},
+	{CCI_REG8(0x0193), 0x40},
+	{CCI_REG8(0x0194), 0xbf},
+	{CCI_REG8(0x0195), 0x40},
+	{CCI_REG8(0x0196), 0xae},
+	{CCI_REG8(0x0197), 0x40},
+	{CCI_REG8(0x0198), 0x4d},
+	{CCI_REG8(0x0199), 0x40},
+	{CCI_REG8(0x019a), 0x6d},
+	{CCI_REG8(0x019b), 0x40},
+	{CCI_REG8(0x019c), 0x80},
+	{CCI_REG8(0x019d), 0x40},
+	{CCI_REG8(0x019e), 0x65},
+	{CCI_REG8(0x019f), 0x40},
+	{CCI_REG8(0x01a0), 0x98},
+	{CCI_REG8(0x01a1), 0x00},
+	{CCI_REG8(0x01a2), 0x7e},
+	{CCI_REG8(0x01a3), 0x00},
+	{CCI_REG8(0x01a4), 0x77},
+	{CCI_REG8(0x01a5), 0x00},
+	{CCI_REG8(0x01a6), 0x7d},
+	{CCI_REG8(0x01a7), 0x00},
+	{CCI_REG8(0x01a8), 0x46},
+	{CCI_REG8(0x01a9), 0x40},
+	{CCI_REG8(0x01aa), 0x5c},
+	{CCI_REG8(0x01ab), 0x40},
+	{CCI_REG8(0x01ac), 0x6e},
+	{CCI_REG8(0x01ad), 0x40},
+	{CCI_REG8(0x01ae), 0x6e},
+	{CCI_REG8(0x01af), 0x40},
+	{CCI_REG8(0x01b0), 0xd3},
+	{CCI_REG8(0x01b1), 0x00},
+	{CCI_REG8(0x01b2), 0xd3},
+	{CCI_REG8(0x01b3), 0x00},
+	{CCI_REG8(0x01b4), 0xec},
+	{CCI_REG8(0x01b5), 0x00},
+	{CCI_REG8(0x01b6), 0xbf},
+	{CCI_REG8(0x01b7), 0x00},
+	{CCI_REG8(0x01b8), 0x54},
+	{CCI_REG8(0x01b9), 0x00},
+	{CCI_REG8(0x01ba), 0x37},
+	{CCI_REG8(0x01bb), 0x00},
+	{CCI_REG8(0x01bc), 0x34},
+	{CCI_REG8(0x01bd), 0x00},
+	{CCI_REG8(0x01be), 0x50},
+	{CCI_REG8(0x01bf), 0x00},
+	{CCI_REG8(0x01c0), 0x2d},
+	{CCI_REG8(0x01c1), 0x40},
+	{CCI_REG8(0x01c2), 0x57},
+	{CCI_REG8(0x01c3), 0x40},
+	{CCI_REG8(0x01c4), 0x53},
+	{CCI_REG8(0x01c5), 0x40},
+	{CCI_REG8(0x01c6), 0x3c},
+	{CCI_REG8(0x01c7), 0x40},
+	{CCI_REG8(0x01c8), 0xb1},
+	{CCI_REG8(0x01c9), 0x40},
+	{CCI_REG8(0x01ca), 0xbd},
+	{CCI_REG8(0x01cb), 0x40},
+	{CCI_REG8(0x01cc), 0xc0},
+	{CCI_REG8(0x01cd), 0x40},
+	{CCI_REG8(0x01ce), 0xbf},
+	{CCI_REG8(0x01cf), 0x40},
+	{CCI_REG8(0x01d0), 0xfc},
+	{CCI_REG8(0x01d1), 0x40},
+	{CCI_REG8(0x01d2), 0x16},
+	{CCI_REG8(0x01d3), 0x41},
+	{CCI_REG8(0x01d4), 0x11},
+	{CCI_REG8(0x01d5), 0x41},
+	{CCI_REG8(0x01d6), 0x0a},
+	{CCI_REG8(0x01d7), 0x41},
+	{CCI_REG8(0x01d8), 0xf8},
+	{CCI_REG8(0x01d9), 0x40},
+	{CCI_REG8(0x01da), 0x1e},
+	{CCI_REG8(0x01db), 0x41},
+	{CCI_REG8(0x01dc), 0x20},
+	{CCI_REG8(0x01dd), 0x41},
+	{CCI_REG8(0x01de), 0x0f},
+	{CCI_REG8(0x01df), 0x41},
+	{CCI_REG8(0x01e0), 0xbe},
+	{CCI_REG8(0x01e1), 0x40},
+	{CCI_REG8(0x01e2), 0xd3},
+	{CCI_REG8(0x01e3), 0x40},
+	{CCI_REG8(0x01e4), 0xd9},
+	{CCI_REG8(0x01e5), 0x40},
+	{CCI_REG8(0x01e6), 0xcb},
+	{CCI_REG8(0x01e7), 0x40},
+	{CCI_REG8(0x01e8), 0x68},
+	{CCI_REG8(0x01e9), 0x40},
+	{CCI_REG8(0x01ea), 0x97},
+	{CCI_REG8(0x01eb), 0x40},
+	{CCI_REG8(0x01ec), 0x9b},
+	{CCI_REG8(0x01ed), 0x40},
+	{CCI_REG8(0x01ee), 0x85},
+	{CCI_REG8(0x01ef), 0x40},
+	{CCI_REG8(0x01f0), 0x75},
+	{CCI_REG8(0x01f1), 0x00},
+	{CCI_REG8(0x01f2), 0x63},
+	{CCI_REG8(0x01f3), 0x00},
+	{CCI_REG8(0x01f4), 0x55},
+	{CCI_REG8(0x01f5), 0x00},
+	{CCI_REG8(0x01f6), 0x58},
+	{CCI_REG8(0x01f7), 0x00},
+	{CCI_REG8(0x01f8), 0x60},
+	{CCI_REG8(0x01f9), 0x40},
+	{CCI_REG8(0x01fa), 0x91},
+	{CCI_REG8(0x01fb), 0x40},
+	{CCI_REG8(0x01fc), 0x94},
+	{CCI_REG8(0x01fd), 0x40},
+	{CCI_REG8(0x01fe), 0x80},
+	{CCI_REG8(0x01ff), 0x40},
+	{CCI_REG8(0x0200), 0x2c},
+	{CCI_REG8(0x0201), 0x00},
+	{CCI_REG8(0x0202), 0x75},
+	{CCI_REG8(0x0203), 0x00},
+	{CCI_REG8(0x0204), 0x5f},
+	{CCI_REG8(0x0205), 0x00},
+	{CCI_REG8(0x0206), 0x59},
+	{CCI_REG8(0x0207), 0x00},
+	{CCI_REG8(0x0208), 0x21},
+	{CCI_REG8(0x0209), 0x00},
+	{CCI_REG8(0x020a), 0x0e},
+	{CCI_REG8(0x020b), 0x40},
+	{CCI_REG8(0x020c), 0x12},
+	{CCI_REG8(0x020d), 0x40},
+	{CCI_REG8(0x020e), 0x03},
+	{CCI_REG8(0x020f), 0x00},
+	{CCI_REG8(0x0210), 0x56},
+	{CCI_REG8(0x0211), 0x40},
+	{CCI_REG8(0x0212), 0x76},
+	{CCI_REG8(0x0213), 0x40},
+	{CCI_REG8(0x0214), 0x7c},
+	{CCI_REG8(0x0215), 0x40},
+	{CCI_REG8(0x0216), 0x66},
+	{CCI_REG8(0x0217), 0x40},
+	{CCI_REG8(0x0218), 0xdc},
+	{CCI_REG8(0x0219), 0x40},
+	{CCI_REG8(0x021a), 0xeb},
+	{CCI_REG8(0x021b), 0x40},
+	{CCI_REG8(0x021c), 0xf2},
+	{CCI_REG8(0x021d), 0x40},
+	{CCI_REG8(0x021e), 0xed},
+	{CCI_REG8(0x021f), 0x40},
+	{CCI_REG8(0x0220), 0x39},
+	{CCI_REG8(0x0221), 0x41},
+	{CCI_REG8(0x0222), 0x41},
+	{CCI_REG8(0x0223), 0x41},
+	{CCI_REG8(0x0224), 0x46},
+	{CCI_REG8(0x0225), 0x41},
+	{CCI_REG8(0x0226), 0x45},
+	{CCI_REG8(0x0227), 0x41},
+	{CCI_REG8(0x0228), 0x3d},
+	{CCI_REG8(0x0229), 0x41},
+	{CCI_REG8(0x022a), 0x51},
+	{CCI_REG8(0x022b), 0x41},
+	{CCI_REG8(0x022c), 0x5d},
+	{CCI_REG8(0x022d), 0x41},
+	{CCI_REG8(0x022e), 0x51},
+	{CCI_REG8(0x022f), 0x41},
+	{CCI_REG8(0x0230), 0xdf},
+	{CCI_REG8(0x0231), 0x40},
+	{CCI_REG8(0x0232), 0xfb},
+	{CCI_REG8(0x0233), 0x40},
+	{CCI_REG8(0x0234), 0xff},
+	{CCI_REG8(0x0235), 0x40},
+	{CCI_REG8(0x0236), 0xeb},
+	{CCI_REG8(0x0237), 0x40},
+	{CCI_REG8(0x0238), 0xa0},
+	{CCI_REG8(0x0239), 0x40},
+	{CCI_REG8(0x023a), 0xc0},
+	{CCI_REG8(0x023b), 0x40},
+	{CCI_REG8(0x023c), 0xd9},
+	{CCI_REG8(0x023d), 0x40},
+	{CCI_REG8(0x023e), 0xbc},
+	{CCI_REG8(0x023f), 0x40},
+	{CCI_REG8(0x0240), 0x1e},
+	{CCI_REG8(0x0241), 0x00},
+	{CCI_REG8(0x0242), 0x07},
+	{CCI_REG8(0x0243), 0x00},
+	{CCI_REG8(0x0244), 0x04},
+	{CCI_REG8(0x0245), 0x40},
+	{CCI_REG8(0x0246), 0x10},
+	{CCI_REG8(0x0247), 0x00},
+	{CCI_REG8(0x0248), 0xa6},
+	{CCI_REG8(0x0249), 0x40},
+	{CCI_REG8(0x024a), 0xa5},
+	{CCI_REG8(0x024b), 0x40},
+	{CCI_REG8(0x024c), 0xd4},
+	{CCI_REG8(0x024d), 0x40},
+	{CCI_REG8(0x024e), 0xd1},
+	{CCI_REG8(0x024f), 0x40},
+	{CCI_REG8(0x0250), 0xe4},
+	{CCI_REG8(0x0251), 0x01},
+	{CCI_REG8(0x0252), 0x3b},
+	{CCI_REG8(0x0253), 0x01},
+	{CCI_REG8(0x0254), 0xa2},
+	{CCI_REG8(0x0255), 0x01},
+	{CCI_REG8(0x0256), 0x43},
+	{CCI_REG8(0x0257), 0x01},
+	{CCI_REG8(0x0258), 0x72},
+	{CCI_REG8(0x0259), 0x00},
+	{CCI_REG8(0x025a), 0x85},
+	{CCI_REG8(0x025b), 0x00},
+	{CCI_REG8(0x025c), 0x73},
+	{CCI_REG8(0x025d), 0x00},
+	{CCI_REG8(0x025e), 0xa9},
+	{CCI_REG8(0x025f), 0x00},
+	{CCI_REG8(0x0260), 0x16},
+	{CCI_REG8(0x0261), 0x00},
+	{CCI_REG8(0x0262), 0x31},
+	{CCI_REG8(0x0263), 0x40},
+	{CCI_REG8(0x0264), 0x1d},
+	{CCI_REG8(0x0265), 0x40},
+	{CCI_REG8(0x0266), 0x1c},
+	{CCI_REG8(0x0267), 0x40},
+	{CCI_REG8(0x0268), 0x87},
+	{CCI_REG8(0x0269), 0x40},
+	{CCI_REG8(0x026a), 0x80},
+	{CCI_REG8(0x026b), 0x40},
+	{CCI_REG8(0x026c), 0x88},
+	{CCI_REG8(0x026d), 0x40},
+	{CCI_REG8(0x026e), 0x8d},
+	{CCI_REG8(0x026f), 0x40},
+	{CCI_REG8(0x0270), 0xaa},
+	{CCI_REG8(0x0271), 0x40},
+	{CCI_REG8(0x0272), 0xde},
+	{CCI_REG8(0x0273), 0x40},
+	{CCI_REG8(0x0274), 0xd1},
+	{CCI_REG8(0x0275), 0x40},
+	{CCI_REG8(0x0276), 0xc3},
+	{CCI_REG8(0x0277), 0x40},
+	{CCI_REG8(0x0278), 0xad},
+	{CCI_REG8(0x0279), 0x40},
+	{CCI_REG8(0x027a), 0xdc},
+	{CCI_REG8(0x027b), 0x40},
+	{CCI_REG8(0x027c), 0xce},
+	{CCI_REG8(0x027d), 0x40},
+	{CCI_REG8(0x027e), 0xc4},
+	{CCI_REG8(0x027f), 0x40},
+	{CCI_REG8(0x0280), 0x87},
+	{CCI_REG8(0x0281), 0x40},
+	{CCI_REG8(0x0282), 0xae},
+	{CCI_REG8(0x0283), 0x40},
+	{CCI_REG8(0x0284), 0xbc},
+	{CCI_REG8(0x0285), 0x40},
+	{CCI_REG8(0x0286), 0xa9},
+	{CCI_REG8(0x0287), 0x40},
+	{CCI_REG8(0x0288), 0x33},
+	{CCI_REG8(0x0289), 0x40},
+	{CCI_REG8(0x028a), 0x69},
+	{CCI_REG8(0x028b), 0x40},
+	{CCI_REG8(0x028c), 0x4f},
+	{CCI_REG8(0x028d), 0x40},
+	{CCI_REG8(0x028e), 0x47},
+	{CCI_REG8(0x028f), 0x40},
+	{CCI_REG8(0x0290), 0xeb},
+	{CCI_REG8(0x0291), 0x00},
+	{CCI_REG8(0x0292), 0xda},
+	{CCI_REG8(0x0293), 0x00},
+	{CCI_REG8(0x0294), 0xc8},
+	{CCI_REG8(0x0295), 0x00},
+	{CCI_REG8(0x0296), 0xb9},
+	{CCI_REG8(0x0297), 0x00},
+	{CCI_REG8(0x0298), 0x1a},
+	{CCI_REG8(0x0299), 0x40},
+	{CCI_REG8(0x029a), 0x7e},
+	{CCI_REG8(0x029b), 0x40},
+	{CCI_REG8(0x029c), 0x43},
+	{CCI_REG8(0x029d), 0x40},
+	{CCI_REG8(0x029e), 0x2a},
+	{CCI_REG8(0x029f), 0x40},
+	{CCI_REG8(0x02f0), 0x11},
+	{CCI_REG8(0x02f1), 0x00},
+	{CCI_REG8(0x02f2), 0x06},
+	{CCI_REG8(0x02f3), 0x00},
+	{CCI_REG8(0x02f4), 0x0e},
+	{CCI_REG8(0x02f5), 0x00},
+	{CCI_REG8(0x02f6), 0x1c},
+	{CCI_REG8(0x02f7), 0x00},
+	{CCI_REG8(0x02f8), 0x0a},
+	{CCI_REG8(0x02f9), 0x00},
+	{CCI_REG8(0x02fa), 0x1b},
+	{CCI_REG8(0x02fb), 0x00},
+	{CCI_REG8(0x02fc), 0x20},
+	{CCI_REG8(0x02fd), 0x00},
+	{CCI_REG8(0x02fe), 0x15},
+	{CCI_REG8(0x02ff), 0x00},
+	{CCI_REG8(0x0300), 0x0d},
+	{CCI_REG8(0x0301), 0x00},
+	{CCI_REG8(0x0302), 0x1e},
+	{CCI_REG8(0x0303), 0x00},
+	{CCI_REG8(0x0304), 0x27},
+	{CCI_REG8(0x0305), 0x00},
+	{CCI_REG8(0x0306), 0x16},
+	{CCI_REG8(0x0307), 0x00},
+	{CCI_REG8(0x0308), 0x10},
+	{CCI_REG8(0x0309), 0x00},
+	{CCI_REG8(0x030a), 0x21},
+	{CCI_REG8(0x030b), 0x00},
+	{CCI_REG8(0x030c), 0x28},
+	{CCI_REG8(0x030d), 0x00},
+	{CCI_REG8(0x030e), 0x20},
+	{CCI_REG8(0x030f), 0x00},
+	{CCI_REG8(0x0310), 0x15},
+	{CCI_REG8(0x0311), 0x00},
+	{CCI_REG8(0x0312), 0x23},
+	{CCI_REG8(0x0313), 0x00},
+	{CCI_REG8(0x0314), 0x2b},
+	{CCI_REG8(0x0315), 0x00},
+	{CCI_REG8(0x0316), 0x21},
+	{CCI_REG8(0x0317), 0x00},
+	{CCI_REG8(0x0318), 0x14},
+	{CCI_REG8(0x0319), 0x00},
+	{CCI_REG8(0x031a), 0x24},
+	{CCI_REG8(0x031b), 0x00},
+	{CCI_REG8(0x031c), 0x29},
+	{CCI_REG8(0x031d), 0x00},
+	{CCI_REG8(0x031e), 0x23},
+	{CCI_REG8(0x031f), 0x00},
+	{CCI_REG8(0x0320), 0x15},
+	{CCI_REG8(0x0321), 0x00},
+	{CCI_REG8(0x0322), 0x21},
+	{CCI_REG8(0x0323), 0x00},
+	{CCI_REG8(0x0324), 0x29},
+	{CCI_REG8(0x0325), 0x00},
+	{CCI_REG8(0x0326), 0x23},
+	{CCI_REG8(0x0327), 0x00},
+	{CCI_REG8(0x0328), 0x0e},
+	{CCI_REG8(0x0329), 0x00},
+	{CCI_REG8(0x032a), 0x1b},
+	{CCI_REG8(0x032b), 0x00},
+	{CCI_REG8(0x032c), 0x20},
+	{CCI_REG8(0x032d), 0x00},
+	{CCI_REG8(0x032e), 0x1d},
+	{CCI_REG8(0x032f), 0x00},
+	{CCI_REG8(0x0330), 0x0f},
+	{CCI_REG8(0x0331), 0x00},
+	{CCI_REG8(0x0332), 0x15},
+	{CCI_REG8(0x0333), 0x00},
+	{CCI_REG8(0x0334), 0x1e},
+	{CCI_REG8(0x0335), 0x00},
+	{CCI_REG8(0x0336), 0x20},
+	{CCI_REG8(0x0337), 0x00},
+	{CCI_REG8(0x0338), 0x0d},
+	{CCI_REG8(0x0339), 0x00},
+	{CCI_REG8(0x033a), 0x1d},
+	{CCI_REG8(0x033b), 0x00},
+	{CCI_REG8(0x033c), 0x21},
+	{CCI_REG8(0x033d), 0x00},
+	{CCI_REG8(0x033e), 0x1e},
+	{CCI_REG8(0x033f), 0x00},
+	{CCI_REG8(0x0340), 0x09},
+	{CCI_REG8(0x0341), 0x00},
+	{CCI_REG8(0x0342), 0x05},
+	{CCI_REG8(0x0343), 0x00},
+	{CCI_REG8(0x0344), 0x03},
+	{CCI_REG8(0x0345), 0x00},
+	{CCI_REG8(0x0346), 0x0f},
+	{CCI_REG8(0x0347), 0x00},
+	{CCI_REG8(0x0348), 0x06},
+	{CCI_REG8(0x0349), 0x00},
+	{CCI_REG8(0x034a), 0x0b},
+	{CCI_REG8(0x034b), 0x00},
+	{CCI_REG8(0x034c), 0x0c},
+	{CCI_REG8(0x034d), 0x00},
+	{CCI_REG8(0x034e), 0x10},
+	{CCI_REG8(0x034f), 0x00},
+	{CCI_REG8(0x0350), 0x0b},
+	{CCI_REG8(0x0351), 0x00},
+	{CCI_REG8(0x0352), 0x11},
+	{CCI_REG8(0x0353), 0x00},
+	{CCI_REG8(0x0354), 0x10},
+	{CCI_REG8(0x0355), 0x00},
+	{CCI_REG8(0x0356), 0x14},
+	{CCI_REG8(0x0357), 0x00},
+	{CCI_REG8(0x0358), 0x0f},
+	{CCI_REG8(0x0359), 0x00},
+	{CCI_REG8(0x035a), 0x12},
+	{CCI_REG8(0x035b), 0x00},
+	{CCI_REG8(0x035c), 0x13},
+	{CCI_REG8(0x035d), 0x00},
+	{CCI_REG8(0x035e), 0x17},
+	{CCI_REG8(0x035f), 0x00},
+	{CCI_REG8(0x0360), 0x0e},
+	{CCI_REG8(0x0361), 0x00},
+	{CCI_REG8(0x0362), 0x14},
+	{CCI_REG8(0x0363), 0x00},
+	{CCI_REG8(0x0364), 0x13},
+	{CCI_REG8(0x0365), 0x00},
+	{CCI_REG8(0x0366), 0x18},
+	{CCI_REG8(0x0367), 0x00},
+	{CCI_REG8(0x0368), 0x11},
+	{CCI_REG8(0x0369), 0x00},
+	{CCI_REG8(0x036a), 0x11},
+	{CCI_REG8(0x036b), 0x00},
+	{CCI_REG8(0x036c), 0x12},
+	{CCI_REG8(0x036d), 0x00},
+	{CCI_REG8(0x036e), 0x19},
+	{CCI_REG8(0x036f), 0x00},
+	{CCI_REG8(0x0370), 0x0e},
+	{CCI_REG8(0x0371), 0x00},
+	{CCI_REG8(0x0372), 0x10},
+	{CCI_REG8(0x0373), 0x00},
+	{CCI_REG8(0x0374), 0x0f},
+	{CCI_REG8(0x0375), 0x00},
+	{CCI_REG8(0x0376), 0x18},
+	{CCI_REG8(0x0377), 0x00},
+	{CCI_REG8(0x0378), 0x10},
+	{CCI_REG8(0x0379), 0x00},
+	{CCI_REG8(0x037a), 0x0d},
+	{CCI_REG8(0x037b), 0x00},
+	{CCI_REG8(0x037c), 0x0f},
+	{CCI_REG8(0x037d), 0x00},
+	{CCI_REG8(0x037e), 0x19},
+	{CCI_REG8(0x037f), 0x00},
+	{CCI_REG8(0x0380), 0x0a},
+	{CCI_REG8(0x0381), 0x00},
+	{CCI_REG8(0x0382), 0x03},
+	{CCI_REG8(0x0383), 0x00},
+	{CCI_REG8(0x0384), 0x01},
+	{CCI_REG8(0x0385), 0x00},
+	{CCI_REG8(0x0386), 0x11},
+	{CCI_REG8(0x0387), 0x00},
+	{CCI_REG8(0x0388), 0x12},
+	{CCI_REG8(0x0389), 0x00},
+	{CCI_REG8(0x038a), 0x0e},
+	{CCI_REG8(0x038b), 0x00},
+	{CCI_REG8(0x038c), 0x0d},
+	{CCI_REG8(0x038d), 0x00},
+	{CCI_REG8(0x038e), 0x1b},
+	{CCI_REG8(0x038f), 0x00},
+	{CCI_REG8(0x0390), 0x02},
+	{CCI_REG8(0x0391), 0x40},
+	{CCI_REG8(0x0392), 0x02},
+	{CCI_REG8(0x0393), 0x40},
+	{CCI_REG8(0x0394), 0x01},
+	{CCI_REG8(0x0395), 0x00},
+	{CCI_REG8(0x0396), 0x0b},
+	{CCI_REG8(0x0397), 0x00},
+	{CCI_REG8(0x0398), 0x01},
+	{CCI_REG8(0x0399), 0x40},
+	{CCI_REG8(0x039a), 0x04},
+	{CCI_REG8(0x039b), 0x00},
+	{CCI_REG8(0x039c), 0x0a},
+	{CCI_REG8(0x039d), 0x00},
+	{CCI_REG8(0x039e), 0x07},
+	{CCI_REG8(0x039f), 0x00},
+	{CCI_REG8(0x03a0), 0x02},
+	{CCI_REG8(0x03a1), 0x00},
+	{CCI_REG8(0x03a2), 0x09},
+	{CCI_REG8(0x03a3), 0x00},
+	{CCI_REG8(0x03a4), 0x0e},
+	{CCI_REG8(0x03a5), 0x00},
+	{CCI_REG8(0x03a6), 0x0d},
+	{CCI_REG8(0x03a7), 0x00},
+	{CCI_REG8(0x03a8), 0x04},
+	{CCI_REG8(0x03a9), 0x00},
+	{CCI_REG8(0x03aa), 0x0b},
+	{CCI_REG8(0x03ab), 0x00},
+	{CCI_REG8(0x03ac), 0x0f},
+	{CCI_REG8(0x03ad), 0x00},
+	{CCI_REG8(0x03ae), 0x0f},
+	{CCI_REG8(0x03af), 0x00},
+	{CCI_REG8(0x03b0), 0x05},
+	{CCI_REG8(0x03b1), 0x00},
+	{CCI_REG8(0x03b2), 0x0b},
+	{CCI_REG8(0x03b3), 0x00},
+	{CCI_REG8(0x03b4), 0x10},
+	{CCI_REG8(0x03b5), 0x00},
+	{CCI_REG8(0x03b6), 0x10},
+	{CCI_REG8(0x03b7), 0x00},
+	{CCI_REG8(0x03b8), 0x05},
+	{CCI_REG8(0x03b9), 0x00},
+	{CCI_REG8(0x03ba), 0x0b},
+	{CCI_REG8(0x03bb), 0x00},
+	{CCI_REG8(0x03bc), 0x0d},
+	{CCI_REG8(0x03bd), 0x00},
+	{CCI_REG8(0x03be), 0x11},
+	{CCI_REG8(0x03bf), 0x00},
+	{CCI_REG8(0x03c0), 0x04},
+	{CCI_REG8(0x03c1), 0x00},
+	{CCI_REG8(0x03c2), 0x08},
+	{CCI_REG8(0x03c3), 0x00},
+	{CCI_REG8(0x03c4), 0x0c},
+	{CCI_REG8(0x03c5), 0x00},
+	{CCI_REG8(0x03c6), 0x10},
+	{CCI_REG8(0x03c7), 0x00},
+	{CCI_REG8(0x03c8), 0x04},
+	{CCI_REG8(0x03c9), 0x00},
+	{CCI_REG8(0x03ca), 0x06},
+	{CCI_REG8(0x03cb), 0x00},
+	{CCI_REG8(0x03cc), 0x09},
+	{CCI_REG8(0x03cd), 0x00},
+	{CCI_REG8(0x03ce), 0x0f},
+	{CCI_REG8(0x03cf), 0x00},
+	{CCI_REG8(0x03d0), 0x01},
+	{CCI_REG8(0x03d1), 0x00},
+	{CCI_REG8(0x03d2), 0x04},
+	{CCI_REG8(0x03d3), 0x40},
+	{CCI_REG8(0x03d4), 0x01},
+	{CCI_REG8(0x03d5), 0x40},
+	{CCI_REG8(0x03d6), 0x0d},
+	{CCI_REG8(0x03d7), 0x00},
+	{CCI_REG8(0x03d8), 0x05},
+	{CCI_REG8(0x03d9), 0x00},
+	{CCI_REG8(0x03da), 0x08},
+	{CCI_REG8(0x03db), 0x00},
+	{CCI_REG8(0x03dc), 0x0a},
+	{CCI_REG8(0x03dd), 0x00},
+	{CCI_REG8(0x03de), 0x11},
+	{CCI_REG8(0x03df), 0x00},
+	{CCI_REG8(0x03e0), 0x07},
+	{CCI_REG8(0x03e1), 0x40},
+	{CCI_REG8(0x03e2), 0x06},
+	{CCI_REG8(0x03e3), 0x40},
+	{CCI_REG8(0x03e4), 0x06},
+	{CCI_REG8(0x03e5), 0x40},
+	{CCI_REG8(0x03e6), 0x01},
+	{CCI_REG8(0x03e7), 0x40},
+	{CCI_REG8(0x03e8), 0x07},
+	{CCI_REG8(0x03e9), 0x40},
+	{CCI_REG8(0x03ec), 0x01},
+	{CCI_REG8(0x03ed), 0x40},
+	{CCI_REG8(0x03ee), 0x04},
+	{CCI_REG8(0x03ef), 0x00},
+	{CCI_REG8(0x03f0), 0x06},
+	{CCI_REG8(0x03f1), 0x40},
+	{CCI_REG8(0x03f2), 0x01},
+	{CCI_REG8(0x03f3), 0x00},
+	{CCI_REG8(0x03f4), 0x01},
+	{CCI_REG8(0x03f5), 0x00},
+	{CCI_REG8(0x03f6), 0x04},
+	{CCI_REG8(0x03f7), 0x00},
+	{CCI_REG8(0x03f8), 0x04},
+	{CCI_REG8(0x03f9), 0x40},
+	{CCI_REG8(0x03fa), 0x02},
+	{CCI_REG8(0x03fb), 0x00},
+	{CCI_REG8(0x03fc), 0x02},
+	{CCI_REG8(0x03fd), 0x00},
+	{CCI_REG8(0x03fe), 0x06},
+	{CCI_REG8(0x03ff), 0x00},
+	{CCI_REG8(0x0400), 0x04},
+	{CCI_REG8(0x0401), 0x40},
+	{CCI_REG8(0x0402), 0x02},
+	{CCI_REG8(0x0403), 0x00},
+	{CCI_REG8(0x0404), 0x02},
+	{CCI_REG8(0x0405), 0x00},
+	{CCI_REG8(0x0406), 0x05},
+	{CCI_REG8(0x0407), 0x00},
+	{CCI_REG8(0x0408), 0x03},
+	{CCI_REG8(0x0409), 0x40},
+	{CCI_REG8(0x040a), 0x01},
+	{CCI_REG8(0x040b), 0x40},
+	{CCI_REG8(0x040c), 0x01},
+	{CCI_REG8(0x040d), 0x00},
+	{CCI_REG8(0x040e), 0x07},
+	{CCI_REG8(0x040f), 0x00},
+	{CCI_REG8(0x0410), 0x05},
+	{CCI_REG8(0x0411), 0x40},
+	{CCI_REG8(0x0412), 0x02},
+	{CCI_REG8(0x0413), 0x40},
+	{CCI_REG8(0x0414), 0x02},
+	{CCI_REG8(0x0415), 0x40},
+	{CCI_REG8(0x0416), 0x05},
+	{CCI_REG8(0x0417), 0x00},
+	{CCI_REG8(0x0418), 0x02},
+	{CCI_REG8(0x0419), 0x40},
+	{CCI_REG8(0x041a), 0x04},
+	{CCI_REG8(0x041b), 0x40},
+	{CCI_REG8(0x041c), 0x03},
+	{CCI_REG8(0x041d), 0x40},
+	{CCI_REG8(0x041e), 0x07},
+	{CCI_REG8(0x041f), 0x00},
+	{CCI_REG8(0x0420), 0x05},
+	{CCI_REG8(0x0421), 0x40},
+	{CCI_REG8(0x0422), 0x0c},
+	{CCI_REG8(0x0423), 0x40},
+	{CCI_REG8(0x0424), 0x0c},
+	{CCI_REG8(0x0425), 0x40},
+	{CCI_REG8(0x0426), 0x03},
+	{CCI_REG8(0x0427), 0x00},
+	{CCI_REG8(0x0428), 0x02},
+	{CCI_REG8(0x0429), 0x40},
+	{CCI_REG8(0x042a), 0x05},
+	{CCI_REG8(0x042b), 0x40},
+	{CCI_REG8(0x042c), 0x04},
+	{CCI_REG8(0x042d), 0x40},
+	{CCI_REG8(0x042e), 0x0a},
+	{CCI_REG8(0x042f), 0x00},
+	{CCI_REG8(0x0430), 0x0d},
+	{CCI_REG8(0x0431), 0x40},
+	{CCI_REG8(0x0432), 0x15},
+	{CCI_REG8(0x0433), 0x40},
+	{CCI_REG8(0x0434), 0x14},
+	{CCI_REG8(0x0435), 0x40},
+	{CCI_REG8(0x0436), 0x02},
+	{CCI_REG8(0x0437), 0x00},
+	{CCI_REG8(0x0438), 0x0f},
+	{CCI_REG8(0x0439), 0x40},
+	{CCI_REG8(0x043a), 0x0b},
+	{CCI_REG8(0x043b), 0x40},
+	{CCI_REG8(0x043c), 0x06},
+	{CCI_REG8(0x043d), 0x40},
+	{CCI_REG8(0x043e), 0x08},
+	{CCI_REG8(0x043f), 0x40},
+	{CCI_REG8(0x0440), 0x11},
+	{CCI_REG8(0x0441), 0x40},
+	{CCI_REG8(0x0442), 0x0a},
+	{CCI_REG8(0x0443), 0x40},
+	{CCI_REG8(0x0444), 0x07},
+	{CCI_REG8(0x0445), 0x40},
+	{CCI_REG8(0x0446), 0x05},
+	{CCI_REG8(0x0447), 0x40},
+	{CCI_REG8(0x0448), 0x11},
+	{CCI_REG8(0x0449), 0x40},
+	{CCI_REG8(0x044a), 0x0d},
+	{CCI_REG8(0x044b), 0x40},
+	{CCI_REG8(0x044c), 0x09},
+	{CCI_REG8(0x044d), 0x40},
+	{CCI_REG8(0x044e), 0x07},
+	{CCI_REG8(0x044f), 0x40},
+	{CCI_REG8(0x0450), 0x12},
+	{CCI_REG8(0x0451), 0x40},
+	{CCI_REG8(0x0452), 0x0c},
+	{CCI_REG8(0x0453), 0x40},
+	{CCI_REG8(0x0454), 0x09},
+	{CCI_REG8(0x0455), 0x40},
+	{CCI_REG8(0x0456), 0x07},
+	{CCI_REG8(0x0457), 0x40},
+	{CCI_REG8(0x0458), 0x12},
+	{CCI_REG8(0x0459), 0x40},
+	{CCI_REG8(0x045a), 0x0f},
+	{CCI_REG8(0x045b), 0x40},
+	{CCI_REG8(0x045c), 0x0d},
+	{CCI_REG8(0x045d), 0x40},
+	{CCI_REG8(0x045e), 0x07},
+	{CCI_REG8(0x045f), 0x40},
+	{CCI_REG8(0x0460), 0x13},
+	{CCI_REG8(0x0461), 0x40},
+	{CCI_REG8(0x0462), 0x10},
+	{CCI_REG8(0x0463), 0x40},
+	{CCI_REG8(0x0464), 0x0e},
+	{CCI_REG8(0x0465), 0x40},
+	{CCI_REG8(0x0466), 0x09},
+	{CCI_REG8(0x0467), 0x40},
+	{CCI_REG8(0x0468), 0x11},
+	{CCI_REG8(0x0469), 0x40},
+	{CCI_REG8(0x046a), 0x11},
+	{CCI_REG8(0x046b), 0x40},
+	{CCI_REG8(0x046c), 0x0e},
+	{CCI_REG8(0x046d), 0x40},
+	{CCI_REG8(0x046e), 0x06},
+	{CCI_REG8(0x046f), 0x40},
+	{CCI_REG8(0x0470), 0x13},
+	{CCI_REG8(0x0471), 0x40},
+	{CCI_REG8(0x0472), 0x1a},
+	{CCI_REG8(0x0473), 0x40},
+	{CCI_REG8(0x0474), 0x17},
+	{CCI_REG8(0x0475), 0x40},
+	{CCI_REG8(0x0476), 0x09},
+	{CCI_REG8(0x0477), 0x40},
+	{CCI_REG8(0x0478), 0x0e},
+	{CCI_REG8(0x0479), 0x40},
+	{CCI_REG8(0x047a), 0x10},
+	{CCI_REG8(0x047b), 0x40},
+	{CCI_REG8(0x047c), 0x0d},
+	{CCI_REG8(0x047d), 0x40},
+	{CCI_REG8(0x047e), 0x03},
+	{CCI_REG8(0x047f), 0x40},
+	{CCI_REG8(0x0480), 0x17},
+	{CCI_REG8(0x0481), 0x40},
+	{CCI_REG8(0x0482), 0x23},
+	{CCI_REG8(0x0483), 0x40},
+	{CCI_REG8(0x0484), 0x1a},
+	{CCI_REG8(0x0485), 0x40},
+	{CCI_REG8(0x0486), 0x0b},
+	{CCI_REG8(0x0487), 0x40},
+	{CCI_REG8(0x0488), 0x19},
+	{CCI_REG8(0x0489), 0x40},
+	{CCI_REG8(0x048a), 0x18},
+	{CCI_REG8(0x048b), 0x40},
+	{CCI_REG8(0x048c), 0x14},
+	{CCI_REG8(0x048d), 0x40},
+	{CCI_REG8(0x048e), 0x0e},
+	{CCI_REG8(0x048f), 0x40},
+	{CCI_REG8(0x0490), 0x1c},
+	{CCI_REG8(0x0491), 0x40},
+	{CCI_REG8(0x0492), 0x19},
+	{CCI_REG8(0x0493), 0x40},
+	{CCI_REG8(0x0494), 0x13},
+	{CCI_REG8(0x0495), 0x40},
+	{CCI_REG8(0x0496), 0x13},
+	{CCI_REG8(0x0497), 0x40},
+	{CCI_REG8(0x0498), 0x1f},
+	{CCI_REG8(0x0499), 0x40},
+	{CCI_REG8(0x049a), 0x1b},
+	{CCI_REG8(0x049b), 0x40},
+	{CCI_REG8(0x049c), 0x19},
+	{CCI_REG8(0x049d), 0x40},
+	{CCI_REG8(0x049e), 0x13},
+	{CCI_REG8(0x049f), 0x40},
+	{CCI_REG8(0x04a0), 0x20},
+	{CCI_REG8(0x04a1), 0x40},
+	{CCI_REG8(0x04a2), 0x1d},
+	{CCI_REG8(0x04a3), 0x40},
+	{CCI_REG8(0x04a4), 0x17},
+	{CCI_REG8(0x04a5), 0x40},
+	{CCI_REG8(0x04a6), 0x15},
+	{CCI_REG8(0x04a7), 0x40},
+	{CCI_REG8(0x04a8), 0x1d},
+	{CCI_REG8(0x04a9), 0x40},
+	{CCI_REG8(0x04aa), 0x1d},
+	{CCI_REG8(0x04ab), 0x40},
+	{CCI_REG8(0x04ac), 0x1b},
+	{CCI_REG8(0x04ad), 0x40},
+	{CCI_REG8(0x04ae), 0x13},
+	{CCI_REG8(0x04af), 0x40},
+	{CCI_REG8(0x04b0), 0x20},
+	{CCI_REG8(0x04b1), 0x40},
+	{CCI_REG8(0x04b2), 0x1f},
+	{CCI_REG8(0x04b3), 0x40},
+	{CCI_REG8(0x04b4), 0x1b},
+	{CCI_REG8(0x04b5), 0x40},
+	{CCI_REG8(0x04b6), 0x13},
+	{CCI_REG8(0x04b7), 0x40},
+	{CCI_REG8(0x04b8), 0x1d},
+	{CCI_REG8(0x04b9), 0x40},
+	{CCI_REG8(0x04ba), 0x20},
+	{CCI_REG8(0x04bb), 0x40},
+	{CCI_REG8(0x04bc), 0x1e},
+	{CCI_REG8(0x04bd), 0x40},
+	{CCI_REG8(0x04be), 0x14},
+	{CCI_REG8(0x04bf), 0x40},
+	{CCI_REG8(0x04c0), 0x1d},
+	{CCI_REG8(0x04c1), 0x40},
+	{CCI_REG8(0x04c2), 0x25},
+	{CCI_REG8(0x04c3), 0x40},
+	{CCI_REG8(0x04c4), 0x20},
+	{CCI_REG8(0x04c5), 0x40},
+	{CCI_REG8(0x04c6), 0x0f},
+	{CCI_REG8(0x04c7), 0x40},
+	{CCI_REG8(0x04c8), 0x19},
+	{CCI_REG8(0x04c9), 0x40},
+	{CCI_REG8(0x04ca), 0x20},
+	{CCI_REG8(0x04cb), 0x40},
+	{CCI_REG8(0x04cc), 0x20},
+	{CCI_REG8(0x04cd), 0x40},
+	{CCI_REG8(0x04ce), 0x10},
+	{CCI_REG8(0x04cf), 0x40},
+	{CCI_REG8(0x04d0), 0x01},
+	{CCI_REG8(0x04d1), 0x00},
+	{CCI_REG8(0x04d2), 0x03},
+	{CCI_REG8(0x04d3), 0x00},
+	{CCI_REG8(0x04d4), 0x0b},
+	{CCI_REG8(0x04d5), 0x40},
+	{CCI_REG8(0x04d6), 0x12},
+	{CCI_REG8(0x04d7), 0x00},
+	{CCI_REG8(0x04d8), 0x07},
+	{CCI_REG8(0x04d9), 0x40},
+	{CCI_REG8(0x04da), 0x06},
+	{CCI_REG8(0x04db), 0x00},
+	{CCI_REG8(0x04dc), 0x0b},
+	{CCI_REG8(0x04dd), 0x00},
+	{CCI_REG8(0x04de), 0x07},
+	{CCI_REG8(0x04df), 0x00},
+	{CCI_REG8(0x04e0), 0x04},
+	{CCI_REG8(0x04e1), 0x40},
+	{CCI_REG8(0x04e2), 0x0a},
+	{CCI_REG8(0x04e3), 0x00},
+	{CCI_REG8(0x04e4), 0x0b},
+	{CCI_REG8(0x04e5), 0x00},
+	{CCI_REG8(0x04e6), 0x0c},
+	{CCI_REG8(0x04e7), 0x00},
+	{CCI_REG8(0x04e8), 0x02},
+	{CCI_REG8(0x04e9), 0x40},
+	{CCI_REG8(0x04ea), 0x05},
+	{CCI_REG8(0x04eb), 0x00},
+	{CCI_REG8(0x04ec), 0x0d},
+	{CCI_REG8(0x04ed), 0x00},
+	{CCI_REG8(0x04ee), 0x0b},
+	{CCI_REG8(0x04ef), 0x00},
+	{CCI_REG8(0x04f2), 0x09},
+	{CCI_REG8(0x04f3), 0x00},
+	{CCI_REG8(0x04f4), 0x0a},
+	{CCI_REG8(0x04f5), 0x00},
+	{CCI_REG8(0x04f6), 0x0d},
+	{CCI_REG8(0x04f7), 0x00},
+	{CCI_REG8(0x04f8), 0x08},
+	{CCI_REG8(0x04f9), 0x40},
+	{CCI_REG8(0x04fa), 0x04},
+	{CCI_REG8(0x04fb), 0x00},
+	{CCI_REG8(0x04fc), 0x08},
+	{CCI_REG8(0x04fd), 0x00},
+	{CCI_REG8(0x04fe), 0x0a},
+	{CCI_REG8(0x04ff), 0x00},
+	{CCI_REG8(0x0500), 0x04},
+	{CCI_REG8(0x0501), 0x40},
+	{CCI_REG8(0x0504), 0x04},
+	{CCI_REG8(0x0505), 0x00},
+	{CCI_REG8(0x0506), 0x06},
+	{CCI_REG8(0x0507), 0x00},
+	{CCI_REG8(0x0508), 0x03},
+	{CCI_REG8(0x0509), 0x40},
+	{CCI_REG8(0x050a), 0x03},
+	{CCI_REG8(0x050b), 0x00},
+	{CCI_REG8(0x050c), 0x09},
+	{CCI_REG8(0x050d), 0x00},
+	{CCI_REG8(0x050e), 0x0f},
+	{CCI_REG8(0x050f), 0x00},
+	{CCI_REG8(0x0510), 0x08},
+	{CCI_REG8(0x0511), 0x40},
+	{CCI_REG8(0x0512), 0x0d},
+	{CCI_REG8(0x0513), 0x40},
+	{CCI_REG8(0x0514), 0x0b},
+	{CCI_REG8(0x0515), 0x40},
+	{CCI_REG8(0x0516), 0x01},
+	{CCI_REG8(0x0517), 0x00},
+	{CCI_REG8(0x051a), 0x01},
+	{CCI_REG8(0x051b), 0x00},
+	{CCI_REG8(0x051c), 0x0f},
+	{CCI_REG8(0x051d), 0x00},
+	{CCI_REG8(0x051e), 0x10},
+	{CCI_REG8(0x051f), 0x00},
+	{CCI_REG8(0x0570), 0x13},
+	{CCI_REG8(0x0571), 0x40},
+	{CCI_REG8(0x0572), 0x2f},
+	{CCI_REG8(0x0573), 0x00},
+	{CCI_REG8(0x0574), 0x04},
+	{CCI_REG8(0x0575), 0x00},
+	{CCI_REG8(0x0576), 0x11},
+	{CCI_REG8(0x0577), 0x00},
+	{CCI_REG8(0x0578), 0x1d},
+	{CCI_REG8(0x0579), 0x00},
+	{CCI_REG8(0x057a), 0x0a},
+	{CCI_REG8(0x057b), 0x00},
+	{CCI_REG8(0x057c), 0x18},
+	{CCI_REG8(0x057d), 0x00},
+	{CCI_REG8(0x057e), 0x21},
+	{CCI_REG8(0x057f), 0x00},
+	{CCI_REG8(0x0580), 0x69},
+	{CCI_REG8(0x0581), 0x00},
+	{CCI_REG8(0x0582), 0x6d},
+	{CCI_REG8(0x0583), 0x00},
+	{CCI_REG8(0x0584), 0x72},
+	{CCI_REG8(0x0585), 0x00},
+	{CCI_REG8(0x0586), 0x79},
+	{CCI_REG8(0x0587), 0x00},
+	{CCI_REG8(0x0588), 0x6f},
+	{CCI_REG8(0x0589), 0x00},
+	{CCI_REG8(0x058a), 0x6a},
+	{CCI_REG8(0x058b), 0x00},
+	{CCI_REG8(0x058c), 0x79},
+	{CCI_REG8(0x058d), 0x00},
+	{CCI_REG8(0x058e), 0x60},
+	{CCI_REG8(0x058f), 0x00},
+	{CCI_REG8(0x0590), 0x72},
+	{CCI_REG8(0x0591), 0x00},
+	{CCI_REG8(0x0592), 0x72},
+	{CCI_REG8(0x0593), 0x00},
+	{CCI_REG8(0x0594), 0x6f},
+	{CCI_REG8(0x0595), 0x00},
+	{CCI_REG8(0x0596), 0x7b},
+	{CCI_REG8(0x0597), 0x00},
+	{CCI_REG8(0x0598), 0x7b},
+	{CCI_REG8(0x0599), 0x00},
+	{CCI_REG8(0x059a), 0x69},
+	{CCI_REG8(0x059b), 0x00},
+	{CCI_REG8(0x059c), 0x7b},
+	{CCI_REG8(0x059d), 0x00},
+	{CCI_REG8(0x059e), 0x65},
+	{CCI_REG8(0x059f), 0x00},
+	{CCI_REG8(0x05a0), 0x79},
+	{CCI_REG8(0x05a1), 0x00},
+	{CCI_REG8(0x05a2), 0x7c},
+	{CCI_REG8(0x05a3), 0x00},
+	{CCI_REG8(0x05a4), 0x72},
+	{CCI_REG8(0x05a5), 0x00},
+	{CCI_REG8(0x05a6), 0x74},
+	{CCI_REG8(0x05a7), 0x00},
+	{CCI_REG8(0x05a8), 0x3e},
+	{CCI_REG8(0x05a9), 0x00},
+	{CCI_REG8(0x05aa), 0x39},
+	{CCI_REG8(0x05ab), 0x00},
+	{CCI_REG8(0x05ac), 0x48},
+	{CCI_REG8(0x05ad), 0x00},
+	{CCI_REG8(0x05ae), 0x50},
+	{CCI_REG8(0x05af), 0x00},
+	{CCI_REG8(0x05b0), 0x10},
+	{CCI_REG8(0x05b1), 0x40},
+	{CCI_REG8(0x05b2), 0x26},
+	{CCI_REG8(0x05b3), 0x40},
+	{CCI_REG8(0x05b4), 0x2c},
+	{CCI_REG8(0x05b5), 0x40},
+	{CCI_REG8(0x05b6), 0x24},
+	{CCI_REG8(0x05b7), 0x40},
+	{CCI_REG8(0x05b8), 0x2f},
+	{CCI_REG8(0x05b9), 0x00},
+	{CCI_REG8(0x05ba), 0x1c},
+	{CCI_REG8(0x05bb), 0x00},
+	{CCI_REG8(0x05bc), 0x33},
+	{CCI_REG8(0x05bd), 0x00},
+	{CCI_REG8(0x05be), 0x65},
+	{CCI_REG8(0x05bf), 0x00},
+	{CCI_REG8(0x05c0), 0x1b},
+	{CCI_REG8(0x05c1), 0x40},
+	{CCI_REG8(0x05c2), 0x3f},
+	{CCI_REG8(0x05c3), 0x40},
+	{CCI_REG8(0x05c4), 0x2f},
+	{CCI_REG8(0x05c5), 0x40},
+	{CCI_REG8(0x05c6), 0x33},
+	{CCI_REG8(0x05c7), 0x40},
+	{CCI_REG8(0x05c8), 0xc0},
+	{CCI_REG8(0x05c9), 0x40},
+	{CCI_REG8(0x05ca), 0xcb},
+	{CCI_REG8(0x05cb), 0x40},
+	{CCI_REG8(0x05cc), 0xcf},
+	{CCI_REG8(0x05cd), 0x40},
+	{CCI_REG8(0x05ce), 0xc1},
+	{CCI_REG8(0x05cf), 0x40},
+	{CCI_REG8(0x05d0), 0xe5},
+	{CCI_REG8(0x05d1), 0x40},
+	{CCI_REG8(0x05d2), 0xfa},
+	{CCI_REG8(0x05d3), 0x40},
+	{CCI_REG8(0x05d4), 0xfa},
+	{CCI_REG8(0x05d5), 0x40},
+	{CCI_REG8(0x05d6), 0xee},
+	{CCI_REG8(0x05d7), 0x40},
+	{CCI_REG8(0x05d8), 0xee},
+	{CCI_REG8(0x05d9), 0x40},
+	{CCI_REG8(0x05da), 0xfd},
+	{CCI_REG8(0x05db), 0x40},
+	{CCI_REG8(0x05dc), 0x02},
+	{CCI_REG8(0x05dd), 0x41},
+	{CCI_REG8(0x05de), 0xed},
+	{CCI_REG8(0x05df), 0x40},
+	{CCI_REG8(0x05e0), 0xef},
+	{CCI_REG8(0x05e1), 0x40},
+	{CCI_REG8(0x05e2), 0xfe},
+	{CCI_REG8(0x05e3), 0x40},
+	{CCI_REG8(0x05e4), 0xfc},
+	{CCI_REG8(0x05e5), 0x40},
+	{CCI_REG8(0x05e6), 0xf9},
+	{CCI_REG8(0x05e7), 0x40},
+	{CCI_REG8(0x05e8), 0xfa},
+	{CCI_REG8(0x05e9), 0x40},
+	{CCI_REG8(0x05ea), 0x02},
+	{CCI_REG8(0x05eb), 0x41},
+	{CCI_REG8(0x05ec), 0x06},
+	{CCI_REG8(0x05ed), 0x41},
+	{CCI_REG8(0x05ee), 0xf6},
+	{CCI_REG8(0x05ef), 0x40},
+	{CCI_REG8(0x05f0), 0xec},
+	{CCI_REG8(0x05f1), 0x40},
+	{CCI_REG8(0x05f2), 0xfe},
+	{CCI_REG8(0x05f3), 0x40},
+	{CCI_REG8(0x05f4), 0xfe},
+	{CCI_REG8(0x05f5), 0x40},
+	{CCI_REG8(0x05f6), 0xf5},
+	{CCI_REG8(0x05f7), 0x40},
+	{CCI_REG8(0x05f8), 0xd4},
+	{CCI_REG8(0x05f9), 0x40},
+	{CCI_REG8(0x05fa), 0xe3},
+	{CCI_REG8(0x05fb), 0x40},
+	{CCI_REG8(0x05fc), 0xe1},
+	{CCI_REG8(0x05fd), 0x40},
+	{CCI_REG8(0x05fe), 0xd9},
+	{CCI_REG8(0x05ff), 0x40},
+	{CCI_REG8(0x0600), 0x19},
+	{CCI_REG8(0x0601), 0x40},
+	{CCI_REG8(0x0602), 0x24},
+	{CCI_REG8(0x0603), 0x40},
+	{CCI_REG8(0x0604), 0x2a},
+	{CCI_REG8(0x0605), 0x40},
+	{CCI_REG8(0x0606), 0x1d},
+	{CCI_REG8(0x0607), 0x40},
+	{CCI_REG8(0x0608), 0xcd},
+	{CCI_REG8(0x0609), 0x40},
+	{CCI_REG8(0x060a), 0xd7},
+	{CCI_REG8(0x060b), 0x40},
+	{CCI_REG8(0x060c), 0xd1},
+	{CCI_REG8(0x060d), 0x40},
+	{CCI_REG8(0x060e), 0xdf},
+	{CCI_REG8(0x060f), 0x40},
+	{CCI_REG8(0x0610), 0x66},
+	{CCI_REG8(0x0611), 0x40},
+	{CCI_REG8(0x0612), 0x65},
+	{CCI_REG8(0x0613), 0x40},
+	{CCI_REG8(0x0614), 0x63},
+	{CCI_REG8(0x0615), 0x40},
+	{CCI_REG8(0x0616), 0x57},
+	{CCI_REG8(0x0617), 0x40},
+	{CCI_REG8(0x0618), 0xca},
+	{CCI_REG8(0x0619), 0x40},
+	{CCI_REG8(0x061a), 0xdc},
+	{CCI_REG8(0x061b), 0x40},
+	{CCI_REG8(0x061c), 0xdc},
+	{CCI_REG8(0x061d), 0x40},
+	{CCI_REG8(0x061e), 0xd2},
+	{CCI_REG8(0x061f), 0x40},
+	{CCI_REG8(0x0620), 0xf0},
+	{CCI_REG8(0x0621), 0x40},
+	{CCI_REG8(0x0622), 0x02},
+	{CCI_REG8(0x0623), 0x41},
+	{CCI_REG8(0x0624), 0xfe},
+	{CCI_REG8(0x0625), 0x40},
+	{CCI_REG8(0x0626), 0xef},
+	{CCI_REG8(0x0627), 0x40},
+	{CCI_REG8(0x0628), 0xfc},
+	{CCI_REG8(0x0629), 0x40},
+	{CCI_REG8(0x062a), 0x09},
+	{CCI_REG8(0x062b), 0x41},
+	{CCI_REG8(0x062c), 0x0a},
+	{CCI_REG8(0x062d), 0x41},
+	{CCI_REG8(0x062e), 0x06},
+	{CCI_REG8(0x062f), 0x41},
+	{CCI_REG8(0x0630), 0x0b},
+	{CCI_REG8(0x0631), 0x41},
+	{CCI_REG8(0x0632), 0x15},
+	{CCI_REG8(0x0633), 0x41},
+	{CCI_REG8(0x0634), 0x12},
+	{CCI_REG8(0x0635), 0x41},
+	{CCI_REG8(0x0636), 0x0c},
+	{CCI_REG8(0x0637), 0x41},
+	{CCI_REG8(0x0638), 0x08},
+	{CCI_REG8(0x0639), 0x41},
+	{CCI_REG8(0x063a), 0x19},
+	{CCI_REG8(0x063b), 0x41},
+	{CCI_REG8(0x063c), 0x15},
+	{CCI_REG8(0x063d), 0x41},
+	{CCI_REG8(0x063e), 0x14},
+	{CCI_REG8(0x063f), 0x41},
+	{CCI_REG8(0x0640), 0x00},
+	{CCI_REG8(0x0641), 0x41},
+	{CCI_REG8(0x0642), 0x09},
+	{CCI_REG8(0x0643), 0x41},
+	{CCI_REG8(0x0644), 0x09},
+	{CCI_REG8(0x0645), 0x41},
+	{CCI_REG8(0x0646), 0x01},
+	{CCI_REG8(0x0647), 0x41},
+	{CCI_REG8(0x0648), 0xe3},
+	{CCI_REG8(0x0649), 0x40},
+	{CCI_REG8(0x064a), 0xf7},
+	{CCI_REG8(0x064b), 0x40},
+	{CCI_REG8(0x064c), 0xf9},
+	{CCI_REG8(0x064d), 0x40},
+	{CCI_REG8(0x064e), 0xec},
+	{CCI_REG8(0x064f), 0x40},
+	{CCI_REG8(0x0650), 0x1f},
+	{CCI_REG8(0x0651), 0x40},
+	{CCI_REG8(0x0652), 0x2b},
+	{CCI_REG8(0x0653), 0x40},
+	{CCI_REG8(0x0654), 0x2e},
+	{CCI_REG8(0x0655), 0x40},
+	{CCI_REG8(0x0656), 0x23},
+	{CCI_REG8(0x0657), 0x40},
+	{CCI_REG8(0x0658), 0xda},
+	{CCI_REG8(0x0659), 0x40},
+	{CCI_REG8(0x065a), 0xee},
+	{CCI_REG8(0x065b), 0x40},
+	{CCI_REG8(0x065c), 0xf3},
+	{CCI_REG8(0x065d), 0x40},
+	{CCI_REG8(0x065e), 0xe4},
+	{CCI_REG8(0x065f), 0x40},
+	{CCI_REG8(0x0660), 0x34},
+	{CCI_REG8(0x0661), 0x40},
+	{CCI_REG8(0x0662), 0x34},
+	{CCI_REG8(0x0663), 0x40},
+	{CCI_REG8(0x0664), 0x39},
+	{CCI_REG8(0x0665), 0x40},
+	{CCI_REG8(0x0666), 0x33},
+	{CCI_REG8(0x0667), 0x40},
+	{CCI_REG8(0x0668), 0xa5},
+	{CCI_REG8(0x0669), 0x40},
+	{CCI_REG8(0x066a), 0xb7},
+	{CCI_REG8(0x066b), 0x40},
+	{CCI_REG8(0x066c), 0xb6},
+	{CCI_REG8(0x066d), 0x40},
+	{CCI_REG8(0x066e), 0xa7},
+	{CCI_REG8(0x066f), 0x40},
+	{CCI_REG8(0x0670), 0xc8},
+	{CCI_REG8(0x0671), 0x40},
+	{CCI_REG8(0x0672), 0xd6},
+	{CCI_REG8(0x0673), 0x40},
+	{CCI_REG8(0x0674), 0xdc},
+	{CCI_REG8(0x0675), 0x40},
+	{CCI_REG8(0x0676), 0xca},
+	{CCI_REG8(0x0677), 0x40},
+	{CCI_REG8(0x0678), 0xd9},
+	{CCI_REG8(0x0679), 0x40},
+	{CCI_REG8(0x067a), 0xe9},
+	{CCI_REG8(0x067b), 0x40},
+	{CCI_REG8(0x067c), 0xe6},
+	{CCI_REG8(0x067d), 0x40},
+	{CCI_REG8(0x067e), 0xda},
+	{CCI_REG8(0x067f), 0x40},
+	{CCI_REG8(0x0680), 0xe4},
+	{CCI_REG8(0x0681), 0x40},
+	{CCI_REG8(0x0682), 0xf1},
+	{CCI_REG8(0x0683), 0x40},
+	{CCI_REG8(0x0684), 0xf2},
+	{CCI_REG8(0x0685), 0x40},
+	{CCI_REG8(0x0686), 0xec},
+	{CCI_REG8(0x0687), 0x40},
+	{CCI_REG8(0x0688), 0xe3},
+	{CCI_REG8(0x0689), 0x40},
+	{CCI_REG8(0x068a), 0xf0},
+	{CCI_REG8(0x068b), 0x40},
+	{CCI_REG8(0x068c), 0xf2},
+	{CCI_REG8(0x068d), 0x40},
+	{CCI_REG8(0x068e), 0xe6},
+	{CCI_REG8(0x068f), 0x40},
+	{CCI_REG8(0x0690), 0xe5},
+	{CCI_REG8(0x0691), 0x40},
+	{CCI_REG8(0x0692), 0xed},
+	{CCI_REG8(0x0693), 0x40},
+	{CCI_REG8(0x0694), 0xf1},
+	{CCI_REG8(0x0695), 0x40},
+	{CCI_REG8(0x0696), 0xe7},
+	{CCI_REG8(0x0697), 0x40},
+	{CCI_REG8(0x0698), 0xc4},
+	{CCI_REG8(0x0699), 0x40},
+	{CCI_REG8(0x069a), 0xd3},
+	{CCI_REG8(0x069b), 0x40},
+	{CCI_REG8(0x069c), 0xd2},
+	{CCI_REG8(0x069d), 0x40},
+	{CCI_REG8(0x069e), 0xca},
+	{CCI_REG8(0x069f), 0x40},
+	{CCI_REG8(0x06a0), 0x08},
+	{CCI_REG8(0x06a1), 0x00},
+	{CCI_REG8(0x06a2), 0x08},
+	{CCI_REG8(0x06a3), 0x40},
+	{CCI_REG8(0x06a4), 0x09},
+	{CCI_REG8(0x06a5), 0x40},
+	{CCI_REG8(0x06a6), 0x05},
+	{CCI_REG8(0x06a7), 0x00},
+	{CCI_REG8(0x06a8), 0xb6},
+	{CCI_REG8(0x06a9), 0x40},
+	{CCI_REG8(0x06aa), 0xc9},
+	{CCI_REG8(0x06ab), 0x40},
+	{CCI_REG8(0x06ac), 0xc7},
+	{CCI_REG8(0x06ad), 0x40},
+	{CCI_REG8(0x06ae), 0xc1},
+	{CCI_REG8(0x06af), 0x40},
+	{CCI_REG8(0x06b0), 0x03},
+	{CCI_REG8(0x06b1), 0x00},
+	{CCI_REG8(0x06b2), 0x0c},
+	{CCI_REG8(0x06b3), 0x40},
+	{CCI_REG8(0x06b4), 0x0e},
+	{CCI_REG8(0x06b5), 0x40},
+	{CCI_REG8(0x06b6), 0x03},
+	{CCI_REG8(0x06b7), 0x40},
+	{CCI_REG8(0x06b8), 0x93},
+	{CCI_REG8(0x06b9), 0x40},
+	{CCI_REG8(0x06ba), 0xa5},
+	{CCI_REG8(0x06bb), 0x40},
+	{CCI_REG8(0x06bc), 0xa3},
+	{CCI_REG8(0x06bd), 0x40},
+	{CCI_REG8(0x06be), 0x9b},
+	{CCI_REG8(0x06bf), 0x40},
+	{CCI_REG8(0x06c0), 0xd0},
+	{CCI_REG8(0x06c1), 0x40},
+	{CCI_REG8(0x06c2), 0xe1},
+	{CCI_REG8(0x06c3), 0x40},
+	{CCI_REG8(0x06c4), 0xe3},
+	{CCI_REG8(0x06c5), 0x40},
+	{CCI_REG8(0x06c6), 0xd6},
+	{CCI_REG8(0x06c7), 0x40},
+	{CCI_REG8(0x06c8), 0xe3},
+	{CCI_REG8(0x06c9), 0x40},
+	{CCI_REG8(0x06ca), 0xf2},
+	{CCI_REG8(0x06cb), 0x40},
+	{CCI_REG8(0x06cc), 0xef},
+	{CCI_REG8(0x06cd), 0x40},
+	{CCI_REG8(0x06ce), 0xe1},
+	{CCI_REG8(0x06cf), 0x40},
+	{CCI_REG8(0x06d0), 0xe5},
+	{CCI_REG8(0x06d1), 0x40},
+	{CCI_REG8(0x06d2), 0xed},
+	{CCI_REG8(0x06d3), 0x40},
+	{CCI_REG8(0x06d4), 0xf2},
+	{CCI_REG8(0x06d5), 0x40},
+	{CCI_REG8(0x06d6), 0xec},
+	{CCI_REG8(0x06d7), 0x40},
+	{CCI_REG8(0x06d8), 0xef},
+	{CCI_REG8(0x06d9), 0x40},
+	{CCI_REG8(0x06da), 0x02},
+	{CCI_REG8(0x06db), 0x41},
+	{CCI_REG8(0x06dc), 0xfd},
+	{CCI_REG8(0x06dd), 0x40},
+	{CCI_REG8(0x06de), 0xf9},
+	{CCI_REG8(0x06df), 0x40},
+	{CCI_REG8(0x06e0), 0xf8},
+	{CCI_REG8(0x06e1), 0x40},
+	{CCI_REG8(0x06e2), 0x04},
+	{CCI_REG8(0x06e3), 0x41},
+	{CCI_REG8(0x06e4), 0x07},
+	{CCI_REG8(0x06e5), 0x41},
+	{CCI_REG8(0x06e6), 0xf6},
+	{CCI_REG8(0x06e7), 0x40},
+	{CCI_REG8(0x06e8), 0xd2},
+	{CCI_REG8(0x06e9), 0x40},
+	{CCI_REG8(0x06ea), 0xe2},
+	{CCI_REG8(0x06eb), 0x40},
+	{CCI_REG8(0x06ec), 0xe5},
+	{CCI_REG8(0x06ed), 0x40},
+	{CCI_REG8(0x06ee), 0xd7},
+	{CCI_REG8(0x06ef), 0x40},
+	{CCI_REG8(0x06f0), 0x0c},
+	{CCI_REG8(0x06f1), 0x00},
+	{CCI_REG8(0x06f2), 0x03},
+	{CCI_REG8(0x06f3), 0x00},
+	{CCI_REG8(0x06f4), 0x03},
+	{CCI_REG8(0x06f5), 0x40},
+	{CCI_REG8(0x06f6), 0x0b},
+	{CCI_REG8(0x06f7), 0x00},
+	{CCI_REG8(0x06f8), 0xc4},
+	{CCI_REG8(0x06f9), 0x40},
+	{CCI_REG8(0x06fa), 0xd5},
+	{CCI_REG8(0x06fb), 0x40},
+	{CCI_REG8(0x06fc), 0xdc},
+	{CCI_REG8(0x06fd), 0x40},
+	{CCI_REG8(0x06fe), 0xcb},
+	{CCI_REG8(0x06ff), 0x40},
+	{CCI_REG8(0x0700), 0x72},
+	{CCI_REG8(0x0701), 0x00},
+	{CCI_REG8(0x0702), 0x5e},
+	{CCI_REG8(0x0703), 0x00},
+	{CCI_REG8(0x0704), 0x7a},
+	{CCI_REG8(0x0705), 0x00},
+	{CCI_REG8(0x0706), 0x63},
+	{CCI_REG8(0x0707), 0x00},
+	{CCI_REG8(0x0708), 0x32},
+	{CCI_REG8(0x0709), 0x40},
+	{CCI_REG8(0x070a), 0x30},
+	{CCI_REG8(0x070b), 0x40},
+	{CCI_REG8(0x070c), 0x3c},
+	{CCI_REG8(0x070d), 0x40},
+	{CCI_REG8(0x070e), 0x28},
+	{CCI_REG8(0x070f), 0x40},
+	{CCI_REG8(0x0710), 0x53},
+	{CCI_REG8(0x0711), 0x40},
+	{CCI_REG8(0x0712), 0x6d},
+	{CCI_REG8(0x0713), 0x40},
+	{CCI_REG8(0x0714), 0x66},
+	{CCI_REG8(0x0715), 0x40},
+	{CCI_REG8(0x0716), 0x57},
+	{CCI_REG8(0x0717), 0x40},
+	{CCI_REG8(0x0718), 0x5d},
+	{CCI_REG8(0x0719), 0x40},
+	{CCI_REG8(0x071a), 0x6f},
+	{CCI_REG8(0x071b), 0x40},
+	{CCI_REG8(0x071c), 0x71},
+	{CCI_REG8(0x071d), 0x40},
+	{CCI_REG8(0x071e), 0x69},
+	{CCI_REG8(0x071f), 0x40},
+	{CCI_REG8(0x0720), 0x6f},
+	{CCI_REG8(0x0721), 0x40},
+	{CCI_REG8(0x0722), 0x7a},
+	{CCI_REG8(0x0723), 0x40},
+	{CCI_REG8(0x0724), 0x71},
+	{CCI_REG8(0x0725), 0x40},
+	{CCI_REG8(0x0726), 0x70},
+	{CCI_REG8(0x0727), 0x40},
+	{CCI_REG8(0x0728), 0x7d},
+	{CCI_REG8(0x0729), 0x40},
+	{CCI_REG8(0x072a), 0x82},
+	{CCI_REG8(0x072b), 0x40},
+	{CCI_REG8(0x072c), 0x8a},
+	{CCI_REG8(0x072d), 0x40},
+	{CCI_REG8(0x072e), 0x7f},
+	{CCI_REG8(0x072f), 0x40},
+	{CCI_REG8(0x0730), 0x71},
+	{CCI_REG8(0x0731), 0x40},
+	{CCI_REG8(0x0732), 0x86},
+	{CCI_REG8(0x0733), 0x40},
+	{CCI_REG8(0x0734), 0x85},
+	{CCI_REG8(0x0735), 0x40},
+	{CCI_REG8(0x0736), 0x7b},
+	{CCI_REG8(0x0737), 0x40},
+	{CCI_REG8(0x0738), 0x42},
+	{CCI_REG8(0x0739), 0x40},
+	{CCI_REG8(0x073a), 0x49},
+	{CCI_REG8(0x073b), 0x40},
+	{CCI_REG8(0x073c), 0x48},
+	{CCI_REG8(0x073d), 0x40},
+	{CCI_REG8(0x073e), 0x47},
+	{CCI_REG8(0x073f), 0x40},
+	{CCI_REG8(0x0740), 0x2c},
+	{CCI_REG8(0x0741), 0x00},
+	{CCI_REG8(0x0742), 0x17},
+	{CCI_REG8(0x0743), 0x00},
+	{CCI_REG8(0x0744), 0x13},
+	{CCI_REG8(0x0745), 0x00},
+	{CCI_REG8(0x0746), 0x22},
+	{CCI_REG8(0x0747), 0x00},
+	{CCI_REG8(0x0748), 0x42},
+	{CCI_REG8(0x0749), 0x40},
+	{CCI_REG8(0x074a), 0x41},
+	{CCI_REG8(0x074b), 0x40},
+	{CCI_REG8(0x074c), 0x36},
+	{CCI_REG8(0x074d), 0x40},
+	{CCI_REG8(0x074e), 0x4c},
+	{CCI_REG8(0x074f), 0x40},
+	{CCI_REG8(0x0750), 0x65},
+	{CCI_REG8(0x0751), 0x40},
+	{CCI_REG8(0x0752), 0x80},
+	{CCI_REG8(0x0753), 0x40},
+	{CCI_REG8(0x0754), 0xaa},
+	{CCI_REG8(0x0755), 0x40},
+	{CCI_REG8(0x0756), 0x6c},
+	{CCI_REG8(0x0757), 0x40},
+	{CCI_REG8(0x0758), 0x16},
+	{CCI_REG8(0x0759), 0x41},
+	{CCI_REG8(0x075a), 0x3b},
+	{CCI_REG8(0x075b), 0x41},
+	{CCI_REG8(0x075c), 0x2c},
+	{CCI_REG8(0x075d), 0x41},
+	{CCI_REG8(0x075e), 0x2e},
+	{CCI_REG8(0x075f), 0x41},
+	{CCI_REG8(0x0760), 0x67},
+	{CCI_REG8(0x0761), 0x41},
+	{CCI_REG8(0x0762), 0x6c},
+	{CCI_REG8(0x0763), 0x41},
+	{CCI_REG8(0x0764), 0x81},
+	{CCI_REG8(0x0765), 0x41},
+	{CCI_REG8(0x0766), 0x7b},
+	{CCI_REG8(0x0767), 0x41},
+	{CCI_REG8(0x0768), 0x90},
+	{CCI_REG8(0x0769), 0x41},
+	{CCI_REG8(0x076a), 0x9d},
+	{CCI_REG8(0x076b), 0x41},
+	{CCI_REG8(0x076c), 0x8d},
+	{CCI_REG8(0x076d), 0x41},
+	{CCI_REG8(0x076e), 0x76},
+	{CCI_REG8(0x076f), 0x41},
+	{CCI_REG8(0x0770), 0x6f},
+	{CCI_REG8(0x0771), 0x41},
+	{CCI_REG8(0x0772), 0x7e},
+	{CCI_REG8(0x0773), 0x41},
+	{CCI_REG8(0x0774), 0x94},
+	{CCI_REG8(0x0775), 0x41},
+	{CCI_REG8(0x0776), 0x92},
+	{CCI_REG8(0x0777), 0x41},
+	{CCI_REG8(0x0778), 0x98},
+	{CCI_REG8(0x0779), 0x41},
+	{CCI_REG8(0x077a), 0xab},
+	{CCI_REG8(0x077b), 0x41},
+	{CCI_REG8(0x077c), 0x9b},
+	{CCI_REG8(0x077d), 0x41},
+	{CCI_REG8(0x077e), 0x9b},
+	{CCI_REG8(0x077f), 0x41},
+	{CCI_REG8(0x0780), 0x96},
+	{CCI_REG8(0x0781), 0x41},
+	{CCI_REG8(0x0782), 0xa4},
+	{CCI_REG8(0x0783), 0x41},
+	{CCI_REG8(0x0784), 0xab},
+	{CCI_REG8(0x0785), 0x41},
+	{CCI_REG8(0x0786), 0x96},
+	{CCI_REG8(0x0787), 0x41},
+	{CCI_REG8(0x0788), 0x85},
+	{CCI_REG8(0x0789), 0x41},
+	{CCI_REG8(0x078a), 0x94},
+	{CCI_REG8(0x078b), 0x41},
+	{CCI_REG8(0x078c), 0x9e},
+	{CCI_REG8(0x078d), 0x41},
+	{CCI_REG8(0x078e), 0x84},
+	{CCI_REG8(0x078f), 0x41},
+	{CCI_REG8(0x0790), 0x07},
+	{CCI_REG8(0x0791), 0x40},
+	{CCI_REG8(0x0792), 0x15},
+	{CCI_REG8(0x0793), 0x40},
+	{CCI_REG8(0x0794), 0x17},
+	{CCI_REG8(0x0795), 0x40},
+	{CCI_REG8(0x0798), 0x58},
+	{CCI_REG8(0x0799), 0x41},
+	{CCI_REG8(0x079a), 0x86},
+	{CCI_REG8(0x079b), 0x41},
+	{CCI_REG8(0x079c), 0xa1},
+	{CCI_REG8(0x079d), 0x41},
+	{CCI_REG8(0x079e), 0x6b},
+	{CCI_REG8(0x079f), 0x41},
+	{CCI_REG8(0x07f0), 0x12},
+	{CCI_REG8(0x07f1), 0x40},
+	{CCI_REG8(0x07f2), 0x44},
+	{CCI_REG8(0x07f3), 0x40},
+	{CCI_REG8(0x07f4), 0x55},
+	{CCI_REG8(0x07f5), 0x40},
+	{CCI_REG8(0x07f6), 0x16},
+	{CCI_REG8(0x07f7), 0x40},
+	{CCI_REG8(0x07f8), 0x42},
+	{CCI_REG8(0x07f9), 0x40},
+	{CCI_REG8(0x07fa), 0x4e},
+	{CCI_REG8(0x07fb), 0x40},
+	{CCI_REG8(0x07fc), 0x4d},
+	{CCI_REG8(0x07fd), 0x40},
+	{CCI_REG8(0x07fe), 0x42},
+	{CCI_REG8(0x07ff), 0x40},
+	{CCI_REG8(0x0800), 0x31},
+	{CCI_REG8(0x0801), 0x40},
+	{CCI_REG8(0x0802), 0x4b},
+	{CCI_REG8(0x0803), 0x40},
+	{CCI_REG8(0x0804), 0x48},
+	{CCI_REG8(0x0805), 0x40},
+	{CCI_REG8(0x0806), 0x30},
+	{CCI_REG8(0x0807), 0x40},
+	{CCI_REG8(0x0808), 0x3c},
+	{CCI_REG8(0x0809), 0x40},
+	{CCI_REG8(0x080a), 0x4e},
+	{CCI_REG8(0x080b), 0x40},
+	{CCI_REG8(0x080c), 0x46},
+	{CCI_REG8(0x080d), 0x40},
+	{CCI_REG8(0x080e), 0x3b},
+	{CCI_REG8(0x080f), 0x40},
+	{CCI_REG8(0x0810), 0x32},
+	{CCI_REG8(0x0811), 0x40},
+	{CCI_REG8(0x0812), 0x43},
+	{CCI_REG8(0x0813), 0x40},
+	{CCI_REG8(0x0814), 0x44},
+	{CCI_REG8(0x0815), 0x40},
+	{CCI_REG8(0x0816), 0x30},
+	{CCI_REG8(0x0817), 0x40},
+	{CCI_REG8(0x0818), 0x33},
+	{CCI_REG8(0x0819), 0x40},
+	{CCI_REG8(0x081a), 0x48},
+	{CCI_REG8(0x081b), 0x40},
+	{CCI_REG8(0x081c), 0x43},
+	{CCI_REG8(0x081d), 0x40},
+	{CCI_REG8(0x081e), 0x39},
+	{CCI_REG8(0x081f), 0x40},
+	{CCI_REG8(0x0820), 0x28},
+	{CCI_REG8(0x0821), 0x40},
+	{CCI_REG8(0x0822), 0x39},
+	{CCI_REG8(0x0823), 0x40},
+	{CCI_REG8(0x0824), 0x38},
+	{CCI_REG8(0x0825), 0x40},
+	{CCI_REG8(0x0826), 0x28},
+	{CCI_REG8(0x0827), 0x40},
+	{CCI_REG8(0x0828), 0x26},
+	{CCI_REG8(0x0829), 0x40},
+	{CCI_REG8(0x082a), 0x3c},
+	{CCI_REG8(0x082b), 0x40},
+	{CCI_REG8(0x082c), 0x3b},
+	{CCI_REG8(0x082d), 0x40},
+	{CCI_REG8(0x082e), 0x21},
+	{CCI_REG8(0x082f), 0x40},
+	{CCI_REG8(0x0830), 0x18},
+	{CCI_REG8(0x0831), 0x40},
+	{CCI_REG8(0x0832), 0x26},
+	{CCI_REG8(0x0833), 0x40},
+	{CCI_REG8(0x0834), 0x27},
+	{CCI_REG8(0x0835), 0x40},
+	{CCI_REG8(0x0836), 0x13},
+	{CCI_REG8(0x0837), 0x40},
+	{CCI_REG8(0x0838), 0x18},
+	{CCI_REG8(0x0839), 0x40},
+	{CCI_REG8(0x083a), 0x3d},
+	{CCI_REG8(0x083b), 0x40},
+	{CCI_REG8(0x083c), 0x42},
+	{CCI_REG8(0x083d), 0x40},
+	{CCI_REG8(0x083e), 0x2a},
+	{CCI_REG8(0x083f), 0x40},
+	{CCI_REG8(0x0840), 0x34},
+	{CCI_REG8(0x0841), 0x40},
+	{CCI_REG8(0x0842), 0x47},
+	{CCI_REG8(0x0843), 0x40},
+	{CCI_REG8(0x0844), 0x3e},
+	{CCI_REG8(0x0845), 0x40},
+	{CCI_REG8(0x0846), 0x33},
+	{CCI_REG8(0x0847), 0x40},
+	{CCI_REG8(0x0848), 0x4f},
+	{CCI_REG8(0x0849), 0x40},
+	{CCI_REG8(0x084a), 0x68},
+	{CCI_REG8(0x084b), 0x40},
+	{CCI_REG8(0x084c), 0x65},
+	{CCI_REG8(0x084d), 0x40},
+	{CCI_REG8(0x084e), 0x4a},
+	{CCI_REG8(0x084f), 0x40},
+	{CCI_REG8(0x0850), 0x62},
+	{CCI_REG8(0x0851), 0x40},
+	{CCI_REG8(0x0852), 0x73},
+	{CCI_REG8(0x0853), 0x40},
+	{CCI_REG8(0x0854), 0x71},
+	{CCI_REG8(0x0855), 0x40},
+	{CCI_REG8(0x0856), 0x5f},
+	{CCI_REG8(0x0857), 0x40},
+	{CCI_REG8(0x0858), 0x63},
+	{CCI_REG8(0x0859), 0x40},
+	{CCI_REG8(0x085a), 0x74},
+	{CCI_REG8(0x085b), 0x40},
+	{CCI_REG8(0x085c), 0x71},
+	{CCI_REG8(0x085d), 0x40},
+	{CCI_REG8(0x085e), 0x62},
+	{CCI_REG8(0x085f), 0x40},
+	{CCI_REG8(0x0860), 0x61},
+	{CCI_REG8(0x0861), 0x40},
+	{CCI_REG8(0x0862), 0x70},
+	{CCI_REG8(0x0863), 0x40},
+	{CCI_REG8(0x0864), 0x6d},
+	{CCI_REG8(0x0865), 0x40},
+	{CCI_REG8(0x0866), 0x5f},
+	{CCI_REG8(0x0867), 0x40},
+	{CCI_REG8(0x0868), 0x59},
+	{CCI_REG8(0x0869), 0x40},
+	{CCI_REG8(0x086a), 0x66},
+	{CCI_REG8(0x086b), 0x40},
+	{CCI_REG8(0x086c), 0x61},
+	{CCI_REG8(0x086d), 0x40},
+	{CCI_REG8(0x086e), 0x55},
+	{CCI_REG8(0x086f), 0x40},
+	{CCI_REG8(0x0870), 0x3e},
+	{CCI_REG8(0x0871), 0x40},
+	{CCI_REG8(0x0872), 0x51},
+	{CCI_REG8(0x0873), 0x40},
+	{CCI_REG8(0x0874), 0x4f},
+	{CCI_REG8(0x0875), 0x40},
+	{CCI_REG8(0x0876), 0x3d},
+	{CCI_REG8(0x0877), 0x40},
+	{CCI_REG8(0x0878), 0x27},
+	{CCI_REG8(0x0879), 0x40},
+	{CCI_REG8(0x087a), 0x37},
+	{CCI_REG8(0x087b), 0x40},
+	{CCI_REG8(0x087c), 0x34},
+	{CCI_REG8(0x087d), 0x40},
+	{CCI_REG8(0x087e), 0x26},
+	{CCI_REG8(0x087f), 0x40},
+	{CCI_REG8(0x0880), 0x1b},
+	{CCI_REG8(0x0881), 0x00},
+	{CCI_REG8(0x0882), 0x05},
+	{CCI_REG8(0x0883), 0x00},
+	{CCI_REG8(0x0884), 0x07},
+	{CCI_REG8(0x0885), 0x00},
+	{CCI_REG8(0x0886), 0x19},
+	{CCI_REG8(0x0887), 0x00},
+	{CCI_REG8(0x0888), 0x29},
+	{CCI_REG8(0x0889), 0x40},
+	{CCI_REG8(0x088a), 0x33},
+	{CCI_REG8(0x088b), 0x40},
+	{CCI_REG8(0x088c), 0x2e},
+	{CCI_REG8(0x088d), 0x40},
+	{CCI_REG8(0x088e), 0x21},
+	{CCI_REG8(0x088f), 0x40},
+	{CCI_REG8(0x0890), 0x33},
+	{CCI_REG8(0x0891), 0x40},
+	{CCI_REG8(0x0892), 0x4e},
+	{CCI_REG8(0x0893), 0x40},
+	{CCI_REG8(0x0894), 0x4f},
+	{CCI_REG8(0x0895), 0x40},
+	{CCI_REG8(0x0896), 0x30},
+	{CCI_REG8(0x0897), 0x40},
+	{CCI_REG8(0x0898), 0x4f},
+	{CCI_REG8(0x0899), 0x40},
+	{CCI_REG8(0x089a), 0x64},
+	{CCI_REG8(0x089b), 0x40},
+	{CCI_REG8(0x089c), 0x61},
+	{CCI_REG8(0x089d), 0x40},
+	{CCI_REG8(0x089e), 0x4b},
+	{CCI_REG8(0x089f), 0x40},
+	{CCI_REG8(0x08a0), 0x5a},
+	{CCI_REG8(0x08a1), 0x40},
+	{CCI_REG8(0x08a2), 0x6f},
+	{CCI_REG8(0x08a3), 0x40},
+	{CCI_REG8(0x08a4), 0x6b},
+	{CCI_REG8(0x08a5), 0x40},
+	{CCI_REG8(0x08a6), 0x58},
+	{CCI_REG8(0x08a7), 0x40},
+	{CCI_REG8(0x08a8), 0x60},
+	{CCI_REG8(0x08a9), 0x40},
+	{CCI_REG8(0x08aa), 0x71},
+	{CCI_REG8(0x08ab), 0x40},
+	{CCI_REG8(0x08ac), 0x6e},
+	{CCI_REG8(0x08ad), 0x40},
+	{CCI_REG8(0x08ae), 0x5e},
+	{CCI_REG8(0x08af), 0x40},
+	{CCI_REG8(0x08b0), 0x5d},
+	{CCI_REG8(0x08b1), 0x40},
+	{CCI_REG8(0x08b2), 0x6d},
+	{CCI_REG8(0x08b3), 0x40},
+	{CCI_REG8(0x08b4), 0x6a},
+	{CCI_REG8(0x08b5), 0x40},
+	{CCI_REG8(0x08b6), 0x5c},
+	{CCI_REG8(0x08b7), 0x40},
+	{CCI_REG8(0x08b8), 0x5b},
+	{CCI_REG8(0x08b9), 0x40},
+	{CCI_REG8(0x08ba), 0x6a},
+	{CCI_REG8(0x08bb), 0x40},
+	{CCI_REG8(0x08bc), 0x68},
+	{CCI_REG8(0x08bd), 0x40},
+	{CCI_REG8(0x08be), 0x59},
+	{CCI_REG8(0x08bf), 0x40},
+	{CCI_REG8(0x08c0), 0x4b},
+	{CCI_REG8(0x08c1), 0x40},
+	{CCI_REG8(0x08c2), 0x5a},
+	{CCI_REG8(0x08c3), 0x40},
+	{CCI_REG8(0x08c4), 0x57},
+	{CCI_REG8(0x08c5), 0x40},
+	{CCI_REG8(0x08c6), 0x46},
+	{CCI_REG8(0x08c7), 0x40},
+	{CCI_REG8(0x08c8), 0x35},
+	{CCI_REG8(0x08c9), 0x40},
+	{CCI_REG8(0x08ca), 0x47},
+	{CCI_REG8(0x08cb), 0x40},
+	{CCI_REG8(0x08cc), 0x45},
+	{CCI_REG8(0x08cd), 0x40},
+	{CCI_REG8(0x08ce), 0x35},
+	{CCI_REG8(0x08cf), 0x40},
+	{CCI_REG8(0x08d0), 0x14},
+	{CCI_REG8(0x08d1), 0x00},
+	{CCI_REG8(0x08d2), 0x01},
+	{CCI_REG8(0x08d3), 0x00},
+	{CCI_REG8(0x08d4), 0x04},
+	{CCI_REG8(0x08d5), 0x00},
+	{CCI_REG8(0x08d6), 0x19},
+	{CCI_REG8(0x08d7), 0x00},
+	{CCI_REG8(0x08d8), 0x2f},
+	{CCI_REG8(0x08d9), 0x40},
+	{CCI_REG8(0x08da), 0x43},
+	{CCI_REG8(0x08db), 0x40},
+	{CCI_REG8(0x08dc), 0x40},
+	{CCI_REG8(0x08dd), 0x40},
+	{CCI_REG8(0x08de), 0x35},
+	{CCI_REG8(0x08df), 0x40},
+	{CCI_REG8(0x08e0), 0x1f},
+	{CCI_REG8(0x08e1), 0x40},
+	{CCI_REG8(0x08e2), 0x34},
+	{CCI_REG8(0x08e3), 0x40},
+	{CCI_REG8(0x08e4), 0x2e},
+	{CCI_REG8(0x08e5), 0x40},
+	{CCI_REG8(0x08e6), 0x1b},
+	{CCI_REG8(0x08e7), 0x40},
+	{CCI_REG8(0x08e8), 0x32},
+	{CCI_REG8(0x08e9), 0x40},
+	{CCI_REG8(0x08ea), 0x46},
+	{CCI_REG8(0x08eb), 0x40},
+	{CCI_REG8(0x08ec), 0x45},
+	{CCI_REG8(0x08ed), 0x40},
+	{CCI_REG8(0x08ee), 0x2f},
+	{CCI_REG8(0x08ef), 0x40},
+	{CCI_REG8(0x08f0), 0x42},
+	{CCI_REG8(0x08f1), 0x40},
+	{CCI_REG8(0x08f2), 0x54},
+	{CCI_REG8(0x08f3), 0x40},
+	{CCI_REG8(0x08f4), 0x50},
+	{CCI_REG8(0x08f5), 0x40},
+	{CCI_REG8(0x08f6), 0x3e},
+	{CCI_REG8(0x08f7), 0x40},
+	{CCI_REG8(0x08f8), 0x48},
+	{CCI_REG8(0x08f9), 0x40},
+	{CCI_REG8(0x08fa), 0x57},
+	{CCI_REG8(0x08fb), 0x40},
+	{CCI_REG8(0x08fc), 0x54},
+	{CCI_REG8(0x08fd), 0x40},
+	{CCI_REG8(0x08fe), 0x46},
+	{CCI_REG8(0x08ff), 0x40},
+	{CCI_REG8(0x0900), 0x4d},
+	{CCI_REG8(0x0901), 0x40},
+	{CCI_REG8(0x0902), 0x59},
+	{CCI_REG8(0x0903), 0x40},
+	{CCI_REG8(0x0904), 0x55},
+	{CCI_REG8(0x0905), 0x40},
+	{CCI_REG8(0x0906), 0x49},
+	{CCI_REG8(0x0907), 0x40},
+	{CCI_REG8(0x0908), 0x45},
+	{CCI_REG8(0x0909), 0x40},
+	{CCI_REG8(0x090a), 0x51},
+	{CCI_REG8(0x090b), 0x40},
+	{CCI_REG8(0x090c), 0x4f},
+	{CCI_REG8(0x090d), 0x40},
+	{CCI_REG8(0x090e), 0x43},
+	{CCI_REG8(0x090f), 0x40},
+	{CCI_REG8(0x0910), 0x32},
+	{CCI_REG8(0x0911), 0x40},
+	{CCI_REG8(0x0912), 0x45},
+	{CCI_REG8(0x0913), 0x40},
+	{CCI_REG8(0x0914), 0x3f},
+	{CCI_REG8(0x0915), 0x40},
+	{CCI_REG8(0x0916), 0x30},
+	{CCI_REG8(0x0917), 0x40},
+	{CCI_REG8(0x0918), 0x23},
+	{CCI_REG8(0x0919), 0x40},
+	{CCI_REG8(0x091a), 0x32},
+	{CCI_REG8(0x091b), 0x40},
+	{CCI_REG8(0x091c), 0x31},
+	{CCI_REG8(0x091d), 0x40},
+	{CCI_REG8(0x091e), 0x1e},
+	{CCI_REG8(0x091f), 0x40},
+	{CCI_REG8(0x0920), 0x28},
+	{CCI_REG8(0x0921), 0x00},
+	{CCI_REG8(0x0922), 0x13},
+	{CCI_REG8(0x0923), 0x00},
+	{CCI_REG8(0x0924), 0x15},
+	{CCI_REG8(0x0925), 0x00},
+	{CCI_REG8(0x0926), 0x24},
+	{CCI_REG8(0x0927), 0x00},
+	{CCI_REG8(0x0928), 0x22},
+	{CCI_REG8(0x0929), 0x40},
+	{CCI_REG8(0x092a), 0x2e},
+	{CCI_REG8(0x092b), 0x40},
+	{CCI_REG8(0x092c), 0x2e},
+	{CCI_REG8(0x092d), 0x40},
+	{CCI_REG8(0x092e), 0x1e},
+	{CCI_REG8(0x092f), 0x40},
+	{CCI_REG8(0x0930), 0x05},
+	{CCI_REG8(0x0931), 0x00},
+	{CCI_REG8(0x0932), 0x10},
+	{CCI_REG8(0x0933), 0x40},
+	{CCI_REG8(0x0934), 0x13},
+	{CCI_REG8(0x0935), 0x40},
+	{CCI_REG8(0x0936), 0x07},
+	{CCI_REG8(0x0937), 0x00},
+	{CCI_REG8(0x0938), 0x2e},
+	{CCI_REG8(0x0939), 0x40},
+	{CCI_REG8(0x093a), 0x40},
+	{CCI_REG8(0x093b), 0x40},
+	{CCI_REG8(0x093c), 0x3c},
+	{CCI_REG8(0x093d), 0x40},
+	{CCI_REG8(0x093e), 0x2a},
+	{CCI_REG8(0x093f), 0x40},
+	{CCI_REG8(0x0940), 0x41},
+	{CCI_REG8(0x0941), 0x40},
+	{CCI_REG8(0x0942), 0x4f},
+	{CCI_REG8(0x0943), 0x40},
+	{CCI_REG8(0x0944), 0x4d},
+	{CCI_REG8(0x0945), 0x40},
+	{CCI_REG8(0x0946), 0x40},
+	{CCI_REG8(0x0947), 0x40},
+	{CCI_REG8(0x0948), 0x48},
+	{CCI_REG8(0x0949), 0x40},
+	{CCI_REG8(0x094a), 0x55},
+	{CCI_REG8(0x094b), 0x40},
+	{CCI_REG8(0x094c), 0x52},
+	{CCI_REG8(0x094d), 0x40},
+	{CCI_REG8(0x094e), 0x45},
+	{CCI_REG8(0x094f), 0x40},
+	{CCI_REG8(0x0950), 0x42},
+	{CCI_REG8(0x0951), 0x40},
+	{CCI_REG8(0x0952), 0x4f},
+	{CCI_REG8(0x0953), 0x40},
+	{CCI_REG8(0x0954), 0x4c},
+	{CCI_REG8(0x0955), 0x40},
+	{CCI_REG8(0x0956), 0x41},
+	{CCI_REG8(0x0957), 0x40},
+	{CCI_REG8(0x0958), 0x44},
+	{CCI_REG8(0x0959), 0x40},
+	{CCI_REG8(0x095a), 0x4d},
+	{CCI_REG8(0x095b), 0x40},
+	{CCI_REG8(0x095c), 0x49},
+	{CCI_REG8(0x095d), 0x40},
+	{CCI_REG8(0x095e), 0x40},
+	{CCI_REG8(0x095f), 0x40},
+	{CCI_REG8(0x0960), 0x31},
+	{CCI_REG8(0x0961), 0x40},
+	{CCI_REG8(0x0962), 0x3e},
+	{CCI_REG8(0x0963), 0x40},
+	{CCI_REG8(0x0964), 0x3c},
+	{CCI_REG8(0x0965), 0x40},
+	{CCI_REG8(0x0966), 0x30},
+	{CCI_REG8(0x0967), 0x40},
+	{CCI_REG8(0x0968), 0x23},
+	{CCI_REG8(0x0969), 0x40},
+	{CCI_REG8(0x096a), 0x32},
+	{CCI_REG8(0x096b), 0x40},
+	{CCI_REG8(0x096c), 0x2f},
+	{CCI_REG8(0x096d), 0x40},
+	{CCI_REG8(0x096e), 0x24},
+	{CCI_REG8(0x096f), 0x40},
+	{CCI_REG8(0x0970), 0x26},
+	{CCI_REG8(0x0971), 0x00},
+	{CCI_REG8(0x0972), 0x17},
+	{CCI_REG8(0x0973), 0x00},
+	{CCI_REG8(0x0974), 0x18},
+	{CCI_REG8(0x0975), 0x00},
+	{CCI_REG8(0x0976), 0x29},
+	{CCI_REG8(0x0977), 0x00},
+	{CCI_REG8(0x0978), 0x23},
+	{CCI_REG8(0x0979), 0x40},
+	{CCI_REG8(0x097a), 0x30},
+	{CCI_REG8(0x097b), 0x40},
+	{CCI_REG8(0x097c), 0x2e},
+	{CCI_REG8(0x097d), 0x40},
+	{CCI_REG8(0x097e), 0x22},
+	{CCI_REG8(0x097f), 0x40},
+	{CCI_REG8(0x0980), 0x19},
+	{CCI_REG8(0x0981), 0x00},
+	{CCI_REG8(0x0982), 0x0e},
+	{CCI_REG8(0x0983), 0x00},
+	{CCI_REG8(0x0984), 0x16},
+	{CCI_REG8(0x0985), 0x00},
+	{CCI_REG8(0x0986), 0x29},
+	{CCI_REG8(0x0987), 0x00},
+	{CCI_REG8(0x0988), 0x15},
+	{CCI_REG8(0x0989), 0x40},
+	{CCI_REG8(0x098a), 0x2c},
+	{CCI_REG8(0x098b), 0x40},
+	{CCI_REG8(0x098c), 0x27},
+	{CCI_REG8(0x098d), 0x40},
+	{CCI_REG8(0x098e), 0x17},
+	{CCI_REG8(0x098f), 0x40},
+	{CCI_REG8(0x0990), 0x33},
+	{CCI_REG8(0x0991), 0x40},
+	{CCI_REG8(0x0992), 0x40},
+	{CCI_REG8(0x0993), 0x40},
+	{CCI_REG8(0x0994), 0x3c},
+	{CCI_REG8(0x0995), 0x40},
+	{CCI_REG8(0x0996), 0x2e},
+	{CCI_REG8(0x0997), 0x40},
+	{CCI_REG8(0x0998), 0x3a},
+	{CCI_REG8(0x0999), 0x40},
+	{CCI_REG8(0x099a), 0x46},
+	{CCI_REG8(0x099b), 0x40},
+	{CCI_REG8(0x099c), 0x41},
+	{CCI_REG8(0x099d), 0x40},
+	{CCI_REG8(0x099e), 0x38},
+	{CCI_REG8(0x099f), 0x40},
+	{CCI_REG8(0x09a0), 0x3c},
+	{CCI_REG8(0x09a1), 0x40},
+	{CCI_REG8(0x09a2), 0x44},
+	{CCI_REG8(0x09a3), 0x40},
+	{CCI_REG8(0x09a4), 0x41},
+	{CCI_REG8(0x09a5), 0x40},
+	{CCI_REG8(0x09a6), 0x37},
+	{CCI_REG8(0x09a7), 0x40},
+	{CCI_REG8(0x09a8), 0x39},
+	{CCI_REG8(0x09a9), 0x40},
+	{CCI_REG8(0x09aa), 0x42},
+	{CCI_REG8(0x09ab), 0x40},
+	{CCI_REG8(0x09ac), 0x3f},
+	{CCI_REG8(0x09ad), 0x40},
+	{CCI_REG8(0x09ae), 0x35},
+	{CCI_REG8(0x09af), 0x40},
+	{CCI_REG8(0x09b0), 0x29},
+	{CCI_REG8(0x09b1), 0x40},
+	{CCI_REG8(0x09b2), 0x35},
+	{CCI_REG8(0x09b3), 0x40},
+	{CCI_REG8(0x09b4), 0x30},
+	{CCI_REG8(0x09b5), 0x40},
+	{CCI_REG8(0x09b6), 0x27},
+	{CCI_REG8(0x09b7), 0x40},
+	{CCI_REG8(0x09b8), 0x15},
+	{CCI_REG8(0x09b9), 0x40},
+	{CCI_REG8(0x09ba), 0x21},
+	{CCI_REG8(0x09bb), 0x40},
+	{CCI_REG8(0x09bc), 0x1d},
+	{CCI_REG8(0x09bd), 0x40},
+	{CCI_REG8(0x09be), 0x10},
+	{CCI_REG8(0x09bf), 0x40},
+	{CCI_REG8(0x09c0), 0x30},
+	{CCI_REG8(0x09c1), 0x00},
+	{CCI_REG8(0x09c2), 0x22},
+	{CCI_REG8(0x09c3), 0x00},
+	{CCI_REG8(0x09c4), 0x25},
+	{CCI_REG8(0x09c5), 0x00},
+	{CCI_REG8(0x09c6), 0x2d},
+	{CCI_REG8(0x09c7), 0x00},
+	{CCI_REG8(0x09c8), 0x16},
+	{CCI_REG8(0x09c9), 0x40},
+	{CCI_REG8(0x09ca), 0x23},
+	{CCI_REG8(0x09cb), 0x40},
+	{CCI_REG8(0x09cc), 0x17},
+	{CCI_REG8(0x09cd), 0x40},
+	{CCI_REG8(0x09ce), 0x0e},
+	{CCI_REG8(0x09cf), 0x40},
+	{CCI_REG8(0x09d0), 0x10},
+	{CCI_REG8(0x09d1), 0x40},
+	{CCI_REG8(0x09d2), 0x43},
+	{CCI_REG8(0x09d3), 0x40},
+	{CCI_REG8(0x09d4), 0x41},
+	{CCI_REG8(0x09d5), 0x40},
+	{CCI_REG8(0x09d6), 0x34},
+	{CCI_REG8(0x09d7), 0x40},
+	{CCI_REG8(0x09d8), 0x4e},
+	{CCI_REG8(0x09d9), 0x40},
+	{CCI_REG8(0x09da), 0x55},
+	{CCI_REG8(0x09db), 0x40},
+	{CCI_REG8(0x09dc), 0x58},
+	{CCI_REG8(0x09dd), 0x40},
+	{CCI_REG8(0x09de), 0x3c},
+	{CCI_REG8(0x09df), 0x40},
+	{CCI_REG8(0x09e0), 0x51},
+	{CCI_REG8(0x09e1), 0x40},
+	{CCI_REG8(0x09e2), 0x66},
+	{CCI_REG8(0x09e3), 0x40},
+	{CCI_REG8(0x09e4), 0x64},
+	{CCI_REG8(0x09e5), 0x40},
+	{CCI_REG8(0x09e6), 0x59},
+	{CCI_REG8(0x09e7), 0x40},
+	{CCI_REG8(0x09e8), 0x5d},
+	{CCI_REG8(0x09e9), 0x40},
+	{CCI_REG8(0x09ea), 0x68},
+	{CCI_REG8(0x09eb), 0x40},
+	{CCI_REG8(0x09ec), 0x6c},
+	{CCI_REG8(0x09ed), 0x40},
+	{CCI_REG8(0x09ee), 0x56},
+	{CCI_REG8(0x09ef), 0x40},
+	{CCI_REG8(0x09f0), 0x4a},
+	{CCI_REG8(0x09f1), 0x40},
+	{CCI_REG8(0x09f2), 0x62},
+	{CCI_REG8(0x09f3), 0x40},
+	{CCI_REG8(0x09f4), 0x59},
+	{CCI_REG8(0x09f5), 0x40},
+	{CCI_REG8(0x09f6), 0x4f},
+	{CCI_REG8(0x09f7), 0x40},
+	{CCI_REG8(0x09f8), 0x56},
+	{CCI_REG8(0x09f9), 0x40},
+	{CCI_REG8(0x09fa), 0x60},
+	{CCI_REG8(0x09fb), 0x40},
+	{CCI_REG8(0x09fc), 0x61},
+	{CCI_REG8(0x09fd), 0x40},
+	{CCI_REG8(0x09fe), 0x53},
+	{CCI_REG8(0x09ff), 0x40},
+	{CCI_REG8(0x0a00), 0x3e},
+	{CCI_REG8(0x0a01), 0x40},
+	{CCI_REG8(0x0a02), 0x4d},
+	{CCI_REG8(0x0a03), 0x40},
+	{CCI_REG8(0x0a04), 0x4b},
+	{CCI_REG8(0x0a05), 0x40},
+	{CCI_REG8(0x0a06), 0x44},
+	{CCI_REG8(0x0a07), 0x40},
+	{CCI_REG8(0x0a08), 0x34},
+	{CCI_REG8(0x0a09), 0x40},
+	{CCI_REG8(0x0a0a), 0x46},
+	{CCI_REG8(0x0a0b), 0x40},
+	{CCI_REG8(0x0a0c), 0x48},
+	{CCI_REG8(0x0a0d), 0x40},
+	{CCI_REG8(0x0a0e), 0x3a},
+	{CCI_REG8(0x0a0f), 0x40},
+	{CCI_REG8(0x0a10), 0x1c},
+	{CCI_REG8(0x0a11), 0x00},
+	{CCI_REG8(0x0a12), 0x06},
+	{CCI_REG8(0x0a13), 0x00},
+	{CCI_REG8(0x0a14), 0x09},
+	{CCI_REG8(0x0a15), 0x00},
+	{CCI_REG8(0x0a16), 0x25},
+	{CCI_REG8(0x0a17), 0x00},
+	{CCI_REG8(0x0a18), 0x32},
+	{CCI_REG8(0x0a19), 0x40},
+	{CCI_REG8(0x0a1a), 0x45},
+	{CCI_REG8(0x0a1b), 0x40},
+	{CCI_REG8(0x0a1c), 0x51},
+	{CCI_REG8(0x0a1d), 0x40},
+	{CCI_REG8(0x0a1e), 0x36},
+	{CCI_REG8(0x0a1f), 0x40},
+	{CCI_REG8(0x0a70), 0x29},
+	{CCI_REG8(0x0a71), 0x00},
+	{CCI_REG8(0x0a72), 0x28},
+	{CCI_REG8(0x0a73), 0x00},
+	{CCI_REG8(0x0a74), 0x16},
+	{CCI_REG8(0x0a75), 0x00},
+	{CCI_REG8(0x0a76), 0x27},
+	{CCI_REG8(0x0a77), 0x00},
+	{CCI_REG8(0x0a78), 0x11},
+	{CCI_REG8(0x0a79), 0x00},
+	{CCI_REG8(0x0a7a), 0x18},
+	{CCI_REG8(0x0a7b), 0x00},
+	{CCI_REG8(0x0a7c), 0x11},
+	{CCI_REG8(0x0a7d), 0x00},
+	{CCI_REG8(0x0a7e), 0x10},
+	{CCI_REG8(0x0a7f), 0x00},
+	{CCI_REG8(0x0a80), 0x11},
+	{CCI_REG8(0x0a81), 0x00},
+	{CCI_REG8(0x0a82), 0x19},
+	{CCI_REG8(0x0a83), 0x00},
+	{CCI_REG8(0x0a84), 0x10},
+	{CCI_REG8(0x0a85), 0x00},
+	{CCI_REG8(0x0a86), 0x0d},
+	{CCI_REG8(0x0a87), 0x00},
+	{CCI_REG8(0x0a88), 0x08},
+	{CCI_REG8(0x0a89), 0x00},
+	{CCI_REG8(0x0a8a), 0x10},
+	{CCI_REG8(0x0a8b), 0x00},
+	{CCI_REG8(0x0a8c), 0x08},
+	{CCI_REG8(0x0a8d), 0x00},
+	{CCI_REG8(0x0a8e), 0x03},
+	{CCI_REG8(0x0a8f), 0x00},
+	{CCI_REG8(0x0a90), 0x04},
+	{CCI_REG8(0x0a91), 0x40},
+	{CCI_REG8(0x0a92), 0x09},
+	{CCI_REG8(0x0a93), 0x00},
+	{CCI_REG8(0x0a96), 0x03},
+	{CCI_REG8(0x0a97), 0x40},
+	{CCI_REG8(0x0a98), 0x06},
+	{CCI_REG8(0x0a99), 0x40},
+	{CCI_REG8(0x0a9a), 0x08},
+	{CCI_REG8(0x0a9b), 0x00},
+	{CCI_REG8(0x0a9e), 0x08},
+	{CCI_REG8(0x0a9f), 0x40},
+	{CCI_REG8(0x0aa0), 0x02},
+	{CCI_REG8(0x0aa1), 0x00},
+	{CCI_REG8(0x0aa2), 0x0b},
+	{CCI_REG8(0x0aa3), 0x00},
+	{CCI_REG8(0x0aa4), 0x02},
+	{CCI_REG8(0x0aa5), 0x00},
+	{CCI_REG8(0x0aa6), 0x01},
+	{CCI_REG8(0x0aa7), 0x00},
+	{CCI_REG8(0x0aa8), 0x02},
+	{CCI_REG8(0x0aa9), 0x00},
+	{CCI_REG8(0x0aaa), 0x0e},
+	{CCI_REG8(0x0aab), 0x00},
+	{CCI_REG8(0x0aac), 0x06},
+	{CCI_REG8(0x0aad), 0x00},
+	{CCI_REG8(0x0aae), 0x02},
+	{CCI_REG8(0x0aaf), 0x00},
+	{CCI_REG8(0x0ab0), 0x08},
+	{CCI_REG8(0x0ab1), 0x00},
+	{CCI_REG8(0x0ab2), 0x15},
+	{CCI_REG8(0x0ab3), 0x00},
+	{CCI_REG8(0x0ab4), 0x0a},
+	{CCI_REG8(0x0ab5), 0x00},
+	{CCI_REG8(0x0ab6), 0x07},
+	{CCI_REG8(0x0ab7), 0x00},
+	{CCI_REG8(0x0ab8), 0x02},
+	{CCI_REG8(0x0ab9), 0x00},
+	{CCI_REG8(0x0aba), 0x12},
+	{CCI_REG8(0x0abb), 0x00},
+	{CCI_REG8(0x0abc), 0x09},
+	{CCI_REG8(0x0abd), 0x00},
+	{CCI_REG8(0x0abe), 0x06},
+	{CCI_REG8(0x0abf), 0x00},
+	{CCI_REG8(0x0ac0), 0x25},
+	{CCI_REG8(0x0ac1), 0x00},
+	{CCI_REG8(0x0ac2), 0x2c},
+	{CCI_REG8(0x0ac3), 0x00},
+	{CCI_REG8(0x0ac4), 0x22},
+	{CCI_REG8(0x0ac5), 0x00},
+	{CCI_REG8(0x0ac6), 0x20},
+	{CCI_REG8(0x0ac7), 0x00},
+	{CCI_REG8(0x0ac8), 0x18},
+	{CCI_REG8(0x0ac9), 0x00},
+	{CCI_REG8(0x0aca), 0x26},
+	{CCI_REG8(0x0acb), 0x00},
+	{CCI_REG8(0x0acc), 0x1b},
+	{CCI_REG8(0x0acd), 0x00},
+	{CCI_REG8(0x0ace), 0x19},
+	{CCI_REG8(0x0acf), 0x00},
+	{CCI_REG8(0x0ad0), 0x15},
+	{CCI_REG8(0x0ad1), 0x00},
+	{CCI_REG8(0x0ad2), 0x23},
+	{CCI_REG8(0x0ad3), 0x00},
+	{CCI_REG8(0x0ad4), 0x18},
+	{CCI_REG8(0x0ad5), 0x00},
+	{CCI_REG8(0x0ad6), 0x14},
+	{CCI_REG8(0x0ad7), 0x00},
+	{CCI_REG8(0x0ad8), 0x0e},
+	{CCI_REG8(0x0ad9), 0x00},
+	{CCI_REG8(0x0ada), 0x1c},
+	{CCI_REG8(0x0adb), 0x00},
+	{CCI_REG8(0x0adc), 0x13},
+	{CCI_REG8(0x0add), 0x00},
+	{CCI_REG8(0x0ade), 0x0f},
+	{CCI_REG8(0x0adf), 0x00},
+	{CCI_REG8(0x0ae0), 0x07},
+	{CCI_REG8(0x0ae1), 0x00},
+	{CCI_REG8(0x0ae2), 0x17},
+	{CCI_REG8(0x0ae3), 0x00},
+	{CCI_REG8(0x0ae4), 0x0c},
+	{CCI_REG8(0x0ae5), 0x00},
+	{CCI_REG8(0x0ae6), 0x07},
+	{CCI_REG8(0x0ae7), 0x00},
+	{CCI_REG8(0x0ae8), 0x04},
+	{CCI_REG8(0x0ae9), 0x00},
+	{CCI_REG8(0x0aea), 0x16},
+	{CCI_REG8(0x0aeb), 0x00},
+	{CCI_REG8(0x0aec), 0x0b},
+	{CCI_REG8(0x0aed), 0x00},
+	{CCI_REG8(0x0aee), 0x04},
+	{CCI_REG8(0x0aef), 0x00},
+	{CCI_REG8(0x0af0), 0x06},
+	{CCI_REG8(0x0af1), 0x00},
+	{CCI_REG8(0x0af2), 0x17},
+	{CCI_REG8(0x0af3), 0x00},
+	{CCI_REG8(0x0af4), 0x0d},
+	{CCI_REG8(0x0af5), 0x00},
+	{CCI_REG8(0x0af6), 0x06},
+	{CCI_REG8(0x0af7), 0x00},
+	{CCI_REG8(0x0af8), 0x08},
+	{CCI_REG8(0x0af9), 0x00},
+	{CCI_REG8(0x0afa), 0x1b},
+	{CCI_REG8(0x0afb), 0x00},
+	{CCI_REG8(0x0afc), 0x10},
+	{CCI_REG8(0x0afd), 0x00},
+	{CCI_REG8(0x0afe), 0x08},
+	{CCI_REG8(0x0aff), 0x00},
+	{CCI_REG8(0x0b00), 0x11},
+	{CCI_REG8(0x0b01), 0x00},
+	{CCI_REG8(0x0b02), 0x21},
+	{CCI_REG8(0x0b03), 0x00},
+	{CCI_REG8(0x0b04), 0x16},
+	{CCI_REG8(0x0b05), 0x00},
+	{CCI_REG8(0x0b06), 0x0f},
+	{CCI_REG8(0x0b07), 0x00},
+	{CCI_REG8(0x0b08), 0x07},
+	{CCI_REG8(0x0b09), 0x00},
+	{CCI_REG8(0x0b0a), 0x1a},
+	{CCI_REG8(0x0b0b), 0x00},
+	{CCI_REG8(0x0b0c), 0x0f},
+	{CCI_REG8(0x0b0d), 0x00},
+	{CCI_REG8(0x0b0e), 0x07},
+	{CCI_REG8(0x0b0f), 0x00},
+	{CCI_REG8(0x0b10), 0x15},
+	{CCI_REG8(0x0b11), 0x00},
+	{CCI_REG8(0x0b12), 0x1f},
+	{CCI_REG8(0x0b13), 0x00},
+	{CCI_REG8(0x0b14), 0x17},
+	{CCI_REG8(0x0b15), 0x00},
+	{CCI_REG8(0x0b16), 0x15},
+	{CCI_REG8(0x0b17), 0x00},
+	{CCI_REG8(0x0b18), 0x12},
+	{CCI_REG8(0x0b19), 0x00},
+	{CCI_REG8(0x0b1a), 0x1d},
+	{CCI_REG8(0x0b1b), 0x00},
+	{CCI_REG8(0x0b1c), 0x13},
+	{CCI_REG8(0x0b1d), 0x00},
+	{CCI_REG8(0x0b1e), 0x0f},
+	{CCI_REG8(0x0b1f), 0x00},
+	{CCI_REG8(0x0b20), 0x10},
+	{CCI_REG8(0x0b21), 0x00},
+	{CCI_REG8(0x0b22), 0x1c},
+	{CCI_REG8(0x0b23), 0x00},
+	{CCI_REG8(0x0b24), 0x13},
+	{CCI_REG8(0x0b25), 0x00},
+	{CCI_REG8(0x0b26), 0x0e},
+	{CCI_REG8(0x0b27), 0x00},
+	{CCI_REG8(0x0b28), 0x0a},
+	{CCI_REG8(0x0b29), 0x00},
+	{CCI_REG8(0x0b2a), 0x17},
+	{CCI_REG8(0x0b2b), 0x00},
+	{CCI_REG8(0x0b2c), 0x0d},
+	{CCI_REG8(0x0b2d), 0x00},
+	{CCI_REG8(0x0b2e), 0x07},
+	{CCI_REG8(0x0b2f), 0x00},
+	{CCI_REG8(0x0b30), 0x02},
+	{CCI_REG8(0x0b31), 0x00},
+	{CCI_REG8(0x0b32), 0x11},
+	{CCI_REG8(0x0b33), 0x00},
+	{CCI_REG8(0x0b34), 0x07},
+	{CCI_REG8(0x0b35), 0x00},
+	{CCI_REG8(0x0b36), 0x00},
+	{CCI_REG8(0x0b37), 0x40},
+	{CCI_REG8(0x0b38), 0x01},
+	{CCI_REG8(0x0b39), 0x40},
+	{CCI_REG8(0x0b3a), 0x10},
+	{CCI_REG8(0x0b3b), 0x00},
+	{CCI_REG8(0x0b3c), 0x06},
+	{CCI_REG8(0x0b3d), 0x00},
+	{CCI_REG8(0x0b3e), 0x03},
+	{CCI_REG8(0x0b3f), 0x40},
+	{CCI_REG8(0x0b40), 0x03},
+	{CCI_REG8(0x0b41), 0x00},
+	{CCI_REG8(0x0b42), 0x12},
+	{CCI_REG8(0x0b43), 0x00},
+	{CCI_REG8(0x0b44), 0x07},
+	{CCI_REG8(0x0b45), 0x00},
+	{CCI_REG8(0x0b46), 0x01},
+	{CCI_REG8(0x0b47), 0x00},
+	{CCI_REG8(0x0b48), 0x04},
+	{CCI_REG8(0x0b49), 0x00},
+	{CCI_REG8(0x0b4a), 0x15},
+	{CCI_REG8(0x0b4b), 0x00},
+	{CCI_REG8(0x0b4c), 0x0a},
+	{CCI_REG8(0x0b4d), 0x00},
+	{CCI_REG8(0x0b4e), 0x01},
+	{CCI_REG8(0x0b4f), 0x00},
+	{CCI_REG8(0x0b50), 0x09},
+	{CCI_REG8(0x0b51), 0x00},
+	{CCI_REG8(0x0b52), 0x1b},
+	{CCI_REG8(0x0b53), 0x00},
+	{CCI_REG8(0x0b54), 0x0e},
+	{CCI_REG8(0x0b55), 0x00},
+	{CCI_REG8(0x0b56), 0x07},
+	{CCI_REG8(0x0b57), 0x00},
+	{CCI_REG8(0x0b58), 0x04},
+	{CCI_REG8(0x0b59), 0x00},
+	{CCI_REG8(0x0b5a), 0x15},
+	{CCI_REG8(0x0b5b), 0x00},
+	{CCI_REG8(0x0b5c), 0x0b},
+	{CCI_REG8(0x0b5d), 0x00},
+	{CCI_REG8(0x0b5e), 0x01},
+	{CCI_REG8(0x0b5f), 0x00},
+	{CCI_REG8(0x0b60), 0x0a},
+	{CCI_REG8(0x0b61), 0x00},
+	{CCI_REG8(0x0b62), 0x1b},
+	{CCI_REG8(0x0b63), 0x00},
+	{CCI_REG8(0x0b64), 0x0d},
+	{CCI_REG8(0x0b65), 0x00},
+	{CCI_REG8(0x0b66), 0x09},
+	{CCI_REG8(0x0b67), 0x00},
+	{CCI_REG8(0x0b68), 0x09},
+	{CCI_REG8(0x0b69), 0x00},
+	{CCI_REG8(0x0b6a), 0x18},
+	{CCI_REG8(0x0b6b), 0x00},
+	{CCI_REG8(0x0b6c), 0x0d},
+	{CCI_REG8(0x0b6d), 0x00},
+	{CCI_REG8(0x0b6e), 0x0a},
+	{CCI_REG8(0x0b6f), 0x00},
+	{CCI_REG8(0x0b70), 0x0b},
+	{CCI_REG8(0x0b71), 0x00},
+	{CCI_REG8(0x0b72), 0x1a},
+	{CCI_REG8(0x0b73), 0x00},
+	{CCI_REG8(0x0b74), 0x10},
+	{CCI_REG8(0x0b75), 0x00},
+	{CCI_REG8(0x0b76), 0x0b},
+	{CCI_REG8(0x0b77), 0x00},
+	{CCI_REG8(0x0b78), 0x07},
+	{CCI_REG8(0x0b79), 0x00},
+	{CCI_REG8(0x0b7a), 0x16},
+	{CCI_REG8(0x0b7b), 0x00},
+	{CCI_REG8(0x0b7c), 0x0c},
+	{CCI_REG8(0x0b7d), 0x00},
+	{CCI_REG8(0x0b7e), 0x07},
+	{CCI_REG8(0x0b7f), 0x00},
+	{CCI_REG8(0x0b80), 0x01},
+	{CCI_REG8(0x0b81), 0x40},
+	{CCI_REG8(0x0b82), 0x11},
+	{CCI_REG8(0x0b83), 0x00},
+	{CCI_REG8(0x0b84), 0x07},
+	{CCI_REG8(0x0b85), 0x00},
+	{CCI_REG8(0x0b88), 0x02},
+	{CCI_REG8(0x0b89), 0x40},
+	{CCI_REG8(0x0b8a), 0x12},
+	{CCI_REG8(0x0b8b), 0x00},
+	{CCI_REG8(0x0b8c), 0x08},
+	{CCI_REG8(0x0b8d), 0x00},
+	{CCI_REG8(0x0b8e), 0x01},
+	{CCI_REG8(0x0b8f), 0x40},
+	{CCI_REG8(0x0b90), 0x03},
+	{CCI_REG8(0x0b91), 0x00},
+	{CCI_REG8(0x0b92), 0x14},
+	{CCI_REG8(0x0b93), 0x00},
+	{CCI_REG8(0x0b94), 0x09},
+	{CCI_REG8(0x0b95), 0x00},
+	{CCI_REG8(0x0b96), 0x02},
+	{CCI_REG8(0x0b97), 0x00},
+	{CCI_REG8(0x0b98), 0x02},
+	{CCI_REG8(0x0b99), 0x00},
+	{CCI_REG8(0x0b9a), 0x16},
+	{CCI_REG8(0x0b9b), 0x00},
+	{CCI_REG8(0x0b9c), 0x0b},
+	{CCI_REG8(0x0b9d), 0x00},
+	{CCI_REG8(0x0b9e), 0x01},
+	{CCI_REG8(0x0b9f), 0x00},
+	{CCI_REG8(0x0ba0), 0x07},
+	{CCI_REG8(0x0ba1), 0x00},
+	{CCI_REG8(0x0ba2), 0x1a},
+	{CCI_REG8(0x0ba3), 0x00},
+	{CCI_REG8(0x0ba4), 0x0f},
+	{CCI_REG8(0x0ba5), 0x00},
+	{CCI_REG8(0x0ba6), 0x06},
+	{CCI_REG8(0x0ba7), 0x00},
+	{CCI_REG8(0x0ba8), 0x02},
+	{CCI_REG8(0x0ba9), 0x00},
+	{CCI_REG8(0x0baa), 0x16},
+	{CCI_REG8(0x0bab), 0x00},
+	{CCI_REG8(0x0bac), 0x0b},
+	{CCI_REG8(0x0bad), 0x00},
+	{CCI_REG8(0x0bae), 0x01},
+	{CCI_REG8(0x0baf), 0x40},
+	{CCI_REG8(0x0bb0), 0x16},
+	{CCI_REG8(0x0bb1), 0x00},
+	{CCI_REG8(0x0bb2), 0x20},
+	{CCI_REG8(0x0bb3), 0x00},
+	{CCI_REG8(0x0bb4), 0x10},
+	{CCI_REG8(0x0bb5), 0x00},
+	{CCI_REG8(0x0bb6), 0x10},
+	{CCI_REG8(0x0bb7), 0x00},
+	{CCI_REG8(0x0bb8), 0x13},
+	{CCI_REG8(0x0bb9), 0x00},
+	{CCI_REG8(0x0bba), 0x20},
+	{CCI_REG8(0x0bbb), 0x00},
+	{CCI_REG8(0x0bbc), 0x16},
+	{CCI_REG8(0x0bbd), 0x00},
+	{CCI_REG8(0x0bbe), 0x12},
+	{CCI_REG8(0x0bbf), 0x00},
+	{CCI_REG8(0x0bc0), 0x1a},
+	{CCI_REG8(0x0bc1), 0x00},
+	{CCI_REG8(0x0bc2), 0x28},
+	{CCI_REG8(0x0bc3), 0x00},
+	{CCI_REG8(0x0bc4), 0x1d},
+	{CCI_REG8(0x0bc5), 0x00},
+	{CCI_REG8(0x0bc6), 0x18},
+	{CCI_REG8(0x0bc7), 0x00},
+	{CCI_REG8(0x0bc8), 0x17},
+	{CCI_REG8(0x0bc9), 0x00},
+	{CCI_REG8(0x0bca), 0x25},
+	{CCI_REG8(0x0bcb), 0x00},
+	{CCI_REG8(0x0bcc), 0x1c},
+	{CCI_REG8(0x0bcd), 0x00},
+	{CCI_REG8(0x0bce), 0x17},
+	{CCI_REG8(0x0bcf), 0x00},
+	{CCI_REG8(0x0bd0), 0x12},
+	{CCI_REG8(0x0bd1), 0x00},
+	{CCI_REG8(0x0bd2), 0x23},
+	{CCI_REG8(0x0bd3), 0x00},
+	{CCI_REG8(0x0bd4), 0x17},
+	{CCI_REG8(0x0bd5), 0x00},
+	{CCI_REG8(0x0bd6), 0x10},
+	{CCI_REG8(0x0bd7), 0x00},
+	{CCI_REG8(0x0bd8), 0x12},
+	{CCI_REG8(0x0bd9), 0x00},
+	{CCI_REG8(0x0bda), 0x23},
+	{CCI_REG8(0x0bdb), 0x00},
+	{CCI_REG8(0x0bdc), 0x19},
+	{CCI_REG8(0x0bdd), 0x00},
+	{CCI_REG8(0x0bde), 0x11},
+	{CCI_REG8(0x0bdf), 0x00},
+	{CCI_REG8(0x0be0), 0x17},
+	{CCI_REG8(0x0be1), 0x00},
+	{CCI_REG8(0x0be2), 0x27},
+	{CCI_REG8(0x0be3), 0x00},
+	{CCI_REG8(0x0be4), 0x1c},
+	{CCI_REG8(0x0be5), 0x00},
+	{CCI_REG8(0x0be6), 0x16},
+	{CCI_REG8(0x0be7), 0x00},
+	{CCI_REG8(0x0be8), 0x17},
+	{CCI_REG8(0x0be9), 0x00},
+	{CCI_REG8(0x0bea), 0x29},
+	{CCI_REG8(0x0beb), 0x00},
+	{CCI_REG8(0x0bec), 0x1e},
+	{CCI_REG8(0x0bed), 0x00},
+	{CCI_REG8(0x0bee), 0x16},
+	{CCI_REG8(0x0bef), 0x00},
+	{CCI_REG8(0x0bf0), 0x1c},
+	{CCI_REG8(0x0bf1), 0x00},
+	{CCI_REG8(0x0bf2), 0x2d},
+	{CCI_REG8(0x0bf3), 0x00},
+	{CCI_REG8(0x0bf4), 0x20},
+	{CCI_REG8(0x0bf5), 0x00},
+	{CCI_REG8(0x0bf6), 0x19},
+	{CCI_REG8(0x0bf7), 0x00},
+	{CCI_REG8(0x0bf8), 0x15},
+	{CCI_REG8(0x0bf9), 0x00},
+	{CCI_REG8(0x0bfa), 0x28},
+	{CCI_REG8(0x0bfb), 0x00},
+	{CCI_REG8(0x0bfc), 0x1d},
+	{CCI_REG8(0x0bfd), 0x00},
+	{CCI_REG8(0x0bfe), 0x13},
+	{CCI_REG8(0x0bff), 0x00},
+	{CCI_REG8(0x0c00), 0x05},
+	{CCI_REG8(0x0c01), 0x00},
+	{CCI_REG8(0x0c02), 0x0e},
+	{CCI_REG8(0x0c03), 0x00},
+	{CCI_REG8(0x0c04), 0x10},
+	{CCI_REG8(0x0c05), 0x00},
+	{CCI_REG8(0x0c06), 0x05},
+	{CCI_REG8(0x0c07), 0x00},
+	{CCI_REG8(0x0c08), 0x09},
+	{CCI_REG8(0x0c09), 0x00},
+	{CCI_REG8(0x0c0a), 0x18},
+	{CCI_REG8(0x0c0b), 0x00},
+	{CCI_REG8(0x0c0c), 0x0d},
+	{CCI_REG8(0x0c0d), 0x00},
+	{CCI_REG8(0x0c0e), 0x06},
+	{CCI_REG8(0x0c0f), 0x00},
+	{CCI_REG8(0x0c10), 0x14},
+	{CCI_REG8(0x0c11), 0x00},
+	{CCI_REG8(0x0c12), 0x22},
+	{CCI_REG8(0x0c13), 0x00},
+	{CCI_REG8(0x0c14), 0x1a},
+	{CCI_REG8(0x0c15), 0x00},
+	{CCI_REG8(0x0c16), 0x13},
+	{CCI_REG8(0x0c17), 0x00},
+	{CCI_REG8(0x0c18), 0x18},
+	{CCI_REG8(0x0c19), 0x00},
+	{CCI_REG8(0x0c1a), 0x26},
+	{CCI_REG8(0x0c1b), 0x00},
+	{CCI_REG8(0x0c1c), 0x1b},
+	{CCI_REG8(0x0c1d), 0x00},
+	{CCI_REG8(0x0c1e), 0x14},
+	{CCI_REG8(0x0c1f), 0x00},
+	{CCI_REG8(0x0c20), 0x10},
+	{CCI_REG8(0x0c21), 0x00},
+	{CCI_REG8(0x0c22), 0x22},
+	{CCI_REG8(0x0c23), 0x00},
+	{CCI_REG8(0x0c24), 0x19},
+	{CCI_REG8(0x0c25), 0x00},
+	{CCI_REG8(0x0c26), 0x10},
+	{CCI_REG8(0x0c27), 0x00},
+	{CCI_REG8(0x0c28), 0x14},
+	{CCI_REG8(0x0c29), 0x00},
+	{CCI_REG8(0x0c2a), 0x26},
+	{CCI_REG8(0x0c2b), 0x00},
+	{CCI_REG8(0x0c2c), 0x1d},
+	{CCI_REG8(0x0c2d), 0x00},
+	{CCI_REG8(0x0c2e), 0x14},
+	{CCI_REG8(0x0c2f), 0x00},
+	{CCI_REG8(0x0c30), 0x1b},
+	{CCI_REG8(0x0c31), 0x00},
+	{CCI_REG8(0x0c32), 0x2c},
+	{CCI_REG8(0x0c33), 0x00},
+	{CCI_REG8(0x0c34), 0x22},
+	{CCI_REG8(0x0c35), 0x00},
+	{CCI_REG8(0x0c36), 0x1b},
+	{CCI_REG8(0x0c37), 0x00},
+	{CCI_REG8(0x0c38), 0x1c},
+	{CCI_REG8(0x0c39), 0x00},
+	{CCI_REG8(0x0c3a), 0x2d},
+	{CCI_REG8(0x0c3b), 0x00},
+	{CCI_REG8(0x0c3c), 0x22},
+	{CCI_REG8(0x0c3d), 0x00},
+	{CCI_REG8(0x0c3e), 0x17},
+	{CCI_REG8(0x0c3f), 0x00},
+	{CCI_REG8(0x0c40), 0x20},
+	{CCI_REG8(0x0c41), 0x00},
+	{CCI_REG8(0x0c42), 0x33},
+	{CCI_REG8(0x0c43), 0x00},
+	{CCI_REG8(0x0c44), 0x29},
+	{CCI_REG8(0x0c45), 0x00},
+	{CCI_REG8(0x0c46), 0x22},
+	{CCI_REG8(0x0c47), 0x00},
+	{CCI_REG8(0x0c48), 0x1b},
+	{CCI_REG8(0x0c49), 0x00},
+	{CCI_REG8(0x0c4a), 0x2e},
+	{CCI_REG8(0x0c4b), 0x00},
+	{CCI_REG8(0x0c4c), 0x23},
+	{CCI_REG8(0x0c4d), 0x00},
+	{CCI_REG8(0x0c4e), 0x18},
+	{CCI_REG8(0x0c4f), 0x00},
+	{CCI_REG8(0x0c50), 0x27},
+	{CCI_REG8(0x0c51), 0x00},
+	{CCI_REG8(0x0c52), 0x38},
+	{CCI_REG8(0x0c53), 0x00},
+	{CCI_REG8(0x0c54), 0x0d},
+	{CCI_REG8(0x0c55), 0x00},
+	{CCI_REG8(0x0c56), 0x1d},
+	{CCI_REG8(0x0c57), 0x00},
+	{CCI_REG8(0x0c58), 0x1b},
+	{CCI_REG8(0x0c59), 0x00},
+	{CCI_REG8(0x0c5a), 0x25},
+	{CCI_REG8(0x0c5b), 0x00},
+	{CCI_REG8(0x0c5c), 0x1e},
+	{CCI_REG8(0x0c5d), 0x00},
+	{CCI_REG8(0x0c5e), 0x22},
+	{CCI_REG8(0x0c5f), 0x00},
+	{CCI_REG8(0x0c60), 0x1b},
+	{CCI_REG8(0x0c61), 0x00},
+	{CCI_REG8(0x0c62), 0x2d},
+	{CCI_REG8(0x0c63), 0x00},
+	{CCI_REG8(0x0c64), 0x1f},
+	{CCI_REG8(0x0c65), 0x00},
+	{CCI_REG8(0x0c66), 0x1e},
+	{CCI_REG8(0x0c67), 0x00},
+	{CCI_REG8(0x0c68), 0x10},
+	{CCI_REG8(0x0c69), 0x00},
+	{CCI_REG8(0x0c6a), 0x21},
+	{CCI_REG8(0x0c6b), 0x00},
+	{CCI_REG8(0x0c6c), 0x17},
+	{CCI_REG8(0x0c6d), 0x00},
+	{CCI_REG8(0x0c6e), 0x19},
+	{CCI_REG8(0x0c6f), 0x00},
+	{CCI_REG8(0x0c70), 0x11},
+	{CCI_REG8(0x0c71), 0x00},
+	{CCI_REG8(0x0c72), 0x20},
+	{CCI_REG8(0x0c73), 0x00},
+	{CCI_REG8(0x0c74), 0x12},
+	{CCI_REG8(0x0c75), 0x00},
+	{CCI_REG8(0x0c76), 0x0c},
+	{CCI_REG8(0x0c77), 0x00},
+	{CCI_REG8(0x0c78), 0x0d},
+	{CCI_REG8(0x0c79), 0x00},
+	{CCI_REG8(0x0c7a), 0x1b},
+	{CCI_REG8(0x0c7b), 0x00},
+	{CCI_REG8(0x0c7c), 0x0e},
+	{CCI_REG8(0x0c7d), 0x00},
+	{CCI_REG8(0x0c7e), 0x0a},
+	{CCI_REG8(0x0c7f), 0x00},
+	{CCI_REG8(0x0c80), 0x0e},
+	{CCI_REG8(0x0c81), 0x00},
+	{CCI_REG8(0x0c82), 0x1f},
+	{CCI_REG8(0x0c83), 0x00},
+	{CCI_REG8(0x0c84), 0x13},
+	{CCI_REG8(0x0c85), 0x00},
+	{CCI_REG8(0x0c86), 0x0e},
+	{CCI_REG8(0x0c87), 0x00},
+	{CCI_REG8(0x0c88), 0x0c},
+	{CCI_REG8(0x0c89), 0x00},
+	{CCI_REG8(0x0c8a), 0x20},
+	{CCI_REG8(0x0c8b), 0x00},
+	{CCI_REG8(0x0c8c), 0x15},
+	{CCI_REG8(0x0c8d), 0x00},
+	{CCI_REG8(0x0c8e), 0x13},
+	{CCI_REG8(0x0c8f), 0x00},
+	{CCI_REG8(0x0c90), 0x12},
+	{CCI_REG8(0x0c91), 0x00},
+	{CCI_REG8(0x0c92), 0x23},
+	{CCI_REG8(0x0c93), 0x00},
+	{CCI_REG8(0x0c94), 0x14},
+	{CCI_REG8(0x0c95), 0x00},
+	{CCI_REG8(0x0c96), 0x0a},
+	{CCI_REG8(0x0c97), 0x00},
+	{CCI_REG8(0x0c98), 0x0f},
+	{CCI_REG8(0x0c99), 0x00},
+	{CCI_REG8(0x0c9a), 0x19},
+	{CCI_REG8(0x0c9b), 0x00},
+	{CCI_REG8(0x0c9c), 0x12},
+	{CCI_REG8(0x0c9d), 0x00},
+	{CCI_REG8(0x0c9e), 0x0c},
+	{CCI_REG8(0x0c9f), 0x00},
+	{CCI_REG8(0xffff), 0x01},
+	{CCI_REG8(0xf920), 0x49},
+	{CCI_REG8(0xf921), 0x01},
+	{CCI_REG8(0xf922), 0x1e},
+	{CCI_REG8(0xf923), 0x01},
+	{CCI_REG8(0xf924), 0x1e},
+	{CCI_REG8(0xf925), 0x01},
+	{CCI_REG8(0xf926), 0x0e},
+	{CCI_REG8(0xf927), 0x01},
+	{CCI_REG8(0xf928), 0x19},
+	{CCI_REG8(0xf929), 0x01},
+	{CCI_REG8(0xf92a), 0xfe},
+	{CCI_REG8(0xf92b), 0x00},
+	{CCI_REG8(0xf92c), 0xfd},
+	{CCI_REG8(0xf92d), 0x00},
+	{CCI_REG8(0xf92e), 0xf6},
+	{CCI_REG8(0xf92f), 0x00},
+	{CCI_REG8(0xf930), 0x16},
+	{CCI_REG8(0xf931), 0x01},
+	{CCI_REG8(0xf932), 0x05},
+	{CCI_REG8(0xf933), 0x01},
+	{CCI_REG8(0xf934), 0x04},
+	{CCI_REG8(0xf935), 0x01},
+	{CCI_REG8(0xf936), 0xff},
+	{CCI_REG8(0xf937), 0x00},
+	{CCI_REG8(0xf938), 0x0a},
+	{CCI_REG8(0xf939), 0x01},
+	{CCI_REG8(0xf93a), 0x00},
+	{CCI_REG8(0xf93b), 0x01},
+	{CCI_REG8(0xf93c), 0xff},
+	{CCI_REG8(0xf93d), 0x00},
+	{CCI_REG8(0xf93e), 0xff},
+	{CCI_REG8(0xf93f), 0x00},
+	{CCI_REG8(0xf940), 0x08},
+	{CCI_REG8(0xf941), 0x01},
+	{CCI_REG8(0xf942), 0x00},
+	{CCI_REG8(0xf943), 0x01},
+	{CCI_REG8(0xf944), 0xff},
+	{CCI_REG8(0xf945), 0x00},
+	{CCI_REG8(0xf946), 0xfe},
+	{CCI_REG8(0xf947), 0x00},
+	{CCI_REG8(0xf948), 0x08},
+	{CCI_REG8(0xf949), 0x01},
+	{CCI_REG8(0xf94a), 0xff},
+	{CCI_REG8(0xf94b), 0x00},
+	{CCI_REG8(0xf94c), 0xfe},
+	{CCI_REG8(0xf94d), 0x00},
+	{CCI_REG8(0xf94e), 0xfc},
+	{CCI_REG8(0xf94f), 0x00},
+	{CCI_REG8(0xf950), 0x0b},
+	{CCI_REG8(0xf951), 0x01},
+	{CCI_REG8(0xf952), 0x00},
+	{CCI_REG8(0xf953), 0x01},
+	{CCI_REG8(0xf954), 0x00},
+	{CCI_REG8(0xf955), 0x01},
+	{CCI_REG8(0xf956), 0xfe},
+	{CCI_REG8(0xf957), 0x00},
+	{CCI_REG8(0xf958), 0x17},
+	{CCI_REG8(0xf959), 0x01},
+	{CCI_REG8(0xf95a), 0x04},
+	{CCI_REG8(0xf95b), 0x01},
+	{CCI_REG8(0xf95c), 0x04},
+	{CCI_REG8(0xf95d), 0x01},
+	{CCI_REG8(0xf95e), 0xfc},
+	{CCI_REG8(0xf95f), 0x00},
+	{CCI_REG8(0xf960), 0x2e},
+	{CCI_REG8(0xf961), 0x01},
+	{CCI_REG8(0xf962), 0x0a},
+	{CCI_REG8(0xf963), 0x01},
+	{CCI_REG8(0xf964), 0x0b},
+	{CCI_REG8(0xf965), 0x01},
+	{CCI_REG8(0xf966), 0xfc},
+	{CCI_REG8(0xf967), 0x00},
+	{CCI_REG8(0xf968), 0x18},
+	{CCI_REG8(0xf969), 0x01},
+	{CCI_REG8(0xf96a), 0x03},
+	{CCI_REG8(0xf96b), 0x01},
+	{CCI_REG8(0xf96c), 0x03},
+	{CCI_REG8(0xf96d), 0x01},
+	{CCI_REG8(0xf96e), 0xfb},
+	{CCI_REG8(0xf96f), 0x00},
+	{CCI_REG8(0xf970), 0x20},
+	{CCI_REG8(0xf971), 0x01},
+	{CCI_REG8(0xf972), 0xff},
+	{CCI_REG8(0xf973), 0x00},
+	{CCI_REG8(0xf974), 0xfe},
+	{CCI_REG8(0xf975), 0x00},
+	{CCI_REG8(0xf976), 0xf4},
+	{CCI_REG8(0xf977), 0x00},
+	{CCI_REG8(0xf978), 0x14},
+	{CCI_REG8(0xf979), 0x01},
+	{CCI_REG8(0xf97a), 0x00},
+	{CCI_REG8(0xf97b), 0x01},
+	{CCI_REG8(0xf97c), 0xff},
+	{CCI_REG8(0xf97d), 0x00},
+	{CCI_REG8(0xf97e), 0xf8},
+	{CCI_REG8(0xf97f), 0x00},
+	{CCI_REG8(0xf980), 0x0a},
+	{CCI_REG8(0xf981), 0x01},
+	{CCI_REG8(0xf982), 0x00},
+	{CCI_REG8(0xf983), 0x01},
+	{CCI_REG8(0xf984), 0xff},
+	{CCI_REG8(0xf985), 0x00},
+	{CCI_REG8(0xf986), 0xfd},
+	{CCI_REG8(0xf987), 0x00},
+	{CCI_REG8(0xf988), 0x04},
+	{CCI_REG8(0xf989), 0x01},
+	{CCI_REG8(0xf98a), 0xff},
+	{CCI_REG8(0xf98b), 0x00},
+	{CCI_REG8(0xf98c), 0xfe},
+	{CCI_REG8(0xf98d), 0x00},
+	{CCI_REG8(0xf98e), 0xfc},
+	{CCI_REG8(0xf98f), 0x00},
+	{CCI_REG8(0xf990), 0x02},
+	{CCI_REG8(0xf991), 0x01},
+	{CCI_REG8(0xf992), 0xff},
+	{CCI_REG8(0xf993), 0x00},
+	{CCI_REG8(0xf994), 0xff},
+	{CCI_REG8(0xf995), 0x00},
+	{CCI_REG8(0xf996), 0xfe},
+	{CCI_REG8(0xf997), 0x00},
+	{CCI_REG8(0xf998), 0x04},
+	{CCI_REG8(0xf999), 0x01},
+	{CCI_REG8(0xf99a), 0x01},
+	{CCI_REG8(0xf99b), 0x01},
+	{CCI_REG8(0xf99c), 0x01},
+	{CCI_REG8(0xf99d), 0x01},
+	{CCI_REG8(0xf99e), 0x00},
+	{CCI_REG8(0xf99f), 0x01},
+	{CCI_REG8(0xf9a0), 0x07},
+	{CCI_REG8(0xf9a1), 0x01},
+	{CCI_REG8(0xf9a2), 0x00},
+	{CCI_REG8(0xf9a3), 0x01},
+	{CCI_REG8(0xf9a4), 0x00},
+	{CCI_REG8(0xf9a5), 0x01},
+	{CCI_REG8(0xf9a6), 0xfd},
+	{CCI_REG8(0xf9a7), 0x00},
+	{CCI_REG8(0xf9a8), 0x0b},
+	{CCI_REG8(0xf9a9), 0x01},
+	{CCI_REG8(0xf9aa), 0xff},
+	{CCI_REG8(0xf9ab), 0x00},
+	{CCI_REG8(0xf9ac), 0xff},
+	{CCI_REG8(0xf9ad), 0x00},
+	{CCI_REG8(0xf9ae), 0xfb},
+	{CCI_REG8(0xf9af), 0x00},
+	{CCI_REG8(0xf9b0), 0x22},
+	{CCI_REG8(0xf9b1), 0x01},
+	{CCI_REG8(0xf9b2), 0x04},
+	{CCI_REG8(0xf9b3), 0x01},
+	{CCI_REG8(0xf9b4), 0x05},
+	{CCI_REG8(0xf9b5), 0x01},
+	{CCI_REG8(0xf9b6), 0xfb},
+	{CCI_REG8(0xf9b7), 0x00},
+	{CCI_REG8(0xf9b8), 0x0b},
+	{CCI_REG8(0xf9b9), 0x01},
+	{CCI_REG8(0xf9ba), 0xff},
+	{CCI_REG8(0xf9bb), 0x00},
+	{CCI_REG8(0xf9bc), 0xff},
+	{CCI_REG8(0xf9bd), 0x00},
+	{CCI_REG8(0xf9be), 0xfb},
+	{CCI_REG8(0xf9bf), 0x00},
+	{CCI_REG8(0xf9c0), 0x1f},
+	{CCI_REG8(0xf9c1), 0x01},
+	{CCI_REG8(0xf9c2), 0x01},
+	{CCI_REG8(0xf9c3), 0x01},
+	{CCI_REG8(0xf9c4), 0x01},
+	{CCI_REG8(0xf9c5), 0x01},
+	{CCI_REG8(0xf9c6), 0xf6},
+	{CCI_REG8(0xf9c7), 0x00},
+	{CCI_REG8(0xf9c8), 0x0f},
+	{CCI_REG8(0xf9c9), 0x01},
+	{CCI_REG8(0xf9ca), 0x00},
+	{CCI_REG8(0xf9cb), 0x01},
+	{CCI_REG8(0xf9cc), 0xff},
+	{CCI_REG8(0xf9cd), 0x00},
+	{CCI_REG8(0xf9ce), 0xfa},
+	{CCI_REG8(0xf9cf), 0x00},
+	{CCI_REG8(0xf9d0), 0x05},
+	{CCI_REG8(0xf9d1), 0x01},
+	{CCI_REG8(0xf9d2), 0xff},
+	{CCI_REG8(0xf9d3), 0x00},
+	{CCI_REG8(0xf9d4), 0xff},
+	{CCI_REG8(0xf9d5), 0x00},
+	{CCI_REG8(0xf9d6), 0xfc},
+	{CCI_REG8(0xf9d7), 0x00},
+	{CCI_REG8(0xf9d8), 0x03},
+	{CCI_REG8(0xf9d9), 0x01},
+	{CCI_REG8(0xf9da), 0x01},
+	{CCI_REG8(0xf9db), 0x01},
+	{CCI_REG8(0xf9dc), 0x00},
+	{CCI_REG8(0xf9dd), 0x01},
+	{CCI_REG8(0xf9de), 0xff},
+	{CCI_REG8(0xf9df), 0x00},
+	{CCI_REG8(0xf9e0), 0x00},
+	{CCI_REG8(0xf9e1), 0x01},
+	{CCI_REG8(0xf9e2), 0x00},
+	{CCI_REG8(0xf9e3), 0x01},
+	{CCI_REG8(0xf9e4), 0x00},
+	{CCI_REG8(0xf9e5), 0x01},
+	{CCI_REG8(0xf9e6), 0xff},
+	{CCI_REG8(0xf9e7), 0x00},
+	{CCI_REG8(0xf9e8), 0xff},
+	{CCI_REG8(0xf9e9), 0x00},
+	{CCI_REG8(0xf9ea), 0x00},
+	{CCI_REG8(0xf9eb), 0x01},
+	{CCI_REG8(0xf9ec), 0x00},
+	{CCI_REG8(0xf9ed), 0x01},
+	{CCI_REG8(0xf9ee), 0xff},
+	{CCI_REG8(0xf9ef), 0x00},
+	{CCI_REG8(0xf9f0), 0x06},
+	{CCI_REG8(0xf9f1), 0x01},
+	{CCI_REG8(0xf9f2), 0x02},
+	{CCI_REG8(0xf9f3), 0x01},
+	{CCI_REG8(0xf9f4), 0x03},
+	{CCI_REG8(0xf9f5), 0x01},
+	{CCI_REG8(0xf9f6), 0x00},
+	{CCI_REG8(0xf9f7), 0x01},
+	{CCI_REG8(0xf9f8), 0x08},
+	{CCI_REG8(0xf9f9), 0x01},
+	{CCI_REG8(0xf9fa), 0xff},
+	{CCI_REG8(0xf9fb), 0x00},
+	{CCI_REG8(0xf9fc), 0xff},
+	{CCI_REG8(0xf9fd), 0x00},
+	{CCI_REG8(0xf9fe), 0xfd},
+	{CCI_REG8(0xf9ff), 0x00},
+	{CCI_REG8(0xfa00), 0x1a},
+	{CCI_REG8(0xfa01), 0x01},
+	{CCI_REG8(0xfa02), 0x00},
+	{CCI_REG8(0xfa03), 0x01},
+	{CCI_REG8(0xfa04), 0x01},
+	{CCI_REG8(0xfa05), 0x01},
+	{CCI_REG8(0xfa06), 0xfa},
+	{CCI_REG8(0xfa07), 0x00},
+	{CCI_REG8(0xfa08), 0x0a},
+	{CCI_REG8(0xfa09), 0x01},
+	{CCI_REG8(0xfa0a), 0x00},
+	{CCI_REG8(0xfa0b), 0x01},
+	{CCI_REG8(0xfa0c), 0x00},
+	{CCI_REG8(0xfa0d), 0x01},
+	{CCI_REG8(0xfa0e), 0xfd},
+	{CCI_REG8(0xfa0f), 0x00},
+	{CCI_REG8(0xfa10), 0x1c},
+	{CCI_REG8(0xfa11), 0x01},
+	{CCI_REG8(0xfa12), 0xff},
+	{CCI_REG8(0xfa13), 0x00},
+	{CCI_REG8(0xfa14), 0xfe},
+	{CCI_REG8(0xfa15), 0x00},
+	{CCI_REG8(0xfa16), 0xf3},
+	{CCI_REG8(0xfa17), 0x00},
+	{CCI_REG8(0xfa18), 0x10},
+	{CCI_REG8(0xfa19), 0x01},
+	{CCI_REG8(0xfa1a), 0x02},
+	{CCI_REG8(0xfa1b), 0x01},
+	{CCI_REG8(0xfa1c), 0x01},
+	{CCI_REG8(0xfa1d), 0x01},
+	{CCI_REG8(0xfa1e), 0xfc},
+	{CCI_REG8(0xfa1f), 0x00},
+	{CCI_REG8(0xfa20), 0x08},
+	{CCI_REG8(0xfa21), 0x01},
+	{CCI_REG8(0xfa22), 0x02},
+	{CCI_REG8(0xfa23), 0x01},
+	{CCI_REG8(0xfa24), 0x02},
+	{CCI_REG8(0xfa25), 0x01},
+	{CCI_REG8(0xfa26), 0xff},
+	{CCI_REG8(0xfa27), 0x00},
+	{CCI_REG8(0xfa28), 0x01},
+	{CCI_REG8(0xfa29), 0x01},
+	{CCI_REG8(0xfa2a), 0x00},
+	{CCI_REG8(0xfa2b), 0x01},
+	{CCI_REG8(0xfa2c), 0x00},
+	{CCI_REG8(0xfa2d), 0x01},
+	{CCI_REG8(0xfa2e), 0xfe},
+	{CCI_REG8(0xfa2f), 0x00},
+	{CCI_REG8(0xfa30), 0x00},
+	{CCI_REG8(0xfa31), 0x01},
+	{CCI_REG8(0xfa32), 0x01},
+	{CCI_REG8(0xfa33), 0x01},
+	{CCI_REG8(0xfa34), 0x01},
+	{CCI_REG8(0xfa35), 0x01},
+	{CCI_REG8(0xfa36), 0x01},
+	{CCI_REG8(0xfa37), 0x01},
+	{CCI_REG8(0xfa38), 0xff},
+	{CCI_REG8(0xfa39), 0x00},
+	{CCI_REG8(0xfa3a), 0xff},
+	{CCI_REG8(0xfa3b), 0x00},
+	{CCI_REG8(0xfa3c), 0xff},
+	{CCI_REG8(0xfa3d), 0x00},
+	{CCI_REG8(0xfa3e), 0xff},
+	{CCI_REG8(0xfa3f), 0x00},
+	{CCI_REG8(0xfa40), 0x05},
+	{CCI_REG8(0xfa41), 0x01},
+	{CCI_REG8(0xfa42), 0x01},
+	{CCI_REG8(0xfa43), 0x01},
+	{CCI_REG8(0xfa44), 0x01},
+	{CCI_REG8(0xfa45), 0x01},
+	{CCI_REG8(0xfa46), 0x00},
+	{CCI_REG8(0xfa47), 0x01},
+	{CCI_REG8(0xfa48), 0x08},
+	{CCI_REG8(0xfa49), 0x01},
+	{CCI_REG8(0xfa4a), 0xff},
+	{CCI_REG8(0xfa4b), 0x00},
+	{CCI_REG8(0xfa4c), 0xff},
+	{CCI_REG8(0xfa4d), 0x00},
+	{CCI_REG8(0xfa4e), 0xfe},
+	{CCI_REG8(0xfa4f), 0x00},
+	{CCI_REG8(0xfa50), 0x17},
+	{CCI_REG8(0xfa51), 0x01},
+	{CCI_REG8(0xfa52), 0xfe},
+	{CCI_REG8(0xfa53), 0x00},
+	{CCI_REG8(0xfa54), 0xfe},
+	{CCI_REG8(0xfa55), 0x00},
+	{CCI_REG8(0xfa56), 0xf8},
+	{CCI_REG8(0xfa57), 0x00},
+	{CCI_REG8(0xfa58), 0x0a},
+	{CCI_REG8(0xfa59), 0x01},
+	{CCI_REG8(0xfa5a), 0x00},
+	{CCI_REG8(0xfa5b), 0x01},
+	{CCI_REG8(0xfa5c), 0x00},
+	{CCI_REG8(0xfa5d), 0x01},
+	{CCI_REG8(0xfa5e), 0xfe},
+	{CCI_REG8(0xfa5f), 0x00},
+	{CCI_REG8(0xfa60), 0x1b},
+	{CCI_REG8(0xfa61), 0x01},
+	{CCI_REG8(0xfa62), 0xfc},
+	{CCI_REG8(0xfa63), 0x00},
+	{CCI_REG8(0xfa64), 0xfb},
+	{CCI_REG8(0xfa65), 0x00},
+	{CCI_REG8(0xfa66), 0xf1},
+	{CCI_REG8(0xfa67), 0x00},
+	{CCI_REG8(0xfa68), 0x14},
+	{CCI_REG8(0xfa69), 0x01},
+	{CCI_REG8(0xfa6a), 0x01},
+	{CCI_REG8(0xfa6b), 0x01},
+	{CCI_REG8(0xfa6c), 0x01},
+	{CCI_REG8(0xfa6d), 0x01},
+	{CCI_REG8(0xfa6e), 0xf9},
+	{CCI_REG8(0xfa6f), 0x00},
+	{CCI_REG8(0xfa70), 0x08},
+	{CCI_REG8(0xfa71), 0x01},
+	{CCI_REG8(0xfa72), 0x01},
+	{CCI_REG8(0xfa73), 0x01},
+	{CCI_REG8(0xfa74), 0x00},
+	{CCI_REG8(0xfa75), 0x01},
+	{CCI_REG8(0xfa76), 0xfd},
+	{CCI_REG8(0xfa77), 0x00},
+	{CCI_REG8(0xfa78), 0x06},
+	{CCI_REG8(0xfa79), 0x01},
+	{CCI_REG8(0xfa7a), 0x02},
+	{CCI_REG8(0xfa7b), 0x01},
+	{CCI_REG8(0xfa7c), 0x02},
+	{CCI_REG8(0xfa7d), 0x01},
+	{CCI_REG8(0xfa7e), 0xff},
+	{CCI_REG8(0xfa7f), 0x00},
+	{CCI_REG8(0xfa80), 0x01},
+	{CCI_REG8(0xfa81), 0x01},
+	{CCI_REG8(0xfa82), 0xff},
+	{CCI_REG8(0xfa83), 0x00},
+	{CCI_REG8(0xfa84), 0xfe},
+	{CCI_REG8(0xfa85), 0x00},
+	{CCI_REG8(0xfa86), 0xfe},
+	{CCI_REG8(0xfa87), 0x00},
+	{CCI_REG8(0xfa88), 0x03},
+	{CCI_REG8(0xfa89), 0x01},
+	{CCI_REG8(0xfa8a), 0x00},
+	{CCI_REG8(0xfa8b), 0x01},
+	{CCI_REG8(0xfa8c), 0x00},
+	{CCI_REG8(0xfa8d), 0x01},
+	{CCI_REG8(0xfa8e), 0xff},
+	{CCI_REG8(0xfa8f), 0x00},
+	{CCI_REG8(0xfa90), 0x07},
+	{CCI_REG8(0xfa91), 0x01},
+	{CCI_REG8(0xfa92), 0x00},
+	{CCI_REG8(0xfa93), 0x01},
+	{CCI_REG8(0xfa94), 0x00},
+	{CCI_REG8(0xfa95), 0x01},
+	{CCI_REG8(0xfa96), 0xff},
+	{CCI_REG8(0xfa97), 0x00},
+	{CCI_REG8(0xfa98), 0x0b},
+	{CCI_REG8(0xfa99), 0x01},
+	{CCI_REG8(0xfa9a), 0xff},
+	{CCI_REG8(0xfa9b), 0x00},
+	{CCI_REG8(0xfa9c), 0xff},
+	{CCI_REG8(0xfa9d), 0x00},
+	{CCI_REG8(0xfa9e), 0xfd},
+	{CCI_REG8(0xfa9f), 0x00},
+	{CCI_REG8(0xfaa0), 0x1d},
+	{CCI_REG8(0xfaa1), 0x01},
+	{CCI_REG8(0xfaa2), 0xff},
+	{CCI_REG8(0xfaa3), 0x00},
+	{CCI_REG8(0xfaa4), 0x00},
+	{CCI_REG8(0xfaa5), 0x01},
+	{CCI_REG8(0xfaa6), 0xf8},
+	{CCI_REG8(0xfaa7), 0x00},
+	{CCI_REG8(0xfaa8), 0x0c},
+	{CCI_REG8(0xfaa9), 0x01},
+	{CCI_REG8(0xfaaa), 0xff},
+	{CCI_REG8(0xfaab), 0x00},
+	{CCI_REG8(0xfaac), 0xff},
+	{CCI_REG8(0xfaad), 0x00},
+	{CCI_REG8(0xfaae), 0xfd},
+	{CCI_REG8(0xfaaf), 0x00},
+	{CCI_REG8(0xfab0), 0x37},
+	{CCI_REG8(0xfab1), 0x01},
+	{CCI_REG8(0xfab2), 0x10},
+	{CCI_REG8(0xfab3), 0x01},
+	{CCI_REG8(0xfab4), 0x0f},
+	{CCI_REG8(0xfab5), 0x01},
+	{CCI_REG8(0xfab6), 0x00},
+	{CCI_REG8(0xfab7), 0x01},
+	{CCI_REG8(0xfab8), 0x16},
+	{CCI_REG8(0xfab9), 0x01},
+	{CCI_REG8(0xfaba), 0xfe},
+	{CCI_REG8(0xfabb), 0x00},
+	{CCI_REG8(0xfabc), 0xfd},
+	{CCI_REG8(0xfabd), 0x00},
+	{CCI_REG8(0xfabe), 0xf3},
+	{CCI_REG8(0xfabf), 0x00},
+	{CCI_REG8(0xfac0), 0x13},
+	{CCI_REG8(0xfac1), 0x01},
+	{CCI_REG8(0xfac2), 0x04},
+	{CCI_REG8(0xfac3), 0x01},
+	{CCI_REG8(0xfac4), 0x04},
+	{CCI_REG8(0xfac5), 0x01},
+	{CCI_REG8(0xfac6), 0xfe},
+	{CCI_REG8(0xfac7), 0x00},
+	{CCI_REG8(0xfac8), 0x0b},
+	{CCI_REG8(0xfac9), 0x01},
+	{CCI_REG8(0xfaca), 0x02},
+	{CCI_REG8(0xfacb), 0x01},
+	{CCI_REG8(0xfacc), 0x01},
+	{CCI_REG8(0xfacd), 0x01},
+	{CCI_REG8(0xface), 0xff},
+	{CCI_REG8(0xfacf), 0x00},
+	{CCI_REG8(0xfad0), 0x08},
+	{CCI_REG8(0xfad1), 0x01},
+	{CCI_REG8(0xfad2), 0x00},
+	{CCI_REG8(0xfad3), 0x01},
+	{CCI_REG8(0xfad4), 0x00},
+	{CCI_REG8(0xfad5), 0x01},
+	{CCI_REG8(0xfad6), 0xfe},
+	{CCI_REG8(0xfad7), 0x00},
+	{CCI_REG8(0xfad8), 0x07},
+	{CCI_REG8(0xfad9), 0x01},
+	{CCI_REG8(0xfada), 0xff},
+	{CCI_REG8(0xfadb), 0x00},
+	{CCI_REG8(0xfadc), 0xff},
+	{CCI_REG8(0xfadd), 0x00},
+	{CCI_REG8(0xfade), 0xfe},
+	{CCI_REG8(0xfadf), 0x00},
+	{CCI_REG8(0xfae0), 0x0c},
+	{CCI_REG8(0xfae1), 0x01},
+	{CCI_REG8(0xfae2), 0xff},
+	{CCI_REG8(0xfae3), 0x00},
+	{CCI_REG8(0xfae4), 0xff},
+	{CCI_REG8(0xfae5), 0x00},
+	{CCI_REG8(0xfae6), 0xfe},
+	{CCI_REG8(0xfae7), 0x00},
+	{CCI_REG8(0xfae8), 0x15},
+	{CCI_REG8(0xfae9), 0x01},
+	{CCI_REG8(0xfaea), 0x00},
+	{CCI_REG8(0xfaeb), 0x01},
+	{CCI_REG8(0xfaec), 0x01},
+	{CCI_REG8(0xfaed), 0x01},
+	{CCI_REG8(0xfaee), 0xfd},
+	{CCI_REG8(0xfaef), 0x00},
+	{CCI_REG8(0xfaf0), 0x22},
+	{CCI_REG8(0xfaf1), 0x01},
+	{CCI_REG8(0xfaf2), 0xfc},
+	{CCI_REG8(0xfaf3), 0x00},
+	{CCI_REG8(0xfaf4), 0xfc},
+	{CCI_REG8(0xfaf5), 0x00},
+	{CCI_REG8(0xfaf6), 0xf4},
+	{CCI_REG8(0xfaf7), 0x00},
+	{CCI_REG8(0xfaf8), 0x15},
+	{CCI_REG8(0xfaf9), 0x01},
+	{CCI_REG8(0xfafa), 0xff},
+	{CCI_REG8(0xfafb), 0x00},
+	{CCI_REG8(0xfafc), 0xfe},
+	{CCI_REG8(0xfafd), 0x00},
+	{CCI_REG8(0xfafe), 0xfb},
+	{CCI_REG8(0xfaff), 0x00},
+	{CCI_REG8(0xfb00), 0xf5},
+	{CCI_REG8(0xfb01), 0x00},
+	{CCI_REG8(0xfb02), 0xe0},
+	{CCI_REG8(0xfb03), 0x00},
+	{CCI_REG8(0xfb04), 0xdf},
+	{CCI_REG8(0xfb05), 0x00},
+	{CCI_REG8(0xfb06), 0xda},
+	{CCI_REG8(0xfb07), 0x00},
+	{CCI_REG8(0xfb08), 0x10},
+	{CCI_REG8(0xfb09), 0x01},
+	{CCI_REG8(0xfb0a), 0x06},
+	{CCI_REG8(0xfb0b), 0x01},
+	{CCI_REG8(0xfb0c), 0x06},
+	{CCI_REG8(0xfb0d), 0x01},
+	{CCI_REG8(0xfb0e), 0x01},
+	{CCI_REG8(0xfb0f), 0x01},
+	{CCI_REG8(0xfb10), 0xfd},
+	{CCI_REG8(0xfb11), 0x00},
+	{CCI_REG8(0xfb12), 0xfd},
+	{CCI_REG8(0xfb13), 0x00},
+	{CCI_REG8(0xfb14), 0xfd},
+	{CCI_REG8(0xfb15), 0x00},
+	{CCI_REG8(0xfb16), 0xfd},
+	{CCI_REG8(0xfb17), 0x00},
+	{CCI_REG8(0xfb18), 0xff},
+	{CCI_REG8(0xfb19), 0x00},
+	{CCI_REG8(0xfb1a), 0x02},
+	{CCI_REG8(0xfb1b), 0x01},
+	{CCI_REG8(0xfb1c), 0x01},
+	{CCI_REG8(0xfb1d), 0x01},
+	{CCI_REG8(0xfb1e), 0xff},
+	{CCI_REG8(0xfb1f), 0x00},
+	{CCI_REG8(0xfb20), 0xf8},
+	{CCI_REG8(0xfb21), 0x00},
+	{CCI_REG8(0xfb22), 0xfd},
+	{CCI_REG8(0xfb23), 0x00},
+	{CCI_REG8(0xfb24), 0xfe},
+	{CCI_REG8(0xfb25), 0x00},
+	{CCI_REG8(0xfb26), 0xfe},
+	{CCI_REG8(0xfb27), 0x00},
+	{CCI_REG8(0xfb28), 0xfd},
+	{CCI_REG8(0xfb29), 0x00},
+	{CCI_REG8(0xfb2a), 0x01},
+	{CCI_REG8(0xfb2b), 0x01},
+	{CCI_REG8(0xfb2c), 0x02},
+	{CCI_REG8(0xfb2d), 0x01},
+	{CCI_REG8(0xfb2e), 0x01},
+	{CCI_REG8(0xfb2f), 0x01},
+	{CCI_REG8(0xfb30), 0x01},
+	{CCI_REG8(0xfb31), 0x01},
+	{CCI_REG8(0xfb32), 0x00},
+	{CCI_REG8(0xfb33), 0x01},
+	{CCI_REG8(0xfb34), 0x01},
+	{CCI_REG8(0xfb35), 0x01},
+	{CCI_REG8(0xfb36), 0xff},
+	{CCI_REG8(0xfb37), 0x00},
+	{CCI_REG8(0xfb38), 0xfe},
+	{CCI_REG8(0xfb39), 0x00},
+	{CCI_REG8(0xfb3a), 0xfd},
+	{CCI_REG8(0xfb3b), 0x00},
+	{CCI_REG8(0xfb3c), 0xfd},
+	{CCI_REG8(0xfb3d), 0x00},
+	{CCI_REG8(0xfb3e), 0xfd},
+	{CCI_REG8(0xfb3f), 0x00},
+	{CCI_REG8(0xfb40), 0x16},
+	{CCI_REG8(0xfb41), 0x01},
+	{CCI_REG8(0xfb42), 0x02},
+	{CCI_REG8(0xfb43), 0x01},
+	{CCI_REG8(0xfb44), 0x03},
+	{CCI_REG8(0xfb45), 0x01},
+	{CCI_REG8(0xfb46), 0xfd},
+	{CCI_REG8(0xfb47), 0x00},
+	{CCI_REG8(0xfb48), 0x02},
+	{CCI_REG8(0xfb49), 0x01},
+	{CCI_REG8(0xfb4a), 0xff},
+	{CCI_REG8(0xfb4b), 0x00},
+	{CCI_REG8(0xfb4c), 0xff},
+	{CCI_REG8(0xfb4d), 0x00},
+	{CCI_REG8(0xfb4e), 0x00},
+	{CCI_REG8(0xfb4f), 0x01},
+	{CCI_REG8(0xfb50), 0x5f},
+	{CCI_REG8(0xfb51), 0x01},
+	{CCI_REG8(0xfb52), 0x2b},
+	{CCI_REG8(0xfb53), 0x01},
+	{CCI_REG8(0xfb54), 0x2b},
+	{CCI_REG8(0xfb55), 0x01},
+	{CCI_REG8(0xfb56), 0x0e},
+	{CCI_REG8(0xfb57), 0x01},
+	{CCI_REG8(0xfb58), 0x2e},
+	{CCI_REG8(0xfb59), 0x01},
+	{CCI_REG8(0xfb5a), 0x08},
+	{CCI_REG8(0xfb5b), 0x01},
+	{CCI_REG8(0xfb5c), 0x07},
+	{CCI_REG8(0xfb5d), 0x01},
+	{CCI_REG8(0xfb5e), 0xf9},
+	{CCI_REG8(0xfb5f), 0x00},
+	{CCI_REG8(0xfb60), 0x26},
+	{CCI_REG8(0xfb61), 0x01},
+	{CCI_REG8(0xfb62), 0x10},
+	{CCI_REG8(0xfb63), 0x01},
+	{CCI_REG8(0xfb64), 0x0f},
+	{CCI_REG8(0xfb65), 0x01},
+	{CCI_REG8(0xfb66), 0x07},
+	{CCI_REG8(0xfb67), 0x01},
+	{CCI_REG8(0xfb68), 0x16},
+	{CCI_REG8(0xfb69), 0x01},
+	{CCI_REG8(0xfb6a), 0x0a},
+	{CCI_REG8(0xfb6b), 0x01},
+	{CCI_REG8(0xfb6c), 0x0a},
+	{CCI_REG8(0xfb6d), 0x01},
+	{CCI_REG8(0xfb6e), 0x08},
+	{CCI_REG8(0xfb6f), 0x01},
+	{CCI_REG8(0xfb70), 0x11},
+	{CCI_REG8(0xfb71), 0x01},
+	{CCI_REG8(0xfb72), 0x08},
+	{CCI_REG8(0xfb73), 0x01},
+	{CCI_REG8(0xfb74), 0x07},
+	{CCI_REG8(0xfb75), 0x01},
+	{CCI_REG8(0xfb76), 0x05},
+	{CCI_REG8(0xfb77), 0x01},
+	{CCI_REG8(0xfb78), 0x0f},
+	{CCI_REG8(0xfb79), 0x01},
+	{CCI_REG8(0xfb7a), 0x07},
+	{CCI_REG8(0xfb7b), 0x01},
+	{CCI_REG8(0xfb7c), 0x06},
+	{CCI_REG8(0xfb7d), 0x01},
+	{CCI_REG8(0xfb7e), 0x02},
+	{CCI_REG8(0xfb7f), 0x01},
+	{CCI_REG8(0xfb80), 0x15},
+	{CCI_REG8(0xfb81), 0x01},
+	{CCI_REG8(0xfb82), 0x0a},
+	{CCI_REG8(0xfb83), 0x01},
+	{CCI_REG8(0xfb84), 0x0a},
+	{CCI_REG8(0xfb85), 0x01},
+	{CCI_REG8(0xfb86), 0x07},
+	{CCI_REG8(0xfb87), 0x01},
+	{CCI_REG8(0xfb88), 0x20},
+	{CCI_REG8(0xfb89), 0x01},
+	{CCI_REG8(0xfb8a), 0x0e},
+	{CCI_REG8(0xfb8b), 0x01},
+	{CCI_REG8(0xfb8c), 0x0d},
+	{CCI_REG8(0xfb8d), 0x01},
+	{CCI_REG8(0xfb8e), 0x04},
+	{CCI_REG8(0xfb8f), 0x01},
+	{CCI_REG8(0xfb90), 0x38},
+	{CCI_REG8(0xfb91), 0x01},
+	{CCI_REG8(0xfb92), 0x15},
+	{CCI_REG8(0xfb93), 0x01},
+	{CCI_REG8(0xfb94), 0x14},
+	{CCI_REG8(0xfb95), 0x01},
+	{CCI_REG8(0xfb96), 0xff},
+	{CCI_REG8(0xfb97), 0x00},
+	{CCI_REG8(0xfb98), 0x20},
+	{CCI_REG8(0xfb99), 0x01},
+	{CCI_REG8(0xfb9a), 0x0d},
+	{CCI_REG8(0xfb9b), 0x01},
+	{CCI_REG8(0xfb9c), 0x0d},
+	{CCI_REG8(0xfb9d), 0x01},
+	{CCI_REG8(0xfb9e), 0x03},
+	{CCI_REG8(0xfb9f), 0x01},
+	{CCI_REG8(0xfba0), 0x31},
+	{CCI_REG8(0xfba1), 0x01},
+	{CCI_REG8(0xfba2), 0x09},
+	{CCI_REG8(0xfba3), 0x01},
+	{CCI_REG8(0xfba4), 0x09},
+	{CCI_REG8(0xfba5), 0x01},
+	{CCI_REG8(0xfba6), 0xf4},
+	{CCI_REG8(0xfba7), 0x00},
+	{CCI_REG8(0xfba8), 0x1e},
+	{CCI_REG8(0xfba9), 0x01},
+	{CCI_REG8(0xfbaa), 0x06},
+	{CCI_REG8(0xfbab), 0x01},
+	{CCI_REG8(0xfbac), 0x05},
+	{CCI_REG8(0xfbad), 0x01},
+	{CCI_REG8(0xfbae), 0xfb},
+	{CCI_REG8(0xfbaf), 0x00},
+	{CCI_REG8(0xfbb0), 0x10},
+	{CCI_REG8(0xfbb1), 0x01},
+	{CCI_REG8(0xfbb2), 0x05},
+	{CCI_REG8(0xfbb3), 0x01},
+	{CCI_REG8(0xfbb4), 0x05},
+	{CCI_REG8(0xfbb5), 0x01},
+	{CCI_REG8(0xfbb6), 0x01},
+	{CCI_REG8(0xfbb7), 0x01},
+	{CCI_REG8(0xfbb8), 0x06},
+	{CCI_REG8(0xfbb9), 0x01},
+	{CCI_REG8(0xfbba), 0x00},
+	{CCI_REG8(0xfbbb), 0x01},
+	{CCI_REG8(0xfbbc), 0x00},
+	{CCI_REG8(0xfbbd), 0x01},
+	{CCI_REG8(0xfbbe), 0xfd},
+	{CCI_REG8(0xfbbf), 0x00},
+	{CCI_REG8(0xfbc0), 0x03},
+	{CCI_REG8(0xfbc1), 0x01},
+	{CCI_REG8(0xfbc2), 0x01},
+	{CCI_REG8(0xfbc3), 0x01},
+	{CCI_REG8(0xfbc4), 0x01},
+	{CCI_REG8(0xfbc5), 0x01},
+	{CCI_REG8(0xfbc6), 0xff},
+	{CCI_REG8(0xfbc7), 0x00},
+	{CCI_REG8(0xfbc8), 0x05},
+	{CCI_REG8(0xfbc9), 0x01},
+	{CCI_REG8(0xfbca), 0x03},
+	{CCI_REG8(0xfbcb), 0x01},
+	{CCI_REG8(0xfbcc), 0x02},
+	{CCI_REG8(0xfbcd), 0x01},
+	{CCI_REG8(0xfbce), 0x01},
+	{CCI_REG8(0xfbcf), 0x01},
+	{CCI_REG8(0xfbd0), 0x09},
+	{CCI_REG8(0xfbd1), 0x01},
+	{CCI_REG8(0xfbd2), 0x03},
+	{CCI_REG8(0xfbd3), 0x01},
+	{CCI_REG8(0xfbd4), 0x03},
+	{CCI_REG8(0xfbd5), 0x01},
+	{CCI_REG8(0xfbd6), 0xff},
+	{CCI_REG8(0xfbd7), 0x00},
+	{CCI_REG8(0xfbd8), 0x0f},
+	{CCI_REG8(0xfbd9), 0x01},
+	{CCI_REG8(0xfbda), 0x05},
+	{CCI_REG8(0xfbdb), 0x01},
+	{CCI_REG8(0xfbdc), 0x04},
+	{CCI_REG8(0xfbdd), 0x01},
+	{CCI_REG8(0xfbde), 0xff},
+	{CCI_REG8(0xfbdf), 0x00},
+	{CCI_REG8(0xfbe0), 0x2a},
+	{CCI_REG8(0xfbe1), 0x01},
+	{CCI_REG8(0xfbe2), 0x0e},
+	{CCI_REG8(0xfbe3), 0x01},
+	{CCI_REG8(0xfbe4), 0x0d},
+	{CCI_REG8(0xfbe5), 0x01},
+	{CCI_REG8(0xfbe6), 0xfe},
+	{CCI_REG8(0xfbe7), 0x00},
+	{CCI_REG8(0xfbe8), 0x0f},
+	{CCI_REG8(0xfbe9), 0x01},
+	{CCI_REG8(0xfbea), 0x04},
+	{CCI_REG8(0xfbeb), 0x01},
+	{CCI_REG8(0xfbec), 0x04},
+	{CCI_REG8(0xfbed), 0x01},
+	{CCI_REG8(0xfbee), 0xfe},
+	{CCI_REG8(0xfbef), 0x00},
+	{CCI_REG8(0xfbf0), 0x2a},
+	{CCI_REG8(0xfbf1), 0x01},
+	{CCI_REG8(0xfbf2), 0x08},
+	{CCI_REG8(0xfbf3), 0x01},
+	{CCI_REG8(0xfbf4), 0x08},
+	{CCI_REG8(0xfbf5), 0x01},
+	{CCI_REG8(0xfbf6), 0xf5},
+	{CCI_REG8(0xfbf7), 0x00},
+	{CCI_REG8(0xfbf8), 0x18},
+	{CCI_REG8(0xfbf9), 0x01},
+	{CCI_REG8(0xfbfa), 0x07},
+	{CCI_REG8(0xfbfb), 0x01},
+	{CCI_REG8(0xfbfc), 0x07},
+	{CCI_REG8(0xfbfd), 0x01},
+	{CCI_REG8(0xfbfe), 0xfe},
+	{CCI_REG8(0xfbff), 0x00},
+	{CCI_REG8(0xfc00), 0x09},
+	{CCI_REG8(0xfc01), 0x01},
+	{CCI_REG8(0xfc02), 0x02},
+	{CCI_REG8(0xfc03), 0x01},
+	{CCI_REG8(0xfc04), 0x02},
+	{CCI_REG8(0xfc05), 0x01},
+	{CCI_REG8(0xfc06), 0xfe},
+	{CCI_REG8(0xfc07), 0x00},
+	{CCI_REG8(0xfc08), 0x03},
+	{CCI_REG8(0xfc09), 0x01},
+	{CCI_REG8(0xfc0a), 0x01},
+	{CCI_REG8(0xfc0b), 0x01},
+	{CCI_REG8(0xfc0c), 0x01},
+	{CCI_REG8(0xfc0d), 0x01},
+	{CCI_REG8(0xfc0e), 0xff},
+	{CCI_REG8(0xfc0f), 0x00},
+	{CCI_REG8(0xfc10), 0xff},
+	{CCI_REG8(0xfc11), 0x00},
+	{CCI_REG8(0xfc12), 0xff},
+	{CCI_REG8(0xfc13), 0x00},
+	{CCI_REG8(0xfc14), 0xff},
+	{CCI_REG8(0xfc15), 0x00},
+	{CCI_REG8(0xfc16), 0xff},
+	{CCI_REG8(0xfc17), 0x00},
+	{CCI_REG8(0xfc18), 0x00},
+	{CCI_REG8(0xfc19), 0x01},
+	{CCI_REG8(0xfc1a), 0x00},
+	{CCI_REG8(0xfc1b), 0x01},
+	{CCI_REG8(0xfc1c), 0xff},
+	{CCI_REG8(0xfc1d), 0x00},
+	{CCI_REG8(0xfc1e), 0x00},
+	{CCI_REG8(0xfc1f), 0x01},
+	{CCI_REG8(0xfc20), 0x07},
+	{CCI_REG8(0xfc21), 0x01},
+	{CCI_REG8(0xfc22), 0x04},
+	{CCI_REG8(0xfc23), 0x01},
+	{CCI_REG8(0xfc24), 0x04},
+	{CCI_REG8(0xfc25), 0x01},
+	{CCI_REG8(0xfc26), 0x01},
+	{CCI_REG8(0xfc27), 0x01},
+	{CCI_REG8(0xfc28), 0x0c},
+	{CCI_REG8(0xfc29), 0x01},
+	{CCI_REG8(0xfc2a), 0x04},
+	{CCI_REG8(0xfc2b), 0x01},
+	{CCI_REG8(0xfc2c), 0x03},
+	{CCI_REG8(0xfc2d), 0x01},
+	{CCI_REG8(0xfc2e), 0x00},
+	{CCI_REG8(0xfc2f), 0x01},
+	{CCI_REG8(0xfc30), 0x24},
+	{CCI_REG8(0xfc31), 0x01},
+	{CCI_REG8(0xfc32), 0x09},
+	{CCI_REG8(0xfc33), 0x01},
+	{CCI_REG8(0xfc34), 0x09},
+	{CCI_REG8(0xfc35), 0x01},
+	{CCI_REG8(0xfc36), 0xfd},
+	{CCI_REG8(0xfc37), 0x00},
+	{CCI_REG8(0xfc38), 0x0e},
+	{CCI_REG8(0xfc39), 0x01},
+	{CCI_REG8(0xfc3a), 0x04},
+	{CCI_REG8(0xfc3b), 0x01},
+	{CCI_REG8(0xfc3c), 0x04},
+	{CCI_REG8(0xfc3d), 0x01},
+	{CCI_REG8(0xfc3e), 0xff},
+	{CCI_REG8(0xfc3f), 0x00},
+	{CCI_REG8(0xfc40), 0x26},
+	{CCI_REG8(0xfc41), 0x01},
+	{CCI_REG8(0xfc42), 0x07},
+	{CCI_REG8(0xfc43), 0x01},
+	{CCI_REG8(0xfc44), 0x07},
+	{CCI_REG8(0xfc45), 0x01},
+	{CCI_REG8(0xfc46), 0xf4},
+	{CCI_REG8(0xfc47), 0x00},
+	{CCI_REG8(0xfc48), 0x19},
+	{CCI_REG8(0xfc49), 0x01},
+	{CCI_REG8(0xfc4a), 0x0a},
+	{CCI_REG8(0xfc4b), 0x01},
+	{CCI_REG8(0xfc4c), 0x0a},
+	{CCI_REG8(0xfc4d), 0x01},
+	{CCI_REG8(0xfc4e), 0x02},
+	{CCI_REG8(0xfc4f), 0x01},
+	{CCI_REG8(0xfc50), 0x0b},
+	{CCI_REG8(0xfc51), 0x01},
+	{CCI_REG8(0xfc52), 0x06},
+	{CCI_REG8(0xfc53), 0x01},
+	{CCI_REG8(0xfc54), 0x06},
+	{CCI_REG8(0xfc55), 0x01},
+	{CCI_REG8(0xfc56), 0x02},
+	{CCI_REG8(0xfc57), 0x01},
+	{CCI_REG8(0xfc58), 0x02},
+	{CCI_REG8(0xfc59), 0x01},
+	{CCI_REG8(0xfc5a), 0x01},
+	{CCI_REG8(0xfc5b), 0x01},
+	{CCI_REG8(0xfc5c), 0x01},
+	{CCI_REG8(0xfc5d), 0x01},
+	{CCI_REG8(0xfc5e), 0xff},
+	{CCI_REG8(0xfc5f), 0x00},
+	{CCI_REG8(0xfc60), 0x01},
+	{CCI_REG8(0xfc61), 0x01},
+	{CCI_REG8(0xfc62), 0x01},
+	{CCI_REG8(0xfc63), 0x01},
+	{CCI_REG8(0xfc64), 0x01},
+	{CCI_REG8(0xfc65), 0x01},
+	{CCI_REG8(0xfc66), 0x01},
+	{CCI_REG8(0xfc67), 0x01},
+	{CCI_REG8(0xfc68), 0x00},
+	{CCI_REG8(0xfc69), 0x01},
+	{CCI_REG8(0xfc6a), 0x00},
+	{CCI_REG8(0xfc6b), 0x01},
+	{CCI_REG8(0xfc6c), 0x00},
+	{CCI_REG8(0xfc6d), 0x01},
+	{CCI_REG8(0xfc6e), 0x00},
+	{CCI_REG8(0xfc6f), 0x01},
+	{CCI_REG8(0xfc70), 0x07},
+	{CCI_REG8(0xfc71), 0x01},
+	{CCI_REG8(0xfc72), 0x03},
+	{CCI_REG8(0xfc73), 0x01},
+	{CCI_REG8(0xfc74), 0x03},
+	{CCI_REG8(0xfc75), 0x01},
+	{CCI_REG8(0xfc76), 0x00},
+	{CCI_REG8(0xfc77), 0x01},
+	{CCI_REG8(0xfc78), 0x0d},
+	{CCI_REG8(0xfc79), 0x01},
+	{CCI_REG8(0xfc7a), 0x03},
+	{CCI_REG8(0xfc7b), 0x01},
+	{CCI_REG8(0xfc7c), 0x03},
+	{CCI_REG8(0xfc7d), 0x01},
+	{CCI_REG8(0xfc7e), 0xff},
+	{CCI_REG8(0xfc7f), 0x00},
+	{CCI_REG8(0xfc80), 0x23},
+	{CCI_REG8(0xfc81), 0x01},
+	{CCI_REG8(0xfc82), 0x07},
+	{CCI_REG8(0xfc83), 0x01},
+	{CCI_REG8(0xfc84), 0x07},
+	{CCI_REG8(0xfc85), 0x01},
+	{CCI_REG8(0xfc86), 0xfc},
+	{CCI_REG8(0xfc87), 0x00},
+	{CCI_REG8(0xfc88), 0x0f},
+	{CCI_REG8(0xfc89), 0x01},
+	{CCI_REG8(0xfc8a), 0x04},
+	{CCI_REG8(0xfc8b), 0x01},
+	{CCI_REG8(0xfc8c), 0x04},
+	{CCI_REG8(0xfc8d), 0x01},
+	{CCI_REG8(0xfc8e), 0xff},
+	{CCI_REG8(0xfc8f), 0x00},
+	{CCI_REG8(0xfc90), 0x25},
+	{CCI_REG8(0xfc91), 0x01},
+	{CCI_REG8(0xfc92), 0x06},
+	{CCI_REG8(0xfc93), 0x01},
+	{CCI_REG8(0xfc94), 0x06},
+	{CCI_REG8(0xfc95), 0x01},
+	{CCI_REG8(0xfc96), 0xf3},
+	{CCI_REG8(0xfc97), 0x00},
+	{CCI_REG8(0xfc98), 0x1b},
+	{CCI_REG8(0xfc99), 0x01},
+	{CCI_REG8(0xfc9a), 0x09},
+	{CCI_REG8(0xfc9b), 0x01},
+	{CCI_REG8(0xfc9c), 0x09},
+	{CCI_REG8(0xfc9d), 0x01},
+	{CCI_REG8(0xfc9e), 0xfe},
+	{CCI_REG8(0xfc9f), 0x00},
+	{CCI_REG8(0xfca0), 0x0e},
+	{CCI_REG8(0xfca1), 0x01},
+	{CCI_REG8(0xfca2), 0x07},
+	{CCI_REG8(0xfca3), 0x01},
+	{CCI_REG8(0xfca4), 0x07},
+	{CCI_REG8(0xfca5), 0x01},
+	{CCI_REG8(0xfca6), 0x02},
+	{CCI_REG8(0xfca7), 0x01},
+	{CCI_REG8(0xfca8), 0x09},
+	{CCI_REG8(0xfca9), 0x01},
+	{CCI_REG8(0xfcaa), 0x04},
+	{CCI_REG8(0xfcab), 0x01},
+	{CCI_REG8(0xfcac), 0x04},
+	{CCI_REG8(0xfcad), 0x01},
+	{CCI_REG8(0xfcae), 0x01},
+	{CCI_REG8(0xfcaf), 0x01},
+	{CCI_REG8(0xfcb0), 0x03},
+	{CCI_REG8(0xfcb1), 0x01},
+	{CCI_REG8(0xfcb2), 0x00},
+	{CCI_REG8(0xfcb3), 0x01},
+	{CCI_REG8(0xfcb4), 0x00},
+	{CCI_REG8(0xfcb5), 0x01},
+	{CCI_REG8(0xfcb6), 0xfe},
+	{CCI_REG8(0xfcb7), 0x00},
+	{CCI_REG8(0xfcb8), 0x06},
+	{CCI_REG8(0xfcb9), 0x01},
+	{CCI_REG8(0xfcba), 0x03},
+	{CCI_REG8(0xfcbb), 0x01},
+	{CCI_REG8(0xfcbc), 0x02},
+	{CCI_REG8(0xfcbd), 0x01},
+	{CCI_REG8(0xfcbe), 0x01},
+	{CCI_REG8(0xfcbf), 0x01},
+	{CCI_REG8(0xfcc0), 0x0c},
+	{CCI_REG8(0xfcc1), 0x01},
+	{CCI_REG8(0xfcc2), 0x03},
+	{CCI_REG8(0xfcc3), 0x01},
+	{CCI_REG8(0xfcc4), 0x03},
+	{CCI_REG8(0xfcc5), 0x01},
+	{CCI_REG8(0xfcc6), 0x01},
+	{CCI_REG8(0xfcc7), 0x01},
+	{CCI_REG8(0xfcc8), 0x13},
+	{CCI_REG8(0xfcc9), 0x01},
+	{CCI_REG8(0xfcca), 0x05},
+	{CCI_REG8(0xfccb), 0x01},
+	{CCI_REG8(0xfccc), 0x04},
+	{CCI_REG8(0xfccd), 0x01},
+	{CCI_REG8(0xfcce), 0x01},
+	{CCI_REG8(0xfccf), 0x01},
+	{CCI_REG8(0xfcd0), 0x2b},
+	{CCI_REG8(0xfcd1), 0x01},
+	{CCI_REG8(0xfcd2), 0x07},
+	{CCI_REG8(0xfcd3), 0x01},
+	{CCI_REG8(0xfcd4), 0x07},
+	{CCI_REG8(0xfcd5), 0x01},
+	{CCI_REG8(0xfcd6), 0xfb},
+	{CCI_REG8(0xfcd7), 0x00},
+	{CCI_REG8(0xfcd8), 0x14},
+	{CCI_REG8(0xfcd9), 0x01},
+	{CCI_REG8(0xfcda), 0x04},
+	{CCI_REG8(0xfcdb), 0x01},
+	{CCI_REG8(0xfcdc), 0x04},
+	{CCI_REG8(0xfcdd), 0x01},
+	{CCI_REG8(0xfcde), 0x01},
+	{CCI_REG8(0xfcdf), 0x01},
+	{CCI_REG8(0xfce0), 0x44},
+	{CCI_REG8(0xfce1), 0x01},
+	{CCI_REG8(0xfce2), 0x21},
+	{CCI_REG8(0xfce3), 0x01},
+	{CCI_REG8(0xfce4), 0x21},
+	{CCI_REG8(0xfce5), 0x01},
+	{CCI_REG8(0xfce6), 0x05},
+	{CCI_REG8(0xfce7), 0x01},
+	{CCI_REG8(0xfce8), 0x1e},
+	{CCI_REG8(0xfce9), 0x01},
+	{CCI_REG8(0xfcea), 0x06},
+	{CCI_REG8(0xfceb), 0x01},
+	{CCI_REG8(0xfcec), 0x06},
+	{CCI_REG8(0xfced), 0x01},
+	{CCI_REG8(0xfcee), 0xf8},
+	{CCI_REG8(0xfcef), 0x00},
+	{CCI_REG8(0xfcf0), 0x1a},
+	{CCI_REG8(0xfcf1), 0x01},
+	{CCI_REG8(0xfcf2), 0x0d},
+	{CCI_REG8(0xfcf3), 0x01},
+	{CCI_REG8(0xfcf4), 0x0d},
+	{CCI_REG8(0xfcf5), 0x01},
+	{CCI_REG8(0xfcf6), 0x05},
+	{CCI_REG8(0xfcf7), 0x01},
+	{CCI_REG8(0xfcf8), 0x0f},
+	{CCI_REG8(0xfcf9), 0x01},
+	{CCI_REG8(0xfcfa), 0x06},
+	{CCI_REG8(0xfcfb), 0x01},
+	{CCI_REG8(0xfcfc), 0x06},
+	{CCI_REG8(0xfcfd), 0x01},
+	{CCI_REG8(0xfcfe), 0x02},
+	{CCI_REG8(0xfcff), 0x01},
+	{CCI_REG8(0xfd00), 0x0c},
+	{CCI_REG8(0xfd01), 0x01},
+	{CCI_REG8(0xfd02), 0x04},
+	{CCI_REG8(0xfd03), 0x01},
+	{CCI_REG8(0xfd04), 0x04},
+	{CCI_REG8(0xfd05), 0x01},
+	{CCI_REG8(0xfd06), 0x00},
+	{CCI_REG8(0xfd07), 0x01},
+	{CCI_REG8(0xfd08), 0x0e},
+	{CCI_REG8(0xfd09), 0x01},
+	{CCI_REG8(0xfd0a), 0x03},
+	{CCI_REG8(0xfd0b), 0x01},
+	{CCI_REG8(0xfd0c), 0x03},
+	{CCI_REG8(0xfd0d), 0x01},
+	{CCI_REG8(0xfd0e), 0x00},
+	{CCI_REG8(0xfd0f), 0x01},
+	{CCI_REG8(0xfd10), 0x14},
+	{CCI_REG8(0xfd11), 0x01},
+	{CCI_REG8(0xfd12), 0x06},
+	{CCI_REG8(0xfd13), 0x01},
+	{CCI_REG8(0xfd14), 0x06},
+	{CCI_REG8(0xfd15), 0x01},
+	{CCI_REG8(0xfd16), 0x03},
+	{CCI_REG8(0xfd17), 0x01},
+	{CCI_REG8(0xfd18), 0x20},
+	{CCI_REG8(0xfd19), 0x01},
+	{CCI_REG8(0xfd1a), 0x07},
+	{CCI_REG8(0xfd1b), 0x01},
+	{CCI_REG8(0xfd1c), 0x07},
+	{CCI_REG8(0xfd1d), 0x01},
+	{CCI_REG8(0xfd1e), 0x01},
+	{CCI_REG8(0xfd1f), 0x01},
+	{CCI_REG8(0xfd20), 0x32},
+	{CCI_REG8(0xfd21), 0x01},
+	{CCI_REG8(0xfd22), 0x05},
+	{CCI_REG8(0xfd23), 0x01},
+	{CCI_REG8(0xfd24), 0x04},
+	{CCI_REG8(0xfd25), 0x01},
+	{CCI_REG8(0xfd26), 0xf5},
+	{CCI_REG8(0xfd27), 0x00},
+	{CCI_REG8(0xfd28), 0x1f},
+	{CCI_REG8(0xfd29), 0x01},
+	{CCI_REG8(0xfd2a), 0x05},
+	{CCI_REG8(0xfd2b), 0x01},
+	{CCI_REG8(0xfd2c), 0x05},
+	{CCI_REG8(0xfd2d), 0x01},
+	{CCI_REG8(0xfd2e), 0xfe},
+	{CCI_REG8(0xfd2f), 0x00},
+	{CCI_REG8(0xfd30), 0xfa},
+	{CCI_REG8(0xfd31), 0x00},
+	{CCI_REG8(0xfd32), 0xe2},
+	{CCI_REG8(0xfd33), 0x00},
+	{CCI_REG8(0xfd34), 0xe2},
+	{CCI_REG8(0xfd35), 0x00},
+	{CCI_REG8(0xfd36), 0xda},
+	{CCI_REG8(0xfd37), 0x00},
+	{CCI_REG8(0xfd38), 0x17},
+	{CCI_REG8(0xfd39), 0x01},
+	{CCI_REG8(0xfd3a), 0x0d},
+	{CCI_REG8(0xfd3b), 0x01},
+	{CCI_REG8(0xfd3c), 0x0d},
+	{CCI_REG8(0xfd3d), 0x01},
+	{CCI_REG8(0xfd3e), 0x07},
+	{CCI_REG8(0xfd3f), 0x01},
+	{CCI_REG8(0xfd40), 0xff},
+	{CCI_REG8(0xfd41), 0x00},
+	{CCI_REG8(0xfd42), 0x00},
+	{CCI_REG8(0xfd43), 0x01},
+	{CCI_REG8(0xfd44), 0x00},
+	{CCI_REG8(0xfd45), 0x01},
+	{CCI_REG8(0xfd46), 0x00},
+	{CCI_REG8(0xfd47), 0x01},
+	{CCI_REG8(0xfd48), 0x00},
+	{CCI_REG8(0xfd49), 0x01},
+	{CCI_REG8(0xfd4a), 0x01},
+	{CCI_REG8(0xfd4b), 0x01},
+	{CCI_REG8(0xfd4c), 0x02},
+	{CCI_REG8(0xfd4d), 0x01},
+	{CCI_REG8(0xfd4e), 0xfe},
+	{CCI_REG8(0xfd4f), 0x00},
+	{CCI_REG8(0xfd50), 0xf8},
+	{CCI_REG8(0xfd51), 0x00},
+	{CCI_REG8(0xfd52), 0xfc},
+	{CCI_REG8(0xfd53), 0x00},
+	{CCI_REG8(0xfd54), 0xfc},
+	{CCI_REG8(0xfd55), 0x00},
+	{CCI_REG8(0xfd56), 0xfe},
+	{CCI_REG8(0xfd57), 0x00},
+	{CCI_REG8(0xfd58), 0xfc},
+	{CCI_REG8(0xfd59), 0x00},
+	{CCI_REG8(0xfd5a), 0x00},
+	{CCI_REG8(0xfd5b), 0x01},
+	{CCI_REG8(0xfd5c), 0x01},
+	{CCI_REG8(0xfd5d), 0x01},
+	{CCI_REG8(0xfd5e), 0x01},
+	{CCI_REG8(0xfd5f), 0x01},
+	{CCI_REG8(0xfd60), 0x00},
+	{CCI_REG8(0xfd61), 0x01},
+	{CCI_REG8(0xfd62), 0xff},
+	{CCI_REG8(0xfd63), 0x00},
+	{CCI_REG8(0xfd64), 0x00},
+	{CCI_REG8(0xfd65), 0x01},
+	{CCI_REG8(0xfd66), 0xfe},
+	{CCI_REG8(0xfd67), 0x00},
+	{CCI_REG8(0xfd68), 0x03},
+	{CCI_REG8(0xfd69), 0x01},
+	{CCI_REG8(0xfd6a), 0x01},
+	{CCI_REG8(0xfd6b), 0x01},
+	{CCI_REG8(0xfd6c), 0x02},
+	{CCI_REG8(0xfd6d), 0x01},
+	{CCI_REG8(0xfd6e), 0x01},
+	{CCI_REG8(0xfd6f), 0x01},
+	{CCI_REG8(0xfd70), 0x20},
+	{CCI_REG8(0xfd71), 0x01},
+	{CCI_REG8(0xfd72), 0x0a},
+	{CCI_REG8(0xfd73), 0x01},
+	{CCI_REG8(0xfd74), 0x0a},
+	{CCI_REG8(0xfd75), 0x01},
+	{CCI_REG8(0xfd76), 0x02},
+	{CCI_REG8(0xfd77), 0x01},
+	{CCI_REG8(0xfd78), 0x06},
+	{CCI_REG8(0xfd79), 0x01},
+	{CCI_REG8(0xfd7a), 0x03},
+	{CCI_REG8(0xfd7b), 0x01},
+	{CCI_REG8(0xfd7c), 0x02},
+	{CCI_REG8(0xfd7d), 0x01},
+	{CCI_REG8(0xfd7e), 0x03},
+	{CCI_REG8(0xfd7f), 0x01},
+	{CCI_REG8(0xfd80), 0x54},
+	{CCI_REG8(0xfd81), 0x01},
+	{CCI_REG8(0xfd82), 0x22},
+	{CCI_REG8(0xfd83), 0x01},
+	{CCI_REG8(0xfd84), 0x22},
+	{CCI_REG8(0xfd85), 0x01},
+	{CCI_REG8(0xfd86), 0x13},
+	{CCI_REG8(0xfd87), 0x01},
+	{CCI_REG8(0xfd88), 0x1e},
+	{CCI_REG8(0xfd89), 0x01},
+	{CCI_REG8(0xfd8a), 0xff},
+	{CCI_REG8(0xfd8b), 0x00},
+	{CCI_REG8(0xfd8c), 0xfe},
+	{CCI_REG8(0xfd8d), 0x00},
+	{CCI_REG8(0xfd8e), 0xf9},
+	{CCI_REG8(0xfd8f), 0x00},
+	{CCI_REG8(0xfd90), 0x1a},
+	{CCI_REG8(0xfd91), 0x01},
+	{CCI_REG8(0xfd92), 0x06},
+	{CCI_REG8(0xfd93), 0x01},
+	{CCI_REG8(0xfd94), 0x06},
+	{CCI_REG8(0xfd95), 0x01},
+	{CCI_REG8(0xfd96), 0x02},
+	{CCI_REG8(0xfd97), 0x01},
+	{CCI_REG8(0xfd98), 0x0c},
+	{CCI_REG8(0xfd99), 0x01},
+	{CCI_REG8(0xfd9a), 0x02},
+	{CCI_REG8(0xfd9b), 0x01},
+	{CCI_REG8(0xfd9c), 0x01},
+	{CCI_REG8(0xfd9d), 0x01},
+	{CCI_REG8(0xfd9e), 0x01},
+	{CCI_REG8(0xfd9f), 0x01},
+	{CCI_REG8(0xfda0), 0x0a},
+	{CCI_REG8(0xfda1), 0x01},
+	{CCI_REG8(0xfda2), 0x01},
+	{CCI_REG8(0xfda3), 0x01},
+	{CCI_REG8(0xfda4), 0x01},
+	{CCI_REG8(0xfda5), 0x01},
+	{CCI_REG8(0xfda6), 0x00},
+	{CCI_REG8(0xfda7), 0x01},
+	{CCI_REG8(0xfda8), 0x09},
+	{CCI_REG8(0xfda9), 0x01},
+	{CCI_REG8(0xfdaa), 0x00},
+	{CCI_REG8(0xfdab), 0x01},
+	{CCI_REG8(0xfdac), 0xff},
+	{CCI_REG8(0xfdad), 0x00},
+	{CCI_REG8(0xfdae), 0xfe},
+	{CCI_REG8(0xfdaf), 0x00},
+	{CCI_REG8(0xfdb0), 0x0e},
+	{CCI_REG8(0xfdb1), 0x01},
+	{CCI_REG8(0xfdb2), 0x01},
+	{CCI_REG8(0xfdb3), 0x01},
+	{CCI_REG8(0xfdb4), 0x02},
+	{CCI_REG8(0xfdb5), 0x01},
+	{CCI_REG8(0xfdb6), 0x00},
+	{CCI_REG8(0xfdb7), 0x01},
+	{CCI_REG8(0xfdb8), 0x1b},
+	{CCI_REG8(0xfdb9), 0x01},
+	{CCI_REG8(0xfdba), 0x05},
+	{CCI_REG8(0xfdbb), 0x01},
+	{CCI_REG8(0xfdbc), 0x05},
+	{CCI_REG8(0xfdbd), 0x01},
+	{CCI_REG8(0xfdbe), 0xff},
+	{CCI_REG8(0xfdbf), 0x00},
+	{CCI_REG8(0xfdc0), 0x35},
+	{CCI_REG8(0xfdc1), 0x01},
+	{CCI_REG8(0xfdc2), 0x0d},
+	{CCI_REG8(0xfdc3), 0x01},
+	{CCI_REG8(0xfdc4), 0x0d},
+	{CCI_REG8(0xfdc5), 0x01},
+	{CCI_REG8(0xfdc6), 0x00},
+	{CCI_REG8(0xfdc7), 0x01},
+	{CCI_REG8(0xfdc8), 0x1b},
+	{CCI_REG8(0xfdc9), 0x01},
+	{CCI_REG8(0xfdca), 0x04},
+	{CCI_REG8(0xfdcb), 0x01},
+	{CCI_REG8(0xfdcc), 0x04},
+	{CCI_REG8(0xfdcd), 0x01},
+	{CCI_REG8(0xfdce), 0xfd},
+	{CCI_REG8(0xfdcf), 0x00},
+	{CCI_REG8(0xfdd0), 0x25},
+	{CCI_REG8(0xfdd1), 0x01},
+	{CCI_REG8(0xfdd2), 0x00},
+	{CCI_REG8(0xfdd3), 0x01},
+	{CCI_REG8(0xfdd4), 0x00},
+	{CCI_REG8(0xfdd5), 0x01},
+	{CCI_REG8(0xfdd6), 0xf7},
+	{CCI_REG8(0xfdd7), 0x00},
+	{CCI_REG8(0xfdd8), 0x17},
+	{CCI_REG8(0xfdd9), 0x01},
+	{CCI_REG8(0xfdda), 0x00},
+	{CCI_REG8(0xfddb), 0x01},
+	{CCI_REG8(0xfddc), 0x00},
+	{CCI_REG8(0xfddd), 0x01},
+	{CCI_REG8(0xfdde), 0xfa},
+	{CCI_REG8(0xfddf), 0x00},
+	{CCI_REG8(0xfde0), 0x0b},
+	{CCI_REG8(0xfde1), 0x01},
+	{CCI_REG8(0xfde2), 0x01},
+	{CCI_REG8(0xfde3), 0x01},
+	{CCI_REG8(0xfde4), 0x00},
+	{CCI_REG8(0xfde5), 0x01},
+	{CCI_REG8(0xfde6), 0xfe},
+	{CCI_REG8(0xfde7), 0x00},
+	{CCI_REG8(0xfde8), 0x05},
+	{CCI_REG8(0xfde9), 0x01},
+	{CCI_REG8(0xfdea), 0xff},
+	{CCI_REG8(0xfdeb), 0x00},
+	{CCI_REG8(0xfdec), 0xfe},
+	{CCI_REG8(0xfded), 0x00},
+	{CCI_REG8(0xfdee), 0xfd},
+	{CCI_REG8(0xfdef), 0x00},
+	{CCI_REG8(0xfdf0), 0x03},
+	{CCI_REG8(0xfdf1), 0x01},
+	{CCI_REG8(0xfdf2), 0x00},
+	{CCI_REG8(0xfdf3), 0x01},
+	{CCI_REG8(0xfdf4), 0xff},
+	{CCI_REG8(0xfdf5), 0x00},
+	{CCI_REG8(0xfdf6), 0xfe},
+	{CCI_REG8(0xfdf7), 0x00},
+	{CCI_REG8(0xfdf8), 0x05},
+	{CCI_REG8(0xfdf9), 0x01},
+	{CCI_REG8(0xfdfa), 0x02},
+	{CCI_REG8(0xfdfb), 0x01},
+	{CCI_REG8(0xfdfc), 0x02},
+	{CCI_REG8(0xfdfd), 0x01},
+	{CCI_REG8(0xfdfe), 0x00},
+	{CCI_REG8(0xfdff), 0x01},
+	{CCI_REG8(0xfe00), 0x08},
+	{CCI_REG8(0xfe01), 0x01},
+	{CCI_REG8(0xfe02), 0x01},
+	{CCI_REG8(0xfe03), 0x01},
+	{CCI_REG8(0xfe04), 0x01},
+	{CCI_REG8(0xfe05), 0x01},
+	{CCI_REG8(0xfe06), 0xfe},
+	{CCI_REG8(0xfe07), 0x00},
+	{CCI_REG8(0xfe08), 0x0d},
+	{CCI_REG8(0xfe09), 0x01},
+	{CCI_REG8(0xfe0a), 0x00},
+	{CCI_REG8(0xfe0b), 0x01},
+	{CCI_REG8(0xfe0c), 0x00},
+	{CCI_REG8(0xfe0d), 0x01},
+	{CCI_REG8(0xfe0e), 0xfd},
+	{CCI_REG8(0xfe0f), 0x00},
+	{CCI_REG8(0xfe10), 0x25},
+	{CCI_REG8(0xfe11), 0x01},
+	{CCI_REG8(0xfe12), 0x05},
+	{CCI_REG8(0xfe13), 0x01},
+	{CCI_REG8(0xfe14), 0x05},
+	{CCI_REG8(0xfe15), 0x01},
+	{CCI_REG8(0xfe16), 0xfe},
+	{CCI_REG8(0xfe17), 0x00},
+	{CCI_REG8(0xfe18), 0x0d},
+	{CCI_REG8(0xfe19), 0x01},
+	{CCI_REG8(0xfe1a), 0xff},
+	{CCI_REG8(0xfe1b), 0x00},
+	{CCI_REG8(0xfe1c), 0x00},
+	{CCI_REG8(0xfe1d), 0x01},
+	{CCI_REG8(0xfe1e), 0xfd},
+	{CCI_REG8(0xfe1f), 0x00},
+	{CCI_REG8(0xfe20), 0x23},
+	{CCI_REG8(0xfe21), 0x01},
+	{CCI_REG8(0xfe22), 0x00},
+	{CCI_REG8(0xfe23), 0x01},
+	{CCI_REG8(0xfe24), 0x00},
+	{CCI_REG8(0xfe25), 0x01},
+	{CCI_REG8(0xfe26), 0xf8},
+	{CCI_REG8(0xfe27), 0x00},
+	{CCI_REG8(0xfe28), 0x12},
+	{CCI_REG8(0xfe29), 0x01},
+	{CCI_REG8(0xfe2a), 0x00},
+	{CCI_REG8(0xfe2b), 0x01},
+	{CCI_REG8(0xfe2c), 0x00},
+	{CCI_REG8(0xfe2d), 0x01},
+	{CCI_REG8(0xfe2e), 0xfb},
+	{CCI_REG8(0xfe2f), 0x00},
+	{CCI_REG8(0xfe30), 0x06},
+	{CCI_REG8(0xfe31), 0x01},
+	{CCI_REG8(0xfe32), 0xff},
+	{CCI_REG8(0xfe33), 0x00},
+	{CCI_REG8(0xfe34), 0xff},
+	{CCI_REG8(0xfe35), 0x00},
+	{CCI_REG8(0xfe36), 0xfc},
+	{CCI_REG8(0xfe37), 0x00},
+	{CCI_REG8(0xfe38), 0x03},
+	{CCI_REG8(0xfe39), 0x01},
+	{CCI_REG8(0xfe3a), 0x01},
+	{CCI_REG8(0xfe3b), 0x01},
+	{CCI_REG8(0xfe3c), 0x00},
+	{CCI_REG8(0xfe3d), 0x01},
+	{CCI_REG8(0xfe3e), 0xff},
+	{CCI_REG8(0xfe3f), 0x00},
+	{CCI_REG8(0xfe40), 0x00},
+	{CCI_REG8(0xfe41), 0x01},
+	{CCI_REG8(0xfe42), 0x00},
+	{CCI_REG8(0xfe43), 0x01},
+	{CCI_REG8(0xfe44), 0x00},
+	{CCI_REG8(0xfe45), 0x01},
+	{CCI_REG8(0xfe46), 0x00},
+	{CCI_REG8(0xfe47), 0x01},
+	{CCI_REG8(0xfe48), 0x00},
+	{CCI_REG8(0xfe49), 0x01},
+	{CCI_REG8(0xfe4a), 0x00},
+	{CCI_REG8(0xfe4b), 0x01},
+	{CCI_REG8(0xfe4c), 0x00},
+	{CCI_REG8(0xfe4d), 0x01},
+	{CCI_REG8(0xfe4e), 0xff},
+	{CCI_REG8(0xfe4f), 0x00},
+	{CCI_REG8(0xfe50), 0x07},
+	{CCI_REG8(0xfe51), 0x01},
+	{CCI_REG8(0xfe52), 0x03},
+	{CCI_REG8(0xfe53), 0x01},
+	{CCI_REG8(0xfe54), 0x03},
+	{CCI_REG8(0xfe55), 0x01},
+	{CCI_REG8(0xfe56), 0x01},
+	{CCI_REG8(0xfe57), 0x01},
+	{CCI_REG8(0xfe58), 0x0a},
+	{CCI_REG8(0xfe59), 0x01},
+	{CCI_REG8(0xfe5a), 0x00},
+	{CCI_REG8(0xfe5b), 0x01},
+	{CCI_REG8(0xfe5c), 0x00},
+	{CCI_REG8(0xfe5d), 0x01},
+	{CCI_REG8(0xfe5e), 0xfe},
+	{CCI_REG8(0xfe5f), 0x00},
+	{CCI_REG8(0xfe60), 0x1d},
+	{CCI_REG8(0xfe61), 0x01},
+	{CCI_REG8(0xfe62), 0x01},
+	{CCI_REG8(0xfe63), 0x01},
+	{CCI_REG8(0xfe64), 0x02},
+	{CCI_REG8(0xfe65), 0x01},
+	{CCI_REG8(0xfe66), 0xfc},
+	{CCI_REG8(0xfe67), 0x00},
+	{CCI_REG8(0xfe68), 0x0b},
+	{CCI_REG8(0xfe69), 0x01},
+	{CCI_REG8(0xfe6a), 0x00},
+	{CCI_REG8(0xfe6b), 0x01},
+	{CCI_REG8(0xfe6c), 0x01},
+	{CCI_REG8(0xfe6d), 0x01},
+	{CCI_REG8(0xfe6e), 0xfe},
+	{CCI_REG8(0xfe6f), 0x00},
+	{CCI_REG8(0xfe70), 0x20},
+	{CCI_REG8(0xfe71), 0x01},
+	{CCI_REG8(0xfe72), 0xfe},
+	{CCI_REG8(0xfe73), 0x00},
+	{CCI_REG8(0xfe74), 0xfd},
+	{CCI_REG8(0xfe75), 0x00},
+	{CCI_REG8(0xfe76), 0xf5},
+	{CCI_REG8(0xfe77), 0x00},
+	{CCI_REG8(0xfe78), 0x12},
+	{CCI_REG8(0xfe79), 0x01},
+	{CCI_REG8(0xfe7a), 0x01},
+	{CCI_REG8(0xfe7b), 0x01},
+	{CCI_REG8(0xfe7c), 0x01},
+	{CCI_REG8(0xfe7d), 0x01},
+	{CCI_REG8(0xfe7e), 0xfd},
+	{CCI_REG8(0xfe7f), 0x00},
+	{CCI_REG8(0xfe80), 0x08},
+	{CCI_REG8(0xfe81), 0x01},
+	{CCI_REG8(0xfe82), 0x02},
+	{CCI_REG8(0xfe83), 0x01},
+	{CCI_REG8(0xfe84), 0x02},
+	{CCI_REG8(0xfe85), 0x01},
+	{CCI_REG8(0xfe86), 0xff},
+	{CCI_REG8(0xfe87), 0x00},
+	{CCI_REG8(0xfe88), 0x01},
+	{CCI_REG8(0xfe89), 0x01},
+	{CCI_REG8(0xfe8a), 0x00},
+	{CCI_REG8(0xfe8b), 0x01},
+	{CCI_REG8(0xfe8c), 0xff},
+	{CCI_REG8(0xfe8d), 0x00},
+	{CCI_REG8(0xfe8e), 0xfe},
+	{CCI_REG8(0xfe8f), 0x00},
+	{CCI_REG8(0xfe90), 0x00},
+	{CCI_REG8(0xfe91), 0x01},
+	{CCI_REG8(0xfe92), 0x01},
+	{CCI_REG8(0xfe93), 0x01},
+	{CCI_REG8(0xfe94), 0x01},
+	{CCI_REG8(0xfe95), 0x01},
+	{CCI_REG8(0xfe96), 0x01},
+	{CCI_REG8(0xfe97), 0x01},
+	{CCI_REG8(0xfe98), 0xff},
+	{CCI_REG8(0xfe99), 0x00},
+	{CCI_REG8(0xfe9a), 0xff},
+	{CCI_REG8(0xfe9b), 0x00},
+	{CCI_REG8(0xfe9c), 0xff},
+	{CCI_REG8(0xfe9d), 0x00},
+	{CCI_REG8(0xfe9e), 0xff},
+	{CCI_REG8(0xfe9f), 0x00},
+	{CCI_REG8(0xfea0), 0x05},
+	{CCI_REG8(0xfea1), 0x01},
+	{CCI_REG8(0xfea2), 0x01},
+	{CCI_REG8(0xfea3), 0x01},
+	{CCI_REG8(0xfea4), 0x01},
+	{CCI_REG8(0xfea5), 0x01},
+	{CCI_REG8(0xfea6), 0x00},
+	{CCI_REG8(0xfea7), 0x01},
+	{CCI_REG8(0xfea8), 0x09},
+	{CCI_REG8(0xfea9), 0x01},
+	{CCI_REG8(0xfeaa), 0x00},
+	{CCI_REG8(0xfeab), 0x01},
+	{CCI_REG8(0xfeac), 0x00},
+	{CCI_REG8(0xfead), 0x01},
+	{CCI_REG8(0xfeae), 0xfe},
+	{CCI_REG8(0xfeaf), 0x00},
+	{CCI_REG8(0xfeb0), 0x1a},
+	{CCI_REG8(0xfeb1), 0x01},
+	{CCI_REG8(0xfeb2), 0xfe},
+	{CCI_REG8(0xfeb3), 0x00},
+	{CCI_REG8(0xfeb4), 0xff},
+	{CCI_REG8(0xfeb5), 0x00},
+	{CCI_REG8(0xfeb6), 0xfa},
+	{CCI_REG8(0xfeb7), 0x00},
+	{CCI_REG8(0xfeb8), 0x0b},
+	{CCI_REG8(0xfeb9), 0x01},
+	{CCI_REG8(0xfeba), 0x00},
+	{CCI_REG8(0xfebb), 0x01},
+	{CCI_REG8(0xfebc), 0x00},
+	{CCI_REG8(0xfebd), 0x01},
+	{CCI_REG8(0xfebe), 0xff},
+	{CCI_REG8(0xfebf), 0x00},
+	{CCI_REG8(0xfec0), 0x1e},
+	{CCI_REG8(0xfec1), 0x01},
+	{CCI_REG8(0xfec2), 0xfb},
+	{CCI_REG8(0xfec3), 0x00},
+	{CCI_REG8(0xfec4), 0xfb},
+	{CCI_REG8(0xfec5), 0x00},
+	{CCI_REG8(0xfec6), 0xf2},
+	{CCI_REG8(0xfec7), 0x00},
+	{CCI_REG8(0xfec8), 0x16},
+	{CCI_REG8(0xfec9), 0x01},
+	{CCI_REG8(0xfeca), 0x01},
+	{CCI_REG8(0xfecb), 0x01},
+	{CCI_REG8(0xfecc), 0x00},
+	{CCI_REG8(0xfecd), 0x01},
+	{CCI_REG8(0xfece), 0xfa},
+	{CCI_REG8(0xfecf), 0x00},
+	{CCI_REG8(0xfed0), 0x09},
+	{CCI_REG8(0xfed1), 0x01},
+	{CCI_REG8(0xfed2), 0x00},
+	{CCI_REG8(0xfed3), 0x01},
+	{CCI_REG8(0xfed4), 0x00},
+	{CCI_REG8(0xfed5), 0x01},
+	{CCI_REG8(0xfed6), 0xfd},
+	{CCI_REG8(0xfed7), 0x00},
+	{CCI_REG8(0xfed8), 0x06},
+	{CCI_REG8(0xfed9), 0x01},
+	{CCI_REG8(0xfeda), 0x01},
+	{CCI_REG8(0xfedb), 0x01},
+	{CCI_REG8(0xfedc), 0x01},
+	{CCI_REG8(0xfedd), 0x01},
+	{CCI_REG8(0xfede), 0xff},
+	{CCI_REG8(0xfedf), 0x00},
+	{CCI_REG8(0xfee0), 0x01},
+	{CCI_REG8(0xfee1), 0x01},
+	{CCI_REG8(0xfee2), 0xfe},
+	{CCI_REG8(0xfee3), 0x00},
+	{CCI_REG8(0xfee4), 0xfe},
+	{CCI_REG8(0xfee5), 0x00},
+	{CCI_REG8(0xfee6), 0xfe},
+	{CCI_REG8(0xfee7), 0x00},
+	{CCI_REG8(0xfee8), 0x03},
+	{CCI_REG8(0xfee9), 0x01},
+	{CCI_REG8(0xfeea), 0x00},
+	{CCI_REG8(0xfeeb), 0x01},
+	{CCI_REG8(0xfeec), 0x00},
+	{CCI_REG8(0xfeed), 0x01},
+	{CCI_REG8(0xfeee), 0xff},
+	{CCI_REG8(0xfeef), 0x00},
+	{CCI_REG8(0xfef0), 0x07},
+	{CCI_REG8(0xfef1), 0x01},
+	{CCI_REG8(0xfef2), 0x00},
+	{CCI_REG8(0xfef3), 0x01},
+	{CCI_REG8(0xfef4), 0x00},
+	{CCI_REG8(0xfef5), 0x01},
+	{CCI_REG8(0xfef6), 0xff},
+	{CCI_REG8(0xfef7), 0x00},
+	{CCI_REG8(0xfef8), 0x0c},
+	{CCI_REG8(0xfef9), 0x01},
+	{CCI_REG8(0xfefa), 0xff},
+	{CCI_REG8(0xfefb), 0x00},
+	{CCI_REG8(0xfefc), 0xff},
+	{CCI_REG8(0xfefd), 0x00},
+	{CCI_REG8(0xfefe), 0xfd},
+	{CCI_REG8(0xfeff), 0x00},
+	{CCI_REG8(0xff00), 0x20},
+	{CCI_REG8(0xff01), 0x01},
+	{CCI_REG8(0xff02), 0xff},
+	{CCI_REG8(0xff03), 0x00},
+	{CCI_REG8(0xff04), 0x00},
+	{CCI_REG8(0xff05), 0x01},
+	{CCI_REG8(0xff06), 0xfa},
+	{CCI_REG8(0xff07), 0x00},
+	{CCI_REG8(0xff08), 0x0d},
+	{CCI_REG8(0xff09), 0x01},
+	{CCI_REG8(0xff0a), 0xff},
+	{CCI_REG8(0xff0b), 0x00},
+	{CCI_REG8(0xff0c), 0xff},
+	{CCI_REG8(0xff0d), 0x00},
+	{CCI_REG8(0xff0e), 0xfd},
+	{CCI_REG8(0xff0f), 0x00},
+	{CCI_REG8(0xff10), 0x3c},
+	{CCI_REG8(0xff11), 0x01},
+	{CCI_REG8(0xff12), 0x10},
+	{CCI_REG8(0xff13), 0x01},
+	{CCI_REG8(0xff14), 0x0f},
+	{CCI_REG8(0xff15), 0x01},
+	{CCI_REG8(0xff16), 0x01},
+	{CCI_REG8(0xff17), 0x01},
+	{CCI_REG8(0xff18), 0x19},
+	{CCI_REG8(0xff19), 0x01},
+	{CCI_REG8(0xff1a), 0xfc},
+	{CCI_REG8(0xff1b), 0x00},
+	{CCI_REG8(0xff1c), 0xfb},
+	{CCI_REG8(0xff1d), 0x00},
+	{CCI_REG8(0xff1e), 0xf5},
+	{CCI_REG8(0xff1f), 0x00},
+	{CCI_REG8(0xff20), 0x14},
+	{CCI_REG8(0xff21), 0x01},
+	{CCI_REG8(0xff22), 0x04},
+	{CCI_REG8(0xff23), 0x01},
+	{CCI_REG8(0xff24), 0x03},
+	{CCI_REG8(0xff25), 0x01},
+	{CCI_REG8(0xff26), 0xfe},
+	{CCI_REG8(0xff27), 0x00},
+	{CCI_REG8(0xff28), 0x0a},
+	{CCI_REG8(0xff29), 0x01},
+	{CCI_REG8(0xff2a), 0x01},
+	{CCI_REG8(0xff2b), 0x01},
+	{CCI_REG8(0xff2c), 0x01},
+	{CCI_REG8(0xff2d), 0x01},
+	{CCI_REG8(0xff2e), 0xff},
+	{CCI_REG8(0xff2f), 0x00},
+	{CCI_REG8(0xff30), 0x08},
+	{CCI_REG8(0xff31), 0x01},
+	{CCI_REG8(0xff32), 0x00},
+	{CCI_REG8(0xff33), 0x01},
+	{CCI_REG8(0xff34), 0xff},
+	{CCI_REG8(0xff35), 0x00},
+	{CCI_REG8(0xff36), 0xfe},
+	{CCI_REG8(0xff37), 0x00},
+	{CCI_REG8(0xff38), 0x07},
+	{CCI_REG8(0xff39), 0x01},
+	{CCI_REG8(0xff3a), 0xfe},
+	{CCI_REG8(0xff3b), 0x00},
+	{CCI_REG8(0xff3c), 0xfe},
+	{CCI_REG8(0xff3d), 0x00},
+	{CCI_REG8(0xff3e), 0xfd},
+	{CCI_REG8(0xff3f), 0x00},
+	{CCI_REG8(0xff40), 0x0c},
+	{CCI_REG8(0xff41), 0x01},
+	{CCI_REG8(0xff42), 0xff},
+	{CCI_REG8(0xff43), 0x00},
+	{CCI_REG8(0xff44), 0xff},
+	{CCI_REG8(0xff45), 0x00},
+	{CCI_REG8(0xff46), 0xfe},
+	{CCI_REG8(0xff47), 0x00},
+	{CCI_REG8(0xff48), 0x17},
+	{CCI_REG8(0xff49), 0x01},
+	{CCI_REG8(0xff4a), 0x00},
+	{CCI_REG8(0xff4b), 0x01},
+	{CCI_REG8(0xff4c), 0x00},
+	{CCI_REG8(0xff4d), 0x01},
+	{CCI_REG8(0xff4e), 0xfd},
+	{CCI_REG8(0xff4f), 0x00},
+	{CCI_REG8(0xff50), 0x25},
+	{CCI_REG8(0xff51), 0x01},
+	{CCI_REG8(0xff52), 0xfc},
+	{CCI_REG8(0xff53), 0x00},
+	{CCI_REG8(0xff54), 0xfd},
+	{CCI_REG8(0xff55), 0x00},
+	{CCI_REG8(0xff56), 0xf5},
+	{CCI_REG8(0xff57), 0x00},
+	{CCI_REG8(0xff58), 0x16},
+	{CCI_REG8(0xff59), 0x01},
+	{CCI_REG8(0xff5a), 0xfe},
+	{CCI_REG8(0xff5b), 0x00},
+	{CCI_REG8(0xff5c), 0xfe},
+	{CCI_REG8(0xff5d), 0x00},
+	{CCI_REG8(0xff5e), 0xfb},
+	{CCI_REG8(0xff5f), 0x00},
+	{CCI_REG8(0xff60), 0xf6},
+	{CCI_REG8(0xff61), 0x00},
+	{CCI_REG8(0xff62), 0xdf},
+	{CCI_REG8(0xff63), 0x00},
+	{CCI_REG8(0xff64), 0xdf},
+	{CCI_REG8(0xff65), 0x00},
+	{CCI_REG8(0xff66), 0xdc},
+	{CCI_REG8(0xff67), 0x00},
+	{CCI_REG8(0xff68), 0x12},
+	{CCI_REG8(0xff69), 0x01},
+	{CCI_REG8(0xff6a), 0x06},
+	{CCI_REG8(0xff6b), 0x01},
+	{CCI_REG8(0xff6c), 0x06},
+	{CCI_REG8(0xff6d), 0x01},
+	{CCI_REG8(0xff6e), 0x02},
+	{CCI_REG8(0xff6f), 0x01},
+	{CCI_REG8(0xff70), 0xfd},
+	{CCI_REG8(0xff71), 0x00},
+	{CCI_REG8(0xff72), 0xfd},
+	{CCI_REG8(0xff73), 0x00},
+	{CCI_REG8(0xff74), 0xfd},
+	{CCI_REG8(0xff75), 0x00},
+	{CCI_REG8(0xff76), 0xfd},
+	{CCI_REG8(0xff77), 0x00},
+	{CCI_REG8(0xff78), 0x00},
+	{CCI_REG8(0xff79), 0x01},
+	{CCI_REG8(0xff7a), 0x01},
+	{CCI_REG8(0xff7b), 0x01},
+	{CCI_REG8(0xff7c), 0x01},
+	{CCI_REG8(0xff7d), 0x01},
+	{CCI_REG8(0xff7e), 0xff},
+	{CCI_REG8(0xff7f), 0x00},
+	{CCI_REG8(0xff80), 0xf8},
+	{CCI_REG8(0xff81), 0x00},
+	{CCI_REG8(0xff82), 0xfd},
+	{CCI_REG8(0xff83), 0x00},
+	{CCI_REG8(0xff84), 0xfd},
+	{CCI_REG8(0xff85), 0x00},
+	{CCI_REG8(0xff86), 0xfe},
+	{CCI_REG8(0xff87), 0x00},
+	{CCI_REG8(0xff88), 0xfd},
+	{CCI_REG8(0xff89), 0x00},
+	{CCI_REG8(0xff8a), 0x01},
+	{CCI_REG8(0xff8b), 0x01},
+	{CCI_REG8(0xff8c), 0x01},
+	{CCI_REG8(0xff8d), 0x01},
+	{CCI_REG8(0xff8e), 0x01},
+	{CCI_REG8(0xff8f), 0x01},
+	{CCI_REG8(0xff90), 0x01},
+	{CCI_REG8(0xff91), 0x01},
+	{CCI_REG8(0xff92), 0x00},
+	{CCI_REG8(0xff93), 0x01},
+	{CCI_REG8(0xff94), 0x01},
+	{CCI_REG8(0xff95), 0x01},
+	{CCI_REG8(0xff96), 0x00},
+	{CCI_REG8(0xff97), 0x01},
+	{CCI_REG8(0xff98), 0xff},
+	{CCI_REG8(0xff99), 0x00},
+	{CCI_REG8(0xff9a), 0xfd},
+	{CCI_REG8(0xff9b), 0x00},
+	{CCI_REG8(0xff9c), 0xfe},
+	{CCI_REG8(0xff9d), 0x00},
+	{CCI_REG8(0xff9e), 0xfd},
+	{CCI_REG8(0xff9f), 0x00},
+	{CCI_REG8(0xffa0), 0x18},
+	{CCI_REG8(0xffa1), 0x01},
+	{CCI_REG8(0xffa2), 0x01},
+	{CCI_REG8(0xffa3), 0x01},
+	{CCI_REG8(0xffa4), 0x02},
+	{CCI_REG8(0xffa5), 0x01},
+	{CCI_REG8(0xffa6), 0x00},
+	{CCI_REG8(0xffa7), 0x01},
+	{CCI_REG8(0xffa8), 0x02},
+	{CCI_REG8(0xffa9), 0x01},
+	{CCI_REG8(0xffaa), 0x00},
+	{CCI_REG8(0xffab), 0x01},
+	{CCI_REG8(0xffac), 0x00},
+	{CCI_REG8(0xffad), 0x01},
+	{CCI_REG8(0xffae), 0x00},
+	{CCI_REG8(0xffaf), 0x01},
+	{CCI_REG8(0xffff), 0x00},
+	{CCI_REG8(0x9bfa), 0x01},
+	{CCI_REG8(0x9bfb), 0x00},
+	{CCI_REG8(0x9cbc), 0xab},
+	{CCI_REG8(0x9cbd), 0x0f},
+	{CCI_REG8(0x9cbe), 0xab},
+	{CCI_REG8(0x9cbf), 0x0f},
+	{CCI_REG8(0x9cc0), 0xca},
+	{CCI_REG8(0x9cc1), 0x0f},
+	{CCI_REG8(0x9cc2), 0xca},
+	{CCI_REG8(0x9cc3), 0x0f},
+	{CCI_REG8(0x9cc4), 0xc8},
+	{CCI_REG8(0x9cc5), 0x0f},
+	{CCI_REG8(0x9cc6), 0xc8},
+	{CCI_REG8(0x9cc7), 0x0f},
+	{CCI_REG8(0x9cc8), 0xb0},
+	{CCI_REG8(0x9cc9), 0x0f},
+	{CCI_REG8(0x9cca), 0xb0},
+	{CCI_REG8(0x9ccb), 0x0f},
+	{CCI_REG8(0x9ccc), 0x94},
+	{CCI_REG8(0x9ccd), 0x0f},
+	{CCI_REG8(0x9cce), 0x94},
+	{CCI_REG8(0x9ccf), 0x0f},
+	{CCI_REG8(0x9cd0), 0x83},
+	{CCI_REG8(0x9cd1), 0x0f},
+	{CCI_REG8(0x9cd2), 0x83},
+	{CCI_REG8(0x9cd3), 0x0f},
+	{CCI_REG8(0x9cd4), 0x80},
+	{CCI_REG8(0x9cd5), 0x0f},
+	{CCI_REG8(0x9cd6), 0x80},
+	{CCI_REG8(0x9cd7), 0x0f},
+	{CCI_REG8(0x9cd8), 0xac},
+	{CCI_REG8(0x9cd9), 0x0f},
+	{CCI_REG8(0x9cda), 0xac},
+	{CCI_REG8(0x9cdb), 0x0f},
+	{CCI_REG8(0x9cdc), 0x0f},
+	{CCI_REG8(0x9cdd), 0x12},
+	{CCI_REG8(0x9cde), 0x0f},
+	{CCI_REG8(0x9cdf), 0x12},
+	{CCI_REG8(0x9ce0), 0x34},
+	{CCI_REG8(0x9ce1), 0x12},
+	{CCI_REG8(0x9ce2), 0x34},
+	{CCI_REG8(0x9ce3), 0x12},
+	{CCI_REG8(0x9ce4), 0x3d},
+	{CCI_REG8(0x9ce5), 0x12},
+	{CCI_REG8(0x9ce6), 0x3d},
+	{CCI_REG8(0x9ce7), 0x12},
+	{CCI_REG8(0x9ce8), 0xf1},
+	{CCI_REG8(0x9ce9), 0x11},
+	{CCI_REG8(0x9cea), 0xf1},
+	{CCI_REG8(0x9ceb), 0x11},
+	{CCI_REG8(0x9cec), 0xe4},
+	{CCI_REG8(0x9ced), 0x0f},
+	{CCI_REG8(0x9cee), 0xe4},
+	{CCI_REG8(0x9cef), 0x0f},
+	{CCI_REG8(0x9cf0), 0x0a},
+	{CCI_REG8(0x9cf1), 0x10},
+	{CCI_REG8(0x9cf2), 0x0a},
+	{CCI_REG8(0x9cf3), 0x10},
+	{CCI_REG8(0x9cf4), 0x09},
+	{CCI_REG8(0x9cf5), 0x10},
+	{CCI_REG8(0x9cf6), 0x09},
+	{CCI_REG8(0x9cf7), 0x10},
+	{CCI_REG8(0x9cf8), 0xfb},
+	{CCI_REG8(0x9cf9), 0x0f},
+	{CCI_REG8(0x9cfa), 0xfb},
+	{CCI_REG8(0x9cfb), 0x0f},
+	{CCI_REG8(0xc8f1), 0xab},
+	{CCI_REG8(0xc8f2), 0x0f},
+	{CCI_REG8(0xc8f3), 0xab},
+	{CCI_REG8(0xc8f4), 0x0f},
+	{CCI_REG8(0xc8f5), 0xca},
+	{CCI_REG8(0xc8f6), 0x0f},
+	{CCI_REG8(0xc8f7), 0xca},
+	{CCI_REG8(0xc8f8), 0x0f},
+	{CCI_REG8(0xc8f9), 0xc8},
+	{CCI_REG8(0xc8fa), 0x0f},
+	{CCI_REG8(0xc8fb), 0xc8},
+	{CCI_REG8(0xc8fc), 0x0f},
+	{CCI_REG8(0xc8fd), 0xb0},
+	{CCI_REG8(0xc8fe), 0x0f},
+	{CCI_REG8(0xc8ff), 0xb0},
+	{CCI_REG8(0xc900), 0x0f},
+	{CCI_REG8(0xc901), 0x94},
+	{CCI_REG8(0xc902), 0x0f},
+	{CCI_REG8(0xc903), 0x94},
+	{CCI_REG8(0xc904), 0x0f},
+	{CCI_REG8(0xc905), 0x83},
+	{CCI_REG8(0xc906), 0x0f},
+	{CCI_REG8(0xc907), 0x83},
+	{CCI_REG8(0xc908), 0x0f},
+	{CCI_REG8(0xc909), 0x80},
+	{CCI_REG8(0xc90a), 0x0f},
+	{CCI_REG8(0xc90b), 0x80},
+	{CCI_REG8(0xc90c), 0x0f},
+	{CCI_REG8(0xc90d), 0xac},
+	{CCI_REG8(0xc90e), 0x0f},
+	{CCI_REG8(0xc90f), 0xac},
+	{CCI_REG8(0xc910), 0x0f},
+	{CCI_REG8(0xc911), 0x0f},
+	{CCI_REG8(0xc912), 0x12},
+	{CCI_REG8(0xc913), 0x0f},
+	{CCI_REG8(0xc914), 0x12},
+	{CCI_REG8(0xc915), 0x34},
+	{CCI_REG8(0xc916), 0x12},
+	{CCI_REG8(0xc917), 0x34},
+	{CCI_REG8(0xc918), 0x12},
+	{CCI_REG8(0xc919), 0x3d},
+	{CCI_REG8(0xc91a), 0x12},
+	{CCI_REG8(0xc91b), 0x3d},
+	{CCI_REG8(0xc91c), 0x12},
+	{CCI_REG8(0xc91d), 0xf1},
+	{CCI_REG8(0xc91e), 0x11},
+	{CCI_REG8(0xc91f), 0xf1},
+	{CCI_REG8(0xc920), 0x11},
+	{CCI_REG8(0xc921), 0xe4},
+	{CCI_REG8(0xc922), 0x0f},
+	{CCI_REG8(0xc923), 0xe4},
+	{CCI_REG8(0xc924), 0x0f},
+	{CCI_REG8(0xc925), 0x0a},
+	{CCI_REG8(0xc926), 0x10},
+	{CCI_REG8(0xc927), 0x0a},
+	{CCI_REG8(0xc928), 0x10},
+	{CCI_REG8(0xc929), 0x09},
+	{CCI_REG8(0xc92a), 0x10},
+	{CCI_REG8(0xc92b), 0x09},
+	{CCI_REG8(0xc92c), 0x10},
+	{CCI_REG8(0xc92d), 0xfb},
+	{CCI_REG8(0xc92e), 0x0f},
+	{CCI_REG8(0xc92f), 0xfb},
+	{CCI_REG8(0xc930), 0x0f},
+	{CCI_REG8(0xca27), 0xab},
+	{CCI_REG8(0xca28), 0x0f},
+	{CCI_REG8(0xca29), 0xab},
+	{CCI_REG8(0xca2a), 0x0f},
+	{CCI_REG8(0xca2b), 0xca},
+	{CCI_REG8(0xca2c), 0x0f},
+	{CCI_REG8(0xca2d), 0xca},
+	{CCI_REG8(0xca2e), 0x0f},
+	{CCI_REG8(0xca2f), 0xc8},
+	{CCI_REG8(0xca30), 0x0f},
+	{CCI_REG8(0xca31), 0xc8},
+	{CCI_REG8(0xca32), 0x0f},
+	{CCI_REG8(0xca33), 0xb0},
+	{CCI_REG8(0xca34), 0x0f},
+	{CCI_REG8(0xca35), 0xb0},
+	{CCI_REG8(0xca36), 0x0f},
+	{CCI_REG8(0xca37), 0x94},
+	{CCI_REG8(0xca38), 0x0f},
+	{CCI_REG8(0xca39), 0x94},
+	{CCI_REG8(0xca3a), 0x0f},
+	{CCI_REG8(0xca3b), 0x83},
+	{CCI_REG8(0xca3c), 0x0f},
+	{CCI_REG8(0xca3d), 0x83},
+	{CCI_REG8(0xca3e), 0x0f},
+	{CCI_REG8(0xca3f), 0x80},
+	{CCI_REG8(0xca40), 0x0f},
+	{CCI_REG8(0xca41), 0x80},
+	{CCI_REG8(0xca42), 0x0f},
+	{CCI_REG8(0xca43), 0xac},
+	{CCI_REG8(0xca44), 0x0f},
+	{CCI_REG8(0xca45), 0xac},
+	{CCI_REG8(0xca46), 0x0f},
+	{CCI_REG8(0xca47), 0x0f},
+	{CCI_REG8(0xca48), 0x12},
+	{CCI_REG8(0xca49), 0x0f},
+	{CCI_REG8(0xca4a), 0x12},
+	{CCI_REG8(0xca4b), 0x34},
+	{CCI_REG8(0xca4c), 0x12},
+	{CCI_REG8(0xca4d), 0x34},
+	{CCI_REG8(0xca4e), 0x12},
+	{CCI_REG8(0xca4f), 0x3d},
+	{CCI_REG8(0xca50), 0x12},
+	{CCI_REG8(0xca51), 0x3d},
+	{CCI_REG8(0xca52), 0x12},
+	{CCI_REG8(0xca53), 0xf1},
+	{CCI_REG8(0xca54), 0x11},
+	{CCI_REG8(0xca55), 0xf1},
+	{CCI_REG8(0xca56), 0x11},
+	{CCI_REG8(0xca57), 0xe4},
+	{CCI_REG8(0xca58), 0x0f},
+	{CCI_REG8(0xca59), 0xe4},
+	{CCI_REG8(0xca5a), 0x0f},
+	{CCI_REG8(0xca5b), 0x0a},
+	{CCI_REG8(0xca5c), 0x10},
+	{CCI_REG8(0xca5d), 0x0a},
+	{CCI_REG8(0xca5e), 0x10},
+	{CCI_REG8(0xca5f), 0x09},
+	{CCI_REG8(0xca60), 0x10},
+	{CCI_REG8(0xca61), 0x09},
+	{CCI_REG8(0xca62), 0x10},
+	{CCI_REG8(0xca63), 0xfb},
+	{CCI_REG8(0xca64), 0x0f},
+	{CCI_REG8(0xca65), 0xfb},
+	{CCI_REG8(0xca66), 0x0f},
+	{CCI_REG8(0xcb5d), 0xab},
+	{CCI_REG8(0xcb5e), 0x0f},
+	{CCI_REG8(0xcb5f), 0xab},
+	{CCI_REG8(0xcb60), 0x0f},
+	{CCI_REG8(0xcb61), 0xca},
+	{CCI_REG8(0xcb62), 0x0f},
+	{CCI_REG8(0xcb63), 0xca},
+	{CCI_REG8(0xcb64), 0x0f},
+	{CCI_REG8(0xcb65), 0xc8},
+	{CCI_REG8(0xcb66), 0x0f},
+	{CCI_REG8(0xcb67), 0xc8},
+	{CCI_REG8(0xcb68), 0x0f},
+	{CCI_REG8(0xcb69), 0xb0},
+	{CCI_REG8(0xcb6a), 0x0f},
+	{CCI_REG8(0xcb6b), 0xb0},
+	{CCI_REG8(0xcb6c), 0x0f},
+	{CCI_REG8(0xcb6d), 0x94},
+	{CCI_REG8(0xcb6e), 0x0f},
+	{CCI_REG8(0xcb6f), 0x94},
+	{CCI_REG8(0xcb70), 0x0f},
+	{CCI_REG8(0xcb71), 0x83},
+	{CCI_REG8(0xcb72), 0x0f},
+	{CCI_REG8(0xcb73), 0x83},
+	{CCI_REG8(0xcb74), 0x0f},
+	{CCI_REG8(0xcb75), 0x80},
+	{CCI_REG8(0xcb76), 0x0f},
+	{CCI_REG8(0xcb77), 0x80},
+	{CCI_REG8(0xcb78), 0x0f},
+	{CCI_REG8(0xcb79), 0xac},
+	{CCI_REG8(0xcb7a), 0x0f},
+	{CCI_REG8(0xcb7b), 0xac},
+	{CCI_REG8(0xcb7c), 0x0f},
+	{CCI_REG8(0xcb7d), 0x0f},
+	{CCI_REG8(0xcb7e), 0x12},
+	{CCI_REG8(0xcb7f), 0x0f},
+	{CCI_REG8(0xcb80), 0x12},
+	{CCI_REG8(0xcb81), 0x34},
+	{CCI_REG8(0xcb82), 0x12},
+	{CCI_REG8(0xcb83), 0x34},
+	{CCI_REG8(0xcb84), 0x12},
+	{CCI_REG8(0xcb85), 0x3d},
+	{CCI_REG8(0xcb86), 0x12},
+	{CCI_REG8(0xcb87), 0x3d},
+	{CCI_REG8(0xcb88), 0x12},
+	{CCI_REG8(0xcb89), 0xf1},
+	{CCI_REG8(0xcb8a), 0x11},
+	{CCI_REG8(0xcb8b), 0xf1},
+	{CCI_REG8(0xcb8c), 0x11},
+	{CCI_REG8(0xcb8d), 0xe4},
+	{CCI_REG8(0xcb8e), 0x0f},
+	{CCI_REG8(0xcb8f), 0xe4},
+	{CCI_REG8(0xcb90), 0x0f},
+	{CCI_REG8(0xcb91), 0x0a},
+	{CCI_REG8(0xcb92), 0x10},
+	{CCI_REG8(0xcb93), 0x0a},
+	{CCI_REG8(0xcb94), 0x10},
+	{CCI_REG8(0xcb95), 0x09},
+	{CCI_REG8(0xcb96), 0x10},
+	{CCI_REG8(0xcb97), 0x09},
+	{CCI_REG8(0xcb98), 0x10},
+	{CCI_REG8(0xcb99), 0xfb},
+	{CCI_REG8(0xcb9a), 0x0f},
+	{CCI_REG8(0xcb9b), 0xfb},
+	{CCI_REG8(0xcb9c), 0x0f},
+	{CCI_REG8(0xcc93), 0xab},
+	{CCI_REG8(0xcc94), 0x0f},
+	{CCI_REG8(0xcc95), 0xab},
+	{CCI_REG8(0xcc96), 0x0f},
+	{CCI_REG8(0xcc97), 0xca},
+	{CCI_REG8(0xcc98), 0x0f},
+	{CCI_REG8(0xcc99), 0xca},
+	{CCI_REG8(0xcc9a), 0x0f},
+	{CCI_REG8(0xcc9b), 0xc8},
+	{CCI_REG8(0xcc9c), 0x0f},
+	{CCI_REG8(0xcc9d), 0xc8},
+	{CCI_REG8(0xcc9e), 0x0f},
+	{CCI_REG8(0xcc9f), 0xb0},
+	{CCI_REG8(0xcca0), 0x0f},
+	{CCI_REG8(0xcca1), 0xb0},
+	{CCI_REG8(0xcca2), 0x0f},
+	{CCI_REG8(0xcca3), 0x94},
+	{CCI_REG8(0xcca4), 0x0f},
+	{CCI_REG8(0xcca5), 0x94},
+	{CCI_REG8(0xcca6), 0x0f},
+	{CCI_REG8(0xcca7), 0x83},
+	{CCI_REG8(0xcca8), 0x0f},
+	{CCI_REG8(0xcca9), 0x83},
+	{CCI_REG8(0xccaa), 0x0f},
+	{CCI_REG8(0xccab), 0x80},
+	{CCI_REG8(0xccac), 0x0f},
+	{CCI_REG8(0xccad), 0x80},
+	{CCI_REG8(0xccae), 0x0f},
+	{CCI_REG8(0xccaf), 0xac},
+	{CCI_REG8(0xccb0), 0x0f},
+	{CCI_REG8(0xccb1), 0xac},
+	{CCI_REG8(0xccb2), 0x0f},
+	{CCI_REG8(0xccb3), 0x0f},
+	{CCI_REG8(0xccb4), 0x12},
+	{CCI_REG8(0xccb5), 0x0f},
+	{CCI_REG8(0xccb6), 0x12},
+	{CCI_REG8(0xccb7), 0x34},
+	{CCI_REG8(0xccb8), 0x12},
+	{CCI_REG8(0xccb9), 0x34},
+	{CCI_REG8(0xccba), 0x12},
+	{CCI_REG8(0xccbb), 0x3d},
+	{CCI_REG8(0xccbc), 0x12},
+	{CCI_REG8(0xccbd), 0x3d},
+	{CCI_REG8(0xccbe), 0x12},
+	{CCI_REG8(0xccbf), 0xf1},
+	{CCI_REG8(0xccc0), 0x11},
+	{CCI_REG8(0xccc1), 0xf1},
+	{CCI_REG8(0xccc2), 0x11},
+	{CCI_REG8(0xccc3), 0xe4},
+	{CCI_REG8(0xccc4), 0x0f},
+	{CCI_REG8(0xccc5), 0xe4},
+	{CCI_REG8(0xccc6), 0x0f},
+	{CCI_REG8(0xccc7), 0x0a},
+	{CCI_REG8(0xccc8), 0x10},
+	{CCI_REG8(0xccc9), 0x0a},
+	{CCI_REG8(0xccca), 0x10},
+	{CCI_REG8(0xcccb), 0x09},
+	{CCI_REG8(0xcccc), 0x10},
+	{CCI_REG8(0xcccd), 0x09},
+	{CCI_REG8(0xccce), 0x10},
+	{CCI_REG8(0xcccf), 0xfb},
+	{CCI_REG8(0xccd0), 0x0f},
+	{CCI_REG8(0xccd1), 0xfb},
+	{CCI_REG8(0xccd2), 0x0f},
+	{CCI_REG8(0xcdc9), 0xab},
+	{CCI_REG8(0xcdca), 0x0f},
+	{CCI_REG8(0xcdcb), 0xab},
+	{CCI_REG8(0xcdcc), 0x0f},
+	{CCI_REG8(0xcdcd), 0xca},
+	{CCI_REG8(0xcdce), 0x0f},
+	{CCI_REG8(0xcdcf), 0xca},
+	{CCI_REG8(0xcdd0), 0x0f},
+	{CCI_REG8(0xcdd1), 0xc8},
+	{CCI_REG8(0xcdd2), 0x0f},
+	{CCI_REG8(0xcdd3), 0xc8},
+	{CCI_REG8(0xcdd4), 0x0f},
+	{CCI_REG8(0xcdd5), 0xb0},
+	{CCI_REG8(0xcdd6), 0x0f},
+	{CCI_REG8(0xcdd7), 0xb0},
+	{CCI_REG8(0xcdd8), 0x0f},
+	{CCI_REG8(0xcdd9), 0x94},
+	{CCI_REG8(0xcdda), 0x0f},
+	{CCI_REG8(0xcddb), 0x94},
+	{CCI_REG8(0xcddc), 0x0f},
+	{CCI_REG8(0xcddd), 0x83},
+	{CCI_REG8(0xcdde), 0x0f},
+	{CCI_REG8(0xcddf), 0x83},
+	{CCI_REG8(0xcde0), 0x0f},
+	{CCI_REG8(0xcde1), 0x80},
+	{CCI_REG8(0xcde2), 0x0f},
+	{CCI_REG8(0xcde3), 0x80},
+	{CCI_REG8(0xcde4), 0x0f},
+	{CCI_REG8(0xcde5), 0xac},
+	{CCI_REG8(0xcde6), 0x0f},
+	{CCI_REG8(0xcde7), 0xac},
+	{CCI_REG8(0xcde8), 0x0f},
+	{CCI_REG8(0xcde9), 0x0f},
+	{CCI_REG8(0xcdea), 0x12},
+	{CCI_REG8(0xcdeb), 0x0f},
+	{CCI_REG8(0xcdec), 0x12},
+	{CCI_REG8(0xcded), 0x34},
+	{CCI_REG8(0xcdee), 0x12},
+	{CCI_REG8(0xcdef), 0x34},
+	{CCI_REG8(0xcdf0), 0x12},
+	{CCI_REG8(0xcdf1), 0x3d},
+	{CCI_REG8(0xcdf2), 0x12},
+	{CCI_REG8(0xcdf3), 0x3d},
+	{CCI_REG8(0xcdf4), 0x12},
+	{CCI_REG8(0xcdf5), 0xf1},
+	{CCI_REG8(0xcdf6), 0x11},
+	{CCI_REG8(0xcdf7), 0xf1},
+	{CCI_REG8(0xcdf8), 0x11},
+	{CCI_REG8(0xcdf9), 0xe4},
+	{CCI_REG8(0xcdfa), 0x0f},
+	{CCI_REG8(0xcdfb), 0xe4},
+	{CCI_REG8(0xcdfc), 0x0f},
+	{CCI_REG8(0xcdfd), 0x0a},
+	{CCI_REG8(0xcdfe), 0x10},
+	{CCI_REG8(0xcdff), 0x0a},
+	{CCI_REG8(0xce00), 0x10},
+	{CCI_REG8(0xce01), 0x09},
+	{CCI_REG8(0xce02), 0x10},
+	{CCI_REG8(0xce03), 0x09},
+	{CCI_REG8(0xce04), 0x10},
+	{CCI_REG8(0xce05), 0xfb},
+	{CCI_REG8(0xce06), 0x0f},
+	{CCI_REG8(0xce07), 0xfb},
+	{CCI_REG8(0xce08), 0x0f},
+	{CCI_REG8(0xceff), 0xab},
+	{CCI_REG8(0xcf00), 0x0f},
+	{CCI_REG8(0xcf01), 0xab},
+	{CCI_REG8(0xcf02), 0x0f},
+	{CCI_REG8(0xcf03), 0xca},
+	{CCI_REG8(0xcf04), 0x0f},
+	{CCI_REG8(0xcf05), 0xca},
+	{CCI_REG8(0xcf06), 0x0f},
+	{CCI_REG8(0xcf07), 0xc8},
+	{CCI_REG8(0xcf08), 0x0f},
+	{CCI_REG8(0xcf09), 0xc8},
+	{CCI_REG8(0xcf0a), 0x0f},
+	{CCI_REG8(0xcf0b), 0xb0},
+	{CCI_REG8(0xcf0c), 0x0f},
+	{CCI_REG8(0xcf0d), 0xb0},
+	{CCI_REG8(0xcf0e), 0x0f},
+	{CCI_REG8(0xcf0f), 0x94},
+	{CCI_REG8(0xcf10), 0x0f},
+	{CCI_REG8(0xcf11), 0x94},
+	{CCI_REG8(0xcf12), 0x0f},
+	{CCI_REG8(0xcf13), 0x83},
+	{CCI_REG8(0xcf14), 0x0f},
+	{CCI_REG8(0xcf15), 0x83},
+	{CCI_REG8(0xcf16), 0x0f},
+	{CCI_REG8(0xcf17), 0x80},
+	{CCI_REG8(0xcf18), 0x0f},
+	{CCI_REG8(0xcf19), 0x80},
+	{CCI_REG8(0xcf1a), 0x0f},
+	{CCI_REG8(0xcf1b), 0xac},
+	{CCI_REG8(0xcf1c), 0x0f},
+	{CCI_REG8(0xcf1d), 0xac},
+	{CCI_REG8(0xcf1e), 0x0f},
+	{CCI_REG8(0xcf1f), 0x0f},
+	{CCI_REG8(0xcf20), 0x12},
+	{CCI_REG8(0xcf21), 0x0f},
+	{CCI_REG8(0xcf22), 0x12},
+	{CCI_REG8(0xcf23), 0x34},
+	{CCI_REG8(0xcf24), 0x12},
+	{CCI_REG8(0xcf25), 0x34},
+	{CCI_REG8(0xcf26), 0x12},
+	{CCI_REG8(0xcf27), 0x3d},
+	{CCI_REG8(0xcf28), 0x12},
+	{CCI_REG8(0xcf29), 0x3d},
+	{CCI_REG8(0xcf2a), 0x12},
+	{CCI_REG8(0xcf2b), 0xf1},
+	{CCI_REG8(0xcf2c), 0x11},
+	{CCI_REG8(0xcf2d), 0xf1},
+	{CCI_REG8(0xcf2e), 0x11},
+	{CCI_REG8(0xcf2f), 0xe4},
+	{CCI_REG8(0xcf30), 0x0f},
+	{CCI_REG8(0xcf31), 0xe4},
+	{CCI_REG8(0xcf32), 0x0f},
+	{CCI_REG8(0xcf33), 0x0a},
+	{CCI_REG8(0xcf34), 0x10},
+	{CCI_REG8(0xcf35), 0x0a},
+	{CCI_REG8(0xcf36), 0x10},
+	{CCI_REG8(0xcf37), 0x09},
+	{CCI_REG8(0xcf38), 0x10},
+	{CCI_REG8(0xcf39), 0x09},
+	{CCI_REG8(0xcf3a), 0x10},
+	{CCI_REG8(0xcf3b), 0xfb},
+	{CCI_REG8(0xcf3c), 0x0f},
+	{CCI_REG8(0xcf3d), 0xfb},
+	{CCI_REG8(0xcf3e), 0x0f},
+	{CCI_REG8(0xac32), 0x80},
+	{CCI_REG8(0xac33), 0x80},
+	{CCI_REG8(0xac34), 0x80},
+	{CCI_REG8(0xac35), 0x80},
+	{CCI_REG8(0xac36), 0x80},
+	{CCI_REG8(0xac37), 0x80},
+	{CCI_REG8(0xac38), 0x80},
+	{CCI_REG8(0xac39), 0x80},
+	{CCI_REG8(0xac3a), 0x80},
+	{CCI_REG8(0xac3b), 0x80},
+	{CCI_REG8(0xac3c), 0x80},
+	{CCI_REG8(0xac3d), 0x80},
+	{CCI_REG8(0xac3e), 0x80},
+	{CCI_REG8(0xac3f), 0x80},
+	{CCI_REG8(0xac40), 0x80},
+	{CCI_REG8(0xac41), 0x80},
+	{CCI_REG8(0xac42), 0x80},
+	{CCI_REG8(0xac43), 0x80},
+	{CCI_REG8(0xac44), 0x80},
+	{CCI_REG8(0xac45), 0x80},
+	{CCI_REG8(0xacb2), 0x00},
+	{CCI_REG8(0xacb3), 0x04},
+	{CCI_REG8(0xacb4), 0x00},
+	{CCI_REG8(0xacb5), 0x04},
+	{CCI_REG8(0xacb6), 0x00},
+	{CCI_REG8(0xacb7), 0x04},
+	{CCI_REG8(0xacb8), 0x00},
+	{CCI_REG8(0xacb9), 0x04},
+	{CCI_REG8(0xacba), 0x00},
+	{CCI_REG8(0xacbb), 0x04},
+	{CCI_REG8(0xacbc), 0x00},
+	{CCI_REG8(0xacbd), 0x04},
+	{CCI_REG8(0xacbe), 0x00},
+	{CCI_REG8(0xacbf), 0x04},
+	{CCI_REG8(0xacc0), 0x00},
+	{CCI_REG8(0xacc1), 0x04},
+	{CCI_REG8(0xacc2), 0x00},
+	{CCI_REG8(0xacc3), 0x04},
+	{CCI_REG8(0xacc4), 0x00},
+	{CCI_REG8(0xacc5), 0x04},
+	{CCI_REG8(0xacc6), 0x00},
+	{CCI_REG8(0xacc7), 0x04},
+	{CCI_REG8(0xacc8), 0x00},
+	{CCI_REG8(0xacc9), 0x04},
+	{CCI_REG8(0xacca), 0x00},
+	{CCI_REG8(0xaccb), 0x04},
+	{CCI_REG8(0xaccc), 0x00},
+	{CCI_REG8(0xaccd), 0x04},
+	{CCI_REG8(0xacce), 0x00},
+	{CCI_REG8(0xaccf), 0x04},
+	{CCI_REG8(0xacd0), 0x00},
+	{CCI_REG8(0xacd1), 0x04},
+	{CCI_REG8(0xacd2), 0x00},
+	{CCI_REG8(0xacd3), 0x04},
+	{CCI_REG8(0xacd4), 0x00},
+	{CCI_REG8(0xacd5), 0x04},
+	{CCI_REG8(0xacd6), 0x00},
+	{CCI_REG8(0xacd7), 0x04},
+	{CCI_REG8(0xacd8), 0x00},
+	{CCI_REG8(0xacd9), 0x04},
+};
+
+static inline struct imx728 *to_imx728(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct imx728, subdev);
+}
+
+static int imx728_wait_for_state(struct imx728 *imx728, enum imx728_sensor_state state)
+{
+	int ret;
+	int i;
+	u64 val;
+
+	for (i = 0; i < 50; i++) {
+		ret = 0; // reset if previous cci_read attempt failed
+		cci_read(imx728->regmap, IMX728_REG_STATE, &val, &ret);
+		if (ret == 0 && val == state) {
+			dev_dbg(imx728->dev, "%s: Enter state %llu\n", __func__, val);
+			return 0;
+		}
+		usleep_range(1000, 10000);
+	}
+
+	return -EBUSY;
+}
+
+static void imx728_init_formats(struct v4l2_subdev_state *state)
+{
+	struct v4l2_mbus_framefmt *format;
+
+	format = v4l2_subdev_state_get_format(state, 0, 0);
+	format->code = imx728_mbus_formats[0];
+	format->width = imx728_framesizes[0].width;
+	format->height = imx728_framesizes[0].height;
+	format->field = V4L2_FIELD_NONE;
+	format->colorspace = V4L2_COLORSPACE_RAW;
+	format->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+	format->xfer_func = V4L2_XFER_FUNC_NONE;
+	format->ycbcr_enc = V4L2_YCBCR_ENC_601;
+}
+
+static int _imx728_set_routing(struct v4l2_subdev *sd,
+			       struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_route routes[] = {
+		{
+			.source_pad = 0,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+		{
+			.source_pad = 0,
+			.source_stream = 1,
+		}
+	};
+
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+
+	int ret;
+
+	ret = v4l2_subdev_set_routing(sd, state, &routing);
+	if (ret < 0)
+		return ret;
+
+	imx728_init_formats(state);
+
+	return 0;
+}
+
+static int imx728_init_state(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_state *state)
+{
+	return _imx728_set_routing(sd, state);
+}
+
+static int imx728_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *state,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+
+	if (code->index >= ARRAY_SIZE(imx728_mbus_formats))
+		return -EINVAL;
+
+	code->code = imx728_mbus_formats[code->index];
+
+	return 0;
+}
+
+static int imx728_enum_frame_sizes(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_state *state,
+				   struct v4l2_subdev_frame_size_enum *fse)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(imx728_mbus_formats); ++i) {
+		if (imx728_mbus_formats[i] == fse->code)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(imx728_mbus_formats))
+		return -EINVAL;
+
+	if (fse->index >= ARRAY_SIZE(imx728_framesizes))
+		return -EINVAL;
+
+	fse->min_width = imx728_framesizes[fse->index].width;
+	fse->max_width = fse->min_width;
+	fse->min_height = imx728_framesizes[fse->index].height;
+	fse->max_height = fse->min_height;
+
+	return 0;
+}
+
+static int imx728_get_selection(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *state,
+				struct v4l2_subdev_selection *sel)
+{
+	struct imx728 *imx728 = to_imx728(sd);
+	struct v4l2_mbus_framefmt *format;
+
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP:
+		format = v4l2_subdev_state_get_format(state, 0, 0);
+
+		sel->r.top = IMX728_PIXEL_ARRAY_MARGIN_TOP
+			+ (IMX728_PIXEL_ARRAY_RECORDING_HEIGHT - format->height) / 2
+			+ imx728->ctrl.v_flip->val;
+		sel->r.left = IMX728_PIXEL_ARRAY_MARGIN_LEFT
+			+ (IMX728_PIXEL_ARRAY_RECORDING_WIDTH - format->width) / 2
+			+ imx728->ctrl.h_flip->val;
+		sel->r.height = format->height;
+		sel->r.width = format->width;
+		return 0;
+	case V4L2_SEL_TGT_NATIVE_SIZE:
+		sel->r.top = 0;
+		sel->r.left = 0;
+		sel->r.width = IMX728_PIXEL_ARRAY_WIDTH;
+		sel->r.height = IMX728_PIXEL_ARRAY_HEIGHT;
+		return 0;
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		sel->r.top = IMX728_PIXEL_ARRAY_MARGIN_TOP;
+		sel->r.left = IMX728_PIXEL_ARRAY_MARGIN_LEFT;
+		sel->r.width = IMX728_PIXEL_ARRAY_RECORDING_WIDTH;
+		sel->r.height = IMX728_PIXEL_ARRAY_RECORDING_HEIGHT;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+
+static int imx728_set_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_state *state,
+			  struct v4l2_subdev_format *fmt)
+{
+	struct imx728 *imx728 = to_imx728(sd);
+	struct v4l2_mbus_framefmt *format;
+	const struct v4l2_area *fsize;
+	unsigned int i;
+	u32 code;
+	int ret = 0;
+
+	if (fmt->pad != 0)
+		return -EINVAL;
+
+	if (fmt->stream != 0)
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(imx728_mbus_formats); ++i) {
+		if (imx728_mbus_formats[i] == fmt->format.code) {
+			code = fmt->format.code;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(imx728_mbus_formats))
+		code = imx728_mbus_formats[0];
+
+	fsize = v4l2_find_nearest_size(imx728_framesizes,
+				       ARRAY_SIZE(imx728_framesizes), width,
+				       height, fmt->format.width,
+				       fmt->format.height);
+
+	mutex_lock(&imx728->lock);
+
+	fmt->format.field = V4L2_FIELD_NONE;
+	fmt->format.colorspace = V4L2_COLORSPACE_RAW;
+	fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_601;
+	fmt->format.quantization = V4L2_QUANTIZATION_FULL_RANGE;
+	fmt->format.xfer_func = V4L2_XFER_FUNC_NONE;
+
+	fmt->format.width = fsize->width;
+	fmt->format.height = fsize->height;
+	fmt->format.code = code;
+
+	format = v4l2_subdev_state_get_format(state, fmt->pad, fmt->stream);
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE && imx728->streaming) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	*format = fmt->format;
+
+done:
+	mutex_unlock(&imx728->lock);
+
+	return ret;
+}
+
+static int imx728_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+				 struct v4l2_mbus_frame_desc *fd)
+{
+	struct v4l2_subdev_state *state;
+	struct v4l2_mbus_framefmt *fmt;
+	u32 bpp;
+	u32 dt;
+	int ret = 0;
+
+	if (pad != 0)
+		return -EINVAL;
+
+	state = v4l2_subdev_lock_and_get_active_state(sd);
+
+	fmt = v4l2_subdev_state_get_format(state, 0, 0);
+	if (!fmt) {
+		ret = -EPIPE;
+		goto out;
+	}
+
+	memset(fd, 0, sizeof(*fd));
+
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+
+	/* pixel stream */
+
+	switch (fmt->code) {
+	case MEDIA_BUS_FMT_SRGGB12_1X12:
+		bpp = 12;
+		dt = 0x2c; /* SRGGB12 */
+		break;
+	default:
+		ret = -EINVAL;
+		goto out;
+	}
+
+	fd->entry[fd->num_entries].stream = 0;
+
+	fd->entry[fd->num_entries].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
+	fd->entry[fd->num_entries].length = fmt->width * fmt->height * bpp / 8;
+	fd->entry[fd->num_entries].pixelcode = fmt->code;
+	fd->entry[fd->num_entries].bus.csi2.vc = 0;
+	fd->entry[fd->num_entries].bus.csi2.dt = dt;
+
+	fd->num_entries++;
+
+out:
+
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int imx728_set_routing(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_state *state,
+			      enum v4l2_subdev_format_whence which,
+			      struct v4l2_subdev_krouting *routing)
+{
+	int ret;
+
+	if (routing->num_routes == 0 || routing->num_routes > 1)
+		return -EINVAL;
+
+	ret = _imx728_set_routing(sd, state);
+
+	return ret;
+}
+
+static int imx728_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct imx728 *imx728 = container_of(ctrl->handler,
+					     struct imx728, ctrl.handler);
+	int ret = 0;
+
+	dev_dbg(imx728->dev, "%s: %s, value: %d\n",
+			__func__, ctrl->name, ctrl->val);
+
+	if (!pm_runtime_get_if_in_use(imx728->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		cci_write(imx728->regmap,
+			IMX728_REG_EXPOSURE_SP1, ctrl->val, &ret);
+		cci_write(imx728->regmap,
+			IMX728_REG_EXPOSURE_SP2, ctrl->val, &ret);
+		cci_write(imx728->regmap,
+			IMX728_REG_EXPOSURE_SP1VS, ctrl->val, &ret);
+		break;
+	case V4L2_CID_ANALOGUE_GAIN:
+		cci_write(imx728->regmap,
+			IMX728_REG_FME_ISP_GAIN_FID0, ctrl->val, &ret);
+		break;
+	case V4L2_CID_HFLIP:
+		cci_update_bits(imx728->regmap, IMX728_REG_FLIP,
+					 0x1, ctrl->val, &ret);
+		cci_update_bits(imx728->regmap, IMX728_REG_HFLIP,
+					  0x1, ctrl->val, &ret);
+		break;
+	case V4L2_CID_VFLIP:
+		cci_update_bits(imx728->regmap, IMX728_REG_FLIP,
+					 0x2, ctrl->val << 1, &ret);
+		cci_update_bits(imx728->regmap, IMX728_REG_VFLIP,
+					 0x1, ctrl->val, &ret);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	pm_runtime_put_noidle(imx728->dev);
+	return ret;
+}
+
+static int imx728_detect(struct imx728 *imx728)
+{
+	int ret = 0;
+	u64 minor, major;
+
+	cci_read(imx728->regmap, IMX728_REG_VMAJOR, &major, &ret);
+	if (ret != 0) {
+		dev_err(imx728->dev, "Could not read PARAM_MAJOR_VER!");
+		return ret;
+	}
+	cci_read(imx728->regmap, IMX728_REG_VMINOR, &minor, &ret);
+	if (ret != 0) {
+		dev_err(imx728->dev, "Could not read PARAM_MINOR_VER!");
+		return ret;
+	}
+	dev_dbg(imx728->dev, "Got version: %lld.%lld", major, minor);
+
+	return 0;
+}
+
+static int imx728_reset(struct imx728 *imx728)
+{
+
+	int ret = 0;
+
+	// Prefer hardware reset if available.
+	if (!IS_ERR_OR_NULL(imx728->reset_gpio)) {
+		gpiod_set_value_cansleep(imx728->reset_gpio, 1);
+		usleep_range(1000, 10000);
+		gpiod_set_value_cansleep(imx728->reset_gpio, 0);
+		msleep(100);
+	} else {
+		// Software reset.
+		cci_write(imx728->regmap, IMX728_REG_RESET_0, 0xc3, &ret);
+		cci_update_bits(imx728->regmap, IMX728_REG_RESET_1, 0x1, 0x1, &ret);
+		msleep(100);
+	}
+
+	return ret;
+}
+
+static int imx728_power_on(struct imx728 *imx728)
+{
+	int ret;
+
+	ret = clk_prepare_enable(imx728->clk);
+	if (ret < 0)
+		return ret;
+
+	imx728_reset(imx728);
+	return 0;
+}
+
+static int imx728_power_off(struct imx728 *imx728)
+{
+
+	if (imx728->reset_gpio) {
+		gpiod_set_value_cansleep(imx728->reset_gpio, 1);
+
+		usleep_range(1, 10);
+	}
+	clk_disable_unprepare(imx728->clk);
+	return 0;
+}
+
+static int imx728_get_frame_interval(struct v4l2_subdev *sd,
+				     struct v4l2_subdev_state *sd_state,
+				     struct v4l2_subdev_frame_interval *fi)
+{
+	struct imx728 *imx728 = to_imx728(sd);
+
+	fi->interval.numerator = 1;
+	fi->interval.denominator = imx728->fps;
+	return 0;
+}
+
+static int imx728_set_frame_interval(struct v4l2_subdev *sd,
+				     struct v4l2_subdev_state *sd_state,
+				     struct v4l2_subdev_frame_interval *fi)
+{
+	struct imx728 *imx728 = to_imx728(sd);
+	u32 req_fps;
+
+	mutex_lock(&imx728->lock);
+
+	if (fi->interval.numerator == 0 || fi->interval.denominator == 0) {
+		fi->interval.denominator = IMX728_FRAMERATE_DEFAULT;
+		fi->interval.numerator = 1;
+	}
+
+	req_fps = clamp_val(DIV_ROUND_CLOSEST(fi->interval.denominator,
+					      fi->interval.numerator),
+			    IMX728_FRAMERATE_MIN, IMX728_FRAMERATE_MAX);
+
+	fi->interval.numerator = 1;
+	fi->interval.denominator = req_fps;
+
+	imx728->fps = req_fps;
+
+	mutex_unlock(&imx728->lock);
+	dev_dbg(imx728->dev, "%s frame rate = %d\n", __func__, imx728->fps);
+
+	return 0;
+}
+
+static int imx728_powerup_to_standby(struct imx728 *imx728)
+{
+	int ret = 0;
+
+	dev_dbg(imx728->dev, "powerup -> standby...");
+
+	ret = imx728_reset(imx728);
+	if (ret) {
+		dev_err(imx728->dev, "Error resetting: %i", ret);
+		return ret;
+	}
+
+	ret = imx728_wait_for_state(imx728, IMX728_SENSOR_STATE_SLEEP);
+	if (ret < 0) {
+		dev_err(imx728->dev, "Could not transition to Sleep state!");
+		return ret;
+	}
+
+	cci_write(imx728->regmap, IMX728_REG_INCK_0, imx728->clk_rate / 1000000, &ret);
+	cci_write(imx728->regmap, IMX728_REG_INCK_1, 0x1, &ret);
+	if (ret < 0) {
+		dev_err(imx728->dev, "Couldn't write INCK frequency!");
+		return ret;
+	}
+
+	cci_write(imx728->regmap, IMX728_REG_SLEEP, 0xff, &ret);
+	if (ret < 0) {
+		dev_err(imx728->dev, "Couldn't write to SLEEP!");
+		return ret;
+	}
+
+	ret = imx728_wait_for_state(imx728, IMX728_SENSOR_STATE_STANDBY);
+	if (ret < 0) {
+		dev_err(imx728->dev, "Couldn't transition from Sleep to Standby state!");
+		return ret;
+	}
+
+	cci_write(imx728->regmap, IMX728_REG_REGMAP, IMX728_REMAP_MODE_STANDBY, &ret);
+	if (ret < 0) {
+		dev_err(imx728->dev, "Couldn't write remap mode!");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int imx728_start_stream(struct imx728 *imx728)
+{
+	struct v4l2_subdev_state *state;
+	struct v4l2_mbus_framefmt *fmt;
+	int ret;
+
+	ret = imx728_powerup_to_standby(imx728);
+	if (ret < 0)
+		return ret;
+
+	state = v4l2_subdev_lock_and_get_active_state(&imx728->subdev);
+	fmt = v4l2_subdev_state_get_format(state, 0, 0);
+	v4l2_subdev_unlock_state(state);
+	if (!fmt)
+		return -EPIPE;
+
+	switch (fmt->code) {
+	case MEDIA_BUS_FMT_SRGGB12_1X12:
+		cci_multi_reg_write(imx728->regmap,
+			imx728_wdr_12bit_3856x2176,
+			ARRAY_SIZE(imx728_wdr_12bit_3856x2176),
+			&ret);
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (ret < 0)
+		return ret;
+	msleep(100);
+
+	cci_write(imx728->regmap,
+		IMX728_REG_UNIT_00, IMX728_FME_SHTVAL_UNIT_MICROSECONDS, &ret);
+	cci_write(imx728->regmap,
+		IMX728_REG_UNIT_01, IMX728_FME_SHTVAL_UNIT_MICROSECONDS, &ret);
+	cci_write(imx728->regmap,
+		IMX728_REG_UNIT_02, IMX728_FME_SHTVAL_UNIT_MICROSECONDS, &ret);
+	if (ret < 0) {
+		dev_err(imx728->dev, "Couldn't set exposure time unit to microseconds!");
+		return ret;
+	}
+
+	cci_write(imx728->regmap, IMX728_REG_OB_0, 0x28, &ret);
+	cci_write(imx728->regmap, IMX728_REG_OB_1, 0x0, &ret);
+	if (ret < 0) {
+		dev_err(imx728->dev, "Error disabling OB output.");
+		return ret;
+	}
+
+	cci_write(imx728->regmap, IMX728_REG_SKEW, 0x0, &ret);
+	if (ret < 0) {
+		dev_err(imx728->dev, "Error disabling skew calibration from sensor to SER");
+		return ret;
+	}
+
+	cci_update_bits(imx728->regmap,
+		IMX728_REG_SUBP_0, 0x7, IMX728_RAW_SEL_SP1H, &ret);
+	cci_update_bits(imx728->regmap,
+		IMX728_REG_SUBP_1, 0x7, IMX728_RAW_SEL_SP1H, &ret);
+	if (ret < 0) {
+		dev_err(imx728->dev, "Failed to set subpixel register");
+		return ret;
+	}
+
+	ret = __v4l2_ctrl_handler_setup(imx728->subdev.ctrl_handler);
+	if (ret < 0) {
+		dev_err(imx728->dev,
+			"%s: failed to apply v4l2 ctrls: %d\n", __func__, ret);
+		return ret;
+	}
+
+	cci_write(imx728->regmap, IMX728_REG_STREAM_02, 0x5c, &ret);
+	if (ret < 0)
+		return ret;
+	cci_write(imx728->regmap, IMX728_REG_STREAM_02, 0xa3, &ret);
+	if (ret < 0)
+		return ret;
+
+	ret = imx728_wait_for_state(imx728, IMX728_SENSOR_STATE_STREAMING);
+	if (ret < 0) {
+		dev_err(imx728->dev, "Could not transition to Streaming!");
+		return ret;
+	}
+
+	msleep(20);
+
+	return 0;
+}
+
+static int imx728_stop_stream(struct imx728 *imx728)
+{
+	int ret;
+
+	cci_write(imx728->regmap, IMX728_REG_STREAM_02, 0xff, &ret);
+	if (ret < 0) {
+		dev_err(imx728->dev, "Error sending stop stream command: %i", ret);
+		return ret;
+	}
+
+	imx728_wait_for_state(imx728, IMX728_SENSOR_STATE_STANDBY);
+	if (ret < 0) {
+		dev_err(imx728->dev, "Couldn't transition out of Streaming mode!");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int imx728_set_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct imx728 *imx728 = to_imx728(sd);
+	int ret;
+
+	mutex_lock(&imx728->lock);
+	if (imx728->streaming == enable) {
+		mutex_unlock(&imx728->lock);
+		return 0;
+	}
+
+	if (enable) {
+		ret = pm_runtime_get_sync(imx728->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(imx728->dev);
+			goto err_unlock;
+		}
+
+		ret = imx728_start_stream(imx728);
+		if (ret < 0)
+			goto err_runtime_put;
+	} else {
+		ret = imx728_stop_stream(imx728);
+		if (ret < 0)
+			goto err_runtime_put;
+		pm_runtime_mark_last_busy(imx728->dev);
+		pm_runtime_put_autosuspend(imx728->dev);
+	}
+
+	imx728->streaming = enable;
+
+	__v4l2_ctrl_grab(imx728->ctrl.h_flip, enable);
+	__v4l2_ctrl_grab(imx728->ctrl.v_flip, enable);
+
+	mutex_unlock(&imx728->lock);
+
+	return 0;
+
+err_runtime_put:
+	pm_runtime_put(imx728->dev);
+
+err_unlock:
+	mutex_unlock(&imx728->lock);
+	dev_err(imx728->dev,
+		"%s: failed to setup streaming %d\n", __func__, ret);
+	return ret;
+}
+
+static const struct v4l2_subdev_core_ops imx728_core_ops = {
+	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_video_ops imx728_subdev_video_ops = {
+	.s_stream = imx728_set_stream,
+};
+
+static const struct v4l2_subdev_pad_ops imx728_subdev_pad_ops = {
+	.enum_frame_size = imx728_enum_frame_sizes,
+	.enum_mbus_code = imx728_enum_mbus_code,
+	.get_fmt = v4l2_subdev_get_fmt,
+	.get_frame_desc = imx728_get_frame_desc,
+	.get_frame_interval = imx728_get_frame_interval,
+	.get_selection = imx728_get_selection,
+	.set_fmt = imx728_set_fmt,
+	.set_frame_interval = imx728_set_frame_interval,
+	.set_routing = imx728_set_routing,
+};
+
+static const struct v4l2_subdev_ops imx728_subdev_ops = {
+	.core  = &imx728_core_ops,
+	.video = &imx728_subdev_video_ops,
+	.pad   = &imx728_subdev_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops imx728_internal_ops = {
+	.init_state = imx728_init_state,
+};
+
+
+static const struct v4l2_ctrl_ops imx728_ctrl_ops = {
+	.s_ctrl = imx728_set_ctrl,
+};
+
+static int imx728_probe(struct i2c_client *client)
+{
+	struct imx728 *imx728;
+	struct v4l2_subdev *sd;
+	struct v4l2_ctrl_handler *ctrl_hdr;
+	int ret;
+
+	imx728 = devm_kzalloc(&client->dev, sizeof(*imx728), GFP_KERNEL);
+	if (!imx728)
+		return -ENOMEM;
+
+	imx728->dev = &client->dev;
+
+	imx728->regmap = devm_cci_regmap_init_i2c(client, 16);
+	if (IS_ERR(imx728->regmap))
+		return PTR_ERR(imx728->regmap);
+
+	imx728->reset_gpio = devm_gpiod_get_optional(imx728->dev,
+					     "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(imx728->reset_gpio))
+		return PTR_ERR(imx728->reset_gpio);
+
+	imx728->clk = devm_clk_get(imx728->dev, "inck");
+	if (IS_ERR(imx728->clk))
+		return PTR_ERR(imx728->clk);
+
+	imx728->clk_rate = clk_get_rate(imx728->clk);
+	if (imx728->clk_rate < 18000000 || imx728->clk_rate > 30000000)
+		return -EINVAL;
+
+	ret = imx728_power_on(imx728);
+	if (ret < 0)
+		return ret;
+
+	ret = imx728_detect(imx728);
+	if (ret < 0)
+		return ret;
+
+	sd = &imx728->subdev;
+	v4l2_i2c_subdev_init(sd, client, &imx728_subdev_ops);
+	sd->internal_ops = &imx728_internal_ops;
+
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS;
+
+	imx728->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &imx728->pad);
+	if (ret < 0) {
+		dev_err(imx728->dev,
+			"%s: media entity init failed %d\n", __func__, ret);
+		return ret;
+	}
+
+	ctrl_hdr = &imx728->ctrl.handler;
+	ret = v4l2_ctrl_handler_init(ctrl_hdr, 8);
+	if (ret < 0) {
+		dev_err(imx728->dev,
+			"%s: ctrl handler init failed: %d\n", __func__, ret);
+		goto err_media_cleanup;
+	}
+
+	mutex_init(&imx728->lock);
+	imx728->ctrl.handler.lock = &imx728->lock;
+	imx728->fps = IMX728_FRAMERATE_DEFAULT;
+
+	imx728->ctrl.exposure = v4l2_ctrl_new_std(ctrl_hdr, &imx728_ctrl_ops,
+						  V4L2_CID_EXPOSURE,
+						  0, 33000,
+						  1,
+						  IMX728_EXPOSURE_DEFAULT);
+
+	imx728->ctrl.again = v4l2_ctrl_new_std(ctrl_hdr, &imx728_ctrl_ops,
+					       V4L2_CID_ANALOGUE_GAIN,
+					       0, 420,
+					       1,
+					       IMX728_AGAIN_DEFAULT);
+
+	imx728->ctrl.h_flip = v4l2_ctrl_new_std(ctrl_hdr, &imx728_ctrl_ops,
+						V4L2_CID_HFLIP, 0, 1, 1, 1);
+
+	imx728->ctrl.v_flip = v4l2_ctrl_new_std(ctrl_hdr, &imx728_ctrl_ops,
+						V4L2_CID_VFLIP, 0, 1, 1, 1);
+
+	imx728->ctrl.pixel_rate = v4l2_ctrl_new_std(ctrl_hdr, &imx728_ctrl_ops,
+					     V4L2_CID_PIXEL_RATE,
+					     IMX728_PIXEL_RATE,
+					     IMX728_PIXEL_RATE, 1,
+					     IMX728_PIXEL_RATE);
+
+	imx728->ctrl.link_freq = v4l2_ctrl_new_int_menu(ctrl_hdr, &imx728_ctrl_ops,
+						 V4L2_CID_LINK_FREQ,
+						 ARRAY_SIZE(imx728_link_freq_menu) - 1, 0,
+						 imx728_link_freq_menu);
+
+	if (imx728->ctrl.link_freq)
+		imx728->ctrl.link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	imx728->subdev.ctrl_handler = ctrl_hdr;
+	if (imx728->ctrl.handler.error) {
+		ret = imx728->ctrl.handler.error;
+		dev_err(imx728->dev,
+			"%s: failed to add the ctrls: %d\n", __func__, ret);
+		goto err_ctrl_free;
+	}
+
+	pm_runtime_set_active(imx728->dev);
+	pm_runtime_enable(imx728->dev);
+	pm_runtime_set_autosuspend_delay(imx728->dev, IMX728_PM_IDLE_TIMEOUT);
+	pm_runtime_use_autosuspend(imx728->dev);
+	pm_runtime_get_noresume(imx728->dev);
+
+	ret = v4l2_subdev_init_finalize(sd);
+	if (ret < 0)
+		goto err_pm_disable;
+
+	ret = v4l2_async_register_subdev(sd);
+	if (ret < 0) {
+		dev_err(imx728->dev,
+			"%s: v4l2 subdev register failed %d\n", __func__, ret);
+		goto err_subdev_cleanup;
+	}
+
+	pm_runtime_mark_last_busy(imx728->dev);
+	pm_runtime_put_autosuspend(imx728->dev);
+	return 0;
+
+err_subdev_cleanup:
+	v4l2_subdev_cleanup(&imx728->subdev);
+
+err_pm_disable:
+	pm_runtime_dont_use_autosuspend(imx728->dev);
+	pm_runtime_put_noidle(imx728->dev);
+	pm_runtime_disable(imx728->dev);
+
+err_ctrl_free:
+	v4l2_ctrl_handler_free(ctrl_hdr);
+	mutex_destroy(&imx728->lock);
+
+err_media_cleanup:
+	media_entity_cleanup(&imx728->subdev.entity);
+
+	return ret;
+}
+
+static int __maybe_unused imx728_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx728 *imx728 = to_imx728(sd);
+	int ret;
+
+	ret = imx728_power_on(imx728);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int __maybe_unused imx728_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx728 *imx728 = to_imx728(sd);
+
+	imx728_power_off(imx728);
+
+	return 0;
+}
+
+static int __maybe_unused imx728_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx728 *imx728 = to_imx728(sd);
+	int ret;
+
+	if (imx728->streaming)
+		imx728_stop_stream(imx728);
+
+	ret = pm_runtime_force_suspend(dev);
+	if (ret < 0)
+		dev_warn(dev, "%s: failed to suspend: %i\n", __func__, ret);
+
+	return 0;
+}
+
+static int __maybe_unused imx728_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx728 *imx728 = to_imx728(sd);
+	int ret;
+
+	ret = pm_runtime_force_resume(dev);
+	if (ret < 0)
+		dev_warn(dev, "%s: failed to resume: %i\n", __func__, ret);
+
+	if (imx728->streaming)
+		ret = imx728_start_stream(imx728);
+
+	if (ret < 0) {
+		imx728_stop_stream(imx728);
+		imx728->streaming = 0;
+		return ret;
+	}
+
+	return 0;
+}
+
+static void imx728_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx728 *imx728 = to_imx728(sd);
+
+	v4l2_async_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&imx728->ctrl.handler);
+	v4l2_subdev_cleanup(&imx728->subdev);
+	media_entity_cleanup(&sd->entity);
+	mutex_destroy(&imx728->lock);
+
+	pm_runtime_disable(imx728->dev);
+	pm_runtime_dont_use_autosuspend(imx728->dev);
+	pm_runtime_set_suspended(imx728->dev);
+}
+
+static const struct dev_pm_ops imx728_pm_ops = {
+	SET_RUNTIME_PM_OPS(imx728_runtime_suspend,
+			   imx728_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(imx728_suspend, imx728_resume)
+};
+
+static const struct of_device_id imx728_dt_id[] = {
+	{ .compatible = "sony,imx728" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, imx728_dt_id);
+
+static struct i2c_driver imx728_i2c_driver = {
+	.driver = {
+		.name = "imx728",
+		.of_match_table = imx728_dt_id,
+		.pm = &imx728_pm_ops,
+	},
+	.probe = imx728_probe,
+	.remove = imx728_remove,
+};
+
+module_i2c_driver(imx728_i2c_driver);
+
+MODULE_DESCRIPTION("Camera Sensor Driver for Sony IMX728");
+MODULE_AUTHOR("Sebastian LaVine <slavine@d3embedded.com>");
+MODULE_LICENSE("GPL");
diff -Naur --no-dereference a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
--- a/drivers/media/i2c/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/i2c/Kconfig	2025-10-23 09:30:40.285462207 -0400
@@ -244,6 +244,18 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called imx355.
 
+config VIDEO_IMX390
+	tristate "Sony IMX390 sensor support"
+	depends on I2C && VIDEO_DEV
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+	help
+	  This is a Video4Linux2 sensor driver for the Sony
+	  IMX390 camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called imx390.
+
 config VIDEO_IMX412
 	tristate "Sony IMX412 sensor support"
 	depends on OF_GPIO
@@ -265,6 +277,18 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called imx415.
 
+config VIDEO_IMX728
+	tristate "Sony IMX728 sensor support"
+	depends on I2C && VIDEO_DEV
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+	help
+	  This is a Video4Linux2 sensor driver for the Sony
+	  IMX728 camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called imx728.
+
 config VIDEO_MAX9271_LIB
 	tristate
 
@@ -374,6 +398,18 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called ov08x40.
 
+config VIDEO_OV1063X
+        tristate "OmniVision OV1063X sensor support"
+        depends on I2C && VIDEO_V4L2_SUBDEV_API
+        depends on MEDIA_CAMERA_SUPPORT && OF && GPIOLIB
+        select V4L2_FWNODE
+        help
+          This is a Video4Linux2 sensor-level driver for the OmniVision
+          OV1063X Sensor.
+
+          To compile this driver as a module, choose M here: the
+          module will be called ov1063x.
+
 config VIDEO_OV13858
 	tristate "OmniVision OV13858 sensor support"
 	help
@@ -386,6 +422,18 @@
 	  This is a Video4Linux2 sensor driver for the OmniVision
 	  OV13B10 camera.
 
+config VIDEO_OV2312
+	tristate "OmniVision OV2312 sensor support"
+	depends on I2C && VIDEO_DEV
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+	help
+	  This is a Video4Linux2 sensor driver for the OmniVision
+	  OV2312 camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ov2312.
+
 config VIDEO_OV2640
 	tristate "OmniVision OV2640 sensor support"
 	help
@@ -643,6 +691,19 @@
 	  To compile this driver as a module, choose M here: the
 	  module's name is ov9734.
 
+config VIDEO_OX05B1S
+	tristate "OmniVision OX05B1S sensor support"
+	depends on OF_GPIO
+	depends on I2C && VIDEO_DEV
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+	help
+	  This is a Video4Linux2 sensor driver for the OmniVision
+	  OX05B1S camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called OX05B1S.
+
 config VIDEO_RDACM20
 	tristate "IMI RDACM20 camera support"
 	select VIDEO_MAX9271_LIB
diff -Naur --no-dereference a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
--- a/drivers/media/i2c/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/i2c/Makefile	2025-10-23 09:30:40.285462207 -0400
@@ -57,8 +57,10 @@
 obj-$(CONFIG_VIDEO_IMX334) += imx334.o
 obj-$(CONFIG_VIDEO_IMX335) += imx335.o
 obj-$(CONFIG_VIDEO_IMX355) += imx355.o
+obj-$(CONFIG_VIDEO_IMX390) += imx390.o
 obj-$(CONFIG_VIDEO_IMX412) += imx412.o
 obj-$(CONFIG_VIDEO_IMX415) += imx415.o
+obj-$(CONFIG_VIDEO_IMX728) += imx728.o
 obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
 obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o
 obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
@@ -84,8 +86,10 @@
 obj-$(CONFIG_VIDEO_OV02A10) += ov02a10.o
 obj-$(CONFIG_VIDEO_OV08D10) += ov08d10.o
 obj-$(CONFIG_VIDEO_OV08X40) += ov08x40.o
+obj-$(CONFIG_VIDEO_OV1063X) += ov1063x.o
 obj-$(CONFIG_VIDEO_OV13858) += ov13858.o
 obj-$(CONFIG_VIDEO_OV13B10) += ov13b10.o
+obj-$(CONFIG_VIDEO_OV2312) += ov2312.o
 obj-$(CONFIG_VIDEO_OV2640) += ov2640.o
 obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
 obj-$(CONFIG_VIDEO_OV2680) += ov2680.o
@@ -114,6 +118,7 @@
 obj-$(CONFIG_VIDEO_OV9640) += ov9640.o
 obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
 obj-$(CONFIG_VIDEO_OV9734) += ov9734.o
+obj-$(CONFIG_VIDEO_OX05B1S) += ox05b1s.o
 obj-$(CONFIG_VIDEO_RDACM20) += rdacm20.o
 obj-$(CONFIG_VIDEO_RDACM21) += rdacm21.o
 obj-$(CONFIG_VIDEO_RJ54N1) += rj54n1cb0c.o
diff -Naur --no-dereference a/drivers/media/i2c/ov1063x.c b/drivers/media/i2c/ov1063x.c
--- a/drivers/media/i2c/ov1063x.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/media/i2c/ov1063x.c	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,1008 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OmniVision OV1063X Camera Driver
+ *
+ * Based on the original driver written by Phil Edworthy.
+ * Copyright (C) 2013 Phil Edworthy
+ * Copyright (C) 2013 Renesas Electronics
+ * Copyright (C) 2025 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This driver has been tested at QVGA, VGA and 720p, and 1280x800 at up to
+ * 30fps and it should work at any resolution in between and any frame rate
+ * up to 30fps.
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+#include <linux/v4l2-mediabus.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-async.h>
+
+#include "ov1063x_regs.h"
+
+/* Register definitions */
+#define OV1063X_STREAM_MODE			0x0100
+
+#define OV1063X_SC_CMMN_PLL_CTRL0		0x3003
+#define OV1063X_SC_CMMN_PLL_CTRL1		0x3004
+#define OV1063X_SC_CMMN_PCLK_DIV_CTRL		0x3007
+#define OV1063X_PID				0x300a
+#define OV1063X_VER				0x300b
+#define OV1063X_SC_CMMN_CLKRST2			0x301c
+#define OV1063X_ANA_ARRAY1			0x3621
+#define OV1063X_SENSOR_RSTGOLOW			0x3702
+#define OV1063X_SENSOR_HLDWIDTH			0x3703
+#define OV1063X_SENSOR_TXWIDTH			0x3704
+#define OV1063X_TIMING_Y_START_ADDR		0x3802
+#define OV1063X_TIMING_Y_END_ADDR		0x3806
+#define OV1063X_TIMING_X_OUTPUT_SIZE		0x3808
+#define OV1063X_TIMING_Y_OUTPUT_SIZE		0x380a
+#define OV1063X_TIMING_HTS			0x380c
+#define OV1063X_TIMING_VTS			0x380e
+#define OV1063X_VFLIP				0x381c
+#define OV1063X_VFLIP_ON			GENMASK(7, 6)
+#define OV1063X_VFLIP_SUBSAMPLE			BIT(0)
+#define OV1063X_HMIRROR				0x381d
+#define OV1063X_HMIRROR_ON			GENMASK(1, 0)
+
+#define OV1063X_FORMAT_CTRL00			0x4300
+#define OV1063X_VFIFO_LLEN_FIRS1_SEL		0x4605
+#define OV1063X_VFIFO_LINE_LENGTH_MAN		0x4606
+#define OV1063X_VFIFO_HSYNC_START_POSITION	0x460a
+#define OV1063X_DVP_MOD_SEL			0x4700
+
+#define OV1063X_ISP_RW05			0x5005
+
+#define OV1063X_HORIZ_COLORCORRECT		0x6900
+#define OV1063X_HORIZ_COLORCORRECT_ON		BIT(0)
+
+#define OV1063X_AEC_MAX_EXP_LONG_1		0xc488
+#define OV1063X_AEC_MAX_EXP_SHORT_1		0xc48a
+#define OV1063X_AWB_SIMPLE_MIN_NUM_1		0xc4cc
+#define OV1063X_AWB_CT_MIN_NUM_1		0xc4ce
+#define OV1063X_VTS_ADDR_1			0xc518
+#define OV1063X_HTS_ADDR			0xc51a
+
+#define OV1063X_FORMAT_YUYV			0x38
+#define OV1063X_FORMAT_YYYU			0x39
+#define OV1063X_FORMAT_UYVY			0x3A
+#define OV1063X_FORMAT_VYUY			0x3B
+
+/* IDs */
+#define OV10633_VERSION_REG			0xa630
+#define OV10635_VERSION_REG			0xa635
+#define OV1063X_VERSION(pid, ver)		(((pid) << 8) | ((ver) & 0xff))
+
+#define OV1063X_SENSOR_WIDTH			1312
+#define OV1063X_SENSOR_HEIGHT			814
+
+#define OV1063X_MAX_WIDTH			1280
+#define OV1063X_MAX_HEIGHT			800
+
+enum ov1063x_model {
+	SENSOR_OV10633,
+	SENSOR_OV10635,
+};
+
+struct ov1063x_color_format {
+	u32 code;
+	u32 colorspace;
+};
+
+struct ov1063x_framesize {
+	u16 width;
+	u16 height;
+};
+
+struct ov1063x_priv {
+	struct v4l2_subdev		subdev;
+	struct v4l2_async_connection asd;
+	struct v4l2_ctrl_handler	hdl;
+	int				model;
+	int				revision;
+	int				xvclk_rate;
+	/* Protects the struct fields below */
+	struct mutex lock;
+
+	int				fps_numerator;
+	int				fps_denominator;
+	struct v4l2_mbus_framefmt	format;
+	int				width;
+	int				height;
+
+	struct regmap			*regmap;
+
+	/* Sensor reference clock */
+	struct clk			*xvclk;
+
+	bool				power;
+
+	/* GPIOs */
+	struct gpio_desc		*resetb_gpio;
+	struct gpio_desc		*pwdn_gpio;
+
+	struct v4l2_ctrl		*colorbar;
+};
+
+static const struct ov1063x_framesize ov1063x_framesizes[] = {
+	{
+		.width		= 1280,
+		.height		= 800,
+	}, {
+		.width		= 1280,
+		.height		= 720,
+	}, {
+		.width		= 752,
+		.height		= 480,
+	}, {
+		.width		= 640,
+		.height		= 480,
+	}, {
+		.width		= 600,
+		.height		= 400,
+	}, {
+		.width		= 352,
+		.height		= 288,
+	}, {
+		.width		= 320,
+		.height		= 240,
+	},
+};
+
+/*
+ * supported color format list
+ */
+static const struct ov1063x_color_format ov1063x_cfmts[] = {
+	{
+		.code		= MEDIA_BUS_FMT_YUYV8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+	},
+	{
+		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+	},
+	{
+		.code		= MEDIA_BUS_FMT_VYUY8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+	},
+	{
+		.code		= MEDIA_BUS_FMT_YVYU8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+	},
+	{
+		.code		= MEDIA_BUS_FMT_YUYV10_2X10,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+	},
+};
+
+static struct ov1063x_priv *to_ov1063x(const struct i2c_client *client)
+{
+	return container_of(i2c_get_clientdata(client), struct ov1063x_priv,
+			subdev);
+}
+
+/* Helper function to write consecutive 8 bit registers */
+static int ov1063x_regmap_write16(struct regmap *map, u16 reg, u16 val)
+{
+	int ret;
+
+	ret = regmap_write(map, reg, val >> 8);
+	if (ret)
+		return ret;
+
+	return regmap_write(map, reg + 1, val & 0xff);
+}
+
+/* Start/Stop streaming from the device */
+static int ov1063x_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ov1063x_priv *priv = to_ov1063x(client);
+	struct regmap *map = priv->regmap;
+	int ret;
+
+	ret = regmap_write(map, OV1063X_STREAM_MODE, enable);
+	if (ret)
+		return ret;
+
+	return regmap_write(map, OV1063X_SC_CMMN_CLKRST2, enable ? 0xf0 : 0x70);
+}
+
+static int ov1063x_set_regs(struct i2c_client *client,
+			    const struct ov1063x_reg *regs, int nr_regs);
+
+/* Set status of additional camera capabilities */
+static int ov1063x_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ov1063x_priv *priv = container_of(ctrl->handler,
+					struct ov1063x_priv, hdl);
+	struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
+	struct regmap *map = priv->regmap;
+	const struct ov1063x_reg *regs;
+	int n_regs, ret;
+
+	switch (ctrl->id) {
+	case V4L2_CID_VFLIP:
+		return regmap_update_bits(map, OV1063X_VFLIP,
+					  OV1063X_VFLIP_ON,
+					  ctrl->val ? OV1063X_VFLIP_ON : 0);
+	case V4L2_CID_HFLIP:
+		ret = regmap_update_bits(map, OV1063X_HORIZ_COLORCORRECT,
+					 OV1063X_HORIZ_COLORCORRECT_ON,
+					 ctrl->val ?
+					 OV1063X_HORIZ_COLORCORRECT_ON : 0);
+		if (ret)
+			return ret;
+
+		return regmap_update_bits(map, OV1063X_HMIRROR,
+					  OV1063X_HMIRROR_ON,
+					  ctrl->val ? OV1063X_HMIRROR_ON : 0);
+	case V4L2_CID_TEST_PATTERN:
+		if (ctrl->val) {
+			n_regs = ARRAY_SIZE(ov1063x_regs_colorbar_enable);
+			regs = ov1063x_regs_colorbar_enable;
+		} else {
+			n_regs = ARRAY_SIZE(ov1063x_regs_colorbar_disable);
+			regs = ov1063x_regs_colorbar_disable;
+		}
+		return ov1063x_set_regs(client, regs, n_regs);
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * Get the best pixel clock (pclk) that meets minimum hts/vts requirements.
+ * xvclk_rate => pre-divider => clk1 => multiplier => clk2 => post-divider
+ * => pclk
+ * We try all valid combinations of settings for the 3 blocks to get the pixel
+ * clock, and from that calculate the actual hts/vts to use. The vts is
+ * extended so as to achieve the required frame rate. The function also returns
+ * the PLL register contents needed to set the pixel clock.
+ */
+static int ov1063x_get_pclk(int xvclk_rate, int *htsmin, int *vtsmin,
+			    int fps_numerator, int fps_denominator,
+			    u8 *r3003, u8 *r3004)
+{
+	int pre_divs[] = { 2, 3, 4, 6, 8, 10, 12, 14 };
+	int pclk;
+	int best_pclk = INT_MAX;
+	int best_hts = 0;
+	int i, j, k;
+	int best_i = 0, best_j = 0, best_k = 0;
+	int clk1, clk2;
+	int hts;
+
+	/* Pre-div, reg 0x3004, bits 6:4 */
+	for (i = 0; i < ARRAY_SIZE(pre_divs); i++) {
+		clk1 = (xvclk_rate / pre_divs[i]) * 2;
+
+		if (clk1 < 3000000 || clk1 > 27000000)
+			continue;
+
+		/* Mult = reg 0x3003, bits 5:0 */
+		for (j = 1; j < 32; j++) {
+			clk2 = (clk1 * j);
+
+			if (clk2 < 200000000 || clk2 > 500000000)
+				continue;
+
+			/* Post-div, reg 0x3004, bits 2:0 */
+			for (k = 0; k < 8; k++) {
+				pclk = clk2 / (2 * (k + 1));
+
+				if (pclk > 96000000)
+					continue;
+
+				hts = *htsmin + 210 + pclk / 300000;
+
+				/* 2 clock cycles for every YUV422 pixel */
+				if (pclk < (((hts * *vtsmin) / fps_denominator)
+					* fps_numerator * 2))
+					continue;
+
+				if (pclk < best_pclk) {
+					best_pclk = pclk;
+					best_hts = hts;
+					best_i = i;
+					best_j = j;
+					best_k = k;
+				}
+			}
+		}
+	}
+
+	/* register contents */
+	*r3003 = (u8)best_j;
+	*r3004 = ((u8)best_i << 4) | (u8)best_k;
+
+	/* Did we get a valid PCLK? */
+	if (best_pclk == INT_MAX)
+		return -1;
+
+	*htsmin = best_hts;
+
+	/* Adjust vts to get as close to the desired frame rate as we can */
+	*vtsmin = best_pclk / ((best_hts / fps_denominator) *
+		  fps_numerator * 2);
+
+	return best_pclk;
+}
+
+static int ov1063x_set_regs(struct i2c_client *client,
+			    const struct ov1063x_reg *regs, int nr_regs)
+{
+	struct ov1063x_priv *priv = to_ov1063x(client);
+	struct regmap *map = priv->regmap;
+	int i, ret;
+	u8 val;
+
+	for (i = 0; i < nr_regs; i++) {
+		if (regs[i].reg == 0x300c) {
+			val = ((client->addr * 2) | 0x1);
+
+			ret = regmap_write(map, regs[i].reg, val);
+			if (ret)
+				return ret;
+		} else {
+			ret = regmap_write(map, regs[i].reg, regs[i].val);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+/* Setup registers according to resolution and color encoding */
+static int ov1063x_set_params(struct i2c_client *client, u32 width, u32 height)
+{
+	struct ov1063x_priv *priv = to_ov1063x(client);
+	struct regmap *map = priv->regmap;
+	int ret = -EINVAL;
+	int pclk;
+	int hts, vts;
+	u8 r3003, r3004, r4300;
+	int tmp;
+	u32 height_pre_subsample;
+	u32 width_pre_subsample;
+	u8 horiz_crop_mode;
+	int nr_isp_pixels;
+	int vert_sub_sample = 0;
+	int horiz_sub_sample = 0;
+	int sensor_width;
+	int n_regs;
+
+	if (width > OV1063X_MAX_WIDTH || height > OV1063X_MAX_HEIGHT)
+		return ret;
+
+	priv->width = width;
+	priv->height = height;
+
+	/* Vertical sub-sampling? */
+	height_pre_subsample = priv->height;
+	if (priv->height <= 400) {
+		vert_sub_sample = 1;
+		height_pre_subsample <<= 1;
+	}
+
+	/* Horizontal sub-sampling? */
+	width_pre_subsample = priv->width;
+	if (priv->width <= 640) {
+		horiz_sub_sample = 1;
+		width_pre_subsample <<= 1;
+	}
+
+	/* Horizontal cropping */
+	if (width_pre_subsample > 768) {
+		sensor_width = OV1063X_SENSOR_WIDTH;
+		horiz_crop_mode = 0x63;
+	} else if (width_pre_subsample > 656) {
+		sensor_width = 768;
+		horiz_crop_mode = 0x6b;
+	} else {
+		sensor_width = 656;
+		horiz_crop_mode = 0x73;
+	}
+
+	/* minimum values for hts and vts */
+	hts = sensor_width;
+	vts = height_pre_subsample + 50;
+	dev_dbg(&client->dev, "fps=(%d/%d), hts=%d, vts=%d\n",
+		priv->fps_numerator, priv->fps_denominator, hts, vts);
+
+	/* Get the best PCLK & adjust hts,vts accordingly */
+	pclk = ov1063x_get_pclk(priv->xvclk_rate, &hts, &vts,
+				priv->fps_numerator, priv->fps_denominator,
+				&r3003, &r3004);
+	if (pclk < 0)
+		return ret;
+	dev_dbg(&client->dev, "pclk=%d, hts=%d, vts=%d\n", pclk, hts, vts);
+	dev_dbg(&client->dev, "r3003=0x%X r3004=0x%X\n", r3003, r3004);
+
+	/* Disable ISP & program all registers that we might modify */
+	ret = ov1063x_set_regs(client, ov1063x_regs_change_mode,
+			       ARRAY_SIZE(ov1063x_regs_change_mode));
+	if (ret)
+		return ret;
+
+	/* Set PLL */
+	ret = regmap_write(map, OV1063X_SC_CMMN_PLL_CTRL0, r3003);
+	if (ret)
+		return ret;
+	ret = regmap_write(map, OV1063X_SC_CMMN_PLL_CTRL1, r3004);
+	if (ret)
+		return ret;
+
+	/* Set HSYNC */
+	ret = regmap_write(map, OV1063X_DVP_MOD_SEL, 0x00);
+	if (ret)
+		return ret;
+
+	switch (priv->format.code) {
+	case MEDIA_BUS_FMT_UYVY8_2X8:
+		r4300 = OV1063X_FORMAT_UYVY;
+		break;
+	case MEDIA_BUS_FMT_VYUY8_2X8:
+		r4300 = OV1063X_FORMAT_VYUY;
+		break;
+	case MEDIA_BUS_FMT_YUYV8_2X8:
+		r4300 = OV1063X_FORMAT_YUYV;
+		break;
+	case MEDIA_BUS_FMT_YVYU8_2X8:
+		r4300 = OV1063X_FORMAT_YYYU;
+		break;
+	default:
+		r4300 = OV1063X_FORMAT_UYVY;
+		break;
+	}
+
+	/* Set format to UYVY */
+	ret = regmap_write(map, OV1063X_FORMAT_CTRL00, r4300);
+	if (ret)
+		return ret;
+
+	dev_dbg(&client->dev, "r4300=0x%X\n", r4300);
+
+	/* Set output to 8-bit yuv */
+	ret = regmap_write(map, OV1063X_VFIFO_LLEN_FIRS1_SEL, 0x08);
+	if (ret)
+		return ret;
+
+	/* Horizontal cropping */
+	ret = regmap_write(map, OV1063X_ANA_ARRAY1, horiz_crop_mode);
+	if (ret)
+		return ret;
+
+	ret = regmap_write(map, OV1063X_SENSOR_RSTGOLOW,
+			   (pclk + 1500000) / 3000000);
+	if (ret)
+		return ret;
+	ret = regmap_write(map, OV1063X_SENSOR_HLDWIDTH,
+			   (pclk + 666666) / 1333333);
+	if (ret)
+		return ret;
+	ret = regmap_write(map, OV1063X_SENSOR_TXWIDTH,
+			   (pclk + 961500) / 1923000);
+	if (ret)
+		return ret;
+
+	/* Vertical cropping */
+	tmp = ((OV1063X_SENSOR_HEIGHT - height_pre_subsample) / 2) & ~0x1;
+	ret = ov1063x_regmap_write16(map, OV1063X_TIMING_Y_START_ADDR, tmp);
+	if (ret)
+		return ret;
+	tmp = tmp + height_pre_subsample + 3;
+	ret = ov1063x_regmap_write16(map, OV1063X_TIMING_Y_END_ADDR, tmp);
+	if (ret)
+		return ret;
+
+	dev_dbg(&client->dev, "width x height = %x x %x\n",
+		priv->width, priv->height);
+	/* Output size */
+	ret = ov1063x_regmap_write16(map, OV1063X_TIMING_X_OUTPUT_SIZE,
+				     priv->width);
+	if (ret)
+		return ret;
+	ret = ov1063x_regmap_write16(map, OV1063X_TIMING_Y_OUTPUT_SIZE,
+				     priv->height);
+	if (ret)
+		return ret;
+
+	dev_dbg(&client->dev, "hts x vts = %x x %x\n", hts, vts);
+
+	ret = ov1063x_regmap_write16(map, OV1063X_TIMING_HTS, hts);
+	if (ret)
+		return ret;
+
+	ret = ov1063x_regmap_write16(map, OV1063X_TIMING_VTS, vts);
+	if (ret)
+		return ret;
+
+	if (vert_sub_sample) {
+		ret = regmap_update_bits(map, OV1063X_VFLIP,
+					 OV1063X_VFLIP_SUBSAMPLE,
+					 OV1063X_VFLIP_SUBSAMPLE);
+		if (ret)
+			return ret;
+		n_regs = ARRAY_SIZE(ov1063x_regs_vert_sub_sample);
+		ret = ov1063x_set_regs(client, ov1063x_regs_vert_sub_sample,
+				       n_regs);
+		if (ret)
+			return ret;
+	}
+
+	ret = ov1063x_regmap_write16(map, OV1063X_VFIFO_LINE_LENGTH_MAN,
+				     2 * hts);
+	if (ret)
+		return ret;
+	ret = ov1063x_regmap_write16(map, OV1063X_VFIFO_HSYNC_START_POSITION,
+				     2 * (hts - width_pre_subsample));
+	if (ret)
+		return ret;
+
+	tmp = (vts - 8) * 16;
+	ret = ov1063x_regmap_write16(map, OV1063X_AEC_MAX_EXP_LONG_1, tmp);
+	if (ret)
+		return ret;
+	ret = ov1063x_regmap_write16(map, OV1063X_AEC_MAX_EXP_SHORT_1, tmp);
+	if (ret)
+		return ret;
+
+	nr_isp_pixels = sensor_width * (priv->height + 4);
+	ret = ov1063x_regmap_write16(map, OV1063X_AWB_SIMPLE_MIN_NUM_1,
+				     nr_isp_pixels / 256);
+	if (ret)
+		return ret;
+	ret = ov1063x_regmap_write16(map, OV1063X_AWB_CT_MIN_NUM_1,
+				     nr_isp_pixels / 256);
+	if (ret)
+		return ret;
+	ret = ov1063x_regmap_write16(map, 0xc512, nr_isp_pixels / 16);
+	if (ret)
+		return ret;
+
+	/* Horizontal sub-sampling */
+	if (horiz_sub_sample) {
+		ret = regmap_write(map, OV1063X_ISP_RW05, 0x9);
+		if (ret)
+			return ret;
+
+		ret = regmap_write(map, OV1063X_SC_CMMN_PCLK_DIV_CTRL, 0x2);
+		if (ret)
+			return ret;
+	}
+
+	ret = ov1063x_regmap_write16(map, OV1063X_VTS_ADDR_1, vts);
+	if (ret)
+		return ret;
+	ret = ov1063x_regmap_write16(map, OV1063X_HTS_ADDR, hts);
+	if (ret)
+		return ret;
+
+	/* Enable ISP blocks */
+	ret = ov1063x_set_regs(client, ov1063x_regs_enable,
+			       ARRAY_SIZE(ov1063x_regs_enable));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/*
+ * V4L2 subdev video and pad level operations
+ */
+static void ov1063x_get_default_format(struct v4l2_mbus_framefmt *mf)
+{
+	mf->width = ov1063x_framesizes[0].width;
+	mf->height = ov1063x_framesizes[0].height;
+	mf->colorspace = ov1063x_cfmts[0].colorspace;
+	mf->code = ov1063x_cfmts[0].code;
+
+	mf->field = V4L2_FIELD_NONE;
+}
+
+static int ov1063x_get_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_state *sd_state,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ov1063x_priv *priv = to_ov1063x(client);
+	struct v4l2_mbus_framefmt *mf;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+		mf = v4l2_subdev_state_get_format(sd_state, 0);
+		mutex_lock(&priv->lock);
+		fmt->format = *mf;
+		mutex_unlock(&priv->lock);
+		return 0;
+	}
+
+	mutex_lock(&priv->lock);
+	fmt->format = priv->format;
+	mutex_unlock(&priv->lock);
+
+	return 0;
+}
+
+static void __ov1063x_try_frame_size(struct v4l2_mbus_framefmt *mf)
+{
+	const struct ov1063x_framesize *fsize = &ov1063x_framesizes[0];
+	const struct ov1063x_framesize *match = NULL;
+	int i = ARRAY_SIZE(ov1063x_framesizes);
+	unsigned int min_err = UINT_MAX;
+
+	while (i--) {
+		int err = abs(fsize->width - mf->width)
+				+ abs(fsize->height - mf->height);
+		if (err < min_err) {
+			min_err = err;
+			match = fsize;
+		}
+		fsize++;
+	}
+
+	if (!match)
+		match = &ov1063x_framesizes[0];
+
+	mf->width  = match->width;
+	mf->height = match->height;
+}
+
+static int ov1063x_set_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_state *sd_state,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int index = ARRAY_SIZE(ov1063x_cfmts);
+	struct ov1063x_priv *priv = to_ov1063x(client);
+	struct v4l2_mbus_framefmt *mf = &fmt->format;
+	int ret = 0;
+
+	__ov1063x_try_frame_size(mf);
+
+	while (--index >= 0)
+		if (ov1063x_cfmts[index].code == mf->code)
+			break;
+
+	if (index < 0)
+		return -EINVAL;
+
+	mf->colorspace = ov1063x_cfmts[index].colorspace;
+	mf->code = ov1063x_cfmts[index].code;
+	mf->field = V4L2_FIELD_NONE;
+
+	mutex_lock(&priv->lock);
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+		mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
+		*mf = fmt->format;
+	} else {
+		priv->format = fmt->format;
+		ret = ov1063x_set_params(client, mf->width, mf->height);
+	}
+
+	mutex_unlock(&priv->lock);
+
+	return ret;
+}
+
+static int ov1063x_enum_mbus_code(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *sd_state,
+				  struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index >= ARRAY_SIZE(ov1063x_cfmts))
+		return -EINVAL;
+
+	code->code = ov1063x_cfmts[code->index].code;
+
+	return 0;
+}
+
+static int ov1063x_enum_frame_sizes(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_state *sd_state,
+				    struct v4l2_subdev_frame_size_enum *fse)
+{
+	int i = ARRAY_SIZE(ov1063x_cfmts);
+
+	if (fse->index >= ARRAY_SIZE(ov1063x_framesizes))
+		return -EINVAL;
+
+	while (--i)
+		if (ov1063x_cfmts[i].code == fse->code)
+			break;
+
+	fse->code = ov1063x_cfmts[i].code;
+
+	fse->min_width  = ov1063x_framesizes[fse->index].width;
+	fse->max_width  = fse->min_width;
+	fse->max_height = ov1063x_framesizes[fse->index].height;
+	fse->min_height = fse->max_height;
+
+	return 0;
+}
+
+static void ov1063x_set_power(struct i2c_client *client, bool on)
+{
+	struct ov1063x_priv *priv = to_ov1063x(client);
+
+	dev_dbg(&client->dev, "%s: on: %d\n", __func__, on);
+
+	if (priv->power == on)
+		return;
+
+	if (on) {
+		if (priv->pwdn_gpio) {
+			gpiod_set_value_cansleep(priv->pwdn_gpio, 1);
+			usleep_range(1000, 1200);
+		}
+		if (priv->resetb_gpio) {
+			gpiod_set_value_cansleep(priv->resetb_gpio, 1);
+			usleep_range(250000, 260000);
+		}
+	} else {
+		if (priv->pwdn_gpio)
+			gpiod_set_value_cansleep(priv->pwdn_gpio, 0);
+		if (priv->resetb_gpio)
+			gpiod_set_value_cansleep(priv->resetb_gpio, 0);
+	}
+
+	priv->power = on;
+}
+
+static int ov1063x_video_probe(struct i2c_client *client)
+{
+	struct ov1063x_priv *priv = to_ov1063x(client);
+	struct regmap *map = priv->regmap;
+	u32 pid, ver;
+	int ret;
+
+	ov1063x_set_power(client, true);
+
+	ret = ov1063x_set_regs(client, ov1063x_regs_default,
+			       ARRAY_SIZE(ov1063x_regs_default));
+	if (ret)
+		return ret;
+
+	usleep_range(500, 510);
+
+	/* check and show product ID and manufacturer ID */
+	ret = regmap_read(map, OV1063X_PID, &pid);
+	if (ret)
+		return ret;
+
+	ret = regmap_read(map, OV1063X_VER, &ver);
+	if (ret)
+		return ret;
+
+	if (OV1063X_VERSION(pid, ver) == OV10635_VERSION_REG) {
+		priv->model = SENSOR_OV10635;
+		priv->revision = 1;
+	} else if (OV1063X_VERSION(pid, ver) == OV10633_VERSION_REG) {
+		priv->model = SENSOR_OV10633;
+		priv->revision = 1;
+	} else {
+		dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
+		return -ENODEV;
+	}
+
+	dev_info(&client->dev, "ov1063x Product ID %x Manufacturer ID %x\n",
+		 pid, ver);
+
+	/* Program all the 'standard' registers */
+
+	return v4l2_ctrl_handler_setup(&priv->hdl);
+}
+
+/*
+ * V4L2 subdev internal operations
+ */
+static int ov1063x_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct v4l2_mbus_framefmt *mf;
+
+	mf = v4l2_subdev_state_get_format(fh->state, 0);
+	ov1063x_get_default_format(mf);
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops ov1063x_ctrl_ops = {
+	.s_ctrl = ov1063x_s_ctrl,
+};
+
+static const char * const ov1063x_test_pattern_menu[] = {
+	"Disabled",
+	"Vertical Color Bars",
+};
+
+static const struct v4l2_subdev_video_ops ov1063x_subdev_video_ops = {
+	.s_stream	= ov1063x_s_stream,
+};
+
+static const struct v4l2_subdev_internal_ops ov1063x_sd_internal_ops = {
+	.open		= ov1063x_open,
+};
+
+static const struct v4l2_subdev_core_ops ov1063x_subdev_core_ops = {
+	.log_status		= v4l2_ctrl_subdev_log_status,
+	.subscribe_event	= v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event	= v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_pad_ops ov1063x_subdev_pad_ops = {
+	.enum_mbus_code		= ov1063x_enum_mbus_code,
+	.enum_frame_size	= ov1063x_enum_frame_sizes,
+	.get_fmt		= ov1063x_get_fmt,
+	.set_fmt		= ov1063x_set_fmt,
+};
+
+static const struct v4l2_subdev_ops ov1063x_subdev_ops = {
+	.core	= &ov1063x_subdev_core_ops,
+	.video	= &ov1063x_subdev_video_ops,
+	.pad	= &ov1063x_subdev_pad_ops,
+};
+
+static const struct regmap_config ov1063x_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 8,
+};
+
+/*
+ * i2c_driver function
+ */
+static int ov1063x_probe(struct i2c_client *client)
+{
+	struct ov1063x_priv *priv;
+	struct v4l2_subdev *sd;
+	struct clk *clk;
+	unsigned int menu_size;
+	int ret = 0;
+
+	priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, priv);
+
+	priv->regmap = devm_regmap_init_i2c(client, &ov1063x_regmap_config);
+	if (IS_ERR(priv->regmap))
+		return PTR_ERR(priv->regmap);
+
+	clk = devm_clk_get(&client->dev, "xvclk");
+	if (IS_ERR(clk)) {
+		dev_err(&client->dev, "xvclk reference is missing!\n");
+		ret = PTR_ERR(clk);
+		goto err;
+	}
+	priv->xvclk = clk;
+
+	priv->xvclk_rate = clk_get_rate(clk);
+	dev_dbg(&client->dev, "xvclk_rate: %d (Hz)\n", priv->xvclk_rate);
+
+	if (priv->xvclk_rate < 6000000 ||
+	    priv->xvclk_rate > 27000000) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	ret = clk_prepare_enable(priv->xvclk);
+	if (ret < 0)
+		goto err;
+
+	/* Default framerate */
+	priv->fps_numerator = 30;
+	priv->fps_denominator = 1;
+	ov1063x_get_default_format(&priv->format);
+	priv->width = priv->format.width;
+	priv->height = priv->format.height;
+
+	sd = &priv->subdev;
+	v4l2_i2c_subdev_init(sd, client, &ov1063x_subdev_ops);
+
+	sd->internal_ops = &ov1063x_sd_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS;
+
+	v4l2_ctrl_handler_init(&priv->hdl, 3);
+	v4l2_ctrl_new_std(&priv->hdl, &ov1063x_ctrl_ops,
+			  V4L2_CID_VFLIP, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ov1063x_ctrl_ops,
+			  V4L2_CID_HFLIP, 0, 1, 1, 0);
+	menu_size = ARRAY_SIZE(ov1063x_test_pattern_menu) - 1;
+	priv->colorbar =
+		v4l2_ctrl_new_std_menu_items(&priv->hdl, &ov1063x_ctrl_ops,
+					     V4L2_CID_TEST_PATTERN, menu_size,
+					     0, 0, ov1063x_test_pattern_menu);
+	priv->subdev.ctrl_handler = &priv->hdl;
+	if (priv->hdl.error) {
+		ret = priv->hdl.error;
+		goto err;
+	}
+
+	mutex_init(&priv->lock);
+
+	/* Optional gpio don't fail if not present */
+	priv->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
+						  GPIOD_OUT_LOW);
+	if (IS_ERR(priv->pwdn_gpio))
+		return PTR_ERR(priv->pwdn_gpio);
+
+	/* Optional gpio don't fail if not present */
+	priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+						    GPIOD_OUT_LOW);
+	if (IS_ERR(priv->resetb_gpio))
+		return PTR_ERR(priv->resetb_gpio);
+
+	ret = ov1063x_video_probe(client);
+	if (ret) {
+		v4l2_ctrl_handler_free(&priv->hdl);
+		goto err;
+	}
+
+	sd->dev = &client->dev;
+	ret = v4l2_async_register_subdev(sd);
+
+	dev_info(&client->dev, "%s sensor driver registered !!\n", sd->name);
+
+	return 0;
+err:
+	clk_disable_unprepare(priv->xvclk);
+	return ret;
+}
+
+static void ov1063x_remove(struct i2c_client *client)
+{
+	struct ov1063x_priv *priv = i2c_get_clientdata(client);
+
+	v4l2_ctrl_handler_free(&priv->hdl);
+	v4l2_async_unregister_subdev(&priv->subdev);
+	ov1063x_set_power(client, false);
+	clk_disable_unprepare(priv->xvclk);
+}
+
+static const struct i2c_device_id ov1063x_id[] = {
+	{ "ov10635", 0 },
+	{ "ov10633", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ov1063x_id);
+
+static const struct of_device_id ov1063x_dt_id[] = {
+	{
+		.compatible = "ovti,ov10635", .data = "ov10635"
+	},
+	{
+		.compatible = "ovti,ov10633", .data = "ov10633"
+	},
+	{
+	}
+};
+MODULE_DEVICE_TABLE(of, ov1063x_dt_id);
+
+static struct i2c_driver ov1063x_i2c_driver = {
+	.driver = {
+		.name	= "ov1063x",
+		.of_match_table = of_match_ptr(ov1063x_dt_id),
+	},
+	.probe = ov1063x_probe,
+	.remove = ov1063x_remove,
+	.id_table = ov1063x_id,
+};
+
+module_i2c_driver(ov1063x_i2c_driver);
+
+MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV1063X");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_LICENSE("GPL");
diff -Naur --no-dereference a/drivers/media/i2c/ov1063x_regs.h b/drivers/media/i2c/ov1063x_regs.h
--- a/drivers/media/i2c/ov1063x_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/media/i2c/ov1063x_regs.h	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,699 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * OmniVision OV1063X Camera Driver
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated -  http://www.ti.com/
+ */
+
+struct ov1063x_reg {
+	u16	reg;
+	u8	val;
+};
+
+static const struct ov1063x_reg ov1063x_regs_default[] = {
+	/* Register configuration for full resolution : 1280x720 */
+		{0x103, 0x1},	 /** Software Reset */
+		{0x301b, 0xff},  /** System Control Clock Reset #1 */
+		{0x301c, 0xff},  /** System Control Clock Reset #2 */
+		{0x301a, 0xff},  /** System Control Clock Reset #0 */
+		{0x300c, 0x61},  /** Serial Camera Control Bus ID */
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x300c, 0x61},
+		{0x3021, 0x3},  /** System Control Misc */
+		{0x3011, 0x2},
+		{0x6900, 0xc},
+		{0x6901, 0x1},
+		{0x3033, 0x8},  /** System clock/4 */
+		{0x3503, 0x10}, /** AEC Delay enabled */
+		{0x302d, 0x2f}, /** Power Down Control */
+		{0x3025, 0x3},  /** Debug Control enabled */
+		/*
+		 * FPS is computed as:
+		 * XVCLK	   = 9MHz
+		 * preDivide   = {/1,/1.5,/2,/3,/4,/5,/6,/7}
+		 * decided based on (0x3004[6:4].
+		 * numerator   = (0x3003[5:0] * XVCLK)/preDivide)
+		 * denominator = (2 * (1+0x3004[2:0]))
+		 * FPS = numerator/denominator.
+		 */
+		/* {0x3003, 0x1B}, */ /* fps = 30fps. */
+		/* {0x3004, 0x03}, */
+		{0x3003, 0x20}, /* fps = 15fps. */
+		{0x3004, 0x3},
+		{0x3005, 0x20},
+		{0x3006, 0x91},
+		{0x3600, 0x74},
+		{0x3601, 0x2b},
+		{0x3612, 0x0},
+		{0x3611, 0x67},
+		{0x3633, 0xba},
+		{0x3602, 0x2f},
+		{0x3603, 0x0},
+		{0x3630, 0xa8},
+		{0x3631, 0x16},
+		{0x3714, 0x10},
+		{0x371d, 0x1},
+		{0x4300, 0x3A}, /* UYVY mode */
+		{0x3007, 0x1},
+		/*
+		 * RAW mode and Pixel CLK selct.
+		 * 0x3024[0] = 1 :: System CLK (0x3003,0x3004)
+		 * 0x3024[0] = 0 :: secondary CLK (0x3005,0x3006)
+		 */
+		{0x3024, 0x1},
+		{0x3020, 0xb},
+		{0x3702, 0xd},
+		{0x3703, 0x20},
+		{0x3704, 0x15},
+		{0x3709, 0x28},
+		{0x370d, 0x0},
+		{0x3712, 0x0},
+		{0x3713, 0x20},
+		{0x3715, 0x4},
+		{0x381d, 0x40},
+		{0x381c, 0x0},
+		{0x3824, 0x10},
+		{0x3815, 0x8c},
+		{0x3804, 0x5},
+		{0x3805, 0x1f},
+		{0x3800, 0x0},
+		{0x3801, 0x0},
+		{0x3806, 0x3},
+		{0x3807, 0x1},
+		{0x3802, 0x0},
+		{0x3803, 0x2e},
+		{0x3808, 0x5},
+		{0x3809, 0x0},
+		{0x380a, 0x2},
+		{0x380b, 0xd0},
+		{0x380c, 0x6},
+		{0x380d, 0xf6}, /* 1280x720 */
+		{0x380e, 0x2},
+		{0x380f, 0xec}, /* 1280x720 */
+		{0x3811, 0x8},
+		{0x381f, 0xc},
+		{0x3621, 0x63},
+		{0x5005, 0x8},
+		{0x56d5, 0x0},
+		{0x56d6, 0x80},
+		{0x56d7, 0x0},
+		{0x56d8, 0x0},
+		{0x56d9, 0x0},
+		{0x56da, 0x80},
+		{0x56db, 0x0},
+		{0x56dc, 0x0},
+		{0x56e8, 0x0},
+		{0x56e9, 0x7f},
+		{0x56ea, 0x0},
+		{0x56eb, 0x7f},
+		{0x5100, 0x0},
+		{0x5101, 0x80},
+		{0x5102, 0x0},
+		{0x5103, 0x80},
+		{0x5104, 0x0},
+		{0x5105, 0x80},
+		{0x5106, 0x0},
+		{0x5107, 0x80},
+		{0x5108, 0x0},
+		{0x5109, 0x0},
+		{0x510a, 0x0},
+		{0x510b, 0x0},
+		{0x510c, 0x0},
+		{0x510d, 0x0},
+		{0x510e, 0x0},
+		{0x510f, 0x0},
+		{0x5110, 0x0},
+		{0x5111, 0x80},
+		{0x5112, 0x0},
+		{0x5113, 0x80},
+		{0x5114, 0x0},
+		{0x5115, 0x80},
+		{0x5116, 0x0},
+		{0x5117, 0x80},
+		{0x5118, 0x0},
+		{0x5119, 0x0},
+		{0x511a, 0x0},
+		{0x511b, 0x0},
+		{0x511c, 0x0},
+		{0x511d, 0x0},
+		{0x511e, 0x0},
+		{0x511f, 0x0},
+		{0x56d0, 0x0},
+		{0x5006, 0x24},
+		{0x5608, 0x0},
+		{0x52d7, 0x6},
+		{0x528d, 0x8},
+		{0x5293, 0x12},
+		{0x52d3, 0x12},
+		{0x5288, 0x6},
+		{0x5289, 0x20},
+		{0x52c8, 0x6},
+		{0x52c9, 0x20},
+		{0x52cd, 0x4},
+		{0x5381, 0x0},
+		{0x5382, 0xff},
+		{0x5589, 0x76},
+		{0x558a, 0x47},
+		{0x558b, 0xef},
+		{0x558c, 0xc9},
+		{0x558d, 0x49},
+		{0x558e, 0x30},
+		{0x558f, 0x67},
+		{0x5590, 0x3f},
+		{0x5591, 0xf0},
+		{0x5592, 0x10},
+		{0x55a2, 0x6d},
+		{0x55a3, 0x55},
+		{0x55a4, 0xc3},
+		{0x55a5, 0xb5},
+		{0x55a6, 0x43},
+		{0x55a7, 0x38},
+		{0x55a8, 0x5f},
+		{0x55a9, 0x4b},
+		{0x55aa, 0xf0},
+		{0x55ab, 0x10},
+		{0x5581, 0x52},
+		{0x5300, 0x1},
+		{0x5301, 0x0},
+		{0x5302, 0x0},
+		{0x5303, 0xe},
+		{0x5304, 0x0},
+		{0x5305, 0xe},
+		{0x5306, 0x0},
+		{0x5307, 0x36},
+		{0x5308, 0x0},
+		{0x5309, 0xd9},
+		{0x530a, 0x0},
+		{0x530b, 0xf},
+		{0x530c, 0x0},
+		{0x530d, 0x2c},
+		{0x530e, 0x0},
+		{0x530f, 0x59},
+		{0x5310, 0x0},
+		{0x5311, 0x7b},
+		{0x5312, 0x0},
+		{0x5313, 0x22},
+		{0x5314, 0x0},
+		{0x5315, 0xd5},
+		{0x5316, 0x0},
+		{0x5317, 0x13},
+		{0x5318, 0x0},
+		{0x5319, 0x18},
+		{0x531a, 0x0},
+		{0x531b, 0x26},
+		{0x531c, 0x0},
+		{0x531d, 0xdc},
+		{0x531e, 0x0},
+		{0x531f, 0x2},
+		{0x5320, 0x0},
+		{0x5321, 0x24},
+		{0x5322, 0x0},
+		{0x5323, 0x56},
+		{0x5324, 0x0},
+		{0x5325, 0x85},
+		{0x5326, 0x0},
+		{0x5327, 0x20},
+		{0x5609, 0x1},
+		{0x560a, 0x40},
+		{0x560b, 0x1},
+		{0x560c, 0x40},
+		{0x560d, 0x0},
+		{0x560e, 0xfa},
+		{0x560f, 0x0},
+		{0x5610, 0xfa},
+		{0x5611, 0x2},
+		{0x5612, 0x80},
+		{0x5613, 0x2},
+		{0x5614, 0x80},
+		{0x5615, 0x1},
+		{0x5616, 0x2c},
+		{0x5617, 0x1},
+		{0x5618, 0x2c},
+		{0x563b, 0x1},
+		{0x563c, 0x1},
+		{0x563d, 0x1},
+		{0x563e, 0x1},
+		{0x563f, 0x3},
+		{0x5640, 0x3},
+		{0x5641, 0x3},
+		{0x5642, 0x5},
+		{0x5643, 0x9},
+		{0x5644, 0x5},
+		{0x5645, 0x5},
+		{0x5646, 0x5},
+		{0x5647, 0x5},
+		{0x5651, 0x0},
+		{0x5652, 0x80},
+		{0x521a, 0x1},
+		{0x521b, 0x3},
+		{0x521c, 0x6},
+		{0x521d, 0xa},
+		{0x521e, 0xe},
+		{0x521f, 0x12},
+		{0x5220, 0x16},
+		{0x5223, 0x2},
+		{0x5225, 0x4},
+		{0x5227, 0x8},
+		{0x5229, 0xc},
+		{0x522b, 0x12},
+		{0x522d, 0x18},
+		{0x522f, 0x1e},
+		{0x5241, 0x4},
+		{0x5242, 0x1},
+		{0x5243, 0x3},
+		{0x5244, 0x6},
+		{0x5245, 0xa},
+		{0x5246, 0xe},
+		{0x5247, 0x12},
+		{0x5248, 0x16},
+		{0x524a, 0x3},
+		{0x524c, 0x4},
+		{0x524e, 0x8},
+		{0x5250, 0xc},
+		{0x5252, 0x12},
+		{0x5254, 0x18},
+		{0x5256, 0x1e},
+		{0x4605, 0x00}, /* 8-bit YUV mode. */
+		{0x4606, 0x7},
+		{0x4607, 0x71},
+		{0x460a, 0x2},
+		{0x460b, 0x70},
+		{0x460c, 0x0},
+		{0x4620, 0xe},
+		{0x4700, 0x4},
+		{0x4701, 0x01},
+		/* {0x4702, 0x1}, */
+		{0x4702, 0x00},  /* 01 */
+		{0x4703, 0x00},
+		{0x4704, 0x00}, /* 01 */
+		/*
+		 * Non-overlapping HSYNC-VSYNC.
+		 * Therefore do not set the VSYNC delay registers.
+		 */
+		{0x4705, 0x00}, /* Vsync delay high byte */
+		{0x4706, 0x00}, /* Vsync delay middle byte */
+		{0x4707, 0x00}, /* Vsync delay low byte{0x4708, 0x1}, */
+		/* {0x4709, 0x50}, */
+		{0x4004, 0x8},
+		{0x4005, 0x18},
+		{0x4001, 0x4},
+		{0x4050, 0x20},
+		{0x4051, 0x22},
+		{0x4057, 0x9c},
+		{0x405a, 0x0},
+		{0x4202, 0x2},
+		{0x3023, 0x10},
+		{0x100, 0x1},
+		{0x100, 0x1},
+		{0x6f0e, 0x0},
+		{0x6f0f, 0x0},
+		{0x460e, 0x8},
+		{0x460f, 0x1},
+		{0x4610, 0x0},
+		{0x4611, 0x1},
+		{0x4612, 0x0},
+		{0x4613, 0x1},
+		{0x4605, 0x00},
+		{0x4608, 0x0},
+		{0x4609, 0x8},
+		{0x6804, 0x0},
+		{0x6805, 0x6},
+		{0x6806, 0x0},
+		{0x5120, 0x0},
+		{0x3510, 0x0},
+		{0x3504, 0x0},
+		{0x6800, 0x0},
+		{0x6f0d, 0x0},
+		{0x5000, 0xff},
+		{0x5001, 0xbf},
+		{0x5002, 0xfe},
+		{0x503d, 0x0},
+		/* {0x503e, 0x00}, */
+		{0xc450, 0x1},
+		{0xc452, 0x4},
+		{0xc453, 0x0},
+		{0xc454, 0x0},
+		{0xc455, 0x0},
+		{0xc456, 0x0},
+		{0xc457, 0x0},
+		{0xc458, 0x0},
+		{0xc459, 0x0},
+		{0xc45b, 0x0},
+		{0xc45c, 0x0},
+		{0xc45d, 0x0},
+		{0xc45e, 0x0},
+		{0xc45f, 0x0},
+		{0xc460, 0x0},
+		{0xc461, 0x1},
+		{0xc462, 0x1},
+		{0xc464, 0x88},
+		{0xc465, 0x0},
+		{0xc466, 0x8a},
+		{0xc467, 0x0},
+		{0xc468, 0x86},
+		{0xc469, 0x0},
+		{0xc46a, 0x40},
+		{0xc46b, 0x50},
+		{0xc46c, 0x30},
+		{0xc46d, 0x28},
+		{0xc46e, 0x60},
+		{0xc46f, 0x40},
+		{0xc47c, 0x1},
+		{0xc47d, 0x38},
+		{0xc47e, 0x0},
+		{0xc47f, 0x0},
+		{0xc480, 0x0},
+		{0xc481, 0xff},
+		{0xc482, 0x0},
+		{0xc483, 0x40},
+		{0xc484, 0x0},
+		{0xc485, 0x18},
+		{0xc486, 0x0},
+		{0xc487, 0x18},
+		{0xc488, 0x2e},
+		{0xc489, 0x80},
+		{0xc48a, 0x2e},
+		{0xc48b, 0x80},
+		{0xc48c, 0x0},
+		{0xc48d, 0x4},
+		{0xc48e, 0x0},
+		{0xc48f, 0x4},
+		{0xc490, 0x7},
+		{0xc492, 0x20},
+		{0xc493, 0x8},
+		{0xc498, 0x2},
+		{0xc499, 0x0},
+		{0xc49a, 0x2},
+		{0xc49b, 0x0},
+		{0xc49c, 0x2},
+		{0xc49d, 0x0},
+		{0xc49e, 0x2},
+		{0xc49f, 0x60},
+		{0xc4a0, 0x4},
+		{0xc4a1, 0x0},
+		{0xc4a2, 0x6},
+		{0xc4a3, 0x0},
+		{0xc4a4, 0x0},
+		{0xc4a5, 0x10},
+		{0xc4a6, 0x0},
+		{0xc4a7, 0x40},
+		{0xc4a8, 0x0},
+		{0xc4a9, 0x80},
+		{0xc4aa, 0xd},
+		{0xc4ab, 0x0},
+		{0xc4ac, 0xf},
+		{0xc4ad, 0xc0},
+		{0xc4b4, 0x1},
+		{0xc4b5, 0x1},
+		{0xc4b6, 0x0},
+		{0xc4b7, 0x1},
+		{0xc4b8, 0x0},
+		{0xc4b9, 0x1},
+		{0xc4ba, 0x1},
+		{0xc4bb, 0x0},
+		{0xc4be, 0x2},
+		{0xc4bf, 0x33},
+		{0xc4c8, 0x3},
+		{0xc4c9, 0xd0},
+		{0xc4ca, 0xe},
+		{0xc4cb, 0x0},
+		{0xc4cc, 0xe},
+		{0xc4cd, 0x51},
+		{0xc4ce, 0xe},
+		{0xc4cf, 0x51},
+		{0xc4d0, 0x4},
+		{0xc4d1, 0x80},
+		{0xc4e0, 0x4},
+		{0xc4e1, 0x2},
+		{0xc4e2, 0x1},
+		{0xc4e4, 0x10},
+		{0xc4e5, 0x20},
+		{0xc4e6, 0x30},
+		{0xc4e7, 0x40},
+		{0xc4e8, 0x50},
+		{0xc4e9, 0x60},
+		{0xc4ea, 0x70},
+		{0xc4eb, 0x80},
+		{0xc4ec, 0x90},
+		{0xc4ed, 0xa0},
+		{0xc4ee, 0xb0},
+		{0xc4ef, 0xc0},
+		{0xc4f0, 0xd0},
+		{0xc4f1, 0xe0},
+		{0xc4f2, 0xf0},
+		{0xc4f3, 0x80},
+		{0xc4f4, 0x0},
+		{0xc4f5, 0x20},
+		{0xc4f6, 0x2},
+		{0xc4f7, 0x0},
+		{0xc4f8, 0x4},
+		{0xc4f9, 0xb},
+		{0xc4fa, 0x0},
+		{0xc4fb, 0x1},
+		{0xc4fc, 0x1},
+		{0xc4fd, 0x1},
+		{0xc4fe, 0x4},
+		{0xc4ff, 0x2},
+		{0xc500, 0x68},
+		{0xc501, 0x74},
+		{0xc502, 0x70},
+		{0xc503, 0x80},
+		{0xc504, 0x5},
+		{0xc505, 0x80},
+		{0xc506, 0x3},
+		{0xc507, 0x80},
+		{0xc508, 0x1},
+		{0xc509, 0xc0},
+		{0xc50a, 0x1},
+		{0xc50b, 0xa0},
+		{0xc50c, 0x1},
+		{0xc50d, 0x2c},
+		{0xc50e, 0x1},
+		{0xc50f, 0xa},
+		{0xc510, 0x0},
+		{0xc511, 0x0},
+		{0xc512, 0xe5},
+		{0xc513, 0x14},
+		{0xc514, 0x4},
+		{0xc515, 0x0},
+		{0xc518, 0x3},
+		{0xc519, 0x48},
+		{0xc51a, 0x7},
+		{0xc51b, 0x70},
+		{0xc2e0, 0x0},
+		{0xc2e1, 0x51},
+		{0xc2e2, 0x0},
+		{0xc2e3, 0xd6},
+		{0xc2e4, 0x1},
+		{0xc2e5, 0x5e},
+		{0xc2e9, 0x1},
+		{0xc2ea, 0x7a},
+		{0xc2eb, 0x90},
+		{0xc2ed, 0x1},
+		{0xc2ee, 0x7a},
+		{0xc2ef, 0x64},
+		{0xc308, 0x0},
+		{0xc309, 0x0},
+		{0xc30a, 0x0},
+		{0xc30c, 0x0},
+		{0xc30d, 0x1},
+		{0xc30e, 0x0},
+		{0xc30f, 0x0},
+		{0xc310, 0x1},
+		{0xc311, 0x60},
+		{0xc312, 0xff},
+		{0xc313, 0x8},
+		{0xc314, 0x1},
+		{0xc315, 0x7f},
+		{0xc316, 0xff},
+		{0xc317, 0xb},
+		{0xc318, 0x0},
+		{0xc319, 0xc},
+		{0xc31a, 0x0},
+		{0xc31b, 0xe0},
+		{0xc31c, 0x0},
+		{0xc31d, 0x14},
+		{0xc31e, 0x0},
+		{0xc31f, 0xc5},
+		{0xc320, 0xff},
+		{0xc321, 0x4b},
+		{0xc322, 0xff},
+		{0xc323, 0xf0},
+		{0xc324, 0xff},
+		{0xc325, 0xe8},
+		{0xc326, 0x0},
+		{0xc327, 0x46},
+		{0xc328, 0xff},
+		{0xc329, 0xd2},
+		{0xc32a, 0xff},
+		{0xc32b, 0xe4},
+		{0xc32c, 0xff},
+		{0xc32d, 0xbb},
+		{0xc32e, 0x0},
+		{0xc32f, 0x61},
+		{0xc330, 0xff},
+		{0xc331, 0xf9},
+		{0xc332, 0x0},
+		{0xc333, 0xd9},
+		{0xc334, 0x0},
+		{0xc335, 0x2e},
+		{0xc336, 0x0},
+		{0xc337, 0xb1},
+		{0xc338, 0xff},
+		{0xc339, 0x64},
+		{0xc33a, 0xff},
+		{0xc33b, 0xeb},
+		{0xc33c, 0xff},
+		{0xc33d, 0xe8},
+		{0xc33e, 0x0},
+		{0xc33f, 0x48},
+		{0xc340, 0xff},
+		{0xc341, 0xd0},
+		{0xc342, 0xff},
+		{0xc343, 0xed},
+		{0xc344, 0xff},
+		{0xc345, 0xad},
+		{0xc346, 0x0},
+		{0xc347, 0x66},
+		{0xc348, 0x1},
+		{0xc349, 0x0},
+		{0x6700, 0x4},
+		{0x6701, 0x7b},
+		{0x6702, 0xfd},
+		{0x6703, 0xf9},
+		{0x6704, 0x3d},
+		{0x6705, 0x71},
+		/*
+		 * 0x6706[3:0] :: XVCLK
+		 * 0x6706[3:0] :: 0 = 6MHz
+		 * 0x6706[3:0] :: 1 = 9MHz
+		 * 0x6706[3:0] :: 8 = 24MHz
+		 * 0x6706[3:0] :: 9 = 27MHz
+		 */
+		{0x6706, 0x71},
+		{0x6708, 0x5},
+		{0x3822, 0x50},
+		{0x6f06, 0x6f},
+		{0x6f07, 0x0},
+		{0x6f0a, 0x6f},
+		{0x6f0b, 0x0},
+		{0x6f00, 0x3},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x3042, 0xf0},
+		{0x301b, 0xf0},
+		{0x301c, 0xf0},
+		{0x301a, 0xf0},
+};
+
+static const struct ov1063x_reg ov1063x_regs_change_mode[] = {
+	{ 0x301b, 0xff }, { 0x301c, 0xff }, { 0x301a, 0xff }, { 0x5005, 0x08 },
+	{ 0x3007, 0x01 }, { 0x381c, 0x00 }, { 0x381f, 0x0C }, { 0x4001, 0x04 },
+	{ 0x4004, 0x08 }, { 0x4050, 0x20 }, { 0x4051, 0x22 }, { 0x6e47, 0x0C },
+	{ 0x4610, 0x05 }, { 0x4613, 0x10 },
+};
+
+static const struct ov1063x_reg ov1063x_regs_bt656[] = {
+	{ 0x4700, 0x02 }, { 0x4302, 0x03 }, { 0x4303, 0xf8 }, { 0x4304, 0x00 },
+	{ 0x4305, 0x08 }, { 0x4306, 0x03 }, { 0x4307, 0xf8 }, { 0x4308, 0x00 },
+	{ 0x4309, 0x08 },
+};
+
+static const struct ov1063x_reg ov1063x_regs_bt656_10bit[] = {
+	{ 0x4700, 0x02 }, { 0x4302, 0x03 }, { 0x4303, 0xfe }, { 0x4304, 0x00 },
+	{ 0x4305, 0x02 }, { 0x4306, 0x03 }, { 0x4307, 0xfe }, { 0x4308, 0x00 },
+	{ 0x4309, 0x02 },
+};
+
+static const struct ov1063x_reg ov1063x_regs_vert_sub_sample[] = {
+	{ 0x381f, 0x06 }, { 0x4001, 0x02 }, { 0x4004, 0x02 }, { 0x4050, 0x10 },
+	{ 0x4051, 0x11 }, { 0x6e47, 0x06 }, { 0x4610, 0x03 }, { 0x4613, 0x0a },
+};
+
+static const struct ov1063x_reg ov1063x_regs_enable[] = {
+	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
+	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
+	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
+	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
+	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
+	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
+	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x301b, 0xf0 }, { 0x301c, 0xf0 },
+	{ 0x301a, 0xf0 },
+};
+
+/*
+ * Datasheet highlight the following sequence to enable and disable
+ * Test Pattern mode i.e. colobar
+ */
+static const struct ov1063x_reg ov1063x_regs_colorbar_enable[] = {
+	{0x5120, 0x01}, {0x56d0, 0x01}, {0x5300, 0x01}, {0x5301, 0x00},
+	{0x5302, 0x00},	{0x5303, 0x00},	{0x5304, 0x00},	{0x5305, 0x00},
+	{0x5306, 0x00},	{0x5307, 0x00},	{0x5308, 0x01},	{0x5309, 0x00},
+	{0x530a, 0x00},	{0x530b, 0x00},	{0x530c, 0x00},	{0x530d, 0x00},
+	{0x530e, 0x00},	{0x530f, 0x00},	{0x5310, 0x01},	{0x5311, 0x00},
+	{0x5312, 0x00},	{0x5313, 0x00},	{0x5314, 0x01},	{0x5315, 0x00},
+	{0x5316, 0x00},	{0x5317, 0x00},	{0x5318, 0x00},	{0x5319, 0x00},
+	{0x531a, 0x00},	{0x531b, 0x00},	{0x531c, 0x01},	{0x531d, 0x00},
+	{0x531e, 0x00},	{0x531f, 0x00},	{0x5320, 0x00},	{0x5321, 0x00},
+	{0x5322, 0x00},	{0x5323, 0x00},	{0x5324, 0x01},	{0x5325, 0x00},
+	{0x5326, 0x00},	{0x5327, 0x00},	{0xc2ea, 0x80},	{0xc2eb, 0x80},
+	{0x5000, 0x79},	{0x503d, 0x80},
+};
+
+static const struct ov1063x_reg ov1063x_regs_colorbar_disable[] = {
+	{0x503d, 0x00},	{0x5120, 0x00},	{0x56d0, 0x00},	{0x5300, 0x01},
+	{0x5301, 0x00},	{0x5302, 0x00},	{0x5303, 0x0e},	{0x5304, 0x00},
+	{0x5305, 0x0e},	{0x5306, 0x00},	{0x5307, 0x36},	{0x5308, 0x00},
+	{0x5309, 0xd9},	{0x530a, 0x00},	{0x530b, 0x0f},	{0x530c, 0x00},
+	{0x530d, 0x2c},	{0x530e, 0x00},	{0x530f, 0x59},	{0x5310, 0x00},
+	{0x5311, 0x7b},	{0x5312, 0x00},	{0x5313, 0x22},	{0x5314, 0x00},
+	{0x5315, 0xd5},	{0x5316, 0x00},	{0x5317, 0x13},	{0x5318, 0x00},
+	{0x5319, 0x18},	{0x531a, 0x00},	{0x531b, 0x26},	{0x531c, 0x00},
+	{0x531d, 0xdc},	{0x531e, 0x00},	{0x531f, 0x02},	{0x5320, 0x00},
+	{0x5321, 0x24},	{0x5322, 0x00},	{0x5323, 0x56},	{0x5324, 0x00},
+	{0x5325, 0x85},	{0x5326, 0x00},	{0x5327, 0x20},	{0xc2ea, 0x7a},
+	{0xc2eb, 0x90},	{0x5000, 0xff},
+};
diff -Naur --no-dereference a/drivers/media/i2c/ov2312.c b/drivers/media/i2c/ov2312.c
--- a/drivers/media/i2c/ov2312.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/media/i2c/ov2312.c	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,804 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Omnivision OV2312 RGB-IR Image Sensor driver
+ *
+ * Copyright (c) 2022 Jai Luthra <j-luthra@ti.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+
+#include "ov2312.h"
+
+struct ov2312 {
+	struct device *dev;
+
+	struct clk *clk;
+	unsigned long clk_rate;
+
+	struct i2c_client *client;
+	struct regmap *regmap;
+	struct gpio_desc *reset_gpio;
+
+	struct v4l2_subdev sd;
+	struct media_pad pad;
+	struct v4l2_mbus_framefmt format;
+
+	struct v4l2_ctrl_handler ctrls;
+	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *again;
+	struct v4l2_ctrl *dgain;
+	struct v4l2_ctrl *h_flip;
+	struct v4l2_ctrl *v_flip;
+
+	u32 fps;
+
+	struct mutex lock; /* For streaming status */
+	unsigned int enable_count;
+};
+
+static inline struct ov2312 *to_ov2312(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct ov2312, sd);
+}
+
+static int ov2312_read(struct ov2312 *ov2312, u16 addr, u32 *val, size_t nbytes)
+{
+	int ret;
+	__le32 val_le = 0;
+
+	ret = regmap_bulk_read(ov2312->regmap, addr, &val_le, nbytes);
+	if (ret < 0) {
+		dev_err(ov2312->dev, "%s: failed to read reg 0x%04x: %d\n",
+			__func__, addr, ret);
+		return ret;
+	}
+
+	*val = le32_to_cpu(val_le);
+	return 0;
+}
+
+static int ov2312_write(struct ov2312 *ov2312, u16 addr, u32 val, size_t nbytes)
+{
+	int ret;
+	__le32 val_le = cpu_to_le32(val);
+
+	ret = regmap_bulk_write(ov2312->regmap, addr, &val_le, nbytes);
+	if (ret < 0)
+		dev_err(ov2312->dev, "%s: failed to write reg 0x%04x: %d\n",
+			__func__, addr, ret);
+	return ret;
+}
+
+static int ov2312_write_table(struct ov2312 *ov2312,
+			      const struct reg_sequence *regs,
+			      unsigned int nr_regs)
+{
+	int ret, i;
+
+	for (i = 0; i < nr_regs; i++) {
+		ret = regmap_write(ov2312->regmap, regs[i].reg, regs[i].def);
+		if (ret < 0) {
+			dev_err(ov2312->dev,
+				"%s: failed to write reg[%d] 0x%04x = 0x%02x (%d)!\n",
+				__func__, i, regs[i].reg, regs[i].def, ret);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static void ov2312_init_formats(struct v4l2_subdev_state *state)
+{
+	struct v4l2_mbus_framefmt *format;
+	int i;
+
+	for (i = 0; i < 2; ++i) {
+		format = v4l2_subdev_state_get_format(state, 0, i);
+		format->code = ov2312_mbus_formats[0];
+		format->width = ov2312_framesizes[0].width;
+		format->height = ov2312_framesizes[0].height;
+		format->field = V4L2_FIELD_NONE;
+		format->colorspace = V4L2_COLORSPACE_DEFAULT;
+	}
+}
+
+static int ov2312_set_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_state *state,
+			  struct v4l2_subdev_format *fmt)
+{
+	struct ov2312 *ov2312 = to_ov2312(sd);
+	struct v4l2_mbus_framefmt *format;
+	const struct v4l2_area *fsize;
+	u32 code;
+	int ret = 0;
+
+	if (fmt->pad != 0)
+		return -EINVAL;
+
+	if (fmt->stream != 0)
+		return -EINVAL;
+
+	/* Sensor only supports a single format. */
+	code = ov2312_mbus_formats[0];
+
+	/* Find the nearest supported frame size. */
+	fsize = v4l2_find_nearest_size(ov2312_framesizes,
+				       ARRAY_SIZE(ov2312_framesizes), width,
+				       height, fmt->format.width,
+				       fmt->format.height);
+
+	v4l2_subdev_lock_state(state);
+
+	/* Update the stored format and return it. */
+	format = v4l2_subdev_state_get_format(state, fmt->pad, fmt->stream);
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE && ov2312->enable_count) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	format->code = code;
+	format->width = fsize->width;
+	format->height = fsize->height;
+
+	fmt->format = *format;
+
+done:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int _ov2312_set_routing(struct v4l2_subdev *sd,
+			       struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_route routes[] = {
+		{
+			.source_pad = 0,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+		{
+			.source_pad = 0,
+			.source_stream = 1,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+	};
+
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+
+	int ret;
+
+	ret = v4l2_subdev_set_routing(sd, state, &routing);
+	if (ret < 0)
+		return ret;
+
+	ov2312_init_formats(state);
+
+	return 0;
+}
+
+static int ov2312_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+				 struct v4l2_mbus_frame_desc *fd)
+{
+	struct v4l2_subdev_state *state;
+	struct v4l2_mbus_framefmt *fmt;
+	u32 bpp;
+	int ret = 0;
+	unsigned int i;
+
+	if (pad != 0)
+		return -EINVAL;
+
+	state = v4l2_subdev_lock_and_get_active_state(sd);
+
+	fmt = v4l2_subdev_state_get_format(state, 0, 0);
+	if (!fmt) {
+		ret = -EPIPE;
+		goto out;
+	}
+
+	memset(fd, 0, sizeof(*fd));
+
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+
+	/* pixel stream - 2 virtual channels */
+
+	bpp = 10;
+
+	for (i = 0; i < 2; ++i) {
+		fd->entry[fd->num_entries].stream = i;
+
+		fd->entry[fd->num_entries].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
+		fd->entry[fd->num_entries].length = fmt->width * fmt->height * bpp / 8;
+		fd->entry[fd->num_entries].pixelcode = fmt->code;
+		fd->entry[fd->num_entries].bus.csi2.vc = i;
+		fd->entry[fd->num_entries].bus.csi2.dt = 0x2b; /* RAW10 */
+
+		fd->num_entries++;
+	}
+
+out:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int ov2312_set_routing(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_state *state,
+			      enum v4l2_subdev_format_whence which,
+			      struct v4l2_subdev_krouting *routing)
+{
+	int ret;
+
+	if (routing->num_routes == 0 || routing->num_routes > 2)
+		return -EINVAL;
+
+	v4l2_subdev_lock_state(state);
+
+	ret = _ov2312_set_routing(sd, state);
+
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int ov2312_init_state(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_state *state)
+{
+	int ret;
+
+	ret = _ov2312_set_routing(sd, state);
+
+	return ret;
+}
+
+static int ov2312_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *state,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index >= ARRAY_SIZE(ov2312_mbus_formats))
+		return -EINVAL;
+
+	code->code = ov2312_mbus_formats[code->index];
+
+	return 0;
+}
+
+static int ov2312_enum_frame_sizes(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_state *state,
+				   struct v4l2_subdev_frame_size_enum *fse)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(ov2312_mbus_formats); ++i) {
+		if (ov2312_mbus_formats[i] == fse->code)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(ov2312_mbus_formats))
+		return -EINVAL;
+
+	if (fse->index >= ARRAY_SIZE(ov2312_framesizes))
+		return -EINVAL;
+
+	fse->min_width = ov2312_framesizes[fse->index].width;
+	fse->max_width = fse->min_width;
+	fse->max_height = ov2312_framesizes[fse->index].height;
+	fse->min_height = fse->max_height;
+
+	return 0;
+}
+
+static int ov2312_get_frame_interval(struct v4l2_subdev *sd,
+					 struct v4l2_subdev_state *state,
+				     struct v4l2_subdev_frame_interval *fi)
+{
+	struct ov2312 *ov2312 = to_ov2312(sd);
+
+	fi->interval.numerator = 1;
+	fi->interval.denominator = ov2312->fps / 2;
+
+	return 0;
+}
+
+static int ov2312_set_frame_interval(struct v4l2_subdev *sd,
+					 struct v4l2_subdev_state *state,
+				     struct v4l2_subdev_frame_interval *fi)
+{
+	struct ov2312 *ov2312 = to_ov2312(sd);
+
+	dev_dbg(ov2312->dev, "%s: Set framerate %dfps\n", __func__,
+		fi->interval.denominator / fi->interval.numerator);
+	if ((fi->interval.denominator / fi->interval.numerator) != ov2312->fps) {
+		dev_err(ov2312->dev, "%s: Framerate can only be %dfps\n",
+			__func__, ov2312->fps);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int ov2312_detect(struct ov2312 *ov2312)
+{
+	int ret;
+	u32 id;
+
+	ret = ov2312_read(ov2312, OV2312_SC_CHIP_ID_HI, &id, 2);
+	if (ret < 0)
+		return ret;
+
+	id = cpu_to_be16(id);
+
+	if (id != OV2312_CHIP_ID) {
+		dev_err(ov2312->dev,
+			"%s: unknown chip ID 0x%04x\n", __func__, id);
+		return -ENODEV;
+	}
+
+	dev_dbg(ov2312->dev, "%s: detected chip ID 0x%04x\n", __func__, id);
+	return 0;
+}
+
+static int ov2312_set_AB_mode(struct ov2312 *ov2312)
+{
+	int i, ret;
+	u32 exposure = ov2312->exposure->val;
+	u32 again = ov2312->again->val;
+	u32 dgain = ov2312->dgain->val;
+	struct reg_sequence ov2312_groupB[] = {
+		{0x3208, 0x00},/* Group B (RGB Dominant VC1) */
+		{OV2312_AEC_PK_EXPO_HI, (exposure >> 8) & 0xff},
+		{OV2312_AEC_PK_EXPO_LO, exposure & 0xff},
+		{OV2312_AEC_PK_AGAIN_HI, (again >> 4) & 0xff},
+		{OV2312_AEC_PK_AGAIN_LO, (again & 0x0f) << 4},
+		{OV2312_AEC_PK_DGAIN_HI, (dgain >> 8) & 0xff},
+		{OV2312_AEC_PK_DGAIN_LO, dgain & 0xff},
+		{0x3920, 0x00},
+		{0x4813, 0x00},/* VC=0. This register takes effect from next frame */
+		{0x3208, 0x10},
+		{0x320D, 0x00},/* Auto mode switch between group0 and group1 ;setting to switch */
+		{0x320D, 0x31},
+		{0x3208, 0xA0},
+	};
+
+	for (i = 0; i < ARRAY_SIZE(ov2312_groupB); i++) {
+		ret = regmap_write(ov2312->regmap, ov2312_groupB[i].reg, ov2312_groupB[i].def);
+		if (ret < 0) {
+			dev_err(ov2312->dev,
+				"%s: failed to write reg[%d] 0x%04x = 0x%02x (%d)!\n",
+				__func__, i, ov2312_groupB[i].reg, ov2312_groupB[i].def, ret);
+			return ret;
+		}
+	}
+
+	msleep(33);
+	return 0;
+}
+
+static int ov2312_set_orientation(struct ov2312 *ov2312)
+{
+	bool v_flip = ov2312->v_flip->val;
+	bool h_flip = ov2312->h_flip->val;
+	u32 reg = (v_flip ? 0x4400 : 0) | (h_flip ? 0x0004 : 0);
+
+	return ov2312_write(ov2312, OV2312_TIMING_VFLIP, be16_to_cpu(reg), 2);
+}
+
+static int ov2312_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ov2312 *ov2312 = container_of(ctrl->handler,
+					     struct ov2312, ctrls);
+	int ret;
+
+	dev_dbg(ov2312->dev, "%s: %s, value: %d\n", __func__,
+		ctrl->name, ctrl->val);
+
+	/*
+	 * If the device is not powered up by the host driver do
+	 * not apply any controls to H/W at this time. Instead
+	 * the controls will be restored right after power-up.
+	 */
+	if (pm_runtime_suspended(ov2312->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+	case V4L2_CID_ANALOGUE_GAIN:
+	case V4L2_CID_DIGITAL_GAIN:
+		ret = ov2312_set_AB_mode(ov2312);
+		break;
+
+	case V4L2_CID_HFLIP:
+	case V4L2_CID_VFLIP:
+		ret = ov2312_set_orientation(ov2312);
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int ov2312_power_on(struct ov2312 *ov2312)
+{
+	int ret;
+
+	ret = clk_prepare_enable(ov2312->clk);
+	if (ret < 0)
+		return ret;
+
+	if (ov2312->reset_gpio) {
+		gpiod_set_value_cansleep(ov2312->reset_gpio, 0);
+		usleep_range(100, 1000);
+		gpiod_set_value_cansleep(ov2312->reset_gpio, 1);
+		msleep(30);
+	}
+	return 0;
+}
+
+static int ov2312_power_off(struct ov2312 *ov2312)
+{
+	if (ov2312->reset_gpio) {
+		gpiod_set_value_cansleep(ov2312->reset_gpio, 0);
+		usleep_range(1, 10);
+	}
+
+	clk_disable_unprepare(ov2312->clk);
+
+	return 0;
+}
+
+static int ov2312_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov2312 *ov2312 = to_ov2312(sd);
+
+	return ov2312_power_on(ov2312);
+}
+
+static int ov2312_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov2312 *ov2312 = to_ov2312(sd);
+
+	return ov2312_power_off(ov2312);
+}
+
+static int ov2312_start_stream(struct ov2312 *ov2312)
+{
+	int ret;
+
+	ret = ov2312_write_table(ov2312, ov2312_1600x1300_60fps_AB,
+				 ARRAY_SIZE(ov2312_1600x1300_60fps_AB));
+	if (ret < 0)
+		return ret;
+
+	/* Update controls on wake up */
+	ret = ov2312_set_orientation(ov2312);
+	if (ret < 0)
+		return ret;
+
+	ret = ov2312_set_AB_mode(ov2312);
+	if (ret < 0)
+		return ret;
+
+	msleep(100);
+
+	/* Set active */
+	ret = ov2312_write(ov2312, OV2312_SYS_MODE_SEL, 1, 1);
+	if (ret < 0)
+		return ret;
+
+	/* No communication is possible for a while after exiting standby */
+	msleep(20);
+	return 0;
+}
+
+static int ov2312_stop_stream(struct ov2312 *ov2312)
+{
+	int ret;
+
+	/* Set standby */
+	ret = ov2312_write(ov2312, OV2312_SYS_MODE_SEL, 0, 1);
+	if (ret < 0)
+		return ret;
+
+	/* No communication is possible for a while after entering standby */
+	usleep_range(10000, 20000);
+	return 0;
+}
+
+static int ov2312_sd_enable_streams(struct v4l2_subdev *sd,
+				       struct v4l2_subdev_state *state,
+				       u32 pad, u64 streams_mask)
+{
+	struct ov2312 *ov2312 = to_ov2312(sd);
+	int ret;
+
+	mutex_lock(&ov2312->lock);
+
+	if (!ov2312->enable_count) {
+		ret = pm_runtime_resume_and_get(ov2312->dev);
+		if (ret < 0)
+			goto err_unlock;
+
+		ret = ov2312_start_stream(ov2312);
+		if (ret < 0)
+			goto err_runtime_put;
+	}
+
+	ov2312->enable_count++;
+
+	mutex_unlock(&ov2312->lock);
+
+	return 0;
+
+err_runtime_put:
+	pm_runtime_put(ov2312->dev);
+
+err_unlock:
+	mutex_unlock(&ov2312->lock);
+	dev_err(ov2312->dev,
+		"%s: failed to enable streams %d\n", __func__, ret);
+	return ret;
+}
+
+static int ov2312_sd_disable_streams(struct v4l2_subdev *sd,
+					struct v4l2_subdev_state *state,
+					u32 pad, u64 streams_mask)
+{
+	struct ov2312 *ov2312 = to_ov2312(sd);
+	int ret;
+
+	mutex_lock(&ov2312->lock);
+
+	if (ov2312->enable_count == 1) {
+		ret = ov2312_stop_stream(ov2312);
+		if (ret < 0)
+			goto err_runtime_put;
+	}
+
+	ov2312->enable_count--;
+	mutex_unlock(&ov2312->lock);
+
+	return 0;
+
+err_runtime_put:
+	mutex_unlock(&ov2312->lock);
+	pm_runtime_put(ov2312->dev);
+	return ret;
+}
+
+static const struct v4l2_subdev_pad_ops ov2312_subdev_pad_ops = {
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = ov2312_set_fmt,
+	.enum_mbus_code = ov2312_enum_mbus_code,
+	.enum_frame_size = ov2312_enum_frame_sizes,
+	.set_routing = ov2312_set_routing,
+	.get_frame_desc	= ov2312_get_frame_desc,
+	.get_frame_interval = ov2312_get_frame_interval,
+	.set_frame_interval = ov2312_set_frame_interval,
+	.enable_streams = ov2312_sd_enable_streams,
+	.disable_streams = ov2312_sd_disable_streams,
+};
+
+static const struct v4l2_subdev_internal_ops ov2312_internal_ops = {
+	.init_state = ov2312_init_state,
+};
+
+static const struct v4l2_subdev_ops ov2312_subdev_ops = {
+	.pad	= &ov2312_subdev_pad_ops,
+};
+
+static const struct v4l2_ctrl_ops ov2312_ctrl_ops = {
+	.s_ctrl	= ov2312_set_ctrl,
+};
+
+static const struct dev_pm_ops ov2312_pm_ops = {
+	SET_RUNTIME_PM_OPS(ov2312_suspend, ov2312_resume, NULL)
+};
+
+static int ov2312_probe(struct i2c_client *client)
+{
+	struct ov2312 *ov2312;
+	struct v4l2_subdev *sd;
+	struct v4l2_ctrl_handler *ctrl_hdr;
+	int ret;
+
+	/* Allocate internal struct */
+	ov2312 = devm_kzalloc(&client->dev, sizeof(*ov2312), GFP_KERNEL);
+	if (!ov2312)
+		return -ENOMEM;
+
+	ov2312->dev = &client->dev;
+	ov2312->client = client;
+
+	/* Initialize I2C Regmap */
+	ov2312->regmap = devm_regmap_init_i2c(client, &ov2312_regmap_config);
+	if (IS_ERR(ov2312->regmap))
+		return PTR_ERR(ov2312->regmap);
+
+	/* Initialize Shutdown GPIO */
+	ov2312->reset_gpio = devm_gpiod_get_optional(ov2312->dev, "reset",
+						     GPIOD_OUT_HIGH);
+	if (IS_ERR(ov2312->reset_gpio))
+		return PTR_ERR(ov2312->reset_gpio);
+
+	ov2312->clk = devm_clk_get(ov2312->dev, "xvclk");
+	if (IS_ERR(ov2312->clk))
+		return PTR_ERR(ov2312->clk);
+
+	ov2312->clk_rate = clk_get_rate(ov2312->clk);
+	dev_info(ov2312->dev, "xvclk rate: %lu Hz\n", ov2312->clk_rate);
+
+	if (ov2312->clk_rate < 6000000 || ov2312->clk_rate > 27000000)
+		return -EINVAL;
+
+	/* Power on */
+	ret = ov2312_power_on(ov2312);
+	if (ret < 0)
+		return ret;
+
+	/* Detect sensor */
+	ret = ov2312_detect(ov2312);
+	if (ret < 0)
+		return ret;
+
+	/* Initialize the subdev and its controls. */
+	sd = &ov2312->sd;
+	v4l2_i2c_subdev_init(sd, client, &ov2312_subdev_ops);
+	sd->internal_ops = &ov2312_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_STREAMS;
+
+	/* Initialize the media entity. */
+	ov2312->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &ov2312->pad);
+	if (ret < 0) {
+		dev_err(ov2312->dev,
+			"%s: media entity init failed %d\n", __func__, ret);
+		return ret;
+	}
+
+	ov2312->fps = OV2312_FRAMERATE_DEFAULT;
+	mutex_init(&ov2312->lock);
+
+	/* Initialize controls */
+	ctrl_hdr = &ov2312->ctrls;
+	ret = v4l2_ctrl_handler_init(ctrl_hdr, 5);
+	if (ret < 0) {
+		dev_err(ov2312->dev,
+			"%s: ctrl handler init failed: %d\n", __func__, ret);
+		goto err_media_cleanup;
+	}
+
+	ov2312->ctrls.lock = &ov2312->lock;
+
+	/* Add new controls */
+	ov2312->exposure = v4l2_ctrl_new_std(ctrl_hdr, &ov2312_ctrl_ops,
+					     V4L2_CID_EXPOSURE, 1,
+					     OV2312_EXPOSURE_MAX,
+					     1, OV2312_EXPOSURE_DEFAULT);
+
+	ov2312->again = v4l2_ctrl_new_std(ctrl_hdr, &ov2312_ctrl_ops,
+					  V4L2_CID_ANALOGUE_GAIN, 0,
+					  OV2312_AGAIN_MAX, 1,
+					  OV2312_AGAIN_DEFAULT);
+
+	ov2312->dgain = v4l2_ctrl_new_std(ctrl_hdr, &ov2312_ctrl_ops,
+					  V4L2_CID_DIGITAL_GAIN, 0,
+					  OV2312_DGAIN_MAX, 1,
+					  OV2312_DGAIN_DEFAULT);
+
+	ov2312->h_flip = v4l2_ctrl_new_std(ctrl_hdr, &ov2312_ctrl_ops,
+					   V4L2_CID_HFLIP, 0, 1, 1, 0);
+
+	ov2312->v_flip = v4l2_ctrl_new_std(ctrl_hdr, &ov2312_ctrl_ops,
+					   V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+	ov2312->sd.ctrl_handler = ctrl_hdr;
+	if (ov2312->ctrls.error) {
+		ret = ov2312->ctrls.error;
+		dev_err(ov2312->dev,
+			"%s: failed to add the ctrls: %d\n", __func__, ret);
+		goto err_ctrl_free;
+	}
+
+	/* PM Runtime */
+	pm_runtime_enable(ov2312->dev);
+	pm_runtime_set_suspended(ov2312->dev);
+
+	ret = v4l2_subdev_init_finalize(sd);
+	if (ret < 0)
+		goto err_pm_disable;
+
+	/* Finally, register the subdev. */
+	ret = v4l2_async_register_subdev(sd);
+	if (ret < 0) {
+		dev_err(ov2312->dev,
+			"%s: v4l2 subdev register failed %d\n", __func__, ret);
+		goto err_subdev_cleanup;
+	}
+
+	dev_info(ov2312->dev, "ov2312 probed\n");
+	return 0;
+
+err_subdev_cleanup:
+	v4l2_subdev_cleanup(&ov2312->sd);
+
+err_pm_disable:
+	pm_runtime_disable(ov2312->dev);
+
+err_ctrl_free:
+	v4l2_ctrl_handler_free(ctrl_hdr);
+	mutex_destroy(&ov2312->lock);
+
+err_media_cleanup:
+	media_entity_cleanup(&ov2312->sd.entity);
+
+	return ret;
+}
+
+static void ov2312_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov2312 *ov2312 = to_ov2312(sd);
+
+	v4l2_async_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&ov2312->ctrls);
+	v4l2_subdev_cleanup(&ov2312->sd);
+	media_entity_cleanup(&sd->entity);
+	mutex_destroy(&ov2312->lock);
+
+	pm_runtime_disable(ov2312->dev);
+}
+
+static const struct i2c_device_id ov2312_id[] = {
+	{ "ov2312", 0 },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(i2c, ov2312_id);
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id ov2312_of_match[] = {
+	{ .compatible = "ovti,ov2312", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ov2312_of_match);
+#endif
+
+static struct i2c_driver ov2312_i2c_driver = {
+	.driver = {
+		.name	= "ov2312",
+		.pm	= &ov2312_pm_ops,
+		.of_match_table = of_match_ptr(ov2312_of_match),
+	},
+	.probe		= ov2312_probe,
+	.remove		= ov2312_remove,
+	.id_table	= ov2312_id,
+};
+
+module_i2c_driver(ov2312_i2c_driver);
+
+MODULE_AUTHOR("Jai Luthra <j-luthra@ti.com>");
+MODULE_DESCRIPTION("OV2312 RGB-IR Image Sensor driver");
+MODULE_LICENSE("GPL");
diff -Naur --no-dereference a/drivers/media/i2c/ov2312.h b/drivers/media/i2c/ov2312.h
--- a/drivers/media/i2c/ov2312.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/media/i2c/ov2312.h	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,267 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Omnivision OV2312 RGB-IR Image Sensor driver
+ *
+ * Copyright (c) 2022 Jai Luthra <j-luthra@ti.com>
+ */
+
+#include <linux/types.h>
+#include <linux/media-bus-format.h>
+
+#define OV2312_CHIP_ID	0x2311
+#define OV2312_FRAMERATE_DEFAULT 60
+
+#define OV2312_OUT_WIDTH	1600
+#define OV2312_OUT_HEIGHT	1300
+#define OV2312_VTS		0x0588
+
+#define OV2312_SYS_MODE_SEL	0x0100
+#define OV2312_SC_CHIP_ID_HI	0x300a
+#define OV2312_SC_CHIP_ID_LO	0x300b
+#define OV2312_AEC_PK_EXPO_HI	0x3501
+#define OV2312_AEC_PK_EXPO_LO	0x3502
+#define OV2312_AEC_PK_AGAIN_HI	0x3508
+#define OV2312_AEC_PK_AGAIN_LO	0x3509
+#define OV2312_AEC_PK_DGAIN_HI	0x350a
+#define OV2312_AEC_PK_DGAIN_LO	0x350b
+#define OV2312_TIMING_VFLIP	0x3820
+#define OV2312_TIMING_HFLIP	0x3821
+
+/* Exposure control */
+#define OV2312_EXPOSURE_MAX	(OV2312_VTS - 12)
+#define OV2312_EXPOSURE_DEFAULT 0x057c
+#define OV2312_IR_EXPOSURE	0x0090
+#define OV2312_IR_STROBE	OV2312_IR_EXPOSURE
+#define OV2312_IR_STROBE_START	(OV2312_VTS - OV2312_IR_EXPOSURE - 7)
+
+/* Analog gain control */
+#define OV2312_AGAIN_MAX	0x1FF
+#define OV2312_AGAIN_DEFAULT	0x010
+
+/* Digital gain control */
+#define OV2312_DGAIN_MAX	0x0FFF
+#define OV2312_DGAIN_DEFAULT	0x0100
+
+static const struct v4l2_area ov2312_framesizes[] = {
+	{
+		.width		= OV2312_OUT_WIDTH,
+		.height		= OV2312_OUT_HEIGHT,
+	},
+};
+
+static const u32 ov2312_mbus_formats[] = {
+	MEDIA_BUS_FMT_SBGGI10_1X10,
+};
+
+static const struct regmap_config ov2312_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 8,
+};
+
+static const struct reg_sequence ov2312_1600x1300_60fps_AB[] = {
+	{0x0103, 0x01},
+	{0x0100, 0x00},
+	{0x010c, 0x02},
+	{0x010b, 0x01},
+	{0x0300, 0x01},
+	{0x0302, 0x32},
+	{0x0303, 0x00},
+	{0x0304, 0x03},
+	{0x0305, 0x02},
+	{0x0306, 0x01},
+	{0x030d, 0x5a},
+	{0x030e, 0x04},
+	{0x3001, 0x02},
+	{0x3004, 0x00},
+	{0x3005, 0x00},
+	{0x3006, 0x0a},
+	{0x3011, 0x0d},
+	{0x3014, 0x04},
+	{0x301c, 0xf0},
+	{0x3020, 0x20},
+	{0x302c, 0x00},
+	{0x302d, 0x00},
+	{0x302e, 0x00},
+	{0x302f, 0x03},
+	{0x3030, 0x10},
+	{0x303f, 0x03},
+	{0x3103, 0x00},
+	{0x3106, 0x08},
+	{0x31ff, 0x01},
+	{0x3501, 0x05},
+	{0x3502, 0x7c},
+	{0x3506, 0x00},
+	{0x3507, 0x00},
+	{0x3620, 0x67},
+	{0x3633, 0x78},
+	{0x3662, 0x65},
+	{0x3664, 0xb0},
+	{0x3666, 0x70},
+	{0x3670, 0x68},
+	{0x3674, 0x10},
+	{0x3675, 0x00},
+	{0x367e, 0x90},
+	{0x3680, 0x84},
+	{0x36a2, 0x04},
+	{0x36a3, 0x80},
+	{0x36b0, 0x00},
+	{0x3700, 0x35},
+	{0x3704, 0x39},
+	{0x370a, 0x50},
+	{0x3712, 0x00},
+	{0x3713, 0x02},
+	{0x3778, 0x00},
+	{0x379b, 0x01},
+	{0x379c, 0x10},
+	{0x3800, 0x00},
+	{0x3801, 0x00},
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	{0x3804, 0x06},
+	{0x3805, 0x4f},
+	{0x3806, 0x05},
+	{0x3807, 0x23},
+	{0x3808, 0x06},
+	{0x3809, 0x40},
+	{0x380a, 0x05},
+	{0x380b, 0x14},
+	{0x380c, 0x03},
+	{0x380d, 0xa8},
+	{0x380e, (OV2312_VTS >> 8) & 0xff},
+	{0x380f, OV2312_VTS & 0xff},
+	{0x3810, 0x00},
+	{0x3811, 0x08},
+	{0x3812, 0x00},
+	{0x3813, 0x08},
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	{0x3816, 0x00},
+	{0x3817, 0x01},
+	{0x3818, 0x00},
+	{0x3819, 0x05},
+	{0x382b, 0x5a},
+	{0x382c, 0x0a},
+	{0x382d, 0xf8},
+	{0x3881, 0x44},
+	{0x3882, 0x02},
+	{0x3883, 0x8c},
+	{0x3885, 0x07},
+	{0x389d, 0x03},
+	{0x38a6, 0x00},
+	{0x38a7, 0x01},
+	{0x38b3, 0x07},
+	{0x38b1, 0x00},
+	{0x38e5, 0x02},
+	{0x38e7, 0x00},
+	{0x38e8, 0x00},
+	{0x3910, 0xff},
+	{0x3911, 0xff},
+	{0x3912, 0x08},
+	{0x3913, 0x00},
+	{0x3914, 0x00},
+	{0x3915, 0x00},
+	{0x391c, 0x00},
+	{0x3920, 0xff},
+	{0x3921, 0x80},
+	{0x3922, 0x00},
+	{0x3923, 0x00},
+	{0x3924, 0x05},
+	{0x3925, 0x00},
+	{0x3926, 0x00},
+	{0x3927, 0x00},
+	{0x3928, 0x1a},
+	{0x392d, 0x03},
+	{0x392e, 0xa8},
+	{0x392f, 0x08},
+	{0x4001, 0x00},
+	{0x4003, 0x40},
+	{0x4008, 0x04},
+	{0x4009, 0x1b},
+	{0x400c, 0x04},
+	{0x400d, 0x1b},
+	{0x4010, 0xf4},
+	{0x4011, 0x00},
+	{0x4016, 0x00},
+	{0x4017, 0x04},
+	{0x4042, 0x11},
+	{0x4043, 0x70},
+	{0x4045, 0x00},
+	{0x4409, 0x5f},
+	{0x4509, 0x00},
+	{0x450b, 0x00},
+	{0x4600, 0x00},
+	{0x4601, 0x80},
+	{0x4708, 0x09},
+	{0x470c, 0x81},
+	{0x4710, 0x06},
+	{0x4711, 0x00},
+	{0x4800, 0x00},
+	{0x481f, 0x30},
+	{0x4837, 0x14},
+	{0x4f00, 0x00},
+	{0x4f07, 0x00},
+	{0x4f08, 0x03},
+	{0x4f09, 0x08},
+	{0x4f0c, 0x05},
+	{0x4f0d, 0xb4},
+	{0x4f10, 0x00},
+	{0x4f11, 0x00},
+	{0x4f12, 0x07},
+	{0x4f13, 0xe2},
+	{0x5000, 0x9f},
+	{0x5001, 0x20},
+	{0x5026, 0x00},
+	{0x5c00, 0x00},
+	{0x5c01, 0x2c},
+	{0x5c02, 0x00},
+	{0x5c03, 0x7f},
+	{0x5e00, 0x00},
+	{0x5e01, 0x41},
+	{0x38b1, 0x02},
+	{0x0100, 0x01},
+	{0x3006, 0x08},/* Strobe control  */
+	{0x3004, 0x02},
+	{0x3007, 0x02},
+	{0x301c, 0x20},
+	{0x3020, 0x20},
+	{0x3025, 0x02},
+	{0x382c, 0x0a},
+	{0x382d, 0xf8},
+	{0x3920, 0xff},
+	{0x3921, 0x00},
+	{0x3923, 0x00},
+	{0x3924, 0x00},
+	{0x3925, 0x00},
+	{0x3926, 0x00},
+	{0x3927, 0x00},
+	{0x3928, 0x80},
+	{0x392b, 0x00},
+	{0x392c, 0x00},
+	{0x392d, 0x03},
+	{0x392e, 0xa8},
+	{0x392f, 0x0b},
+	{0x38b3, 0x07},
+	{0x3885, 0x07},
+	{0x382b, 0x3a},
+	{0x3670, 0x68},
+	{0x301C, 0xF0},/* AB mode - Group auto switch example setting */
+	{0x3209, 0x01},/* Stay in Group A for 1 Frame */
+	{0x320A, 0x01},/* Stay in Group B for 1 Frame */
+	{0x320B, 0x00},
+	{0x320C, 0x00},
+	{0x3208, 0x01},/* Group A (IR Dominant VC0) */
+	{OV2312_AEC_PK_EXPO_HI, (OV2312_IR_EXPOSURE >> 8) & 0xff},
+	{OV2312_AEC_PK_EXPO_LO, OV2312_IR_EXPOSURE & 0xff},
+	{OV2312_AEC_PK_AGAIN_HI, 0x01},
+	{OV2312_AEC_PK_AGAIN_LO, 0x00},
+	{OV2312_AEC_PK_DGAIN_HI, 0x01},
+	{OV2312_AEC_PK_DGAIN_LO, 0x00},
+	{0x3920, 0xff},/* IR Strobe duty cycle */
+	{0x3927, (OV2312_IR_STROBE >> 8) & 0xff},
+	{0x3928, OV2312_IR_STROBE & 0xff},
+	{0x3929, (OV2312_IR_STROBE_START >> 8) & 0xff},
+	{0x392a, OV2312_IR_STROBE_START & 0xff},
+	{0x4813, 0x01},/* VC=1. This register takes effect from next frame */
+	{0x3208, 0x11},
+
+};
diff -Naur --no-dereference a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
--- a/drivers/media/i2c/ov5640.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/i2c/ov5640.c	2025-10-23 09:30:40.285462207 -0400
@@ -25,6 +25,7 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-subdev.h>
+#include <media/mipi-csi2.h>
 
 /* min/typical/max system clock (xclk) frequencies */
 #define OV5640_XCLK_MIN  6000000
@@ -3780,6 +3781,44 @@
 	return 0;
 }
 
+static int ov5640_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+				 struct v4l2_mbus_frame_desc *fd)
+{
+	struct ov5640_dev *sensor = to_ov5640_dev(sd);
+	u32 bpp;
+
+	if (pad != 0)
+		return -EINVAL;
+
+	mutex_lock(&sensor->lock);
+
+	memset(fd, 0, sizeof(*fd));
+
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+
+	/* pixel stream */
+
+	bpp = ov5640_code_to_bpp(sensor, sensor->fmt.code);
+
+	fd->entry[fd->num_entries].stream = 0;
+
+	fd->entry[fd->num_entries].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
+	fd->entry[fd->num_entries].length =
+		(sensor->current_mode->width
+		 * sensor->current_mode->height * bpp) / 8;
+	fd->entry[fd->num_entries].pixelcode = sensor->fmt.code;
+	fd->entry[fd->num_entries].bus.csi2.vc = 0;
+	if (sensor->fmt.code == MEDIA_BUS_FMT_SRGGB8_1X8)
+		fd->entry[fd->num_entries].bus.csi2.dt = MIPI_CSI2_DT_RAW8;
+	else
+		fd->entry[fd->num_entries].bus.csi2.dt = MIPI_CSI2_DT_YUV422_8B;
+	fd->num_entries++;
+
+	mutex_unlock(&sensor->lock);
+
+	return 0;
+}
+
 static const struct v4l2_subdev_core_ops ov5640_core_ops = {
 	.log_status = v4l2_ctrl_subdev_log_status,
 	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
@@ -3799,6 +3838,7 @@
 	.set_frame_interval = ov5640_set_frame_interval,
 	.enum_frame_size = ov5640_enum_frame_size,
 	.enum_frame_interval = ov5640_enum_frame_interval,
+	.get_frame_desc	= ov5640_get_frame_desc,
 };
 
 static const struct v4l2_subdev_ops ov5640_subdev_ops = {
diff -Naur --no-dereference a/drivers/media/i2c/ox05b1s.c b/drivers/media/i2c/ox05b1s.c
--- a/drivers/media/i2c/ox05b1s.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/media/i2c/ox05b1s.c	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,1211 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OmniVision OX05B1S RGB-IR Image Sensor driver
+ *
+ * Copyright (c) 2023-2024 Abhishek Sharma <abhishek.sharma@ti.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+
+#include <linux/media-bus-format.h>
+
+#define OX05B_CHIP_ID			0x0558
+#define OX05B_FRAMERATE_DEFAULT	60
+
+#define OX05B_OUT_WIDTH		2592
+#define OX05B_OUT_HEIGHT	1944
+
+#define OX05B_SYS_MODE_SEL		0x0100
+#define OX05B_SC_CHIP_ID_HI		0x300a
+#define OX05B_AEC_PK_EXPO_HI	0x3501
+#define OX05B_AEC_PK_EXPO_LO	0x3502
+#define OX05B_AEC_PK_AGAIN_HI	0x3508
+#define OX05B_AEC_PK_AGAIN_LO	0x3509
+#define OX05B_AEC_PK_DGAIN_HI	0x350a
+#define OX05B_AEC_PK_DGAIN_LO	0x350b
+#define OX05B_DEFAULT_LINK_FREQ	480000000
+
+/*
+ * Exposure control
+ * Set max value as 0x850 (frame length = 2128) - 30 = 0x0832 for 16.66 ms exposure
+ * Set default value to be 1000 (0x03E8).
+ */
+#define OX05B_EXPOSURE_MAX	0x0832
+#define OX05B_EXPOSURE_DEFAULT	0x03E8
+
+/* Analog gain control */
+#define OX05B_AGAIN_MAX		0x0F80
+#define OX05B_AGAIN_DEFAULT	0x010
+
+/* Digital gain control */
+#define OX05B_DGAIN_MAX 0x0FFF
+#define OX05B_DGAIN_DEFAULT	0x0100
+
+static const struct v4l2_area ox05b_framesizes[] = {
+	{
+		.width          = OX05B_OUT_WIDTH,
+		.height         = OX05B_OUT_HEIGHT,
+	},
+};
+
+static const u32 ox05b_mbus_formats[] = {
+	MEDIA_BUS_FMT_SBGGI10_1X10,
+};
+
+static const struct regmap_config ox05b_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 8,
+};
+
+static const s64 ox05b_link_freq_menu[] = {
+	OX05B_DEFAULT_LINK_FREQ,
+};
+
+static const struct reg_sequence ox05b_linear_2592x1944[] = {
+	{0x0107, 0x01}, {0x0104, 0x00}, {0x0301, 0x1a}, {0x0304, 0x01},
+	{0x0305, 0xe0}, {0x0306, 0x04}, {0x0307, 0x01}, {0x0321, 0x03},
+	{0x0324, 0x01}, {0x0325, 0x80}, {0x0341, 0x03}, {0x0344, 0x01},
+	{0x0345, 0xb0}, {0x0347, 0x07}, {0x034b, 0x06}, {0x0360, 0x80},
+	{0x040b, 0x5c}, {0x040c, 0xcd}, {0x2805, 0xff}, {0x2806, 0x0f},
+	{0x3000, 0x00}, {0x3001, 0x00}, {0x3002, 0x10}, {0x3004, 0x00},
+	{0x3009, 0x2e}, {0x3010, 0x41}, {0x3015, 0xf0}, {0x3016, 0xf0},
+	{0x3017, 0xf0}, {0x3018, 0xf0}, {0x301a, 0x78}, {0x301b, 0xb4},
+	{0x301f, 0xe9}, {0x3024, 0x80}, {0x302b, 0x00}, {0x3039, 0x00},
+	{0x3044, 0x70}, {0x3101, 0x32}, {0x3182, 0x10}, {0x3187, 0xff},
+	{0x320a, 0x00}, {0x320b, 0x00}, {0x320c, 0x00}, {0x320d, 0x00},
+	{0x320e, 0x00}, {0x320f, 0x00}, {0x3211, 0x61}, {0x3212, 0x00},
+	{0x3215, 0xcc}, {0x3218, 0x06}, {0x3251, 0x00}, {0x3252, 0xe4},
+	{0x3253, 0x00}, {0x3304, 0x11}, {0x3305, 0x00}, {0x3306, 0x01},
+	{0x3307, 0x00}, {0x3308, 0x02}, {0x3309, 0x00}, {0x330a, 0x02},
+	{0x330b, 0x00}, {0x330c, 0x02}, {0x330d, 0x00}, {0x330e, 0x02},
+	{0x330f, 0x00}, {0x3310, 0x02}, {0x3311, 0x00}, {0x3312, 0x02},
+	{0x3313, 0x00}, {0x3314, 0x02}, {0x3315, 0x00}, {0x3316, 0x02},
+	{0x3317, 0x11}, {0x3400, 0x0c}, {0x3421, 0x00}, {0x3422, 0x00},
+	{0x3423, 0x00}, {0x3424, 0x00}, {0x3425, 0x00}, {0x3426, 0x00},
+	{0x3427, 0x00}, {0x3428, 0x00}, {0x3429, 0x00}, {0x342a, 0x00},
+	{0x342b, 0x00}, {0x342c, 0x00}, {0x342d, 0x00}, {0x342e, 0x00},
+	{0x3500, 0x00}, {0x3501, 0x00}, {0x3502, 0x08}, {0x3503, 0xa8},
+	{0x3504, 0x08}, {0x3505, 0x00}, {0x3506, 0x00}, {0x3507, 0x00},
+	{0x3508, 0x01}, {0x3509, 0x00}, {0x350a, 0x01}, {0x350b, 0x00},
+	{0x350c, 0x00}, {0x351e, 0x00}, {0x351f, 0x00}, {0x3541, 0x00},
+	{0x3542, 0x08}, {0x3603, 0x65}, {0x3604, 0x24}, {0x3608, 0x08},
+	{0x3610, 0x00}, {0x3612, 0x00}, {0x3619, 0x09}, {0x361a, 0x27},
+	{0x3620, 0x40}, {0x3622, 0x15}, {0x3623, 0x0e}, {0x3624, 0x1f},
+	{0x3625, 0x1f}, {0x362a, 0x01}, {0x362b, 0x00}, {0x3633, 0x88},
+	{0x3634, 0x86}, {0x3636, 0x80}, {0x3638, 0x5b}, {0x363b, 0x22},
+	{0x363c, 0x07}, {0x363d, 0x11}, {0x363e, 0x21}, {0x363f, 0x24},
+	{0x3640, 0xd3}, {0x3641, 0x00}, {0x3650, 0xe4}, {0x3651, 0x80},
+	{0x3652, 0xff}, {0x3653, 0x00}, {0x3654, 0x05}, {0x3655, 0xf8},
+	{0x3656, 0x00}, {0x3660, 0x00}, {0x3664, 0x00}, {0x366a, 0x80},
+	{0x366b, 0x00}, {0x3670, 0x00}, {0x3674, 0x00}, {0x3684, 0x6d},
+	{0x3685, 0x6d}, {0x3686, 0x6d}, {0x3687, 0x6d}, {0x368c, 0x07},
+	{0x368d, 0x07}, {0x368e, 0x07}, {0x368f, 0x07}, {0x3690, 0x04},
+	{0x3691, 0x04}, {0x3692, 0x04}, {0x3693, 0x04}, {0x3698, 0x00},
+	{0x369e, 0x1f}, {0x369f, 0x19}, {0x36a0, 0x05}, {0x36a2, 0x19},
+	{0x36a3, 0x05}, {0x36a4, 0x07}, {0x36a5, 0x27}, {0x36a6, 0x00},
+	{0x36a7, 0x80}, {0x36e3, 0x09}, {0x3700, 0x07}, {0x3701, 0x1b},
+	{0x3702, 0x0a}, {0x3703, 0x21}, {0x3704, 0x19}, {0x3705, 0x07},
+	{0x3706, 0x36}, {0x370a, 0x1c}, {0x370b, 0x02}, {0x370c, 0x00},
+	{0x370d, 0x6e}, {0x370f, 0x80}, {0x3710, 0x10}, {0x3712, 0x09},
+	{0x3714, 0x42}, {0x3715, 0x00}, {0x3716, 0x02}, {0x3717, 0xa2},
+	{0x3718, 0x41}, {0x371a, 0x80}, {0x371b, 0x0a}, {0x371c, 0x0a},
+	{0x371d, 0x08}, {0x371e, 0x01}, {0x371f, 0x20}, {0x3720, 0x0e},
+	{0x3721, 0x22}, {0x3722, 0x0c}, {0x3727, 0x84}, {0x3728, 0x03},
+	{0x3729, 0x64}, {0x372a, 0x0c}, {0x372b, 0x14}, {0x372d, 0x50},
+	{0x372e, 0x14}, {0x3731, 0x11}, {0x3732, 0x24}, {0x3733, 0x00},
+	{0x3734, 0x00}, {0x3735, 0x12}, {0x3736, 0x00}, {0x373b, 0x0b},
+	{0x373c, 0x14}, {0x373f, 0x3e}, {0x3740, 0x12}, {0x3741, 0x12},
+	{0x3753, 0x80}, {0x3754, 0x01}, {0x3756, 0x11}, {0x375c, 0x0f},
+	{0x375d, 0x35}, {0x375e, 0x0f}, {0x375f, 0x37}, {0x3760, 0x0f},
+	{0x3761, 0x27}, {0x3762, 0x3f}, {0x3763, 0x5d}, {0x3764, 0x01},
+	{0x3765, 0x17}, {0x3766, 0x02}, {0x3768, 0x52}, {0x376a, 0x30},
+	{0x376b, 0x02}, {0x376c, 0x08}, {0x376d, 0x2a}, {0x376e, 0x00},
+	{0x376f, 0x18}, {0x3770, 0x2c}, {0x3771, 0x0c}, {0x3776, 0xc0},
+	{0x3778, 0x00}, {0x3779, 0x80}, {0x377a, 0x00}, {0x377d, 0x14},
+	{0x377e, 0x0c}, {0x379f, 0x00}, {0x37a3, 0x40}, {0x37a4, 0x03},
+	{0x37a5, 0x10}, {0x37a6, 0x02}, {0x37a7, 0x0e}, {0x37a9, 0x00},
+	{0x37aa, 0x08}, {0x37ab, 0x08}, {0x37ac, 0x36}, {0x37ad, 0x40},
+	{0x37b0, 0x48}, {0x37d0, 0x00}, {0x37d1, 0x0b}, {0x37d2, 0x0c},
+	{0x37d3, 0x10}, {0x37d4, 0x10}, {0x37d5, 0x10}, {0x37d8, 0x0e},
+	{0x37d9, 0x0e}, {0x37da, 0x3c}, {0x37db, 0x52}, {0x37dc, 0x50},
+	{0x37dd, 0x00}, {0x37de, 0x55}, {0x37df, 0x7d}, {0x37e5, 0x88},
+	{0x37e7, 0x68}, {0x37e8, 0x07}, {0x37f0, 0x00}, {0x37f1, 0x0e},
+	{0x37f2, 0x35}, {0x37f3, 0x14}, {0x37f4, 0x0c}, {0x37f5, 0x14},
+	{0x37f6, 0x0c}, {0x37f7, 0x35}, {0x37f8, 0x35}, {0x37f9, 0x37},
+	{0x37fa, 0x37}, {0x37fb, 0x37}, {0x3800, 0x00}, {0x3801, 0x00},
+	{0x3802, 0x00}, {0x3803, 0x00}, {0x3804, 0x0a}, {0x3805, 0x2f},
+	{0x3806, 0x07}, {0x3807, 0xa7}, {0x3808, 0x0a}, {0x3809, 0x20},
+	{0x380a, 0x07}, {0x380b, 0x98}, {0x380c, 0x01}, {0x380d, 0x78},
+	{0x380e, 0x08}, {0x380f, 0x50}, {0x3810, 0x00}, {0x3811, 0x05},
+	{0x3812, 0x00}, {0x3813, 0x08}, {0x3814, 0x11}, {0x3815, 0x11},
+	{0x3820, 0x40}, {0x3821, 0x04}, {0x3822, 0x10}, {0x3823, 0x00},
+	{0x3826, 0x00}, {0x3827, 0x00}, {0x382b, 0x03}, {0x382c, 0x0c},
+	{0x382d, 0x15}, {0x382e, 0x01}, {0x3830, 0x00}, {0x3838, 0x00},
+	{0x383b, 0x00}, {0x3840, 0x00}, {0x384a, 0xa2}, {0x3858, 0x00},
+	{0x3859, 0x00}, {0x3860, 0x00}, {0x3861, 0x00}, {0x3866, 0x10},
+	{0x3867, 0x07}, {0x3868, 0x01}, {0x3869, 0x01}, {0x386a, 0x01},
+	{0x386b, 0x01}, {0x386c, 0x46}, {0x386d, 0x07}, {0x386e, 0xd2},
+	{0x3871, 0x01}, {0x3872, 0x01}, {0x3873, 0x01}, {0x3874, 0x01},
+	{0x3880, 0x00}, {0x3881, 0x00}, {0x3882, 0x00}, {0x3883, 0x00},
+	{0x3884, 0x00}, {0x3885, 0x00}, {0x3886, 0x00}, {0x3887, 0x00},
+	{0x3888, 0x00}, {0x3889, 0x00}, {0x3900, 0x13}, {0x3901, 0x19},
+	{0x3902, 0x05}, {0x3903, 0x00}, {0x3904, 0x00}, {0x3908, 0x00},
+	{0x3909, 0x18}, {0x390a, 0x00}, {0x390b, 0x11}, {0x390c, 0x15},
+	{0x390d, 0x84}, {0x390f, 0x88}, {0x3910, 0x00}, {0x3911, 0x00},
+	{0x3912, 0x03}, {0x3913, 0x62}, {0x3914, 0x00}, {0x3915, 0x06},
+	{0x3916, 0x0c}, {0x3917, 0x81}, {0x3918, 0xc8}, {0x3919, 0x94},
+	{0x391a, 0x17}, {0x391b, 0x05}, {0x391c, 0x81}, {0x391d, 0x05},
+	{0x391e, 0x81}, {0x391f, 0x05}, {0x3920, 0x81}, {0x3921, 0x14},
+	{0x3922, 0x0b}, {0x3929, 0x00}, {0x392a, 0x00}, {0x392b, 0xc8},
+	{0x392c, 0x81}, {0x392f, 0x00}, {0x3930, 0x00}, {0x3931, 0x00},
+	{0x3932, 0x00}, {0x3933, 0x00}, {0x3934, 0x1b}, {0x3935, 0xc0},
+	{0x3936, 0x1c}, {0x3937, 0x21}, {0x3938, 0x0d}, {0x3939, 0x92},
+	{0x393a, 0x85}, {0x393b, 0x8a}, {0x393c, 0x06}, {0x393d, 0x8b},
+	{0x393e, 0x0f}, {0x393f, 0x14}, {0x3940, 0x0f}, {0x3941, 0x14},
+	{0x3945, 0xc0}, {0x3946, 0x05}, {0x3947, 0xc0}, {0x3948, 0x01},
+	{0x3949, 0x00}, {0x394a, 0x00}, {0x394b, 0x0b}, {0x394c, 0x0c},
+	{0x394d, 0x0b}, {0x394e, 0x09}, {0x3951, 0xc7}, {0x3952, 0x0f},
+	{0x3953, 0x0f}, {0x3954, 0x0f}, {0x3955, 0x00}, {0x3956, 0x27},
+	{0x3957, 0x27}, {0x3958, 0x27}, {0x3959, 0x01}, {0x395a, 0x02},
+	{0x395b, 0x14}, {0x395c, 0x36}, {0x395e, 0xc0}, {0x3964, 0x55},
+	{0x3965, 0x55}, {0x3966, 0x88}, {0x3967, 0x88}, {0x3968, 0x66},
+	{0x3969, 0x66}, {0x396d, 0x80}, {0x396e, 0xff}, {0x396f, 0x10},
+	{0x3970, 0x80}, {0x3971, 0x80}, {0x3972, 0x00}, {0x397a, 0x55},
+	{0x397b, 0x10}, {0x397c, 0x10}, {0x397d, 0x10}, {0x397e, 0x10},
+	{0x3980, 0xfc}, {0x3981, 0xfc}, {0x3982, 0x66}, {0x3983, 0xfc},
+	{0x3984, 0xfc}, {0x3985, 0x66}, {0x3986, 0x00}, {0x3987, 0x00},
+	{0x3988, 0x00}, {0x3989, 0x00}, {0x398a, 0x00}, {0x398b, 0x00},
+	{0x398c, 0x00}, {0x398d, 0x00}, {0x398e, 0x00}, {0x398f, 0x00},
+	{0x3990, 0x00}, {0x3991, 0x00}, {0x3992, 0x00}, {0x3993, 0x00},
+	{0x3994, 0x00}, {0x3995, 0x00}, {0x3996, 0x00}, {0x3997, 0x0f},
+	{0x3998, 0x0c}, {0x3999, 0x0c}, {0x399a, 0x0c}, {0x399b, 0xf0},
+	{0x399c, 0x14}, {0x399d, 0x0d}, {0x399e, 0x00}, {0x399f, 0x0c},
+	{0x39a0, 0x0c}, {0x39a1, 0x0c}, {0x39a2, 0x00}, {0x39a3, 0x0f},
+	{0x39a4, 0x0c}, {0x39a5, 0x0c}, {0x39a6, 0x0c}, {0x39a7, 0x0c},
+	{0x39a8, 0x0f}, {0x39a9, 0xff}, {0x39aa, 0xbf}, {0x39ab, 0x3f},
+	{0x39ac, 0x7e}, {0x39ad, 0xff}, {0x39ae, 0x00}, {0x39af, 0x00},
+	{0x39b0, 0x00}, {0x39b1, 0x00}, {0x39b2, 0x00}, {0x39b3, 0x00},
+	{0x39b4, 0x00}, {0x39b5, 0x00}, {0x39b6, 0x00}, {0x39b7, 0x00},
+	{0x39b8, 0x00}, {0x39b9, 0x00}, {0x39ba, 0x00}, {0x39bb, 0x00},
+	{0x39bc, 0x00}, {0x39c2, 0x00}, {0x39c3, 0x00}, {0x39c4, 0x00},
+	{0x39c5, 0x00}, {0x39c7, 0x00}, {0x39c8, 0x00}, {0x39c9, 0x00},
+	{0x39ca, 0x01}, {0x39cb, 0x00}, {0x39cc, 0x85}, {0x39cd, 0x09},
+	{0x39cf, 0x04}, {0x39d0, 0x85}, {0x39d1, 0x09}, {0x39d2, 0x04},
+	{0x39d4, 0x02}, {0x39d5, 0x0e}, {0x39db, 0x00}, {0x39dc, 0x01},
+	{0x39dd, 0x0c}, {0x39e5, 0xff}, {0x39e6, 0xff}, {0x39fa, 0x38},
+	{0x39fb, 0x07}, {0x39ff, 0x00}, {0x3a05, 0x00}, {0x3a06, 0x07},
+	{0x3a07, 0x0d}, {0x3a08, 0x08}, {0x3a09, 0xb2}, {0x3a0a, 0x0a},
+	{0x3a0b, 0x3c}, {0x3a0c, 0x0b}, {0x3a0d, 0xe1}, {0x3a0e, 0x03},
+	{0x3a0f, 0x85}, {0x3a10, 0x0b}, {0x3a11, 0xff}, {0x3a12, 0x00},
+	{0x3a13, 0x01}, {0x3a14, 0x0c}, {0x3a15, 0x04}, {0x3a17, 0x09},
+	{0x3a18, 0x20}, {0x3a19, 0x09}, {0x3a1a, 0x9d}, {0x3a1b, 0x09},
+	{0x3a1e, 0x34}, {0x3a1f, 0x09}, {0x3a20, 0x89}, {0x3a21, 0x09},
+	{0x3a48, 0xbe}, {0x3a52, 0x00}, {0x3a53, 0x01}, {0x3a54, 0x0c},
+	{0x3a55, 0x04}, {0x3a58, 0x0c}, {0x3a59, 0x04}, {0x3a5a, 0x01},
+	{0x3a5b, 0x00}, {0x3a5c, 0x01}, {0x3a5d, 0xe8}, {0x3a62, 0x03},
+	{0x3a63, 0x86}, {0x3a64, 0x0b}, {0x3a65, 0xbe}, {0x3a6a, 0xdc},
+	{0x3a6b, 0x0b}, {0x3a6c, 0x1a}, {0x3a6d, 0x06}, {0x3a6e, 0x01},
+	{0x3a6f, 0x04}, {0x3a70, 0xdc}, {0x3a71, 0x0b}, {0x3a83, 0x10},
+	{0x3a84, 0x00}, {0x3a85, 0x08}, {0x3a87, 0x00}, {0x3a88, 0x6b},
+	{0x3a89, 0x01}, {0x3a8a, 0x53}, {0x3a8f, 0x00}, {0x3a90, 0x00},
+	{0x3a91, 0x00}, {0x3a92, 0x00}, {0x3a93, 0x60}, {0x3a94, 0xea},
+	{0x3a98, 0x00}, {0x3a99, 0x31}, {0x3a9a, 0x01}, {0x3a9b, 0x04},
+	{0x3a9c, 0xdc}, {0x3a9d, 0x0b}, {0x3aa4, 0x0f}, {0x3aad, 0x00},
+	{0x3aae, 0x3e}, {0x3aaf, 0x02}, {0x3ab0, 0x77}, {0x3ab2, 0x00},
+	{0x3ab3, 0x08}, {0x3ab6, 0x0b}, {0x3ab7, 0xff}, {0x3aba, 0x0b},
+	{0x3abb, 0xfa}, {0x3abd, 0x05}, {0x3abe, 0x09}, {0x3abf, 0x1e},
+	{0x3ac0, 0x00}, {0x3ac1, 0x63}, {0x3ac2, 0x01}, {0x3ac3, 0x55},
+	{0x3ac8, 0x00}, {0x3ac9, 0x2a}, {0x3aca, 0x01}, {0x3acb, 0x36},
+	{0x3acc, 0x00}, {0x3acd, 0x6f}, {0x3ad0, 0x00}, {0x3ad1, 0x79},
+	{0x3ad2, 0x02}, {0x3ad3, 0x59}, {0x3ad4, 0x06}, {0x3ad5, 0x5a},
+	{0x3ad6, 0x08}, {0x3ad7, 0x3a}, {0x3ad8, 0x00}, {0x3ad9, 0x79},
+	{0x3ada, 0x02}, {0x3adb, 0x59}, {0x3adc, 0x09}, {0x3add, 0x89},
+	{0x3ade, 0x0b}, {0x3adf, 0x69}, {0x3ae0, 0x03}, {0x3ae1, 0xc1},
+	{0x3ae2, 0x0b}, {0x3ae3, 0xaf}, {0x3ae4, 0x00}, {0x3ae5, 0x3e},
+	{0x3ae6, 0x02}, {0x3ae7, 0x77}, {0x3ae8, 0x00}, {0x3aea, 0x0b},
+	{0x3aeb, 0xbe}, {0x3aee, 0x08}, {0x3aef, 0x80}, {0x3af0, 0x09},
+	{0x3af1, 0x70}, {0x3af2, 0x08}, {0x3af3, 0x94}, {0x3af4, 0x09},
+	{0x3af5, 0x5c}, {0x3af6, 0x03}, {0x3af7, 0x85}, {0x3af8, 0x08},
+	{0x3af9, 0x80}, {0x3afa, 0x0b}, {0x3afb, 0xaf}, {0x3afc, 0x01},
+	{0x3afd, 0x5a}, {0x3b1e, 0x00}, {0x3b20, 0xa5}, {0x3b21, 0x00},
+	{0x3b22, 0x00}, {0x3b23, 0x00}, {0x3b24, 0x05}, {0x3b25, 0x00},
+	{0x3b26, 0x00}, {0x3b27, 0x00}, {0x3b28, 0x1a}, {0x3b2f, 0x40},
+	{0x3b40, 0x08}, {0x3b41, 0x70}, {0x3b42, 0x05}, {0x3b43, 0xf0},
+	{0x3b44, 0x01}, {0x3b45, 0x54}, {0x3b46, 0x01}, {0x3b47, 0x54},
+	{0x3b56, 0x08}, {0x3b80, 0x00}, {0x3b81, 0x00}, {0x3b82, 0x64},
+	{0x3b83, 0x00}, {0x3b84, 0x00}, {0x3b85, 0x64}, {0x3b9d, 0x61},
+	{0x3ba8, 0x38}, {0x3c11, 0x33}, {0x3c12, 0x3d}, {0x3c13, 0x00},
+	{0x3c14, 0xbe}, {0x3c15, 0x0b}, {0x3c16, 0xa8}, {0x3c17, 0x03},
+	{0x3c18, 0x9c}, {0x3c19, 0x0b}, {0x3c1a, 0x0f}, {0x3c1b, 0x97},
+	{0x3c1c, 0x00}, {0x3c1d, 0x3c}, {0x3c1e, 0x02}, {0x3c1f, 0x78},
+	{0x3c20, 0x06}, {0x3c21, 0x80}, {0x3c22, 0x08}, {0x3c23, 0x0f},
+	{0x3c24, 0x97}, {0x3c25, 0x00}, {0x3c26, 0x3c}, {0x3c27, 0x02},
+	{0x3c28, 0xa7}, {0x3c29, 0x09}, {0x3c2a, 0xaf}, {0x3c2b, 0x0b},
+	{0x3c2c, 0x38}, {0x3c2d, 0xf9}, {0x3c2e, 0x0b}, {0x3c2f, 0xfd},
+	{0x3c30, 0x05}, {0x3c35, 0x8c}, {0x3c3e, 0xc3}, {0x3c43, 0xcb},
+	{0x3c44, 0x00}, {0x3c45, 0xff}, {0x3c46, 0x0b}, {0x3c48, 0x3b},
+	{0x3c49, 0x40}, {0x3c4a, 0x00}, {0x3c4b, 0x5b}, {0x3c4c, 0x02},
+	{0x3c4d, 0x02}, {0x3c4e, 0x00}, {0x3c4f, 0x04}, {0x3c50, 0x0c},
+	{0x3c51, 0x00}, {0x3c52, 0x3b}, {0x3c53, 0x3a}, {0x3c54, 0x07},
+	{0x3c55, 0x9e}, {0x3c56, 0x07}, {0x3c57, 0x9e}, {0x3c58, 0x07},
+	{0x3c59, 0xe8}, {0x3c5a, 0x03}, {0x3c5b, 0x33}, {0x3c5c, 0xa8},
+	{0x3c5d, 0x07}, {0x3c5e, 0xd0}, {0x3c5f, 0x07}, {0x3c60, 0x32},
+	{0x3c61, 0x00}, {0x3c62, 0xd0}, {0x3c63, 0x07}, {0x3c64, 0x80},
+	{0x3c65, 0x80}, {0x3c66, 0x3f}, {0x3c67, 0x01}, {0x3c68, 0x00},
+	{0x3c69, 0xd0}, {0x3c6a, 0x07}, {0x3c6b, 0x01}, {0x3c6c, 0x00},
+	{0x3c6d, 0xcd}, {0x3c6e, 0x07}, {0x3c6f, 0xd1}, {0x3c70, 0x07},
+	{0x3c71, 0x01}, {0x3c72, 0x00}, {0x3c73, 0xc3}, {0x3c74, 0x01},
+	{0x3c75, 0x00}, {0x3c76, 0xcd}, {0x3c77, 0x07}, {0x3c78, 0xea},
+	{0x3c79, 0x03}, {0x3c7a, 0xcd}, {0x3c7b, 0x07}, {0x3c7c, 0x08},
+	{0x3c7d, 0x06}, {0x3c7e, 0x03}, {0x3c85, 0x3a}, {0x3c86, 0x08},
+	{0x3c87, 0x69}, {0x3c88, 0x0b}, {0x3c8f, 0xb2}, {0x3c90, 0x08},
+	{0x3c91, 0xe1}, {0x3c92, 0x0b}, {0x3c93, 0x06}, {0x3c94, 0x03},
+	{0x3c9b, 0x35}, {0x3c9c, 0x08}, {0x3c9d, 0x64}, {0x3c9e, 0x0b},
+	{0x3ca5, 0xb7}, {0x3ca6, 0x08}, {0x3ca7, 0xe6}, {0x3ca8, 0x0b},
+	{0x3ca9, 0x83}, {0x3caa, 0x3c}, {0x3cab, 0x01}, {0x3cac, 0x00},
+	{0x3cad, 0x9e}, {0x3cae, 0x07}, {0x3caf, 0x85}, {0x3cb0, 0x03},
+	{0x3cb1, 0xbc}, {0x3cb2, 0x0b}, {0x3cb7, 0x3c}, {0x3cb8, 0x01},
+	{0x3cb9, 0x00}, {0x3cba, 0xbc}, {0x3cbb, 0x07}, {0x3cbc, 0xa3},
+	{0x3cbd, 0x03}, {0x3cbe, 0x9e}, {0x3cbf, 0x0b}, {0x3cc4, 0x99},
+	{0x3cc5, 0xe9}, {0x3cc6, 0x99}, {0x3cc7, 0xe9}, {0x3cc8, 0x33},
+	{0x3cc9, 0x03}, {0x3cca, 0x33}, {0x3ccb, 0x03}, {0x3cce, 0x66},
+	{0x3ccf, 0x66}, {0x3cd0, 0x00}, {0x3cd1, 0x04}, {0x3cd2, 0xf4},
+	{0x3cd3, 0xb7}, {0x3cd4, 0x03}, {0x3cd5, 0x10}, {0x3cd6, 0x06},
+	{0x3cd7, 0x30}, {0x3cd8, 0x08}, {0x3cd9, 0x5f}, {0x3cda, 0x0b},
+	{0x3cdd, 0x44}, {0x3cde, 0x44}, {0x3cdf, 0x04}, {0x3ce0, 0x00},
+	{0x3ce1, 0x00}, {0x3ce3, 0x00}, {0x3ce4, 0x00}, {0x3ce5, 0x00},
+	{0x3ce6, 0x00}, {0x3ce7, 0x00}, {0x3ce8, 0x00}, {0x3ce9, 0x00},
+	{0x3cea, 0x00}, {0x3ceb, 0x00}, {0x3cec, 0x00}, {0x3ced, 0x00},
+	{0x3cee, 0x00}, {0x3cef, 0x85}, {0x3cf0, 0x03}, {0x3cf1, 0xaf},
+	{0x3cf2, 0x0b}, {0x3cf3, 0x03}, {0x3cf4, 0x2c}, {0x3cf5, 0x00},
+	{0x3cf6, 0x42}, {0x3cf7, 0x00}, {0x3cf8, 0x03}, {0x3cf9, 0x2c},
+	{0x3cfa, 0x00}, {0x3cfb, 0x42}, {0x3cfc, 0x00}, {0x3cfd, 0x03},
+	{0x3cfe, 0x01}, {0x3d81, 0x00}, {0x3e94, 0x0f}, {0x3e95, 0x5f},
+	{0x3e96, 0x02}, {0x3e97, 0x3c}, {0x3e98, 0x00}, {0x3e9f, 0x00},
+	{0x3f00, 0x00}, {0x3f05, 0x03}, {0x3f07, 0x01}, {0x3f08, 0x55},
+	{0x3f09, 0x25}, {0x3f0a, 0x35}, {0x3f0b, 0x20}, {0x3f11, 0x05},
+	{0x3f12, 0x05}, {0x3f40, 0x00}, {0x3f41, 0x03}, {0x3f43, 0x10},
+	{0x3f44, 0x02}, {0x3f45, 0xe6}, {0x4000, 0xf9}, {0x4001, 0x2b},
+	{0x4008, 0x04}, {0x4009, 0x1b}, {0x400a, 0x03}, {0x400e, 0x10},
+	{0x4010, 0x04}, {0x4011, 0xf7}, {0x4032, 0x3e}, {0x4033, 0x02},
+	{0x4050, 0x02}, {0x4051, 0x0d}, {0x40f9, 0x00}, {0x4200, 0x00},
+	{0x4204, 0x00}, {0x4205, 0x00}, {0x4206, 0x00}, {0x4207, 0x00},
+	{0x4208, 0x00}, {0x4244, 0x00}, {0x4300, 0x00}, {0x4301, 0xff},
+	{0x4302, 0xf0}, {0x4303, 0x00}, {0x4304, 0xff}, {0x4305, 0xf0},
+	{0x4306, 0x00}, {0x4308, 0x00}, {0x430a, 0x90}, {0x430b, 0x11},
+	{0x4310, 0x00}, {0x4316, 0x00}, {0x431c, 0x00}, {0x431e, 0x00},
+	{0x4410, 0x08}, {0x4433, 0x08}, {0x4434, 0xf8}, {0x4508, 0x80},
+	{0x4509, 0x10}, {0x450b, 0x83}, {0x4511, 0x00}, {0x4580, 0x09},
+	{0x4587, 0x00}, {0x458c, 0x00}, {0x4640, 0x00}, {0x4641, 0xc1},
+	{0x4642, 0x00}, {0x4643, 0x00}, {0x4649, 0x00}, {0x4681, 0x04},
+	{0x4682, 0x10}, {0x4683, 0xa0}, {0x4698, 0x07}, {0x4699, 0xf0},
+	{0x4710, 0x00}, {0x4802, 0x00}, {0x481b, 0x3c}, {0x4837, 0x10},
+	{0x4860, 0x00}, {0x4883, 0x00}, {0x4884, 0x09}, {0x4885, 0x80},
+	{0x4886, 0x00}, {0x4888, 0x10}, {0x488b, 0x00}, {0x488c, 0x10},
+	{0x4980, 0x03}, {0x4981, 0x06}, {0x4984, 0x00}, {0x4985, 0x00},
+	{0x4a14, 0x04}, {0x4b01, 0x44}, {0x4b03, 0x80}, {0x4d06, 0xc8},
+	{0x4d09, 0xdf}, {0x4d15, 0x7d}, {0x4d34, 0x7d}, {0x4d3c, 0x7d},
+	{0x4f00, 0x7f}, {0x4f01, 0xff}, {0x4f03, 0x00}, {0x4f04, 0x18},
+	{0x4f05, 0x13}, {0x5000, 0x6e}, {0x5001, 0x00}, {0x500a, 0x00},
+	{0x5080, 0x00}, {0x5081, 0x00}, {0x5082, 0x00}, {0x5083, 0x00},
+	{0x5100, 0x00}, {0x5103, 0x00}, {0x5180, 0x70}, {0x5181, 0x70},
+	{0x5182, 0x73}, {0x5183, 0xff}, {0x5249, 0x06}, {0x524f, 0x06},
+	{0x5281, 0x18}, {0x5282, 0x08}, {0x5283, 0x08}, {0x5284, 0x18},
+	{0x5285, 0x18}, {0x5286, 0x08}, {0x5287, 0x08}, {0x5288, 0x18},
+	{0x5289, 0x2d}, {0x6000, 0x40}, {0x6001, 0x40}, {0x6002, 0x00},
+	{0x6003, 0x00}, {0x6004, 0x00}, {0x6005, 0x00}, {0x6006, 0x00},
+	{0x6007, 0x00}, {0x6008, 0x00}, {0x6009, 0x00}, {0x600a, 0x00},
+	{0x600b, 0x00}, {0x600c, 0x02}, {0x600d, 0x00}, {0x600e, 0x04},
+	{0x600f, 0x00}, {0x6010, 0x06}, {0x6011, 0x00}, {0x6012, 0x00},
+	{0x6013, 0x00}, {0x6014, 0x02}, {0x6015, 0x00}, {0x6016, 0x04},
+	{0x6017, 0x00}, {0x6018, 0x06}, {0x6019, 0x00}, {0x601a, 0x01},
+	{0x601b, 0x00}, {0x601c, 0x01}, {0x601d, 0x00}, {0x601e, 0x01},
+	{0x601f, 0x00}, {0x6020, 0x01}, {0x6021, 0x00}, {0x6022, 0x01},
+	{0x6023, 0x00}, {0x6024, 0x01}, {0x6025, 0x00}, {0x6026, 0x01},
+	{0x6027, 0x00}, {0x6028, 0x01}, {0x6029, 0x00}, {0x3501, 0x08},
+	{0x3502, 0x32}, {0x320a, 0x01}, {0x320b, 0x01}, {0x320c, 0x00},
+	{0x320d, 0x00},
+};
+
+struct ox05b {
+	struct device *dev;
+	struct clk *clk;
+	unsigned long clk_rate;
+	struct i2c_client *client;
+	struct regmap *regmap;
+	struct gpio_desc *pwdn_gpio;
+	struct v4l2_subdev subdev;
+	struct media_pad pad;
+	struct v4l2_mbus_framefmt format;
+	struct v4l2_ctrl_handler handler;
+	/* Added for RGB dominant stream */
+	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *again;
+	struct v4l2_ctrl *dgain;
+	/* Added for IR dominant stream */
+	struct v4l2_ctrl *ir_exposure;
+	struct v4l2_ctrl *ir_again;
+	struct v4l2_ctrl *ir_dgain;
+	u32 fps;
+	struct mutex lock; /* For streaming status */
+	bool streaming;
+	struct v4l2_ctrl *link_freq;
+};
+
+static inline struct ox05b *to_ox05b(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct ox05b, subdev);
+}
+
+static int ox05b_read(struct ox05b *ox05b, u16 addr, u32 *val, size_t nbytes)
+{
+	int ret;
+	__le32 val_le = 0;
+
+	ret = regmap_bulk_read(ox05b->regmap, addr, &val_le, nbytes);
+	if (ret < 0) {
+		dev_err(ox05b->dev, "%s: failed to read reg 0x%04x: %d\n",
+			__func__, addr, ret);
+		return ret;
+	}
+
+	*val = le32_to_cpu(val_le);
+	return 0;
+}
+
+static int ox05b_write(struct ox05b *ox05b, u16 addr, u32 val, size_t nbytes)
+{
+	int ret;
+	__le32 val_le = cpu_to_le32(val);
+
+	ret = regmap_bulk_write(ox05b->regmap, addr, &val_le, nbytes);
+	if (ret < 0) {
+		dev_err(ox05b->dev, "%s: failed to write reg 0x%04x: %d\n",
+			__func__, addr, ret);
+	}
+	return ret;
+}
+
+static int ox05b_write_table(struct ox05b *ox05b,
+			     const struct reg_sequence *regs,
+			     unsigned int nr_regs)
+{
+	int ret;
+
+	ret = regmap_multi_reg_write(ox05b->regmap, regs, nr_regs);
+	if (ret < 0) {
+		dev_err(ox05b->dev, "%s: failed to write reg table (%d)!\n",
+			__func__, ret);
+	}
+	return ret;
+}
+
+static void ox05b_init_formats(struct v4l2_subdev_state *state)
+{
+	struct v4l2_mbus_framefmt *format;
+	int i;
+
+	for (i = 0; i < 2; ++i) {
+		format = v4l2_subdev_state_get_format(state, 0, i);
+		format->code = ox05b_mbus_formats[0];
+		format->width = ox05b_framesizes[0].width;
+		format->height = ox05b_framesizes[0].height;
+		format->field = V4L2_FIELD_NONE;
+		format->colorspace = V4L2_COLORSPACE_SRGB;
+	}
+}
+
+static int ox05b_set_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_subdev_state *state,
+			 struct v4l2_subdev_format *fmt)
+{
+	struct ox05b *ox05b = to_ox05b(sd);
+	struct v4l2_mbus_framefmt *format;
+	const struct v4l2_area *fsize;
+	u32 code;
+	int ret = 0;
+
+	if (fmt->pad != 0)
+		return -EINVAL;
+
+	if (fmt->stream != 0)
+		return -EINVAL;
+
+	/* Sensor only supports a single format. */
+	code = ox05b_mbus_formats[0];
+
+	/* Find the nearest supported frame size. */
+	fsize = v4l2_find_nearest_size(ox05b_framesizes,
+				       ARRAY_SIZE(ox05b_framesizes), width,
+				       height, fmt->format.width,
+				       fmt->format.height);
+
+	format = v4l2_subdev_state_get_format(state, fmt->pad, fmt->stream);
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE && ox05b->streaming)
+		ret = -EBUSY;
+
+	format->code = code;
+	format->width = fsize->width;
+	format->height = fsize->height;
+
+	fmt->format = *format;
+
+	return ret;
+}
+
+static int _ox05b_set_routing(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_route routes[] = {
+		{
+			.source_pad = 0,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+		{
+			.source_pad = 0,
+			.source_stream = 1,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+	};
+
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+
+	int ret;
+
+	ret = v4l2_subdev_set_routing(sd, state, &routing);
+	if (ret < 0)
+		return ret;
+
+	ox05b_init_formats(state);
+
+	return 0;
+}
+
+static int ox05b_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+				struct v4l2_mbus_frame_desc *fd)
+{
+	struct v4l2_subdev_state *state;
+	struct v4l2_mbus_framefmt *fmt;
+	u32 bpp;
+	int ret = 0;
+	unsigned int i;
+
+	if (pad != 0)
+		return -EINVAL;
+	state = v4l2_subdev_lock_and_get_active_state(sd);
+	fmt = v4l2_subdev_state_get_format(state, 0, 0);
+	if (!fmt) {
+		ret = -EPIPE;
+		goto out;
+	}
+	memset(fd, 0, sizeof(*fd));
+
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+
+	/* pixel stream - 2 virtual channels*/
+
+	bpp = 10;
+
+	for (i = 0; i < 2; ++i) {
+		fd->entry[fd->num_entries].stream = i;
+
+		fd->entry[fd->num_entries].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
+		fd->entry[fd->num_entries].length = fmt->width * fmt->height * bpp / 8;
+		fd->entry[fd->num_entries].pixelcode = fmt->code;
+		fd->entry[fd->num_entries].bus.csi2.vc = i;
+		fd->entry[fd->num_entries].bus.csi2.dt = 0x2b; /* RAW10 */
+
+		fd->num_entries++;
+	}
+
+out:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int ox05b_set_routing(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state,
+			     enum v4l2_subdev_format_whence which,
+			     struct v4l2_subdev_krouting *routing)
+{
+	int ret;
+
+	if (routing->num_routes == 0 || routing->num_routes > 2)
+		return -EINVAL;
+
+	v4l2_subdev_lock_state(state);
+
+	ret = _ox05b_set_routing(sd, state);
+
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int ox05b_init_state(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_state *state)
+{
+	int ret;
+
+	ret = _ox05b_set_routing(sd, state);
+
+	return ret;
+}
+
+static int ox05b_enum_mbus_code(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *state,
+				struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index >= ARRAY_SIZE(ox05b_mbus_formats))
+		return -EINVAL;
+
+	code->code = ox05b_mbus_formats[code->index];
+
+	return 0;
+}
+
+static int ox05b_enum_frame_sizes(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *state,
+				  struct v4l2_subdev_frame_size_enum *fse)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(ox05b_mbus_formats); ++i) {
+		if (ox05b_mbus_formats[i] == fse->code)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(ox05b_mbus_formats))
+		return -EINVAL;
+
+	if (fse->index >= ARRAY_SIZE(ox05b_framesizes))
+		return -EINVAL;
+
+	fse->min_width = ox05b_framesizes[fse->index].width;
+	fse->max_width = fse->min_width;
+	fse->max_height = ox05b_framesizes[fse->index].height;
+	fse->min_height = fse->max_height;
+
+	return 0;
+}
+
+static int ox05b_get_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_state *sd_state,
+				    struct v4l2_subdev_frame_interval *fi)
+{
+	struct ox05b *ox05b = to_ox05b(sd);
+
+	fi->interval.numerator = 1;
+	fi->interval.denominator = ox05b->fps;
+	return 0;
+}
+
+static int ox05b_set_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_state *sd_state,
+				    struct v4l2_subdev_frame_interval *fi)
+{
+	struct ox05b *ox05b = to_ox05b(sd);
+
+	dev_dbg(ox05b->dev, "%s: Set framerate %dfps\n", __func__,
+		fi->interval.denominator / fi->interval.numerator);
+	if ((fi->interval.denominator / fi->interval.numerator) != ox05b->fps) {
+		dev_err(ox05b->dev, "%s: Framerate can only be %dfps\n",
+			__func__, ox05b->fps);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int ox05b_detect(struct ox05b *ox05b)
+{
+	int ret;
+	u32 id;
+
+	ret = ox05b_read(ox05b, OX05B_SC_CHIP_ID_HI, &id, 2);
+	if (ret < 0)
+		return ret;
+
+	if (id != OX05B_CHIP_ID) {
+		dev_err(ox05b->dev,
+			"%s: unknown chip ID 0x%04x\n", __func__, id);
+		return -ENODEV;
+	}
+
+	dev_info(ox05b->dev, "%s: detected chip ID 0x%04x\n", __func__, id);
+	return 0;
+}
+
+static int ox05b_set_groupA(struct ox05b *ox05b)
+{
+	int i, ret;
+	u32 exposure = ox05b->ir_exposure->val;
+	u32 again = ox05b->ir_again->val;
+	u32 dgain = ox05b->ir_dgain->val;
+	const struct reg_sequence ox05b_groupA[] = {
+		{0x3208, 0x01}, /* Group 1 (IR Dominant VC0) hold start */
+		{OX05B_AEC_PK_EXPO_HI, (exposure >> 8) & 0xff}, /* Exposure time Hi */
+		{OX05B_AEC_PK_EXPO_LO, exposure & 0xff}, /* Exposure time Low */
+		{OX05B_AEC_PK_AGAIN_HI, (again >> 4) & 0xff}, /* Analog gain Hi */
+		{OX05B_AEC_PK_AGAIN_LO, (again & 0x0f) << 4}, /* Analog gain Low */
+		{OX05B_AEC_PK_DGAIN_HI, (dgain >> 8) & 0xff}, /* Digital gain Hi */
+		{OX05B_AEC_PK_DGAIN_LO, dgain & 0xff}, /* Digital gain Lo */
+		{0x4813, 0x01}, /* VC=1. This register takes effect from next frame. */
+		{0x3208, 0x11}, /* Group 1 (IR Dominant VC0) hold end*/
+	};
+
+	for (i = 0; i < ARRAY_SIZE(ox05b_groupA); i++) {
+		ret = regmap_write(ox05b->regmap, ox05b_groupA[i].reg, ox05b_groupA[i].def);
+		if (ret < 0) {
+			dev_err(ox05b->dev,
+				"%s: failed to write reg[%d] 0x%04x = 0x%02x (%d)!\n",
+				__func__, i, ox05b_groupA[i].reg, ox05b_groupA[i].def, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int ox05b_set_groupB(struct ox05b *ox05b)
+{
+	int i, ret;
+	u32 exposure = ox05b->exposure->val;
+	u32 again = ox05b->again->val;
+	u32 dgain = ox05b->dgain->val;
+	const struct reg_sequence ox05b_groupB[] = {
+		{0x3208, 0x00}, /* Group 0 (RGB Dominant VC1) hold start */
+		{OX05B_AEC_PK_EXPO_HI, (exposure >> 8) & 0xff}, /* Exposure time Hi */
+		{OX05B_AEC_PK_EXPO_LO, exposure & 0xff}, /* Exposure time Low */
+		{OX05B_AEC_PK_AGAIN_HI, (again >> 4) & 0xff}, /* Analog gain Hi */
+		{OX05B_AEC_PK_AGAIN_LO, (again & 0x0f) << 4}, /* Analog gain Low */
+		{OX05B_AEC_PK_DGAIN_HI, (dgain >> 8) & 0xff}, /* Digital gain Hi */
+		{OX05B_AEC_PK_DGAIN_LO, dgain & 0xff}, /* Digital gain Lo */
+		{0x4813, 0x00}, /* VC=0. This register takes effect from next frame. */
+		{0x3208, 0x10}, /* Group 0 (RGB Dominant VC1) hold end*/
+	};
+
+	for (i = 0; i < ARRAY_SIZE(ox05b_groupB); i++) {
+		ret = regmap_write(ox05b->regmap, ox05b_groupB[i].reg, ox05b_groupB[i].def);
+		if (ret < 0) {
+			dev_err(ox05b->dev,
+				"%s: failed to write reg[%d] 0x%04x = 0x%02x (%d)!\n",
+				__func__, i, ox05b_groupB[i].reg, ox05b_groupB[i].def, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int ox05b_set_AB_mode_regs(struct ox05b *ox05b)
+{
+	int i, ret;
+	const struct reg_sequence ox5b_AB_mode_regs[] = {
+		{0x3211, 0xF1}, /* AB mode enable */
+		{0x3212, 0x21}, /* Enable sync between holds of group 0 and group 1*/
+		{0x3208, 0xA0}, /* Always use for repeat launch */
+	};
+
+	for (i = 0; i < ARRAY_SIZE(ox5b_AB_mode_regs); i++) {
+		ret = regmap_write(ox05b->regmap, ox5b_AB_mode_regs[i].reg,
+				   ox5b_AB_mode_regs[i].def);
+		if (ret < 0) {
+			dev_err(ox05b->dev,
+				"%s: failed to write reg[%d] 0x%04x = 0x%02x (%d)!\n",
+				__func__, i, ox5b_AB_mode_regs[i].reg,
+				ox5b_AB_mode_regs[i].def, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int ox05b_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ox05b *ox05b = container_of(ctrl->handler, struct ox05b, handler);
+	int ret;
+
+	dev_dbg(ox05b->dev, "%s: %s, value: %d\n", __func__,
+		ctrl->name, ctrl->val);
+
+	/*
+	 * If the device is not powered up by the host driver do
+	 * not apply any controls to H/W at this time. Instead
+	 * the controls will be restored right after power-up.
+	 */
+	if (pm_runtime_suspended(ox05b->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+	case V4L2_CID_ANALOGUE_GAIN:
+	case V4L2_CID_DIGITAL_GAIN:
+		ret = ox05b_set_groupB(ox05b);
+		break;
+	case V4L2_CID_IR_EXPOSURE:
+	case V4L2_CID_IR_ANALOGUE_GAIN:
+	case V4L2_CID_IR_DIGITAL_GAIN:
+		ret = ox05b_set_groupA(ox05b);
+		break;
+	case V4L2_CID_HFLIP:
+	case V4L2_CID_VFLIP:
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int ox05b_power_on(struct ox05b *ox05b)
+{
+	int ret;
+
+	ret = clk_prepare_enable(ox05b->clk);
+	if (ret < 0)
+		return ret;
+
+	if (ox05b->pwdn_gpio) {
+		gpiod_set_value_cansleep(ox05b->pwdn_gpio, 1);
+		usleep_range(100, 1000);
+		gpiod_set_value_cansleep(ox05b->pwdn_gpio, 0);
+		msleep(30);
+	}
+	return 0;
+}
+
+static int ox05b_power_off(struct ox05b *ox05b)
+{
+	if (ox05b->pwdn_gpio) {
+		gpiod_set_value_cansleep(ox05b->pwdn_gpio, 1);
+		usleep_range(1, 10);
+	}
+
+	clk_disable_unprepare(ox05b->clk);
+
+	return 0;
+}
+
+static int ox05b_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ox05b *ox05b = to_ox05b(sd);
+
+	return ox05b_power_on(ox05b);
+}
+
+static int ox05b_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ox05b *ox05b = to_ox05b(sd);
+
+	return ox05b_power_off(ox05b);
+}
+
+static int ox05b_start_stream(struct ox05b *ox05b)
+{
+	int ret;
+
+	ret = ox05b_write_table(ox05b, ox05b_linear_2592x1944,
+				ARRAY_SIZE(ox05b_linear_2592x1944));
+	if (ret < 0)
+		return ret;
+
+	msleep(20);
+
+	/* set registers for IR frame */
+	ret = ox05b_set_groupA(ox05b);
+	if (ret < 0)
+		return ret;
+
+	/* set registers for RGB frame */
+	ret = ox05b_set_groupB(ox05b);
+	if (ret < 0)
+		return ret;
+
+	/* set registers specific to AB mode */
+	ret = ox05b_set_AB_mode_regs(ox05b);
+
+	/* Set active */
+	ret = ox05b_write(ox05b, OX05B_SYS_MODE_SEL, 0x01, 1);
+	if (ret < 0)
+		return ret;
+
+	/* No communication is possible for a while after exiting standby.
+	 * we want the sensor to have sufficient time to process
+	 * the new configurations. The same type of delays have been programmed
+	 * in the OV2312 driver.
+	 * TODO: check if there is a status register to poll for sensor readiness.
+	 */
+	msleep(20);
+
+	return 0;
+}
+
+static int ox05b_stop_stream(struct ox05b *ox05b)
+{
+	int ret;
+
+	/* Set standby */
+	ret = ox05b_write(ox05b, OX05B_SYS_MODE_SEL, 0, 1);
+	if (ret < 0)
+		return ret;
+
+	/* No communication is possible for a while after entering standby */
+	usleep_range(10000, 20000);
+	return 0;
+}
+
+static int ox05b_set_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct ox05b *ox05b = to_ox05b(sd);
+	int ret;
+
+	mutex_lock(&ox05b->lock);
+	if (ox05b->streaming == enable) {
+		mutex_unlock(&ox05b->lock);
+		return 0;
+	}
+
+	if (enable) {
+		ret = pm_runtime_resume_and_get(ox05b->dev);
+		if (ret < 0)
+			goto err_unlock;
+
+		ret = ox05b_start_stream(ox05b);
+		if (ret < 0)
+			goto err_runtime_put;
+
+	} else {
+		ret = ox05b_stop_stream(ox05b);
+		if (ret < 0)
+			goto err_runtime_put;
+		pm_runtime_put(ox05b->dev);
+	}
+
+	ox05b->streaming = enable;
+
+	mutex_unlock(&ox05b->lock);
+	return 0;
+
+err_runtime_put:
+	pm_runtime_put(ox05b->dev);
+
+err_unlock:
+	mutex_unlock(&ox05b->lock);
+	dev_err(ox05b->dev,
+		"%s: failed to setup streaming %d\n", __func__, ret);
+	return ret;
+}
+
+static int ox05b_sd_enable_streams(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_state *state,
+				   u32 pad, u64 streams_mask)
+{
+	struct ox05b *ox05b = to_ox05b(sd);
+	int ret;
+
+	mutex_lock(&ox05b->lock);
+
+	if (ox05b->streaming) {
+		mutex_unlock(&ox05b->lock);
+		return 0;
+	}
+
+	ret = pm_runtime_resume_and_get(ox05b->dev);
+	if (ret < 0)
+		goto err_unlock;
+
+	ret = ox05b_start_stream(ox05b);
+	if (ret < 0)
+		goto err_runtime_put;
+
+	ox05b->streaming = true;
+	mutex_unlock(&ox05b->lock);
+	return 0;
+
+err_runtime_put:
+	pm_runtime_put(ox05b->dev);
+
+err_unlock:
+	mutex_unlock(&ox05b->lock);
+	dev_err(ox05b->dev,
+		"%s: failed to enable streams %d\n", __func__, ret);
+	return ret;
+}
+
+static int ox05b_sd_disable_streams(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_state *state,
+				    u32 pad, u64 streams_mask)
+{
+	struct ox05b *ox05b = to_ox05b(sd);
+	int ret;
+
+	mutex_lock(&ox05b->lock);
+
+	if (!ox05b->streaming) {
+		mutex_unlock(&ox05b->lock);
+		return 0;
+	}
+
+	ret = ox05b_stop_stream(ox05b);
+		if (ret < 0)
+			goto err_runtime_put;
+
+	ox05b->streaming = false;
+	mutex_unlock(&ox05b->lock);
+
+	return 0;
+
+err_runtime_put:
+	pm_runtime_put(ox05b->dev);
+	return ret;
+}
+
+static const struct v4l2_subdev_video_ops ox05b_subdev_video_ops = {
+	.s_stream = ox05b_set_stream,
+};
+
+static const struct v4l2_subdev_pad_ops ox05b_subdev_pad_ops = {
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = ox05b_set_fmt,
+	.enum_mbus_code	= ox05b_enum_mbus_code,
+	.enum_frame_size = ox05b_enum_frame_sizes,
+	.set_routing = ox05b_set_routing,
+	.get_frame_desc	= ox05b_get_frame_desc,
+	.get_frame_interval = ox05b_get_frame_interval,
+	.set_frame_interval = ox05b_set_frame_interval,
+	.enable_streams = ox05b_sd_enable_streams,
+	.disable_streams = ox05b_sd_disable_streams,
+};
+
+static const struct v4l2_subdev_ops ox05b_subdev_ops = {
+	.video	= &ox05b_subdev_video_ops,
+	.pad	= &ox05b_subdev_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops ox05b_internal_ops = {
+		.init_state = ox05b_init_state,
+};
+
+static const struct v4l2_ctrl_ops ox05b_ctrl_ops = {
+	.s_ctrl	= ox05b_set_ctrl,
+};
+
+static const struct dev_pm_ops ox05b_pm_ops = {
+	SET_RUNTIME_PM_OPS(ox05b_suspend, ox05b_resume, NULL)
+};
+
+static int ox05b_probe(struct i2c_client *client)
+{
+	struct ox05b *ox05b;
+	struct v4l2_subdev *sd;
+	struct v4l2_ctrl_handler *ctrl_hdr;
+	int ret;
+	/* Allocate internal struct */
+	ox05b = devm_kzalloc(&client->dev, sizeof(*ox05b), GFP_KERNEL);
+	if (!ox05b)
+		return -ENOMEM;
+	ox05b->dev = &client->dev;
+
+	/* Initialize I2C Regmap */
+	ox05b->regmap = devm_regmap_init_i2c(client, &ox05b_regmap_config);
+	if (IS_ERR(ox05b->regmap))
+		return PTR_ERR(ox05b->regmap);
+
+	/* Initialize Powerdown GPIO */
+	ox05b->pwdn_gpio = devm_gpiod_get_optional(ox05b->dev, "pwdn", GPIOD_OUT_LOW);
+	if (IS_ERR(ox05b->pwdn_gpio))
+		return PTR_ERR(ox05b->pwdn_gpio);
+
+	ox05b->clk = devm_clk_get(ox05b->dev, "inck");
+	if (IS_ERR(ox05b->clk))
+		return PTR_ERR(ox05b->clk);
+
+	ox05b->clk_rate = clk_get_rate(ox05b->clk);
+
+	if (ox05b->clk_rate < 6000000 || ox05b->clk_rate > 27000000)
+		return -EINVAL;
+
+	/* Power on */
+	ret = ox05b_power_on(ox05b);
+	if (ret < 0)
+		return ret;
+
+	/* Detect sensor */
+	ret = ox05b_detect(ox05b);
+	if (ret < 0)
+		return ret;
+
+	/* Initialize the subdev and its controls. */
+	sd = &ox05b->subdev;
+	v4l2_i2c_subdev_init(sd, client, &ox05b_subdev_ops);
+	sd->internal_ops = &ox05b_internal_ops;
+
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS |
+		     V4L2_SUBDEV_FL_STREAMS;
+
+	/* Initialize the media entity. */
+	ox05b->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &ox05b->pad);
+	if (ret < 0) {
+		dev_err(ox05b->dev,
+			"%s: media entity init failed %d\n", __func__, ret);
+		return ret;
+	}
+
+	ox05b->fps = OX05B_FRAMERATE_DEFAULT;
+	mutex_init(&ox05b->lock);
+	/* Initialize controls */
+	ctrl_hdr = &ox05b->handler;
+	ret = v4l2_ctrl_handler_init(ctrl_hdr, 7);
+	if (ret < 0) {
+		dev_err(ox05b->dev,
+			"%s: ctrl handler init failed: %d\n", __func__, ret);
+		goto err_media_cleanup;
+	}
+
+	ox05b->handler.lock = &ox05b->lock;
+
+	/* Add new controls */
+	ox05b->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdr, &ox05b_ctrl_ops,
+						  V4L2_CID_LINK_FREQ,
+						  ARRAY_SIZE(ox05b_link_freq_menu) - 1, 0,
+						  ox05b_link_freq_menu);
+	if (ox05b->link_freq)
+		ox05b->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	ox05b->exposure = v4l2_ctrl_new_std(ctrl_hdr, &ox05b_ctrl_ops,
+					    V4L2_CID_EXPOSURE, 0,
+					    OX05B_EXPOSURE_MAX,
+					    1, OX05B_EXPOSURE_DEFAULT);
+
+	ox05b->again = v4l2_ctrl_new_std(ctrl_hdr, &ox05b_ctrl_ops,
+					 V4L2_CID_ANALOGUE_GAIN, 0,
+					 OX05B_AGAIN_MAX, 1,
+					 OX05B_AGAIN_DEFAULT);
+	ox05b->dgain = v4l2_ctrl_new_std(ctrl_hdr, &ox05b_ctrl_ops,
+					 V4L2_CID_DIGITAL_GAIN, 0,
+					 OX05B_DGAIN_MAX, 1,
+					 OX05B_DGAIN_DEFAULT);
+
+	/* Added new control for IR frames. */
+	ox05b->ir_exposure = v4l2_ctrl_new_std(ctrl_hdr, &ox05b_ctrl_ops,
+					       V4L2_CID_IR_EXPOSURE, 0,
+					       OX05B_EXPOSURE_MAX,
+					       1, OX05B_EXPOSURE_DEFAULT);
+
+	ox05b->ir_again = v4l2_ctrl_new_std(ctrl_hdr, &ox05b_ctrl_ops,
+					    V4L2_CID_IR_ANALOGUE_GAIN, 0,
+					    OX05B_AGAIN_MAX, 1,
+					    OX05B_AGAIN_DEFAULT);
+
+	ox05b->ir_dgain = v4l2_ctrl_new_std(ctrl_hdr, &ox05b_ctrl_ops,
+					    V4L2_CID_IR_DIGITAL_GAIN, 0,
+					    OX05B_DGAIN_MAX, 1,
+					    OX05B_DGAIN_DEFAULT);
+
+	ox05b->subdev.ctrl_handler = ctrl_hdr;
+	if (ox05b->handler.error) {
+		ret = ox05b->handler.error;
+		dev_err(ox05b->dev,
+			"%s: failed to add the ctrls: %d\n", __func__, ret);
+		goto err_ctrl_free;
+	}
+
+	/* PM Runtime */
+	pm_runtime_enable(ox05b->dev);
+	pm_runtime_set_suspended(ox05b->dev);
+
+	ret = v4l2_subdev_init_finalize(sd);
+	if (ret < 0) {
+		dev_err(ox05b->dev, "%s: failed to init subdev: %d\n", __func__, ret);
+		goto err_pm_disable;
+	}
+
+	/* Finally, register the subdev. */
+	ret = v4l2_async_register_subdev(sd);
+	if (ret < 0) {
+		dev_err(ox05b->dev,
+			"%s: v4l2 subdev register failed %d\n", __func__, ret);
+		goto err_subdev_cleanup;
+	}
+
+	dev_info(ox05b->dev, "ox05b1s probed!\n");
+	return 0;
+
+err_subdev_cleanup:
+	v4l2_subdev_cleanup(&ox05b->subdev);
+
+err_pm_disable:
+	pm_runtime_disable(ox05b->dev);
+
+err_ctrl_free:
+	v4l2_ctrl_handler_free(ctrl_hdr);
+	mutex_destroy(&ox05b->lock);
+
+err_media_cleanup:
+	media_entity_cleanup(&ox05b->subdev.entity);
+
+	return ret;
+}
+
+static void ox05b_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ox05b *ox05b = to_ox05b(sd);
+
+	v4l2_async_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&ox05b->handler);
+	v4l2_subdev_cleanup(&ox05b->subdev);
+	media_entity_cleanup(&sd->entity);
+	mutex_destroy(&ox05b->lock);
+
+	pm_runtime_disable(ox05b->dev);
+}
+
+static const struct of_device_id ox05b_of_match[] = {
+	{ .compatible = "ovti,ox05b" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, ox05b_of_match);
+
+static struct i2c_driver ox05b_i2c_driver = {
+	.driver = {
+		.name = "ox05b",
+		.of_match_table = ox05b_of_match,
+		.pm = &ox05b_pm_ops,
+	},
+	.probe =  ox05b_probe,
+	.remove = ox05b_remove,
+};
+
+module_i2c_driver(ox05b_i2c_driver);
+
+MODULE_AUTHOR("Abhishek Sharma <abhishek.sharma@ti.com>");
+MODULE_DESCRIPTION("OX05B1S RGB-IR Image Sensor driver");
+MODULE_LICENSE("GPL");
diff -Naur --no-dereference a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
--- a/drivers/media/platform/cadence/cdns-csi2rx.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c	2025-10-23 09:30:40.285462207 -0400
@@ -53,10 +53,31 @@
 
 #define CSI2RX_STREAM_CFG_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x00c)
 #define CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF		(1 << 8)
+#define CSI2RX_STREAM_CFG_NUM_PIXELS_MASK		GENMASK(5, 4)
+#define CSI2RX_STREAM_CFG_NUM_PIXELS(n)			((n) >> 1)
 
 #define CSI2RX_LANES_MAX	4
 #define CSI2RX_STREAMS_MAX	4
 
+#define CSI2RX_ERROR_IRQS_REG			0x28
+#define CSI2RX_ERROR_IRQS_MASK_REG		0x2C
+
+#define CSI2RX_STREAM3_FIFO_OVERFLOW_IRQ	BIT(19)
+#define CSI2RX_STREAM2_FIFO_OVERFLOW_IRQ	BIT(18)
+#define CSI2RX_STREAM1_FIFO_OVERFLOW_IRQ	BIT(17)
+#define CSI2RX_STREAM0_FIFO_OVERFLOW_IRQ	BIT(16)
+#define CSI2RX_FRONT_TRUNC_HDR_IRQ		BIT(12)
+#define CSI2RX_PROT_TRUNCATED_PACKET_IRQ	BIT(11)
+#define CSI2RX_FRONT_LP_NO_PAYLOAD_IRQ		BIT(10)
+#define CSI2RX_SP_INVALID_RCVD_IRQ		BIT(9)
+#define CSI2RX_DATA_ID_IRQ			BIT(7)
+#define CSI2RX_HEADER_CORRECTED_ECC_IRQ	BIT(6)
+#define CSI2RX_HEADER_ECC_IRQ			BIT(5)
+#define CSI2RX_PAYLOAD_CRC_IRQ			BIT(4)
+
+#define CSI2RX_ECC_ERRORS		GENMASK(7, 4)
+#define CSI2RX_PACKET_ERRORS		GENMASK(12, 9)
+
 enum csi2rx_pads {
 	CSI2RX_PAD_SINK,
 	CSI2RX_PAD_SOURCE_STREAM0,
@@ -68,12 +89,38 @@
 
 struct csi2rx_fmt {
 	u32				code;
+	/* width of a single pixel on CSI-2 bus */
 	u8				bpp;
+	/* max pixels per clock supported on output bus */
+	u8				max_pixels;
+};
+
+struct csi2rx_event {
+	u32 mask;
+	const char *name;
+};
+
+static const struct csi2rx_event csi2rx_events[] = {
+	{ CSI2RX_STREAM3_FIFO_OVERFLOW_IRQ, "Overflow of the Stream 3 FIFO detected" },
+	{ CSI2RX_STREAM2_FIFO_OVERFLOW_IRQ, "Overflow of the Stream 2 FIFO detected" },
+	{ CSI2RX_STREAM1_FIFO_OVERFLOW_IRQ, "Overflow of the Stream 1 FIFO detected" },
+	{ CSI2RX_STREAM0_FIFO_OVERFLOW_IRQ, "Overflow of the Stream 0 FIFO detected" },
+	{ CSI2RX_FRONT_TRUNC_HDR_IRQ, "A truncated header [short or long] has been received" },
+	{ CSI2RX_PROT_TRUNCATED_PACKET_IRQ, "A truncated long packet has been received" },
+	{ CSI2RX_FRONT_LP_NO_PAYLOAD_IRQ, "A truncated long packet has been received. No payload" },
+	{ CSI2RX_SP_INVALID_RCVD_IRQ, "A reserved or invalid short packet has been received" },
+	{ CSI2RX_DATA_ID_IRQ, "Data ID error in the header packet" },
+	{ CSI2RX_HEADER_CORRECTED_ECC_IRQ, "ECC error detected and corrected" },
+	{ CSI2RX_HEADER_ECC_IRQ, "Unrecoverable ECC error" },
+	{ CSI2RX_PAYLOAD_CRC_IRQ, "CRC error" },
 };
 
+#define CSI2RX_NUM_EVENTS		ARRAY_SIZE(csi2rx_events)
+
 struct csi2rx_priv {
 	struct device			*dev;
 	unsigned int			count;
+	int				error_irq;
 
 	/*
 	 * Used to prevent race conditions between multiple,
@@ -90,11 +137,14 @@
 	struct reset_control		*pixel_rst[CSI2RX_STREAMS_MAX];
 	struct phy			*dphy;
 
+	u32				vc_select[CSI2RX_STREAMS_MAX];
+	u8				num_pixels[CSI2RX_STREAMS_MAX];
 	u8				lanes[CSI2RX_LANES_MAX];
 	u8				num_lanes;
 	u8				max_lanes;
 	u8				max_streams;
 	bool				has_internal_dphy;
+	u32				events[CSI2RX_NUM_EVENTS];
 
 	struct v4l2_subdev		subdev;
 	struct v4l2_async_notifier	notifier;
@@ -106,24 +156,96 @@
 };
 
 static const struct csi2rx_fmt formats[] = {
-	{ .code	= MEDIA_BUS_FMT_YUYV8_1X16, .bpp = 16, },
-	{ .code	= MEDIA_BUS_FMT_UYVY8_1X16, .bpp = 16, },
-	{ .code	= MEDIA_BUS_FMT_YVYU8_1X16, .bpp = 16, },
-	{ .code	= MEDIA_BUS_FMT_VYUY8_1X16, .bpp = 16, },
-	{ .code	= MEDIA_BUS_FMT_SBGGR8_1X8, .bpp = 8, },
-	{ .code	= MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, },
-	{ .code	= MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, },
-	{ .code	= MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, },
-	{ .code	= MEDIA_BUS_FMT_Y8_1X8,     .bpp = 8, },
-	{ .code	= MEDIA_BUS_FMT_SBGGR10_1X10, .bpp = 10, },
-	{ .code	= MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, },
-	{ .code	= MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, },
-	{ .code	= MEDIA_BUS_FMT_SRGGB10_1X10, .bpp = 10, },
-	{ .code	= MEDIA_BUS_FMT_RGB565_1X16,  .bpp = 16, },
-	{ .code	= MEDIA_BUS_FMT_RGB888_1X24,  .bpp = 24, },
-	{ .code	= MEDIA_BUS_FMT_BGR888_1X24,  .bpp = 24, },
+	{ .code	= MEDIA_BUS_FMT_YUYV8_1X16, .bpp = 16, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_UYVY8_1X16, .bpp = 16, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_YVYU8_1X16, .bpp = 16, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_VYUY8_1X16, .bpp = 16, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SBGGR8_1X8, .bpp = 8, .max_pixels = 4, },
+	{ .code	= MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, .max_pixels = 4, },
+	{ .code	= MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, .max_pixels = 4, },
+	{ .code	= MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, .max_pixels = 4, },
+	{ .code	= MEDIA_BUS_FMT_Y8_1X8,     .bpp = 8, .max_pixels = 4, },
+	{ .code	= MEDIA_BUS_FMT_Y10_1X10,     .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SRGGI10_1X10, .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SGRIG10_1X10, .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SBGGI10_1X10, .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SGBIG10_1X10, .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SGIRG10_1X10, .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SIGGR10_1X10, .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SGIBG10_1X10, .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SIGGB10_1X10, .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SBGGR10_1X10, .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SRGGB10_1X10, .bpp = 10, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SBGGR12_1X12, .bpp = 12, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SGBRG12_1X12, .bpp = 12, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SGRBG12_1X12, .bpp = 12, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_SRGGB12_1X12, .bpp = 12, .max_pixels = 2, },
+	{ .code	= MEDIA_BUS_FMT_RGB565_1X16,  .bpp = 16, .max_pixels = 1, },
+	{ .code	= MEDIA_BUS_FMT_RGB888_1X24,  .bpp = 24, .max_pixels = 1, },
+	{ .code	= MEDIA_BUS_FMT_BGR888_1X24,  .bpp = 24, .max_pixels = 1, },
 };
 
+static void csi2rx_configure_error_irq_mask(void __iomem *base,
+					    struct csi2rx_priv *csi2rx)
+{
+	u32 error_irq_mask = 0;
+
+	error_irq_mask |= CSI2RX_ECC_ERRORS;
+	error_irq_mask |= CSI2RX_PACKET_ERRORS;
+
+	/*
+	 * Iterate through all source pads and check if they are linked
+	 * to an active remote pad. If an active remote pad is found,
+	 * calculate the corresponding bit position and set it in
+	 * mask, enabling the stream overflow error in the mask.
+	 */
+	for (int i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++) {
+		struct media_pad *remote_pad;
+
+		remote_pad = media_pad_remote_pad_first(&csi2rx->pads[i]);
+		if (remote_pad) {
+			int pad = i - CSI2RX_PAD_SOURCE_STREAM0;
+			u32 bit_mask = CSI2RX_STREAM0_FIFO_OVERFLOW_IRQ << pad;
+
+			error_irq_mask |= bit_mask;
+		}
+	}
+
+	writel(error_irq_mask, base + CSI2RX_ERROR_IRQS_MASK_REG);
+}
+
+static irqreturn_t csi2rx_irq_handler(int irq, void *dev_id)
+{
+	struct csi2rx_priv *csi2rx = dev_id;
+	int i;
+	u32 error_status;
+
+	error_status = readl(csi2rx->base + CSI2RX_ERROR_IRQS_REG);
+
+	for (i = 0; i < CSI2RX_NUM_EVENTS; i++)
+		if (error_status & csi2rx_events[i].mask)
+			csi2rx->events[i]++;
+
+	writel(error_status, csi2rx->base + CSI2RX_ERROR_IRQS_REG);
+
+	return IRQ_HANDLED;
+}
+
+
+/**
+ * cdns_csi2rx_negotiate_ppc - Negotiate pixel-per-clock on output interface
+ *
+ * @subdev: point to &struct v4l2_subdev
+ * @pad: pad number of the source pad
+ * @ppc: pointer to requested pixel-per-clock value
+ *
+ * Returns 0 on success, negative error code otherwise.
+ */
+int cdns_csi2rx_negotiate_ppc(struct v4l2_subdev *subdev, unsigned int pad,
+			      u8 *ppc);
+
 static const struct csi2rx_fmt *csi2rx_get_fmt_by_code(u32 code)
 {
 	unsigned int i;
@@ -135,6 +257,21 @@
 	return NULL;
 }
 
+static int csi2rx_get_frame_desc_from_source(struct csi2rx_priv *csi2rx,
+					     struct v4l2_mbus_frame_desc *fd)
+{
+	struct media_pad *remote_pad;
+
+	remote_pad = media_entity_remote_source_pad_unique(&csi2rx->subdev.entity);
+	if (!remote_pad) {
+		dev_err(csi2rx->dev, "No remote pad found for sink\n");
+		return -ENODEV;
+	}
+
+	return v4l2_subdev_call(csi2rx->source_subdev, pad, get_frame_desc,
+				remote_pad->index, fd);
+}
+
 static inline
 struct csi2rx_priv *v4l2_subdev_to_csi2rx(struct v4l2_subdev *subdev)
 {
@@ -164,27 +301,43 @@
 
 static int csi2rx_configure_ext_dphy(struct csi2rx_priv *csi2rx)
 {
+	struct v4l2_ctrl_handler *handler = csi2rx->source_subdev->ctrl_handler;
 	union phy_configure_opts opts = { };
 	struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
-	struct v4l2_subdev_format sd_fmt = {
-		.which	= V4L2_SUBDEV_FORMAT_ACTIVE,
-		.pad	= CSI2RX_PAD_SINK,
-	};
+	struct v4l2_mbus_framefmt *framefmt;
+	struct v4l2_subdev_state *state;
 	const struct csi2rx_fmt *fmt;
 	s64 link_freq;
 	int ret;
 
-	ret = v4l2_subdev_call_state_active(&csi2rx->subdev, pad, get_fmt,
-					    &sd_fmt);
-	if (ret < 0)
-		return ret;
+	if (v4l2_ctrl_find(handler, V4L2_CID_LINK_FREQ)) {
+		link_freq = v4l2_get_link_freq(handler, 0, 0);
+	} else {
+		state = v4l2_subdev_get_locked_active_state(&csi2rx->subdev);
+		framefmt = v4l2_subdev_state_get_format(state, CSI2RX_PAD_SINK,
+							0);
+
+		if (framefmt) {
+			fmt = csi2rx_get_fmt_by_code(framefmt->code);
+		} else {
+			dev_err(csi2rx->dev,
+				"Did not find active sink format\n");
+			return -EINVAL;
+		}
+
+		link_freq = v4l2_get_link_freq(handler, fmt->bpp,
+					       2 * csi2rx->num_lanes);
 
-	fmt = csi2rx_get_fmt_by_code(sd_fmt.format.code);
+		dev_warn(csi2rx->dev,
+			 "Guessing link frequency using bitdepth of stream 0.\n");
+		dev_warn(csi2rx->dev,
+			 "V4L2_CID_LINK_FREQ control is required for multi format sources.\n");
+	}
 
-	link_freq = v4l2_get_link_freq(csi2rx->source_subdev->ctrl_handler,
-				       fmt->bpp, 2 * csi2rx->num_lanes);
-	if (link_freq < 0)
+	if (link_freq < 0) {
+		dev_err(csi2rx->dev, "Unable to calculate link frequency\n");
 		return link_freq;
+	}
 
 	ret = phy_mipi_dphy_get_default_config_for_hsclk(link_freq,
 							 csi2rx->num_lanes, cfg);
@@ -218,6 +371,9 @@
 	reset_control_deassert(csi2rx->p_rst);
 	csi2rx_reset(csi2rx);
 
+	if (csi2rx->error_irq >= 0)
+		csi2rx_configure_error_irq_mask(csi2rx->base, csi2rx);
+
 	reg = csi2rx->num_lanes << 8;
 	for (i = 0; i < csi2rx->num_lanes; i++) {
 		reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, csi2rx->lanes[i]);
@@ -274,14 +430,12 @@
 
 		reset_control_deassert(csi2rx->pixel_rst[i]);
 
-		writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF,
-		       csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
+		reg = CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF;
+		reg |= FIELD_PREP(CSI2RX_STREAM_CFG_NUM_PIXELS_MASK,
+				  csi2rx->num_pixels[i]);
+		writel(reg, csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
 
-		/*
-		 * Enable one virtual channel. When multiple virtual channels
-		 * are supported this will have to be changed.
-		 */
-		writel(CSI2RX_STREAM_DATA_CFG_VC_SELECT(0),
+		writel(csi2rx->vc_select[i],
 		       csi2rx->base + CSI2RX_STREAM_DATA_CFG_REG(i));
 
 		writel(CSI2RX_STREAM_CTRL_START,
@@ -294,16 +448,10 @@
 
 	reset_control_deassert(csi2rx->sys_rst);
 
-	ret = v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, true);
-	if (ret)
-		goto err_disable_sysclk;
-
 	clk_disable_unprepare(csi2rx->p_clk);
 
 	return 0;
 
-err_disable_sysclk:
-	clk_disable_unprepare(csi2rx->sys_clk);
 err_disable_pixclk:
 	for (; i > 0; i--) {
 		reset_control_assert(csi2rx->pixel_rst[i - 1]);
@@ -329,6 +477,7 @@
 	clk_prepare_enable(csi2rx->p_clk);
 	reset_control_assert(csi2rx->sys_rst);
 	clk_disable_unprepare(csi2rx->sys_clk);
+	writel(0, csi2rx->base + CSI2RX_ERROR_IRQS_MASK_REG);
 
 	for (i = 0; i < csi2rx->max_streams; i++) {
 		writel(CSI2RX_STREAM_CTRL_STOP,
@@ -350,9 +499,6 @@
 	reset_control_assert(csi2rx->p_rst);
 	clk_disable_unprepare(csi2rx->p_clk);
 
-	if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false))
-		dev_warn(csi2rx->dev, "Couldn't disable our subdev\n");
-
 	if (csi2rx->dphy) {
 		writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
 
@@ -361,37 +507,169 @@
 	}
 }
 
-static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable)
+static void csi2rx_update_vc_select(struct csi2rx_priv *csi2rx,
+				    struct v4l2_subdev_state *state)
+{
+	struct v4l2_mbus_frame_desc fd = {0};
+	struct v4l2_subdev_route *route;
+	unsigned int i;
+	int ret;
+
+	/* Capture VC=0 by default */
+	for (i = 0; i < CSI2RX_STREAMS_MAX; i++)
+		csi2rx->vc_select[i] = CSI2RX_STREAM_DATA_CFG_VC_SELECT(0);
+
+	ret = csi2rx_get_frame_desc_from_source(csi2rx, &fd);
+	if (ret || fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
+		dev_dbg(csi2rx->dev,
+			"Failed to get source frame desc, allowing only VC=0\n");
+		return;
+	}
+
+	/* If source provides per-stream VC info, use it to filter by VC */
+	for (i = 0; i < CSI2RX_STREAMS_MAX; i++)
+		csi2rx->vc_select[i] = 0;
+
+	for_each_active_route(&state->routing, route) {
+		u32 cdns_stream = route->source_pad - CSI2RX_PAD_SOURCE_STREAM0;
+
+		for (i = 0; i < fd.num_entries; i++) {
+			u32 vc = fd.entry[i].bus.csi2.vc;
+
+			if (fd.entry[i].stream == route->sink_stream)
+				csi2rx->vc_select[cdns_stream] |=
+					CSI2RX_STREAM_DATA_CFG_VC_SELECT(vc);
+		}
+	}
+}
+
+static int csi2rx_enable_streams(struct v4l2_subdev *subdev,
+				 struct v4l2_subdev_state *state, u32 pad,
+				 u64 streams_mask)
 {
 	struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
-	int ret = 0;
+	struct media_pad *remote_pad;
+	u64 sink_streams;
+	int ret;
+
+	remote_pad = media_pad_remote_pad_first(&csi2rx->pads[CSI2RX_PAD_SINK]);
+	if (!remote_pad) {
+		dev_err(csi2rx->dev,
+			"Failed to find connected source\n");
+		return -ENODEV;
+	}
+
+	sink_streams = v4l2_subdev_state_xlate_streams(state, pad,
+						       CSI2RX_PAD_SINK,
+						       &streams_mask);
 
 	mutex_lock(&csi2rx->lock);
+	/*
+	 * If we're not the first users, there's no need to
+	 * enable the whole controller.
+	 */
+	if (!csi2rx->count) {
+		ret = csi2rx_start(csi2rx);
+		if (ret)
+			goto err_stream_start;
+	}
 
-	if (enable) {
-		/*
-		 * If we're not the first users, there's no need to
-		 * enable the whole controller.
-		 */
-		if (!csi2rx->count) {
-			ret = csi2rx_start(csi2rx);
-			if (ret)
-				goto out;
-		}
+	/* Start streaming on the source */
+	ret = v4l2_subdev_enable_streams(csi2rx->source_subdev, remote_pad->index,
+					 sink_streams);
+	if (ret) {
+		dev_err(csi2rx->dev,
+			"Failed to start streams %#llx on subdev\n",
+			sink_streams);
+		goto err_subdev_enable;
+	}
 
-		csi2rx->count++;
-	} else {
-		csi2rx->count--;
+	csi2rx->count++;
+	mutex_unlock(&csi2rx->lock);
 
-		/*
-		 * Let the last user turn off the lights.
-		 */
-		if (!csi2rx->count)
-			csi2rx_stop(csi2rx);
+	return 0;
+
+err_subdev_enable:
+	if (!csi2rx->count)
+		csi2rx_stop(csi2rx);
+err_stream_start:
+	mutex_unlock(&csi2rx->lock);
+	return ret;
+}
+
+static int csi2rx_disable_streams(struct v4l2_subdev *subdev,
+				  struct v4l2_subdev_state *state, u32 pad,
+				  u64 streams_mask)
+{
+	struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
+	struct media_pad *remote_pad;
+	u64 sink_streams;
+
+	sink_streams = v4l2_subdev_state_xlate_streams(state, pad,
+						       CSI2RX_PAD_SINK,
+						       &streams_mask);
+
+	remote_pad = media_pad_remote_pad_first(&csi2rx->pads[CSI2RX_PAD_SINK]);
+	if (!remote_pad ||
+	    v4l2_subdev_disable_streams(csi2rx->source_subdev,
+					remote_pad->index, sink_streams)) {
+		dev_err(csi2rx->dev, "Couldn't disable our subdev\n");
 	}
 
-out:
+	mutex_lock(&csi2rx->lock);
+	csi2rx->count--;
+	/*
+	 * Let the last user turn off the lights.
+	 */
+	if (!csi2rx->count)
+		csi2rx_stop(csi2rx);
 	mutex_unlock(&csi2rx->lock);
+
+	return 0;
+}
+
+static int csi2rx_log_status(struct v4l2_subdev *sd)
+{
+	struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(sd);
+	unsigned int i;
+
+	for (i = 0; i < CSI2RX_NUM_EVENTS; i++) {
+		if (csi2rx->events[i])
+			dev_info(csi2rx->dev, "%s events: %d\n",
+				 csi2rx_events[i].name,
+				 csi2rx->events[i]);
+	}
+
+	return 0;
+}
+
+static int csi2rx_s_stream_fallback(struct v4l2_subdev *sd, int enable)
+{
+	struct v4l2_subdev_state *state;
+	struct v4l2_subdev_route *route;
+	u64 mask[CSI2RX_PAD_MAX] = {0};
+	int i, ret;
+
+	/* Find the stream mask on all source pads */
+	state = v4l2_subdev_lock_and_get_active_state(sd);
+	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++) {
+		for_each_active_route(&state->routing, route) {
+			if (route->source_pad == i)
+				mask[i] |= BIT_ULL(route->source_stream);
+		}
+	}
+	v4l2_subdev_unlock_state(state);
+
+	/* Start streaming on each pad */
+	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++) {
+		if (enable)
+			ret = v4l2_subdev_enable_streams(sd, i, mask[i]);
+		else
+			ret = v4l2_subdev_disable_streams(sd, i, mask[i]);
+		if (ret)
+			return ret;
+	}
+
 	return ret;
 }
 
@@ -407,12 +685,58 @@
 	return 0;
 }
 
+static int _csi2rx_set_routing(struct v4l2_subdev *subdev,
+			       struct v4l2_subdev_state *state,
+			       struct v4l2_subdev_krouting *routing)
+{
+	static const struct v4l2_mbus_framefmt format = {
+		.width = 640,
+		.height = 480,
+		.code = MEDIA_BUS_FMT_UYVY8_1X16,
+		.field = V4L2_FIELD_NONE,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.ycbcr_enc = V4L2_YCBCR_ENC_601,
+		.quantization = V4L2_QUANTIZATION_LIM_RANGE,
+		.xfer_func = V4L2_XFER_FUNC_SRGB,
+	};
+	int ret;
+
+	if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX)
+		return -EINVAL;
+
+	ret = v4l2_subdev_routing_validate(subdev, routing,
+					   V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+	if (ret)
+		return ret;
+
+	return v4l2_subdev_set_routing_with_fmt(subdev, state, routing, &format);
+}
+
+static int csi2rx_set_routing(struct v4l2_subdev *subdev,
+			      struct v4l2_subdev_state *state,
+			      enum v4l2_subdev_format_whence which,
+			      struct v4l2_subdev_krouting *routing)
+{
+	struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
+	int ret;
+
+	if (which == V4L2_SUBDEV_FORMAT_ACTIVE && csi2rx->count)
+		return -EBUSY;
+
+	ret = _csi2rx_set_routing(subdev, state, routing);
+	if (ret)
+		return ret;
+
+	csi2rx_update_vc_select(csi2rx, state);
+
+	return 0;
+}
+
 static int csi2rx_set_fmt(struct v4l2_subdev *subdev,
 			  struct v4l2_subdev_state *state,
 			  struct v4l2_subdev_format *format)
 {
 	struct v4l2_mbus_framefmt *fmt;
-	unsigned int i;
 
 	/* No transcoding, source and sink formats must match. */
 	if (format->pad != CSI2RX_PAD_SINK)
@@ -424,14 +748,16 @@
 	format->format.field = V4L2_FIELD_NONE;
 
 	/* Set sink format */
-	fmt = v4l2_subdev_state_get_format(state, format->pad);
+	fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);
 	*fmt = format->format;
 
-	/* Propagate to source formats */
-	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++) {
-		fmt = v4l2_subdev_state_get_format(state, i);
-		*fmt = format->format;
-	}
+	/* Propagate to source format */
+	fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
+							   format->stream);
+	if (!fmt)
+		return -EINVAL;
+
+	*fmt = format->format;
 
 	return 0;
 }
@@ -439,34 +765,148 @@
 static int csi2rx_init_state(struct v4l2_subdev *subdev,
 			     struct v4l2_subdev_state *state)
 {
-	struct v4l2_subdev_format format = {
-		.pad = CSI2RX_PAD_SINK,
-		.format = {
-			.width = 640,
-			.height = 480,
-			.code = MEDIA_BUS_FMT_UYVY8_1X16,
-			.field = V4L2_FIELD_NONE,
-			.colorspace = V4L2_COLORSPACE_SRGB,
-			.ycbcr_enc = V4L2_YCBCR_ENC_601,
-			.quantization = V4L2_QUANTIZATION_LIM_RANGE,
-			.xfer_func = V4L2_XFER_FUNC_SRGB,
+	struct v4l2_subdev_route routes[] = {
+		{
+			.sink_pad = CSI2RX_PAD_SINK,
+			.sink_stream = 0,
+			.source_pad = CSI2RX_PAD_SOURCE_STREAM0,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
 		},
 	};
 
-	return csi2rx_set_fmt(subdev, state, &format);
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+
+	return _csi2rx_set_routing(subdev, state, &routing);
+}
+
+static int csi2rx_get_frame_desc(struct v4l2_subdev *subdev, unsigned int pad,
+				 struct v4l2_mbus_frame_desc *fd)
+{
+	struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
+	struct v4l2_mbus_frame_desc source_fd = {0};
+	struct v4l2_subdev_route *route;
+	struct v4l2_subdev_state *state;
+	int ret;
+
+	ret = csi2rx_get_frame_desc_from_source(csi2rx, &source_fd);
+	if (ret)
+		return ret;
+
+	memset(fd, 0, sizeof(*fd));
+
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+
+	state = v4l2_subdev_lock_and_get_active_state(subdev);
+
+	for_each_active_route(&state->routing, route) {
+		struct v4l2_mbus_frame_desc_entry *source_entry = NULL;
+		unsigned int i;
+
+		if (route->source_pad != pad)
+			continue;
+
+		for (i = 0; i < source_fd.num_entries; i++) {
+			if (source_fd.entry[i].stream == route->sink_stream) {
+				source_entry = &source_fd.entry[i];
+				break;
+			}
+		}
+
+		if (!source_entry) {
+			dev_err(csi2rx->dev,
+				"Failed to find stream from source frame desc\n");
+			ret = -EPIPE;
+			goto err_missing_stream;
+		}
+
+		fd->entry[fd->num_entries].stream = route->source_stream;
+		fd->entry[fd->num_entries].flags = source_entry->flags;
+		fd->entry[fd->num_entries].length = source_entry->length;
+		fd->entry[fd->num_entries].pixelcode = source_entry->pixelcode;
+		fd->entry[fd->num_entries].bus.csi2.vc =
+			source_entry->bus.csi2.vc;
+		fd->entry[fd->num_entries].bus.csi2.dt =
+			source_entry->bus.csi2.dt;
+
+		fd->num_entries++;
+	}
+
+err_missing_stream:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+int cdns_csi2rx_negotiate_ppc(struct v4l2_subdev *subdev, unsigned int pad,
+			      u8 *ppc)
+{
+	struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
+	const struct csi2rx_fmt *csi_fmt;
+	struct v4l2_subdev_route *route;
+	struct v4l2_subdev_state *state;
+	struct v4l2_mbus_framefmt *fmt;
+	int ret = 0;
+
+	if (!ppc || pad < CSI2RX_PAD_SOURCE_STREAM0 || pad >= CSI2RX_PAD_MAX)
+		return -EINVAL;
+
+	state = v4l2_subdev_lock_and_get_active_state(subdev);
+	/* Check all streams on requested pad */
+	for_each_active_route(&state->routing, route) {
+		if (route->source_pad != pad)
+			continue;
+
+		fmt = v4l2_subdev_state_get_format(state, route->source_pad,
+						   route->source_stream);
+		if (!fmt) {
+			ret = -EPIPE;
+			*ppc = 1;
+			break;
+		}
+
+		csi_fmt = csi2rx_get_fmt_by_code(fmt->code);
+		if (!csi_fmt) {
+			ret = -EINVAL;
+			*ppc = 1;
+			break;
+		}
+
+		/* Reduce requested PPC if it is too high for this stream */
+		*ppc = min(*ppc, csi_fmt->max_pixels);
+	}
+	v4l2_subdev_unlock_state(state);
+
+	csi2rx->num_pixels[pad - CSI2RX_PAD_SOURCE_STREAM0] =
+		CSI2RX_STREAM_CFG_NUM_PIXELS(*ppc);
+
+	return ret;
 }
+EXPORT_SYMBOL(cdns_csi2rx_negotiate_ppc);
 
 static const struct v4l2_subdev_pad_ops csi2rx_pad_ops = {
-	.enum_mbus_code	= csi2rx_enum_mbus_code,
-	.get_fmt	= v4l2_subdev_get_fmt,
-	.set_fmt	= csi2rx_set_fmt,
+	.enum_mbus_code		= csi2rx_enum_mbus_code,
+	.get_fmt		= v4l2_subdev_get_fmt,
+	.set_fmt		= csi2rx_set_fmt,
+	.get_frame_desc		= csi2rx_get_frame_desc,
+	.set_routing		= csi2rx_set_routing,
+	.enable_streams		= csi2rx_enable_streams,
+	.disable_streams	= csi2rx_disable_streams,
+};
+
+static const struct v4l2_subdev_core_ops csi2rx_core_ops = {
+	.log_status	= csi2rx_log_status,
 };
 
 static const struct v4l2_subdev_video_ops csi2rx_video_ops = {
-	.s_stream	= csi2rx_s_stream,
+	.s_stream	= csi2rx_s_stream_fallback,
 };
 
 static const struct v4l2_subdev_ops csi2rx_subdev_ops = {
+	.core		= &csi2rx_core_ops,
 	.video		= &csi2rx_video_ops,
 	.pad		= &csi2rx_pad_ops,
 };
@@ -695,7 +1135,8 @@
 	csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++)
 		csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
-	csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	csi2rx->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE |
+		V4L2_SUBDEV_FL_STREAMS;
 	csi2rx->subdev.entity.ops = &csi2rx_media_ops;
 
 	ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
@@ -703,6 +1144,21 @@
 	if (ret)
 		goto err_cleanup;
 
+	csi2rx->error_irq = platform_get_irq_byname_optional(pdev, "error_irq");
+
+	if (csi2rx->error_irq < 0) {
+		dev_dbg(csi2rx->dev, "Optional interrupt not defined, proceeding without it\n");
+	} else {
+		ret = devm_request_irq(csi2rx->dev, csi2rx->error_irq,
+				       csi2rx_irq_handler, 0,
+				       dev_name(&pdev->dev), csi2rx);
+		if (ret) {
+			dev_err(csi2rx->dev,
+				"Unable to request interrupt: %d\n", ret);
+			goto err_cleanup;
+		}
+	}
+
 	ret = v4l2_subdev_init_finalize(&csi2rx->subdev);
 	if (ret)
 		goto err_cleanup;
diff -Naur --no-dereference a/drivers/media/platform/chips-media/wave5/Kconfig b/drivers/media/platform/chips-media/wave5/Kconfig
--- a/drivers/media/platform/chips-media/wave5/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/chips-media/wave5/Kconfig	2025-10-23 09:30:40.285462207 -0400
@@ -7,6 +7,7 @@
 	select VIDEOBUF2_DMA_CONTIG
 	select VIDEOBUF2_VMALLOC
 	select V4L2_MEM2MEM_DEV
+	select VIDEOBUF2_DMA_SG
 	select GENERIC_ALLOCATOR
 	help
 	  Chips&Media stateful encoder and decoder driver.
diff -Naur --no-dereference a/drivers/media/platform/chips-media/wave5/wave5.h b/drivers/media/platform/chips-media/wave5/wave5.h
--- a/drivers/media/platform/chips-media/wave5/wave5.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/chips-media/wave5/wave5.h	2025-10-23 09:30:40.285462207 -0400
@@ -62,6 +62,9 @@
 
 int wave5_vpu_init(struct device *dev, u8 *fw, size_t size);
 
+int wave5_vpu_sleep_wake(struct device *dev, bool i_sleep_wake, const uint16_t *code,
+			 size_t size);
+
 int wave5_vpu_reset(struct device *dev, enum sw_reset_mode reset_mode);
 
 int wave5_vpu_build_up_dec_param(struct vpu_instance *inst, struct dec_open_param *param);
@@ -111,6 +114,8 @@
 
 int wave5_vpu_encode(struct vpu_instance *inst, struct enc_param *option, u32 *fail_res);
 
+int wave5_vpu_enc_apply_change_param(struct vpu_instance *inst, u32 *fail_res);
+
 int wave5_vpu_enc_get_result(struct vpu_instance *inst, struct enc_output_info *result);
 
 int wave5_vpu_enc_finish_seq(struct vpu_instance *inst, u32 *fail_res);
diff -Naur --no-dereference a/drivers/media/platform/chips-media/wave5/wave5-helper.c b/drivers/media/platform/chips-media/wave5/wave5-helper.c
--- a/drivers/media/platform/chips-media/wave5/wave5-helper.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/chips-media/wave5/wave5-helper.c	2025-10-23 09:30:40.285462207 -0400
@@ -7,6 +7,8 @@
 
 #include "wave5-helper.h"
 
+#define DEFAULT_BS_SIZE(width, height) ((width) * (height) / 8 * 3)
+
 const char *state_to_str(enum vpu_instance_state state)
 {
 	switch (state) {
@@ -50,6 +52,8 @@
 	list_del_init(&inst->list);
 	ida_free(&inst->dev->inst_ida, inst->id);
 	kfree(inst->codec_info);
+	kfree(inst->map_index);
+	kfree(inst->mapped_dma_addr);
 	kfree(inst);
 }
 
@@ -58,9 +62,14 @@
 			     char *name)
 {
 	struct vpu_instance *inst = wave5_to_vpu_inst(filp->private_data);
-	struct vpu_device *dev = inst->dev;
 	int ret = 0;
 
+	if (inst->run_thread) {
+		kthread_stop(inst->run_thread);
+		up(&inst->run_sem);
+		inst->run_thread = NULL;
+	}
+
 	v4l2_m2m_ctx_release(inst->v4l2_fh.m2m_ctx);
 	if (inst->state != VPU_INST_STATE_NONE) {
 		u32 fail_res;
@@ -78,18 +87,6 @@
 	}
 
 	wave5_cleanup_instance(inst);
-	if (dev->irq < 0) {
-		ret = mutex_lock_interruptible(&dev->dev_lock);
-		if (ret)
-			return ret;
-
-		if (list_empty(&dev->instances)) {
-			dev_dbg(dev->dev, "Disabling the hrtimer\n");
-			hrtimer_cancel(&dev->hrtimer);
-		}
-
-		mutex_unlock(&dev->dev_lock);
-	}
 
 	return ret;
 }
@@ -230,3 +227,25 @@
 		v4l2_m2m_buf_done(vbuf, state);
 	}
 }
+
+void wave5_update_pix_fmt(struct v4l2_pix_format_mplane *pix_mp,
+			  int pix_fmt_type,
+			  unsigned int width,
+			  unsigned int height,
+			  const struct v4l2_frmsize_stepwise *frmsize)
+{
+	v4l2_apply_frmsize_constraints(&width, &height, frmsize);
+
+	if (pix_fmt_type == VPU_FMT_TYPE_CODEC) {
+		pix_mp->width = width;
+		pix_mp->height = height;
+		pix_mp->num_planes = 1;
+		pix_mp->plane_fmt[0].bytesperline = 0;
+		pix_mp->plane_fmt[0].sizeimage = max(DEFAULT_BS_SIZE(width, height),
+						     pix_mp->plane_fmt[0].sizeimage);
+	} else {
+		v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, width, height);
+	}
+	pix_mp->flags = 0;
+	pix_mp->field = V4L2_FIELD_NONE;
+}
diff -Naur --no-dereference a/drivers/media/platform/chips-media/wave5/wave5-helper.h b/drivers/media/platform/chips-media/wave5/wave5-helper.h
--- a/drivers/media/platform/chips-media/wave5/wave5-helper.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/chips-media/wave5/wave5-helper.h	2025-10-23 09:30:40.285462207 -0400
@@ -11,7 +11,7 @@
 #include "wave5-vpu.h"
 
 #define FMT_TYPES	2
-#define MAX_FMTS	12
+#define MAX_FMTS	16
 
 const char *state_to_str(enum vpu_instance_state state);
 void wave5_cleanup_instance(struct vpu_instance *inst);
@@ -28,4 +28,9 @@
 						   const struct vpu_format fmt_list[MAX_FMTS]);
 enum wave_std wave5_to_vpu_std(unsigned int v4l2_pix_fmt, enum vpu_instance_type type);
 void wave5_return_bufs(struct vb2_queue *q, u32 state);
+void wave5_update_pix_fmt(struct v4l2_pix_format_mplane *pix_mp,
+			  int pix_fmt_type,
+			  unsigned int width,
+			  unsigned int height,
+			  const struct v4l2_frmsize_stepwise *frmsize);
 #endif
diff -Naur --no-dereference a/drivers/media/platform/chips-media/wave5/wave5-hw.c b/drivers/media/platform/chips-media/wave5/wave5-hw.c
--- a/drivers/media/platform/chips-media/wave5/wave5-hw.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/chips-media/wave5/wave5-hw.c	2025-10-23 09:30:40.285462207 -0400
@@ -40,6 +40,16 @@
 
 #define FASTIO_ADDRESS_MASK		GENMASK(15, 0)
 #define SEQ_PARAM_PROFILE_MASK		GENMASK(30, 24)
+#define SEQ_BG_PARAM_REG_DATA		0x3800410
+
+#define ENC_AVC_INTRA_IDR_PARAM_MASK	0x7ff
+#define ENC_AVC_INTRA_PERIOD_SHIFT		6
+#define ENC_AVC_IDR_PERIOD_SHIFT		17
+#define ENC_AVC_FORCED_IDR_HEADER_SHIFT		28
+
+#define ENC_HEVC_INTRA_QP_SHIFT			3
+#define ENC_HEVC_FORCED_IDR_HEADER_SHIFT	9
+#define ENC_HEVC_INTRA_PERIOD_SHIFT		16
 
 static void _wave5_print_reg_err(struct vpu_device *vpu_dev, u32 reg_fail_reason,
 				 const char *func);
@@ -93,7 +103,7 @@
 		dev_dbg(dev, "%s: queueing failure: 0x%x\n", func, reg_val);
 		break;
 	case WAVE5_SYSERR_RESULT_NOT_READY:
-		dev_err(dev, "%s: result not ready: 0x%x\n", func, reg_fail_reason);
+		dev_dbg(dev, "%s: result not ready: 0x%x\n", func, reg_fail_reason);
 		break;
 	case WAVE5_SYSERR_ACCESS_VIOLATION_HW:
 		dev_err(dev, "%s: access violation: 0x%x\n", func, reg_fail_reason);
@@ -185,6 +195,19 @@
 	return vpu_read_reg(vpu_dev, W5_VCPU_CUR_PC) != 0;
 }
 
+static dma_addr_t wave5_read_reg_for_mem_addr(struct vpu_instance *inst,
+					      unsigned int reg_addr)
+{
+	dma_addr_t addr;
+	dma_addr_t high_addr = inst->dev->ext_addr;
+	u32 val;
+
+	val = vpu_read_reg(inst->dev, reg_addr);
+	addr = ((high_addr << 32) | val);
+
+	return addr;
+}
+
 unsigned int wave5_vpu_get_product_id(struct vpu_device *vpu_dev)
 {
 	u32 val = vpu_read_reg(vpu_dev, W5_PRODUCT_NUMBER);
@@ -466,7 +489,8 @@
 	vpu_write_reg(vpu_dev, W5_HW_OPTION, 0);
 
 	if (vpu_dev->product_code != WAVE515_CODE) {
-		wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0);
+		reg_val = (vpu_dev->ext_addr & 0xFFFF);
+		wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, reg_val);
 		wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0);
 		vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0);
 	}
@@ -572,7 +596,7 @@
 
 	if (inst->dev->product_code != WAVE515_CODE) {
 		/* This register must be reset explicitly */
-		vpu_write_reg(inst->dev, W5_CMD_EXT_ADDR, 0);
+		vpu_write_reg(inst->dev, W5_CMD_EXT_ADDR, inst->dev->ext_addr);
 		vpu_write_reg(inst->dev, W5_CMD_NUM_CQ_DEPTH_M1,
 			      WAVE521_COMMAND_QUEUE_DEPTH - 1);
 	}
@@ -1160,7 +1184,8 @@
 		vpu_write_reg(vpu_dev, W5_HW_OPTION, 0);
 
 		if (vpu_dev->product_code != WAVE515_CODE) {
-			wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0);
+			reg_val = (vpu_dev->ext_addr & 0xFFFF);
+			wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, reg_val);
 			wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0);
 			vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0);
 		}
@@ -1219,7 +1244,7 @@
 	return setup_wave5_properties(dev);
 }
 
-static int wave5_vpu_sleep_wake(struct device *dev, bool i_sleep_wake, const uint16_t *code,
+int wave5_vpu_sleep_wake(struct device *dev, bool i_sleep_wake, const uint16_t *code,
 				size_t size)
 {
 	u32 reg_val;
@@ -1285,7 +1310,8 @@
 		vpu_write_reg(vpu_dev, W5_HW_OPTION, 0);
 
 		if (vpu_dev->product_code != WAVE515_CODE) {
-			wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0);
+			reg_val = (vpu_dev->ext_addr & 0xFFFF);
+			wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, reg_val);
 			wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0);
 			vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0);
 		}
@@ -1520,7 +1546,7 @@
 	if (ret)
 		return inst->codec_info->dec_info.stream_rd_ptr;
 
-	return vpu_read_reg(inst->dev, W5_RET_QUERY_DEC_BS_RD_PTR);
+	return wave5_read_reg_for_mem_addr(inst, W5_RET_QUERY_DEC_BS_RD_PTR);
 }
 
 int wave5_dec_set_rd_ptr(struct vpu_instance *inst, dma_addr_t addr)
@@ -1571,7 +1597,7 @@
 
 	reg_val = (open_param->line_buf_int_en << 6) | BITSTREAM_ENDIANNESS_BIG_ENDIAN;
 	vpu_write_reg(inst->dev, W5_CMD_BS_PARAM, reg_val);
-	vpu_write_reg(inst->dev, W5_CMD_EXT_ADDR, 0);
+	vpu_write_reg(inst->dev, W5_CMD_EXT_ADDR, inst->dev->ext_addr);
 	vpu_write_reg(inst->dev, W5_CMD_NUM_CQ_DEPTH_M1, WAVE521_COMMAND_QUEUE_DEPTH - 1);
 
 	/* This register must be reset explicitly */
@@ -1753,6 +1779,9 @@
 			(p_param->skip_intra_trans << 25) |
 			(p_param->strong_intra_smooth_enable << 27) |
 			(p_param->en_still_picture << 30);
+	else if (inst->std == W_AVC_ENC)
+		reg_val |= (p_param->constraint_set1_flag << 29);
+
 	vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_SPS_PARAM, reg_val);
 
 	reg_val = (p_param->lossless_enable) |
@@ -1772,12 +1801,14 @@
 
 	if (inst->std == W_AVC_ENC)
 		vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_INTRA_PARAM, p_param->intra_qp |
-				((p_param->intra_period & 0x7ff) << 6) |
-				((p_param->avc_idr_period & 0x7ff) << 17));
+				((p_param->intra_period & ENC_AVC_INTRA_IDR_PARAM_MASK) << ENC_AVC_INTRA_PERIOD_SHIFT) |
+				((p_param->avc_idr_period & ENC_AVC_INTRA_IDR_PARAM_MASK) << ENC_AVC_IDR_PERIOD_SHIFT) |
+				(p_param->forced_idr_header_enable << ENC_AVC_FORCED_IDR_HEADER_SHIFT));
 	else if (inst->std == W_HEVC_ENC)
 		vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_INTRA_PARAM,
-			      p_param->decoding_refresh_type | (p_param->intra_qp << 3) |
-				(p_param->intra_period << 16));
+				p_param->decoding_refresh_type | (p_param->intra_qp << ENC_HEVC_INTRA_QP_SHIFT) |
+				(p_param->forced_idr_header_enable << ENC_HEVC_FORCED_IDR_HEADER_SHIFT) |
+				(p_param->intra_period << ENC_HEVC_INTRA_PERIOD_SHIFT));
 
 	reg_val = (p_param->rdo_skip << 2) |
 		(p_param->lambda_scaling_enable << 3) |
@@ -1822,7 +1853,7 @@
 	vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_RC_BIT_RATIO_LAYER_4_7, 0);
 	vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_ROT_PARAM, rot_mir_mode);
 
-	vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_BG_PARAM, 0);
+	vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_BG_PARAM, SEQ_BG_PARAM_REG_DATA | p_param->bg_detection);
 	vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_CUSTOM_LAMBDA_ADDR, 0);
 	vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_CONF_WIN_TOP_BOT,
 		      p_param->conf_win_bot << 16 | p_param->conf_win_top);
@@ -2139,6 +2170,18 @@
 	return ret;
 }
 
+int wave5_vpu_enc_apply_change_param(struct vpu_instance *inst, u32 *fail_res)
+{
+	/* SET_PARAM + COMMON */
+	vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_SET_PARAM_OPTION, OPT_CHANGE_PARAM);
+	vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_SET_PARAM_ENABLE, inst->change_param_flags);
+
+	if (inst->change_param_flags & W5_ENC_CHANGE_PARAM_RC_TARGET_RATE)
+		vpu_write_reg(inst->dev, W5_CMD_ENC_SEQ_RC_TARGET_RATE, inst->bit_rate);
+
+	return send_firmware_command(inst, W5_ENC_SET_PARAM, true, NULL, fail_res);
+}
+
 int wave5_vpu_encode(struct vpu_instance *inst, struct enc_param *option, u32 *fail_res)
 {
 	u32 src_frame_format;
@@ -2186,7 +2229,11 @@
 			      (option->code_option.encode_eos << 6) |
 			      (option->code_option.encode_eob << 7));
 
-	vpu_write_reg(inst->dev, W5_CMD_ENC_PIC_PIC_PARAM, 0);
+	vpu_write_reg(inst->dev, W5_CMD_ENC_PIC_PIC_PARAM, (option->force_pictype_enable<<20) |
+								(option->force_pic_type<<21));
+
+	option->force_pictype_enable = 0;
+	option->force_pic_type = 0;
 
 	if (option->src_end_flag)
 		/* no more source images. */
@@ -2354,10 +2401,10 @@
 	result->recon_frame_index = vpu_read_reg(inst->dev, W5_RET_ENC_PIC_IDX);
 	result->enc_pic_byte = vpu_read_reg(inst->dev, W5_RET_ENC_PIC_BYTE);
 	result->enc_src_idx = vpu_read_reg(inst->dev, W5_RET_ENC_USED_SRC_IDX);
-	p_enc_info->stream_wr_ptr = vpu_read_reg(inst->dev, W5_RET_ENC_WR_PTR);
-	p_enc_info->stream_rd_ptr = vpu_read_reg(inst->dev, W5_RET_ENC_RD_PTR);
+	p_enc_info->stream_wr_ptr = wave5_read_reg_for_mem_addr(inst, W5_RET_ENC_WR_PTR);
+	p_enc_info->stream_rd_ptr = wave5_read_reg_for_mem_addr(inst, W5_RET_ENC_RD_PTR);
 
-	result->bitstream_buffer = vpu_read_reg(inst->dev, W5_RET_ENC_RD_PTR);
+	result->bitstream_buffer = wave5_read_reg_for_mem_addr(inst, W5_RET_ENC_RD_PTR);
 	result->rd_ptr = p_enc_info->stream_rd_ptr;
 	result->wr_ptr = p_enc_info->stream_wr_ptr;
 
diff -Naur --no-dereference a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c
--- a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c	2025-10-23 09:30:40.285462207 -0400
@@ -6,6 +6,8 @@
  */
 
 #include <linux/bug.h>
+#include <linux/pm_runtime.h>
+#include <linux/delay.h>
 #include "wave5-vpuapi.h"
 #include "wave5-regdefine.h"
 #include "wave5.h"
@@ -81,6 +83,7 @@
 			ret = mutex_lock_interruptible(&inst->dev->hw_lock);
 			if (ret)
 				return ret;
+
 			if (dec_info.index_frame_display > 0)
 				wave5_vpu_dec_set_disp_flag(inst, dec_info.index_frame_display);
 		}
@@ -210,9 +213,13 @@
 	if (!inst->codec_info)
 		return -EINVAL;
 
+	pm_runtime_resume_and_get(inst->dev->dev);
+
 	ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
-	if (ret)
+	if (ret) {
+		pm_runtime_put_sync(inst->dev->dev);
 		return ret;
+	}
 
 	do {
 		ret = wave5_vpu_dec_finish_seq(inst, fail_res);
@@ -244,7 +251,8 @@
 
 unlock_and_return:
 	mutex_unlock(&vpu_dev->hw_lock);
-
+	mutex_destroy(&inst->feed_lock);
+	pm_runtime_put_sync(inst->dev->dev);
 	return ret;
 }
 
@@ -712,6 +720,8 @@
 	if (!inst->codec_info)
 		return -EINVAL;
 
+	pm_runtime_resume_and_get(inst->dev->dev);
+
 	ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
 	if (ret)
 		return ret;
@@ -746,6 +756,8 @@
 
 	mutex_unlock(&vpu_dev->hw_lock);
 
+	pm_runtime_put_sync(inst->dev->dev);
+
 	return 0;
 }
 
@@ -827,6 +839,21 @@
 	return 0;
 }
 
+int wave5_vpu_enc_change_param(struct vpu_instance *inst, u32 *fail_res)
+{
+	int ret;
+	struct vpu_device *vpu_dev = inst->dev;
+
+	ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
+	if (ret)
+		return ret;
+
+	ret = wave5_vpu_enc_apply_change_param(inst, fail_res);
+	mutex_unlock(&vpu_dev->hw_lock);
+
+	return ret;
+}
+
 int wave5_vpu_enc_start_one_frame(struct vpu_instance *inst, struct enc_param *param, u32 *fail_res)
 {
 	struct enc_info *p_enc_info = &inst->codec_info->enc_info;
diff -Naur --no-dereference a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h
--- a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h	2025-10-23 09:30:40.285462207 -0400
@@ -10,6 +10,7 @@
 
 #include <linux/idr.h>
 #include <linux/genalloc.h>
+#include <linux/devfreq.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/v4l2-ctrls.h>
@@ -48,6 +49,10 @@
 #define WAVE5_DEC_HEVC_BUF_SIZE(_w, _h) (DIV_ROUND_UP(_w, 64) * DIV_ROUND_UP(_h, 64) * 256 + 64)
 #define WAVE5_DEC_AVC_BUF_SIZE(_w, _h) ((((ALIGN(_w, 256) / 16) * (ALIGN(_h, 16) / 16)) + 16) * 80)
 
+#define IS_WRAP(_v, _max) ((_v % _max) ? 1 : 0)
+#define DEC_BUF_OFFSET 3
+#define MAX_TIMESTAMP_CIR_BUF 30
+
 #define WAVE5_FBC_LUMA_TABLE_SIZE(_w, _h) (ALIGN(_h, 64) * ALIGN(_w, 256) / 32)
 #define WAVE5_FBC_CHROMA_TABLE_SIZE(_w, _h) (ALIGN((_h), 64) * ALIGN((_w) / 2, 256) / 32)
 #define WAVE5_ENC_AVC_BUF_SIZE(_w, _h) (ALIGN(_w, 64) * ALIGN(_h, 64) / 32)
@@ -459,6 +464,27 @@
 #define MAX_NUM_SPATIAL_LAYER 3
 #define MAX_GOP_NUM 8
 
+enum enc_change_param {
+	// COMMON parameters which can be changed frame by frame.
+	W5_ENC_CHANGE_PARAM_PPS                 = (1<<0),
+	W5_ENC_CHANGE_PARAM_INTRA_PARAM         = (1<<1),
+	W5_ENC_CHANGE_PARAM_RC_FRAME_RATE       = (1<<6),
+	W5_ENC_CHANGE_PARAM_RC_TARGET_RATE      = (1<<8),
+	W5_ENC_CHANGE_PARAM_RC                  = (1<<9),
+	W5_ENC_CHANGE_PARAM_RC_MIN_MAX_QP       = (1<<10),
+	W5_ENC_CHANGE_PARAM_RC_BIT_RATIO_LAYER  = (1<<11),
+	W5_ENC_CHANGE_PARAM_RC_INTER_MIN_MAX_QP = (1<<12),
+	W5_ENC_CHANGE_PARAM_RC_WEIGHT           = (1<<13),
+	W5_ENC_CHANGE_PARAM_INDEPEND_SLICE      = (1<<16),
+	W5_ENC_CHANGE_PARAM_DEPEND_SLICE        = (1<<17),
+	W5_ENC_CHANGE_PARAM_RDO                 = (1<<18),
+	W5_ENC_CHANGE_PARAM_NR                  = (1<<19),
+	W5_ENC_CHANGE_PARAM_BG                  = (1<<20),
+	W5_ENC_CHANGE_PARAM_CUSTOM_MD           = (1<<21),
+	W5_ENC_CHANGE_PARAM_CUSTOM_LAMBDA       = (1<<22),
+	W5_ENC_CHANGE_PARAM_VUI_HRD_PARAM       = (1<<23),
+};
+
 struct custom_gop_pic_param {
 	u32 pic_type; /* picture type of nth picture in the custom GOP */
 	u32 poc_offset; /* POC of nth picture in the custom GOP */
@@ -568,6 +594,10 @@
 	u32 lambda_scaling_enable: 1; /* enable lambda scaling using custom GOP */
 	u32 transform8x8_enable: 1; /* enable 8x8 intra prediction and 8x8 transform */
 	u32 mb_level_rc_enable: 1; /* enable MB-level rate control */
+	u32 forced_idr_header_enable: 1; /* enable header encoding before IDR frame */
+	u32 constraint_set1_flag: 1; /* enable CBP */
+	u32 forced_idr_pictype_enable: 1;
+	u32 bg_detection: 1; /* enable background detection */
 };
 
 struct enc_open_param {
@@ -611,16 +641,18 @@
 
 struct enc_param {
 	struct frame_buffer *source_frame;
-	u32 pic_stream_buffer_addr;
+	dma_addr_t pic_stream_buffer_addr;
 	u64 pic_stream_buffer_size;
 	u32 src_idx; /* source frame buffer index */
 	struct enc_code_opt code_option;
 	u64 pts; /* presentation timestamp (PTS) of the input source */
 	bool src_end_flag;
+	s32  force_pictype_enable; /* A flag to use a force picture type (WAVE only) */
+	s32  force_pic_type;       /* A force picture type (I, P, B, IDR). It is valid when forcePicTypeEnable is 1. (WAVE only) */
 };
 
 struct enc_output_info {
-	u32 bitstream_buffer;
+	dma_addr_t bitstream_buffer;
 	u32 bitstream_size; /* byte size of encoded bitstream */
 	u32 pic_type: 2; /* <<vpuapi_h_pic_type>> */
 	s32 recon_frame_index;
@@ -667,8 +699,8 @@
 	struct dec_open_param open_param;
 	struct dec_initial_info initial_info;
 	struct dec_initial_info new_seq_info; /* temporal new sequence information */
-	u32 stream_wr_ptr;
-	u32 stream_rd_ptr;
+	dma_addr_t stream_wr_ptr;
+	dma_addr_t stream_rd_ptr;
 	u32 frame_display_flag;
 	dma_addr_t stream_buf_start_addr;
 	dma_addr_t stream_buf_end_addr;
@@ -705,8 +737,8 @@
 struct enc_info {
 	struct enc_open_param open_param;
 	struct enc_initial_info initial_info;
-	u32 stream_rd_ptr;
-	u32 stream_wr_ptr;
+	dma_addr_t stream_rd_ptr;
+	dma_addr_t stream_wr_ptr;
 	dma_addr_t stream_buf_start_addr;
 	dma_addr_t stream_buf_end_addr;
 	u32 stream_buf_size;
@@ -755,7 +787,9 @@
 	struct gen_pool *sram_pool;
 	struct vpu_buf sram_buf;
 	void __iomem *vdb_register;
+	struct devfreq *vpu_devfreq;
 	u32 product_code;
+	u32 ext_addr;
 	struct ida inst_ida;
 	struct clk_bulk_data *clks;
 	struct hrtimer hrtimer;
@@ -764,6 +798,13 @@
 	int vpu_poll_interval;
 	int num_clks;
 	struct reset_control *resets;
+	bool opp_table_detected;
+};
+
+struct timestamp_circ_buf {
+	u64 buf[MAX_TIMESTAMP_CIR_BUF];
+	int head;
+	int tail;
 };
 
 struct vpu_instance;
@@ -801,21 +842,29 @@
 	struct frame_buffer frame_buf[MAX_REG_FRAME];
 	struct vpu_buf frame_vbuf[MAX_REG_FRAME];
 	u32 fbc_buf_count;
+	u32 dst_buf_count; // number of ready buffers for display
 	u32 queued_src_buf_num;
 	u32 queued_dst_buf_num;
 	struct list_head avail_src_bufs;
 	struct list_head avail_dst_bufs;
 	struct v4l2_rect conf_win;
 	u64 timestamp;
+	struct timestamp_circ_buf time_stamp;
 	enum frame_buffer_format output_format;
 	bool cbcr_interleave;
 	bool nv21;
 	bool eos;
+	bool retry;
+	bool empty_queue;
+	int queuing_num;
+	struct mutex feed_lock; /* lock for feeding bitstream buffers */
 	struct vpu_buf bitstream_vbuf;
 	dma_addr_t last_rd_ptr;
 	size_t remaining_consumed_bytes;
 	bool needs_reallocation;
 
+	struct semaphore run_sem;
+	struct task_struct *run_thread;
 	unsigned int min_src_buf_count;
 	unsigned int rot_angle;
 	unsigned int mirror_direction;
@@ -826,7 +875,12 @@
 	unsigned int rc_enable;
 	unsigned int bit_rate;
 	unsigned int encode_aud;
+	unsigned int change_param_flags;
 	struct enc_wave_param enc_param;
+	unsigned int *map_index;
+	dma_addr_t *mapped_dma_addr;
+	unsigned int cap_io_mode;
+	struct mutex inst_lock;
 };
 
 void wave5_vdi_write_register(struct vpu_device *vpu_dev, u32 addr, u32 data);
@@ -856,6 +910,7 @@
 dma_addr_t wave5_vpu_dec_get_rd_ptr(struct vpu_instance *inst);
 int wave5_vpu_dec_reset_framebuffer(struct vpu_instance *inst, unsigned int index);
 int wave5_vpu_dec_give_command(struct vpu_instance *inst, enum codec_command cmd, void *parameter);
+int wave5_vpu_enc_change_param(struct vpu_instance *inst, u32 *fail_res);
 int wave5_vpu_dec_get_bitstream_buffer(struct vpu_instance *inst, dma_addr_t *prd_ptr,
 				       dma_addr_t *pwr_ptr, size_t *size);
 int wave5_vpu_dec_update_bitstream_buffer(struct vpu_instance *inst, size_t size);
diff -Naur --no-dereference a/drivers/media/platform/chips-media/wave5/wave5-vpu.c b/drivers/media/platform/chips-media/wave5/wave5-vpu.c
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu.c	2025-10-23 09:30:40.285462207 -0400
@@ -11,6 +11,9 @@
 #include <linux/firmware.h>
 #include <linux/interrupt.h>
 #include <linux/reset.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_opp.h>
+#include <linux/devfreq.h>
 #include "wave5-vpu.h"
 #include "wave5-regdefine.h"
 #include "wave5-vpuconfig.h"
@@ -50,17 +53,18 @@
 	u32 seq_done;
 	u32 cmd_done;
 	u32 irq_reason;
-	struct vpu_instance *inst;
+	u32 irq_subreason;
+	struct vpu_instance *inst, *tmp;
 	struct vpu_device *dev = dev_id;
 
 	irq_reason = wave5_vdi_read_register(dev, W5_VPU_VINT_REASON);
 	seq_done = wave5_vdi_read_register(dev, W5_RET_SEQ_DONE_INSTANCE_INFO);
 	cmd_done = wave5_vdi_read_register(dev, W5_RET_QUEUE_CMD_DONE_INST);
+
 	wave5_vdi_write_register(dev, W5_VPU_VINT_REASON_CLR, irq_reason);
 	wave5_vdi_write_register(dev, W5_VPU_VINT_CLEAR, 0x1);
 
-	list_for_each_entry(inst, &dev->instances, list) {
-
+	list_for_each_entry_safe(inst, tmp, &dev->instances, list) {
 		if (irq_reason & BIT(INT_WAVE5_INIT_SEQ) ||
 		    irq_reason & BIT(INT_WAVE5_ENC_SET_PARAM)) {
 			if (dev->product_code == WAVE515_CODE &&
@@ -81,7 +85,9 @@
 		    irq_reason & BIT(INT_WAVE5_ENC_PIC)) {
 			if (cmd_done & BIT(inst->id)) {
 				cmd_done &= ~BIT(inst->id);
-				wave5_vdi_write_register(dev, W5_RET_QUEUE_CMD_DONE_INST,
+				irq_subreason = wave5_vdi_read_register(dev, W5_VPU_VINT_REASON);
+				if (!(irq_subreason & BIT(INT_WAVE5_DEC_PIC)))
+					wave5_vdi_write_register(dev, W5_RET_QUEUE_CMD_DONE_INST,
 							 cmd_done);
 				inst->ops->finish_process(inst);
 			}
@@ -153,6 +159,85 @@
 	return 0;
 }
 
+static int wave5_pm_suspend(struct device *dev)
+{
+	struct vpu_device *vpu = dev_get_drvdata(dev);
+
+	if (pm_runtime_suspended(dev))
+		return 0;
+
+	if (vpu->irq < 0)
+		hrtimer_cancel(&vpu->hrtimer);
+
+	wave5_vpu_sleep_wake(dev, true, NULL, 0);
+	clk_bulk_disable_unprepare(vpu->num_clks, vpu->clks);
+
+	return 0;
+}
+
+static int wave5_pm_resume(struct device *dev)
+{
+	struct vpu_device *vpu = dev_get_drvdata(dev);
+	int ret = 0;
+
+	wave5_vpu_sleep_wake(dev, false, NULL, 0);
+	ret = clk_bulk_prepare_enable(vpu->num_clks, vpu->clks);
+	if (ret) {
+		dev_err(dev, "Enabling clocks, fail: %d\n", ret);
+		return ret;
+	}
+
+	if (vpu->irq < 0 && !hrtimer_active(&vpu->hrtimer))
+		hrtimer_start(&vpu->hrtimer, ns_to_ktime(vpu->vpu_poll_interval * NSEC_PER_MSEC),
+			      HRTIMER_MODE_REL_PINNED);
+
+	return ret;
+}
+
+static const struct dev_pm_ops wave5_pm_ops = {
+	SET_RUNTIME_PM_OPS(wave5_pm_suspend, wave5_pm_resume, NULL)
+};
+
+static int vpu_devfreq_target(struct device *dev, unsigned long *freq, u32 flags)
+{
+	struct vpu_device *vpu = dev_get_drvdata(dev);
+	unsigned long target_freq = *freq;
+	struct dev_pm_opp *opp;
+	unsigned long acq_freq;
+	int ret;
+
+	if (!vpu->opp_table_detected) {
+		dev_err(vpu->dev, "No OPP table in device tree\n");
+		return -EINVAL;
+	}
+
+	opp = dev_pm_opp_find_freq_ceil(vpu->dev, &target_freq);
+	if (IS_ERR(opp)) {
+		opp = dev_pm_opp_find_freq_floor(vpu->dev, &target_freq);
+		if (IS_ERR(opp)) {
+			dev_err(vpu->dev, "Failed to get floor value\n");
+			return -EINVAL;
+		}
+	}
+
+	dev_pm_opp_put(opp);
+	acq_freq = dev_pm_opp_get_freq(opp);
+	ret = dev_pm_opp_set_rate(vpu->dev, acq_freq);
+	if (ret) {
+		dev_err(vpu->dev, "Error setting the clock\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static struct devfreq_dev_profile vpu_devfreq_profile = {
+	.target = vpu_devfreq_target,
+	.freq_table = NULL,
+	.max_state = 0,
+	.polling_ms = 0,
+};
+
 static int wave5_vpu_probe(struct platform_device *pdev)
 {
 	int ret;
@@ -166,8 +251,8 @@
 		return -EINVAL;
 	}
 
-	/* physical addresses limited to 32 bits */
-	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+	/* physical addresses limited to 48 bits */
+	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48));
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to set DMA mask: %d\n", ret);
 		return ret;
@@ -225,6 +310,7 @@
 		goto err_clk_dis;
 	}
 	dev->product = wave5_vpu_get_product_id(dev);
+	dev->ext_addr = ((dev->common_mem.daddr >> 32) & 0xFFFF);
 
 	dev->irq = platform_get_irq(pdev, 0);
 	if (dev->irq < 0) {
@@ -248,6 +334,23 @@
 		}
 	}
 
+	dev->opp_table_detected = TRUE;
+	ret = dev_pm_opp_of_add_table(&pdev->dev);
+	if (ret == -ENODEV) {
+		dev->opp_table_detected = FALSE;
+		dev_err(&pdev->dev, "OPP table not found in device tree\n");
+	} else if (ret < 0) {
+		dev_err(&pdev->dev, "Invalid OPP table in device tree\n");
+		goto err_vdi_release;
+	} else {
+		dev->vpu_devfreq = devm_devfreq_add_device(&pdev->dev, &vpu_devfreq_profile, "userspace", NULL);
+		if (IS_ERR(dev->vpu_devfreq)) {
+			dev_pm_opp_of_remove_table(&pdev->dev);
+			return PTR_ERR(dev->vpu_devfreq);
+		}
+	}
+
+
 	INIT_LIST_HEAD(&dev->instances);
 	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
 	if (ret) {
@@ -281,6 +384,12 @@
 		 (match_data->flags & WAVE5_IS_DEC) ? "'DECODE'" : "");
 	dev_info(&pdev->dev, "Product Code:      0x%x\n", dev->product_code);
 	dev_info(&pdev->dev, "Firmware Revision: %u\n", fw_revision);
+
+	pm_runtime_set_autosuspend_delay(&pdev->dev, 5000);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	wave5_vpu_sleep_wake(&pdev->dev, true, NULL, 0);
+
 	return 0;
 
 err_enc_unreg:
@@ -310,6 +419,14 @@
 		hrtimer_cancel(&dev->hrtimer);
 	}
 
+	if (dev->opp_table_detected) {
+		devm_devfreq_remove_device(&pdev->dev, dev->vpu_devfreq);
+		dev_pm_opp_of_remove_table(&pdev->dev);
+	}
+
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
 	mutex_destroy(&dev->dev_lock);
 	mutex_destroy(&dev->hw_lock);
 	reset_control_assert(dev->resets);
@@ -337,6 +454,7 @@
 	.driver = {
 		.name = VPU_PLATFORM_DEVICE_NAME,
 		.of_match_table = of_match_ptr(wave5_dt_ids),
+		.pm = &wave5_pm_ops,
 		},
 	.probe = wave5_vpu_probe,
 	.remove_new = wave5_vpu_remove,
diff -Naur --no-dereference a/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h b/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h
--- a/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h	2025-10-23 09:30:40.285462207 -0400
@@ -32,10 +32,29 @@
 
 #define MAX_NUM_INSTANCE                32
 
-#define W5_MIN_ENC_PIC_WIDTH            256
-#define W5_MIN_ENC_PIC_HEIGHT           128
-#define W5_MAX_ENC_PIC_WIDTH            8192
-#define W5_MAX_ENC_PIC_HEIGHT           8192
+#define W5_DEF_DEC_PIC_WIDTH            720U
+#define W5_DEF_DEC_PIC_HEIGHT           480U
+#define W5_MIN_DEC_PIC_8_WIDTH          8U
+#define W5_MIN_DEC_PIC_8_HEIGHT         8U
+#define W5_MIN_DEC_PIC_32_WIDTH         32U
+#define W5_MIN_DEC_PIC_32_HEIGHT        32U
+#define W5_MAX_DEC_PIC_WIDTH            8192U
+#define W5_MAX_DEC_PIC_HEIGHT           4320U
+#define W5_DEC_CODEC_STEP_WIDTH         1U
+#define W5_DEC_CODEC_STEP_HEIGHT        1U
+#define W5_DEC_RAW_STEP_WIDTH           32U
+#define W5_DEC_RAW_STEP_HEIGHT          16U
+
+#define W5_DEF_ENC_PIC_WIDTH            416U
+#define W5_DEF_ENC_PIC_HEIGHT           240U
+#define W5_MIN_ENC_PIC_WIDTH            256U
+#define W5_MIN_ENC_PIC_HEIGHT           128U
+#define W5_MAX_ENC_PIC_WIDTH            8192U
+#define W5_MAX_ENC_PIC_HEIGHT           8192U
+#define W5_ENC_CODEC_STEP_WIDTH         8U
+#define W5_ENC_CODEC_STEP_HEIGHT        8U
+#define W5_ENC_RAW_STEP_WIDTH           32U
+#define W5_ENC_RAW_STEP_HEIGHT          16U
 
 //  application specific configuration
 #define VPU_ENC_TIMEOUT                 60000
diff -Naur --no-dereference a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c	2025-10-23 09:30:40.285462207 -0400
@@ -5,120 +5,127 @@
  * Copyright (C) 2021-2023 CHIPS&MEDIA INC
  */
 
+#include <linux/pm_runtime.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/atomic.h>
 #include "wave5-helper.h"
 
 #define VPU_DEC_DEV_NAME "C&M Wave5 VPU decoder"
 #define VPU_DEC_DRV_NAME "wave5-dec"
 
-#define DEFAULT_SRC_SIZE(width, height) ({			\
-	(width) * (height) / 8 * 3;					\
-})
+static const struct v4l2_frmsize_stepwise dec_hevc_frmsize = {
+	.min_width = W5_MIN_DEC_PIC_8_WIDTH,
+	.max_width = W5_MAX_DEC_PIC_WIDTH,
+	.step_width = W5_DEC_CODEC_STEP_WIDTH,
+	.min_height = W5_MIN_DEC_PIC_8_HEIGHT,
+	.max_height = W5_MAX_DEC_PIC_HEIGHT,
+	.step_height = W5_DEC_CODEC_STEP_HEIGHT,
+};
+
+static const struct v4l2_frmsize_stepwise dec_h264_frmsize = {
+	.min_width = W5_MIN_DEC_PIC_32_WIDTH,
+	.max_width = W5_MAX_DEC_PIC_WIDTH,
+	.step_width = W5_DEC_CODEC_STEP_WIDTH,
+	.min_height = W5_MIN_DEC_PIC_32_HEIGHT,
+	.max_height = W5_MAX_DEC_PIC_HEIGHT,
+	.step_height = W5_DEC_CODEC_STEP_HEIGHT,
+};
+
+static const struct v4l2_frmsize_stepwise dec_raw_frmsize = {
+	.min_width = W5_MIN_DEC_PIC_8_WIDTH,
+	.max_width = W5_MAX_DEC_PIC_WIDTH,
+	.step_width = W5_DEC_RAW_STEP_WIDTH,
+	.min_height = W5_MIN_DEC_PIC_8_HEIGHT,
+	.max_height = W5_MAX_DEC_PIC_HEIGHT,
+	.step_height = W5_DEC_RAW_STEP_HEIGHT,
+};
 
 static const struct vpu_format dec_fmt_list[FMT_TYPES][MAX_FMTS] = {
 	[VPU_FMT_TYPE_CODEC] = {
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_HEVC,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_hevc_frmsize,
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_H264,
-			.max_width = 8192,
-			.min_width = 32,
-			.max_height = 4320,
-			.min_height = 32,
+			.v4l2_frmsize = &dec_h264_frmsize,
 		},
 	},
 	[VPU_FMT_TYPE_RAW] = {
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV420,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_raw_frmsize,
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_NV12,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_raw_frmsize,
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_NV21,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_raw_frmsize,
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV422P,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_raw_frmsize,
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_NV16,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_raw_frmsize,
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_NV61,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_raw_frmsize,
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV420M,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_raw_frmsize,
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_NV12M,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_raw_frmsize,
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_NV21M,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_raw_frmsize,
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV422M,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_raw_frmsize,
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_NV16M,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_raw_frmsize,
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_NV61M,
-			.max_width = 8192,
-			.min_width = 8,
-			.max_height = 4320,
-			.min_height = 8,
+			.v4l2_frmsize = &dec_raw_frmsize,
 		},
 	}
 };
 
+static int initialize_sequence(struct vpu_instance *inst);
+static bool wave5_is_draining_or_eos(struct vpu_instance *inst);
+static int fill_ringbuffer(struct vpu_instance *inst);
+
+static int run_thread(void *data)
+{
+	struct vpu_instance *inst = (struct vpu_instance *)data;
+	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
+
+	while (!kthread_should_stop()) {
+		if (down_interruptible(&inst->run_sem))
+			continue;
+
+		if (kthread_should_stop())
+			break;
+
+		v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
+	}
+
+	return 0;
+}
+
 /*
  * Make sure that the state switch is allowed and add logging for debugging
  * purposes
@@ -187,6 +194,7 @@
 	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
 	struct v4l2_m2m_buffer *buf, *n;
 	size_t consumed_bytes = 0;
+	int head = 0;
 
 	if (rd_ptr >= inst->last_rd_ptr) {
 		consumed_bytes = rd_ptr - inst->last_rd_ptr;
@@ -213,7 +221,12 @@
 		dev_dbg(inst->dev->dev, "%s: removing src buffer %i",
 			__func__, src_buf->vb2_buf.index);
 		src_buf = v4l2_m2m_src_buf_remove(m2m_ctx);
-		inst->timestamp = src_buf->vb2_buf.timestamp;
+		head = inst->time_stamp.head;
+		inst->time_stamp.buf[head] = src_buf->vb2_buf.timestamp;
+		inst->time_stamp.head++;
+
+		if (IS_WRAP(inst->time_stamp.head, MAX_TIMESTAMP_CIR_BUF) == 0)
+			inst->time_stamp.head = 0;
 		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
 		consumed_bytes -= src_size;
 
@@ -233,74 +246,6 @@
 	inst->remaining_consumed_bytes = consumed_bytes;
 }
 
-static void wave5_update_pix_fmt(struct v4l2_pix_format_mplane *pix_mp, unsigned int width,
-				 unsigned int height)
-{
-	switch (pix_mp->pixelformat) {
-	case V4L2_PIX_FMT_YUV420:
-	case V4L2_PIX_FMT_NV12:
-	case V4L2_PIX_FMT_NV21:
-		pix_mp->width = round_up(width, 32);
-		pix_mp->height = round_up(height, 16);
-		pix_mp->plane_fmt[0].bytesperline = round_up(width, 32);
-		pix_mp->plane_fmt[0].sizeimage = width * height * 3 / 2;
-		break;
-	case V4L2_PIX_FMT_YUV422P:
-	case V4L2_PIX_FMT_NV16:
-	case V4L2_PIX_FMT_NV61:
-		pix_mp->width = round_up(width, 32);
-		pix_mp->height = round_up(height, 16);
-		pix_mp->plane_fmt[0].bytesperline = round_up(width, 32);
-		pix_mp->plane_fmt[0].sizeimage = width * height * 2;
-		break;
-	case V4L2_PIX_FMT_YUV420M:
-		pix_mp->width = round_up(width, 32);
-		pix_mp->height = round_up(height, 16);
-		pix_mp->plane_fmt[0].bytesperline = round_up(width, 32);
-		pix_mp->plane_fmt[0].sizeimage = width * height;
-		pix_mp->plane_fmt[1].bytesperline = round_up(width, 32) / 2;
-		pix_mp->plane_fmt[1].sizeimage = width * height / 4;
-		pix_mp->plane_fmt[2].bytesperline = round_up(width, 32) / 2;
-		pix_mp->plane_fmt[2].sizeimage = width * height / 4;
-		break;
-	case V4L2_PIX_FMT_NV12M:
-	case V4L2_PIX_FMT_NV21M:
-		pix_mp->width = round_up(width, 32);
-		pix_mp->height = round_up(height, 16);
-		pix_mp->plane_fmt[0].bytesperline = round_up(width, 32);
-		pix_mp->plane_fmt[0].sizeimage = width * height;
-		pix_mp->plane_fmt[1].bytesperline = round_up(width, 32);
-		pix_mp->plane_fmt[1].sizeimage = width * height / 2;
-		break;
-	case V4L2_PIX_FMT_YUV422M:
-		pix_mp->width = round_up(width, 32);
-		pix_mp->height = round_up(height, 16);
-		pix_mp->plane_fmt[0].bytesperline = round_up(width, 32);
-		pix_mp->plane_fmt[0].sizeimage = width * height;
-		pix_mp->plane_fmt[1].bytesperline = round_up(width, 32) / 2;
-		pix_mp->plane_fmt[1].sizeimage = width * height / 2;
-		pix_mp->plane_fmt[2].bytesperline = round_up(width, 32) / 2;
-		pix_mp->plane_fmt[2].sizeimage = width * height / 2;
-		break;
-	case V4L2_PIX_FMT_NV16M:
-	case V4L2_PIX_FMT_NV61M:
-		pix_mp->width = round_up(width, 32);
-		pix_mp->height = round_up(height, 16);
-		pix_mp->plane_fmt[0].bytesperline = round_up(width, 32);
-		pix_mp->plane_fmt[0].sizeimage = width * height;
-		pix_mp->plane_fmt[1].bytesperline = round_up(width, 32);
-		pix_mp->plane_fmt[1].sizeimage = width * height;
-		break;
-	default:
-		pix_mp->width = width;
-		pix_mp->height = height;
-		pix_mp->plane_fmt[0].bytesperline = 0;
-		pix_mp->plane_fmt[0].sizeimage = max(DEFAULT_SRC_SIZE(width, height),
-						     pix_mp->plane_fmt[0].sizeimage);
-		break;
-	}
-}
-
 static int start_decode(struct vpu_instance *inst, u32 *fail_res)
 {
 	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
@@ -316,7 +261,6 @@
 		switch_state(inst, VPU_INST_STATE_STOP);
 
 		dev_dbg(inst->dev->dev, "%s: pic run failed / finish job", __func__);
-		v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
 	}
 
 	return ret;
@@ -388,6 +332,8 @@
 	}
 
 	if (p_dec_info->initial_info_obtained) {
+		const struct vpu_format *vpu_fmt;
+
 		inst->conf_win.left = initial_info->pic_crop_rect.left;
 		inst->conf_win.top = initial_info->pic_crop_rect.top;
 		inst->conf_win.width = initial_info->pic_width -
@@ -395,10 +341,27 @@
 		inst->conf_win.height = initial_info->pic_height -
 			initial_info->pic_crop_rect.top - initial_info->pic_crop_rect.bottom;
 
-		wave5_update_pix_fmt(&inst->src_fmt, initial_info->pic_width,
-				     initial_info->pic_height);
-		wave5_update_pix_fmt(&inst->dst_fmt, initial_info->pic_width,
-				     initial_info->pic_height);
+		vpu_fmt = wave5_find_vpu_fmt(inst->src_fmt.pixelformat,
+				dec_fmt_list[VPU_FMT_TYPE_CODEC]);
+		if (!vpu_fmt)
+			return -EINVAL;
+
+		wave5_update_pix_fmt(&inst->src_fmt,
+					VPU_FMT_TYPE_CODEC,
+					initial_info->pic_width,
+					initial_info->pic_height,
+					vpu_fmt->v4l2_frmsize);
+
+		vpu_fmt = wave5_find_vpu_fmt(inst->dst_fmt.pixelformat,
+				dec_fmt_list[VPU_FMT_TYPE_RAW]);
+		if (!vpu_fmt)
+			return -EINVAL;
+
+		wave5_update_pix_fmt(&inst->dst_fmt,
+					VPU_FMT_TYPE_RAW,
+					initial_info->pic_width,
+					initial_info->pic_height,
+					vpu_fmt->v4l2_frmsize);
 	}
 
 	v4l2_event_queue_fh(fh, &vpu_event_src_ch);
@@ -414,24 +377,36 @@
 	struct vb2_v4l2_buffer *dec_buf = NULL;
 	struct vb2_v4l2_buffer *disp_buf = NULL;
 	struct vb2_queue *dst_vq = v4l2_m2m_get_dst_vq(m2m_ctx);
-	struct queue_status_info q_status;
+	int index_to_remove = -1;
+	int tail = 0;
 
 	dev_dbg(inst->dev->dev, "%s: Fetch output info from firmware.", __func__);
 
 	ret = wave5_vpu_dec_get_output_info(inst, &dec_info);
 	if (ret) {
-		dev_warn(inst->dev->dev, "%s: could not get output info.", __func__);
+		dev_dbg(inst->dev->dev, "%s: could not get output info.", __func__);
 		v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
 		return;
 	}
 
 	dev_dbg(inst->dev->dev, "%s: rd_ptr %pad wr_ptr %pad", __func__, &dec_info.rd_ptr,
 		&dec_info.wr_ptr);
-	wave5_handle_src_buffer(inst, dec_info.rd_ptr);
 
 	dev_dbg(inst->dev->dev, "%s: dec_info dec_idx %i disp_idx %i", __func__,
 		dec_info.index_frame_decoded, dec_info.index_frame_display);
 
+	if (inst->std == W_AVC_DEC &&
+	    dec_info.index_frame_decoded == DECODED_IDX_FLAG_SKIP &&
+	    dec_info.index_frame_display == DISPLAY_IDX_FLAG_NO_FB) {
+		struct vb2_v4l2_buffer *src_buf = v4l2_m2m_src_buf_remove(m2m_ctx);
+
+		if (src_buf)
+			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
+		return;
+	}
+
+	wave5_handle_src_buffer(inst, dec_info.rd_ptr);
+
 	if (!vb2_is_streaming(dst_vq)) {
 		dev_dbg(inst->dev->dev, "%s: capture is not streaming..", __func__);
 		v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
@@ -446,7 +421,7 @@
 						       dec_info.index_frame_decoded);
 		if (vb) {
 			dec_buf = to_vb2_v4l2_buffer(vb);
-			dec_buf->vb2_buf.timestamp = inst->timestamp;
+			//dec_buf->vb2_buf.timestamp = inst->timestamp;
 		} else {
 			dev_warn(inst->dev->dev, "%s: invalid decoded frame index %i",
 				 __func__, dec_info.index_frame_decoded);
@@ -454,7 +429,14 @@
 	}
 
 	if (dec_info.index_frame_display >= 0) {
-		disp_buf = v4l2_m2m_dst_buf_remove_by_idx(m2m_ctx, dec_info.index_frame_display);
+		if (inst->cap_io_mode == VB2_MEMORY_DMABUF) {
+			mutex_lock(&inst->inst_lock);
+			index_to_remove = inst->map_index[dec_info.index_frame_display];
+			mutex_unlock(&inst->inst_lock);
+			disp_buf = v4l2_m2m_dst_buf_remove_by_idx(m2m_ctx, index_to_remove);
+		} else
+			disp_buf = v4l2_m2m_dst_buf_remove_by_idx(m2m_ctx,
+					dec_info.index_frame_display);
 		if (!disp_buf)
 			dev_warn(inst->dev->dev, "%s: invalid display frame index %i",
 				 __func__, dec_info.index_frame_display);
@@ -481,6 +463,13 @@
 					      inst->dst_fmt.plane_fmt[2].sizeimage);
 		}
 
+		tail = inst->time_stamp.tail;
+		disp_buf->vb2_buf.timestamp = inst->time_stamp.buf[tail];
+		inst->time_stamp.tail++;
+
+		if (IS_WRAP(inst->time_stamp.tail, MAX_TIMESTAMP_CIR_BUF) == 0)
+			inst->time_stamp.tail = 0;
+
 		/* TODO implement interlace support */
 		disp_buf->field = V4L2_FIELD_NONE;
 		dst_vpu_buf->display = true;
@@ -509,17 +498,6 @@
 		spin_unlock_irqrestore(&inst->state_spinlock, flags);
 	}
 
-	/*
-	 * During a resolution change and while draining, the firmware may flush
-	 * the reorder queue regardless of having a matching decoding operation
-	 * pending. Only terminate the job if there are no more IRQ coming.
-	 */
-	wave5_vpu_dec_give_command(inst, DEC_GET_QUEUE_STATUS, &q_status);
-	if (q_status.report_queue_count == 0 &&
-	    (q_status.instance_queue_count == 0 || dec_info.sequence_changed)) {
-		dev_dbg(inst->dev->dev, "%s: finishing job.\n", __func__);
-		v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
-	}
 }
 
 static int wave5_vpu_dec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
@@ -530,6 +508,31 @@
 	return 0;
 }
 
+static void wave5_vpu_dec_feed_remaining(struct vpu_instance *inst)
+{
+	int ret = 0;
+	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
+	u32 fail_res = 0;
+
+	mutex_lock(&inst->feed_lock);
+	ret = fill_ringbuffer(inst);
+	mutex_unlock(&inst->feed_lock);
+	if (ret) {
+		dev_warn(inst->dev->dev, "Filling ring buffer failed\n");
+		return;
+	}
+
+	ret = start_decode(inst, &fail_res);
+	if (ret) {
+		dev_err(inst->dev->dev,
+			"Frame decoding on m2m context (%p), fail: %d (result: %d)\n",
+			m2m_ctx, ret, fail_res);
+	}
+
+	v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
+}
+
+
 static int wave5_vpu_dec_enum_framesizes(struct file *f, void *fh, struct v4l2_frmsizeenum *fsize)
 {
 	const struct vpu_format *vpu_fmt;
@@ -545,12 +548,9 @@
 	}
 
 	fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
-	fsize->stepwise.min_width = vpu_fmt->min_width;
-	fsize->stepwise.max_width = vpu_fmt->max_width;
-	fsize->stepwise.step_width = 1;
-	fsize->stepwise.min_height = vpu_fmt->min_height;
-	fsize->stepwise.max_height = vpu_fmt->max_height;
-	fsize->stepwise.step_height = 1;
+	fsize->stepwise = *vpu_fmt->v4l2_frmsize;
+	fsize->stepwise.step_width = W5_DEC_CODEC_STEP_WIDTH;
+	fsize->stepwise.step_height = W5_DEC_CODEC_STEP_HEIGHT;
 
 	return 0;
 }
@@ -573,6 +573,7 @@
 {
 	struct vpu_instance *inst = wave5_to_vpu_inst(fh);
 	struct dec_info *p_dec_info = &inst->codec_info->dec_info;
+	const struct v4l2_frmsize_stepwise *frmsize;
 	const struct vpu_format *vpu_fmt;
 	int width, height;
 
@@ -586,14 +587,12 @@
 		width = inst->dst_fmt.width;
 		height = inst->dst_fmt.height;
 		f->fmt.pix_mp.pixelformat = inst->dst_fmt.pixelformat;
-		f->fmt.pix_mp.num_planes = inst->dst_fmt.num_planes;
+		frmsize = &dec_raw_frmsize;
 	} else {
-		const struct v4l2_format_info *info = v4l2_format_info(vpu_fmt->v4l2_pix_fmt);
-
-		width = clamp(f->fmt.pix_mp.width, vpu_fmt->min_width, vpu_fmt->max_width);
-		height = clamp(f->fmt.pix_mp.height, vpu_fmt->min_height, vpu_fmt->max_height);
+		width = f->fmt.pix_mp.width;
+		height = f->fmt.pix_mp.height;
 		f->fmt.pix_mp.pixelformat = vpu_fmt->v4l2_pix_fmt;
-		f->fmt.pix_mp.num_planes = info->mem_planes;
+		frmsize = vpu_fmt->v4l2_frmsize;
 	}
 
 	if (p_dec_info->initial_info_obtained) {
@@ -601,9 +600,10 @@
 		height = inst->dst_fmt.height;
 	}
 
-	wave5_update_pix_fmt(&f->fmt.pix_mp, width, height);
-	f->fmt.pix_mp.flags = 0;
-	f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+	wave5_update_pix_fmt(&f->fmt.pix_mp, VPU_FMT_TYPE_RAW,
+					     width,
+					     height,
+					     frmsize);
 	f->fmt.pix_mp.colorspace = inst->colorspace;
 	f->fmt.pix_mp.ycbcr_enc = inst->ycbcr_enc;
 	f->fmt.pix_mp.quantization = inst->quantization;
@@ -715,7 +715,9 @@
 static int wave5_vpu_dec_try_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
 {
 	struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+	const struct v4l2_frmsize_stepwise *frmsize;
 	const struct vpu_format *vpu_fmt;
+	int width, height;
 
 	dev_dbg(inst->dev->dev,
 		"%s: fourcc: %u width: %u height: %u num_planes: %u colorspace: %u field: %u\n",
@@ -724,20 +726,21 @@
 
 	vpu_fmt = wave5_find_vpu_fmt(f->fmt.pix_mp.pixelformat, dec_fmt_list[VPU_FMT_TYPE_CODEC]);
 	if (!vpu_fmt) {
+		width = inst->src_fmt.width;
+		height = inst->src_fmt.height;
 		f->fmt.pix_mp.pixelformat = inst->src_fmt.pixelformat;
-		f->fmt.pix_mp.num_planes = inst->src_fmt.num_planes;
-		wave5_update_pix_fmt(&f->fmt.pix_mp, inst->src_fmt.width, inst->src_fmt.height);
+		frmsize = &dec_hevc_frmsize;
 	} else {
-		int width = clamp(f->fmt.pix_mp.width, vpu_fmt->min_width, vpu_fmt->max_width);
-		int height = clamp(f->fmt.pix_mp.height, vpu_fmt->min_height, vpu_fmt->max_height);
-
+		width = f->fmt.pix_mp.width;
+		height = f->fmt.pix_mp.height;
 		f->fmt.pix_mp.pixelformat = vpu_fmt->v4l2_pix_fmt;
-		f->fmt.pix_mp.num_planes = 1;
-		wave5_update_pix_fmt(&f->fmt.pix_mp, width, height);
+		frmsize = vpu_fmt->v4l2_frmsize;
 	}
 
-	f->fmt.pix_mp.flags = 0;
-	f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+	wave5_update_pix_fmt(&f->fmt.pix_mp, VPU_FMT_TYPE_CODEC,
+					     width,
+					     height,
+					     frmsize);
 
 	return 0;
 }
@@ -745,6 +748,7 @@
 static int wave5_vpu_dec_s_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
 {
 	struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+	const struct vpu_format *vpu_fmt;
 	int i, ret;
 
 	dev_dbg(inst->dev->dev,
@@ -779,7 +783,14 @@
 	inst->quantization = f->fmt.pix_mp.quantization;
 	inst->xfer_func = f->fmt.pix_mp.xfer_func;
 
-	wave5_update_pix_fmt(&inst->dst_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height);
+	vpu_fmt = wave5_find_vpu_fmt(inst->dst_fmt.pixelformat, dec_fmt_list[VPU_FMT_TYPE_RAW]);
+	if (!vpu_fmt)
+		return -EINVAL;
+
+	wave5_update_pix_fmt(&inst->dst_fmt, VPU_FMT_TYPE_RAW,
+					     f->fmt.pix_mp.width,
+					     f->fmt.pix_mp.height,
+					     vpu_fmt->v4l2_frmsize);
 
 	return 0;
 }
@@ -853,11 +864,20 @@
 	}
 
 	if (inst->state != VPU_INST_STATE_NONE) {
+		struct vb2_v4l2_buffer *vbuf;
+		struct vpu_src_buffer *vpu_buf;
 		/*
 		 * Temporarily release the state_spinlock so that subsequent
 		 * calls do not block on a mutex while inside this spinlock.
 		 */
 		spin_unlock_irqrestore(&inst->state_spinlock, flags);
+		vbuf = v4l2_m2m_last_src_buf(m2m_ctx);
+		if (vbuf) {
+			vpu_buf = wave5_to_vpu_src_buf(vbuf);
+			if (!vpu_buf->consumed)
+				wave5_vpu_dec_feed_remaining(inst);
+		}
+
 		ret = wave5_vpu_dec_set_eos_on_firmware(inst);
 		if (ret)
 			return ret;
@@ -1002,6 +1022,7 @@
 	struct vpu_instance *inst = vb2_get_drv_priv(q);
 	struct v4l2_pix_format_mplane inst_format =
 		(q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? inst->src_fmt : inst->dst_fmt;
+	unsigned int i;
 
 	dev_dbg(inst->dev->dev, "%s: num_buffers: %u | num_planes: %u | type: %u\n", __func__,
 		*num_buffers, *num_planes, q->type);
@@ -1012,34 +1033,27 @@
 		sizes[0] = inst_format.plane_fmt[0].sizeimage;
 		dev_dbg(inst->dev->dev, "%s: size[0]: %u\n", __func__, sizes[0]);
 	} else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		inst->cap_io_mode = q->memory; // need to obtain memory type
 		if (*num_buffers < inst->fbc_buf_count)
 			*num_buffers = inst->fbc_buf_count;
 
-		if (*num_planes == 1) {
-			if (inst->output_format == FORMAT_422)
-				sizes[0] = inst_format.width * inst_format.height * 2;
-			else
-				sizes[0] = inst_format.width * inst_format.height * 3 / 2;
-			dev_dbg(inst->dev->dev, "%s: size[0]: %u\n", __func__, sizes[0]);
-		} else if (*num_planes == 2) {
-			sizes[0] = inst_format.width * inst_format.height;
-			if (inst->output_format == FORMAT_422)
-				sizes[1] = inst_format.width * inst_format.height;
-			else
-				sizes[1] = inst_format.width * inst_format.height / 2;
-			dev_dbg(inst->dev->dev, "%s: size[0]: %u | size[1]: %u\n",
-				__func__, sizes[0], sizes[1]);
-		} else if (*num_planes == 3) {
-			sizes[0] = inst_format.width * inst_format.height;
-			if (inst->output_format == FORMAT_422) {
-				sizes[1] = inst_format.width * inst_format.height / 2;
-				sizes[2] = inst_format.width * inst_format.height / 2;
-			} else {
-				sizes[1] = inst_format.width * inst_format.height / 4;
-				sizes[2] = inst_format.width * inst_format.height / 4;
-			}
-			dev_dbg(inst->dev->dev, "%s: size[0]: %u | size[1]: %u | size[2]: %u\n",
-				__func__, sizes[0], sizes[1], sizes[2]);
+		inst->dst_buf_count = *num_buffers;
+
+		inst->map_index = kzalloc((*num_buffers * sizeof(unsigned int)), GFP_KERNEL);
+		if (!(inst->map_index)) {
+			dev_dbg(inst->dev->dev, "%s: map index alloc fail\n", __func__);
+			return -ENOMEM;
+		}
+
+		inst->mapped_dma_addr = kzalloc((*num_buffers * sizeof(dma_addr_t)), GFP_KERNEL);
+		if (!(inst->map_index)) {
+			dev_dbg(inst->dev->dev, "%s: mapped addr alloc fail\n", __func__);
+			return -ENOMEM;
+		}
+
+		for (i = 0; i < *num_planes; i++) {
+			sizes[i] = inst_format.plane_fmt[i].sizeimage;
+			dev_dbg(inst->dev->dev, "%s: size[%u]: %u\n", __func__, i, sizes[i]);
 		}
 	}
 
@@ -1052,7 +1066,7 @@
 	int non_linear_num;
 	int fb_stride = 0, fb_height = 0;
 	int luma_size, chroma_size;
-	int ret, i;
+	int ret, i, buffers_ready;
 	struct v4l2_m2m_buffer *buf, *n;
 	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
 	u32 bitdepth = inst->codec_info->dec_info.initial_info.luma_bitdepth;
@@ -1072,7 +1086,16 @@
 		return -EINVAL;
 	}
 
-	linear_num = v4l2_m2m_num_dst_bufs_ready(m2m_ctx);
+	buffers_ready = v4l2_m2m_num_dst_bufs_ready(m2m_ctx);
+
+	if (inst->cap_io_mode == VB2_MEMORY_DMABUF) {
+		if (buffers_ready == (inst->fbc_buf_count + DEC_BUF_OFFSET))
+			linear_num = buffers_ready;
+		else
+			linear_num = inst->dst_buf_count;
+	} else
+		linear_num = buffers_ready;
+
 	non_linear_num = inst->fbc_buf_count;
 
 	for (i = 0; i < non_linear_num; i++) {
@@ -1126,6 +1149,10 @@
 		u32 fb_stride = inst->dst_fmt.width;
 		u32 luma_size = fb_stride * inst->dst_fmt.height;
 		u32 chroma_size;
+		dma_addr_t addr;
+
+		addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+		inst->mapped_dma_addr[vb->index] = addr;
 
 		if (inst->output_format == FORMAT_422)
 			chroma_size = fb_stride * inst->dst_fmt.height / 2;
@@ -1174,25 +1201,36 @@
 	 * Mark all frame buffers as out of display, to avoid using them before
 	 * the application have them queued.
 	 */
-	for (i = 0; i < v4l2_m2m_num_dst_bufs_ready(m2m_ctx); i++) {
-		ret = wave5_vpu_dec_set_disp_flag(inst, i);
-		if (ret) {
-			dev_dbg(inst->dev->dev,
-				"%s: Setting display flag of buf index: %u, fail: %d\n",
-				__func__, i, ret);
+	if (inst->cap_io_mode != VB2_MEMORY_DMABUF) {
+		for (i = 0; i < v4l2_m2m_num_dst_bufs_ready(m2m_ctx); i++) {
+			ret = wave5_vpu_dec_set_disp_flag(inst, i);
+			if (ret) {
+				dev_dbg(inst->dev->dev,
+					"%s: Setting display flag of buf index: %u, fail: %d\n",
+					__func__, i, ret);
+			}
 		}
-	}
 
-	v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) {
-		struct vb2_v4l2_buffer *vbuf = &buf->vb;
+		v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) {
+			struct vb2_v4l2_buffer *vbuf = &buf->vb;
 
-		ret = wave5_vpu_dec_clr_disp_flag(inst, vbuf->vb2_buf.index);
-		if (ret)
-			dev_dbg(inst->dev->dev,
-				"%s: Clearing display flag of buf index: %u, fail: %d\n",
-				__func__, i, ret);
+			ret = wave5_vpu_dec_clr_disp_flag(inst, vbuf->vb2_buf.index);
+			if (ret)
+				dev_dbg(inst->dev->dev,
+					"%s: Clearing display flag of buf index: %u, fail: %d\n",
+					__func__, i, ret);
+		}
+	} else {
+		for (i = (linear_num - DEC_BUF_OFFSET); i < linear_num; i++) {
+			ret = wave5_vpu_dec_set_disp_flag(inst, i);
+			if (ret)
+				dev_dbg(inst->dev->dev,
+					"%s: Setting display flag of buf index: %u, fail: %d\n",
+					__func__, i, ret);
+		}
 	}
 
+
 	return 0;
 }
 
@@ -1226,8 +1264,8 @@
 static int fill_ringbuffer(struct vpu_instance *inst)
 {
 	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
-	struct v4l2_m2m_buffer *buf, *n;
-	int ret;
+	struct vpu_src_buffer *vpu_buf;
+	int ret = 0;
 
 	if (m2m_ctx->last_src_buf)  {
 		struct vpu_src_buffer *vpu_buf = wave5_to_vpu_src_buf(m2m_ctx->last_src_buf);
@@ -1238,9 +1276,8 @@
 		}
 	}
 
-	v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) {
-		struct vb2_v4l2_buffer *vbuf = &buf->vb;
-		struct vpu_src_buffer *vpu_buf = wave5_to_vpu_src_buf(vbuf);
+	list_for_each_entry(vpu_buf, &inst->avail_src_bufs, list) {
+		struct vb2_v4l2_buffer *vbuf = &vpu_buf->v4l2_m2m_buf.vb;
 		struct vpu_buf *ring_buffer = &inst->bitstream_vbuf;
 		size_t src_size = vb2_get_plane_payload(&vbuf->vb2_buf, 0);
 		void *src_buf = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
@@ -1300,9 +1337,13 @@
 			dev_dbg(inst->dev->dev, "last src buffer written to the ring buffer\n");
 			break;
 		}
+
+		inst->queuing_num++;
+		list_del_init(&vpu_buf->list);
+		break;
 	}
 
-	return 0;
+	return ret;
 }
 
 static void wave5_vpu_dec_buf_queue_src(struct vb2_buffer *vb)
@@ -1316,30 +1357,84 @@
 	vbuf->sequence = inst->queued_src_buf_num++;
 
 	v4l2_m2m_buf_queue(m2m_ctx, vbuf);
+
+	INIT_LIST_HEAD(&vpu_buf->list);
+	mutex_lock(&inst->feed_lock);
+	list_add_tail(&vpu_buf->list, &inst->avail_src_bufs);
+	mutex_unlock(&inst->feed_lock);
+
 }
 
 static void wave5_vpu_dec_buf_queue_dst(struct vb2_buffer *vb)
 {
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 	struct vpu_instance *inst = vb2_get_drv_priv(vb->vb2_queue);
+	struct vpu_dst_buffer *vpu_buf = wave5_to_vpu_dst_buf(vbuf);
 	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
+	dma_addr_t addr;
+	int i, ret, act_index = -1;
 
-	vbuf->sequence = inst->queued_dst_buf_num++;
+	addr = vb2_dma_contig_plane_dma_addr(vb, 0);
 
 	if (inst->state == VPU_INST_STATE_PIC_RUN) {
-		struct vpu_dst_buffer *vpu_buf = wave5_to_vpu_dst_buf(vbuf);
-		int ret;
-
-		/*
-		 * The buffer is already registered just clear the display flag
-		 * to let the firmware know it can be used.
-		 */
-		vpu_buf->display = false;
-		ret = wave5_vpu_dec_clr_disp_flag(inst, vb->index);
-		if (ret) {
-			dev_dbg(inst->dev->dev,
-				"%s: Clearing the display flag of buffer index: %u, fail: %d\n",
-				__func__, vb->index, ret);
+		if (inst->cap_io_mode == VB2_MEMORY_DMABUF) {
+			mutex_lock(&inst->inst_lock);
+			if (vb->index < (inst->dst_buf_count - DEC_BUF_OFFSET)) {
+				for (i = 0; i < inst->dst_buf_count; i++) {
+					if (inst->mapped_dma_addr[i] == addr) {
+						act_index = i;
+						break;
+					}
+				}
+
+				if (act_index >= 0) {
+					vpu_buf->display = false;
+					ret = wave5_vpu_dec_clr_disp_flag(inst, act_index);
+					if (ret) {
+						dev_dbg(inst->dev->dev,
+							"%s: Clearing the display flag of buffer index: %u, fail: %d\n",
+							__func__, vb->index, ret);
+					}
+					inst->map_index[act_index] = vb->index;
+				} else {
+					pr_err("%s Address not found for index : %d: %lx\n",
+					    __func__, vb->index, (unsigned long) addr);
+					v4l2_m2m_dst_buf_remove_by_idx(
+						inst->v4l2_fh.m2m_ctx,
+						vb->index);
+					v4l2_m2m_buf_done(
+						to_vb2_v4l2_buffer(vb),
+						VB2_BUF_STATE_ERROR);
+					mutex_unlock(&inst->inst_lock);
+					return;
+				}
+			}
+			mutex_unlock(&inst->inst_lock);
+		} else {
+			/*
+			 * The buffer is already registered just clear the display flag
+			 * to let the firmware know it can be used.
+			 */
+			vpu_buf->display = false;
+			ret = wave5_vpu_dec_clr_disp_flag(inst, vb->index);
+			if (ret) {
+				dev_dbg(inst->dev->dev,
+					"%s: Clearing the display flag of buffer index: %u, fail: %d\n",
+					__func__, vb->index, ret);
+			}
+		}
+	} else if (inst->state == VPU_INST_STATE_INIT_SEQ) {
+		if (inst->cap_io_mode == VB2_MEMORY_DMABUF) {
+			if (inst->queued_dst_buf_num < (inst->dst_buf_count - DEC_BUF_OFFSET)) {
+				vpu_buf->display = false;
+				ret = wave5_vpu_dec_clr_disp_flag(inst, vb->index);
+				if (ret) {
+					dev_dbg(inst->dev->dev,
+					"%s: Clearing the display flag of buffer index: %u, fail: %d\n",
+					__func__, vb->index, ret);
+				}
+				inst->map_index[vb->index] = vb->index;
+			}
 		}
 	}
 
@@ -1354,7 +1449,16 @@
 		send_eos_event(inst);
 		v4l2_m2m_last_buffer_done(m2m_ctx, vbuf);
 	} else {
-		v4l2_m2m_buf_queue(m2m_ctx, vbuf);
+		if (inst->cap_io_mode == VB2_MEMORY_DMABUF)
+			if (vb->index < (inst->dst_buf_count - DEC_BUF_OFFSET)) {
+				v4l2_m2m_buf_queue(m2m_ctx, vbuf);
+				vbuf->sequence = inst->queued_dst_buf_num++;
+			} else
+				v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		else {
+			vbuf->sequence = inst->queued_dst_buf_num++;
+			v4l2_m2m_buf_queue(inst->v4l2_fh.m2m_ctx, vbuf);
+		}
 	}
 }
 
@@ -1367,8 +1471,11 @@
 		__func__, vb->type, vb->index, vb2_plane_size(&vbuf->vb2_buf, 0),
 		vb2_plane_size(&vbuf->vb2_buf, 1), vb2_plane_size(&vbuf->vb2_buf, 2));
 
-	if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+	if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		if (inst->empty_queue)
+			inst->empty_queue = false;
 		wave5_vpu_dec_buf_queue_src(vb);
+	}
 	else if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
 		wave5_vpu_dec_buf_queue_dst(vb);
 }
@@ -1398,6 +1505,7 @@
 	int ret = 0;
 
 	dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type);
+	pm_runtime_resume_and_get(inst->dev->dev);
 
 	v4l2_m2m_update_start_streaming_state(m2m_ctx, q);
 
@@ -1423,6 +1531,33 @@
 		ret = switch_state(inst, VPU_INST_STATE_OPEN);
 		if (ret)
 			goto free_bitstream_vbuf;
+
+		ret = fill_ringbuffer(inst);
+		if (ret)
+			dev_err(inst->dev->dev, "Filling ring buffer failed\n");
+
+		ret = initialize_sequence(inst);
+		if (ret) {
+			unsigned long flags;
+
+			spin_lock_irqsave(&inst->state_spinlock, flags);
+			if (wave5_is_draining_or_eos(inst) &&
+			    wave5_last_src_buffer_consumed(inst->v4l2_fh.m2m_ctx)) {
+				struct vb2_queue *dst_vq = v4l2_m2m_get_dst_vq(m2m_ctx);
+
+				switch_state(inst, VPU_INST_STATE_STOP);
+
+				if (vb2_is_streaming(dst_vq))
+					send_eos_event(inst);
+				else
+					handle_dynamic_resolution_change(inst);
+
+				flag_last_buffer_done(inst);
+			}
+			spin_unlock_irqrestore(&inst->state_spinlock, flags);
+		} else {
+			switch_state(inst, VPU_INST_STATE_INIT_SEQ);
+		}
 	} else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		struct dec_initial_info *initial_info =
 			&inst->codec_info->dec_info.initial_info;
@@ -1444,12 +1579,16 @@
 
 	}
 
+	pm_runtime_mark_last_busy(inst->dev->dev);
+	pm_runtime_put_autosuspend(inst->dev->dev);
+
 	return ret;
 
 free_bitstream_vbuf:
 	wave5_vdi_free_dma_memory(inst->dev, &inst->bitstream_vbuf);
 return_buffers:
 	wave5_return_bufs(q, VB2_BUF_STATE_QUEUED);
+	pm_runtime_put_autosuspend(inst->dev->dev);
 	return ret;
 }
 
@@ -1460,6 +1599,7 @@
 	struct vb2_v4l2_buffer *buf;
 	int ret;
 	dma_addr_t new_rd_ptr;
+	struct vpu_src_buffer *vpu_buf, *tmp;
 	struct dec_output_info dec_info;
 	unsigned int i;
 
@@ -1471,6 +1611,12 @@
 				__func__, i, ret);
 	}
 
+	inst->retry = false;
+	inst->queuing_num = 0;
+
+	list_for_each_entry_safe(vpu_buf, tmp, &inst->avail_src_bufs, list)
+		list_del_init(&vpu_buf->list);
+
 	while ((buf = v4l2_m2m_src_buf_remove(m2m_ctx))) {
 		dev_dbg(inst->dev->dev, "%s: (Multiplanar) buf type %4u | index %4u\n",
 			__func__, buf->vb2_buf.type, buf->vb2_buf.index);
@@ -1550,6 +1696,8 @@
 	bool check_cmd = TRUE;
 
 	dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type);
+	pm_runtime_resume_and_get(inst->dev->dev);
+	inst->empty_queue = false;
 
 	while (check_cmd) {
 		struct queue_status_info q_status;
@@ -1557,10 +1705,8 @@
 
 		wave5_vpu_dec_give_command(inst, DEC_GET_QUEUE_STATUS, &q_status);
 
-		if (q_status.report_queue_count == 0)
-			break;
-
-		if (wave5_vpu_wait_interrupt(inst, VPU_DEC_TIMEOUT) < 0)
+		if ((inst->state == VPU_INST_STATE_STOP || q_status.instance_queue_count == 0) &&
+			q_status.report_queue_count == 0)
 			break;
 
 		if (wave5_vpu_dec_get_output_info(inst, &dec_output_info))
@@ -1573,6 +1719,10 @@
 		streamoff_output(q);
 	else
 		streamoff_capture(q);
+
+	pm_runtime_mark_last_busy(inst->dev->dev);
+	pm_runtime_put_autosuspend(inst->dev->dev);
+
 }
 
 static const struct vb2_ops wave5_vpu_dec_vb2_ops = {
@@ -1587,20 +1737,17 @@
 static void wave5_set_default_format(struct v4l2_pix_format_mplane *src_fmt,
 				     struct v4l2_pix_format_mplane *dst_fmt)
 {
-	unsigned int dst_pix_fmt = dec_fmt_list[VPU_FMT_TYPE_RAW][0].v4l2_pix_fmt;
-	const struct v4l2_format_info *dst_fmt_info = v4l2_format_info(dst_pix_fmt);
-
 	src_fmt->pixelformat = dec_fmt_list[VPU_FMT_TYPE_CODEC][0].v4l2_pix_fmt;
-	src_fmt->field = V4L2_FIELD_NONE;
-	src_fmt->flags = 0;
-	src_fmt->num_planes = 1;
-	wave5_update_pix_fmt(src_fmt, 720, 480);
-
-	dst_fmt->pixelformat = dst_pix_fmt;
-	dst_fmt->field = V4L2_FIELD_NONE;
-	dst_fmt->flags = 0;
-	dst_fmt->num_planes = dst_fmt_info->mem_planes;
-	wave5_update_pix_fmt(dst_fmt, 736, 480);
+	wave5_update_pix_fmt(src_fmt, VPU_FMT_TYPE_CODEC,
+				      W5_DEF_DEC_PIC_WIDTH,
+				      W5_DEF_DEC_PIC_HEIGHT,
+				      &dec_hevc_frmsize);
+
+	dst_fmt->pixelformat = dec_fmt_list[VPU_FMT_TYPE_RAW][0].v4l2_pix_fmt;
+	wave5_update_pix_fmt(dst_fmt, VPU_FMT_TYPE_RAW,
+				      W5_DEF_DEC_PIC_WIDTH,
+				      W5_DEF_DEC_PIC_HEIGHT,
+				      &dec_raw_frmsize);
 }
 
 static int wave5_vpu_dec_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
@@ -1616,8 +1763,11 @@
 {
 	struct dec_initial_info initial_info;
 	int ret = 0;
+	inst->time_stamp.head = 0;
+	inst->time_stamp.tail = 0;
 
 	memset(&initial_info, 0, sizeof(struct dec_initial_info));
+	memset(&inst->time_stamp.buf, 0, MAX_TIMESTAMP_CIR_BUF*sizeof(u64));
 
 	ret = wave5_vpu_dec_issue_seq_init(inst);
 	if (ret) {
@@ -1657,13 +1807,25 @@
 	struct queue_status_info q_status;
 	u32 fail_res = 0;
 	int ret = 0;
+	unsigned long flags;
 
 	dev_dbg(inst->dev->dev, "%s: Fill the ring buffer with new bitstream data", __func__);
+	pm_runtime_resume_and_get(inst->dev->dev);
 
-	ret = fill_ringbuffer(inst);
-	if (ret) {
-		dev_warn(inst->dev->dev, "Filling ring buffer failed\n");
-		goto finish_job_and_return;
+	if (!inst->retry) {
+		mutex_lock(&inst->feed_lock);
+		ret = fill_ringbuffer(inst);
+		mutex_unlock(&inst->feed_lock);
+		if (ret < 0) {
+			dev_warn(inst->dev->dev, "Filling ring buffer failed\n");
+			goto finish_job_and_return;
+		} else if (!inst->eos &&
+			   inst->queuing_num == 0 &&
+			   inst->state == VPU_INST_STATE_PIC_RUN) {
+			dev_dbg(inst->dev->dev, "%s: no bitstream for feeding, so skip ", __func__);
+			inst->empty_queue = true;
+			goto finish_job_and_return;
+		}
 	}
 
 	switch (inst->state) {
@@ -1699,7 +1861,9 @@
 		 * we had a chance to switch, which leads to an invalid state
 		 * change.
 		 */
+		spin_lock_irqsave(&inst->state_spinlock, flags);
 		switch_state(inst, VPU_INST_STATE_PIC_RUN);
+		spin_unlock_irqrestore(&inst->state_spinlock, flags);
 
 		/*
 		 * During DRC, the picture decoding remains pending, so just leave the job
@@ -1714,12 +1878,14 @@
 		ret = wave5_prepare_fb(inst);
 		if (ret) {
 			dev_warn(inst->dev->dev, "Framebuffer preparation, fail: %d\n", ret);
+			spin_lock_irqsave(&inst->state_spinlock, flags);
 			switch_state(inst, VPU_INST_STATE_STOP);
+			spin_unlock_irqrestore(&inst->state_spinlock, flags);
 			break;
 		}
 
 		if (q_status.instance_queue_count) {
-			dev_dbg(inst->dev->dev, "%s: leave with active job", __func__);
+			v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
 			return;
 		}
 
@@ -1730,19 +1896,25 @@
 			dev_err(inst->dev->dev,
 				"Frame decoding on m2m context (%p), fail: %d (result: %d)\n",
 				m2m_ctx, ret, fail_res);
-			break;
+			goto finish_job_and_return;
 		}
 		/* Return so that we leave this job active */
-		dev_dbg(inst->dev->dev, "%s: leave with active job", __func__);
-		return;
-	default:
-		WARN(1, "Execution of a job in state %s illegal.\n", state_to_str(inst->state));
+		if (fail_res == WAVE5_SYSERR_QUEUEING_FAIL) {
+			inst->retry = true;
+		} else {
+			inst->retry = false;
+			if (!inst->eos)
+				inst->queuing_num--;
+		}
 		break;
+	default:
+		dev_dbg(inst->dev->dev, "Execution of a job in state %s illegal.\n",
+			state_to_str(inst->state));
 	}
 
 finish_job_and_return:
 	dev_dbg(inst->dev->dev, "%s: leave and finish job", __func__);
-	v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
+	up(&inst->run_sem);
 }
 
 static void wave5_vpu_dec_job_abort(void *priv)
@@ -1793,7 +1965,8 @@
 				"No capture buffer ready to decode!\n");
 			break;
 		} else if (!wave5_is_draining_or_eos(inst) &&
-			   !v4l2_m2m_num_src_bufs_ready(m2m_ctx)) {
+			   (!v4l2_m2m_num_src_bufs_ready(m2m_ctx) ||
+			    inst->empty_queue)) {
 			dev_dbg(inst->dev->dev,
 				"No bitstream data to decode!\n");
 			break;
@@ -1833,6 +2006,9 @@
 	inst->ops = &wave5_vpu_dec_inst_ops;
 
 	spin_lock_init(&inst->state_spinlock);
+	mutex_init(&inst->feed_lock);
+	mutex_init(&inst->inst_lock);
+	INIT_LIST_HEAD(&inst->avail_src_bufs);
 
 	inst->codec_info = kzalloc(sizeof(*inst->codec_info), GFP_KERNEL);
 	if (!inst->codec_info)
@@ -1904,14 +2080,13 @@
 	if (inst->dev->product_code != WAVE515_CODE)
 		wave5_vdi_allocate_sram(inst->dev);
 
+	sema_init(&inst->run_sem, 1);
+	inst->run_thread = kthread_run(run_thread, inst, "run thread");
+
 	ret = mutex_lock_interruptible(&dev->dev_lock);
 	if (ret)
 		goto cleanup_inst;
 
-	if (dev->irq < 0 && !hrtimer_active(&dev->hrtimer) && list_empty(&dev->instances))
-		hrtimer_start(&dev->hrtimer, ns_to_ktime(dev->vpu_poll_interval * NSEC_PER_MSEC),
-			      HRTIMER_MODE_REL_PINNED);
-
 	list_add_tail(&inst->list, &dev->instances);
 
 	mutex_unlock(&dev->dev_lock);
diff -Naur --no-dereference a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c	2025-10-23 09:30:40.285462207 -0400
@@ -5,70 +5,106 @@
  * Copyright (C) 2021-2023 CHIPS&MEDIA INC
  */
 
+#include <linux/pm_runtime.h>
 #include "wave5-helper.h"
 
 #define VPU_ENC_DEV_NAME "C&M Wave5 VPU encoder"
 #define VPU_ENC_DRV_NAME "wave5-enc"
 
+static const struct v4l2_frmsize_stepwise enc_frmsize[FMT_TYPES] = {
+	[VPU_FMT_TYPE_CODEC] = {
+		.min_width = W5_MIN_ENC_PIC_WIDTH,
+		.max_width = W5_MAX_ENC_PIC_WIDTH,
+		.step_width = W5_ENC_CODEC_STEP_WIDTH,
+		.min_height = W5_MIN_ENC_PIC_HEIGHT,
+		.max_height = W5_MAX_ENC_PIC_HEIGHT,
+		.step_height = W5_ENC_CODEC_STEP_HEIGHT,
+	},
+	[VPU_FMT_TYPE_RAW] = {
+		.min_width = W5_MIN_ENC_PIC_WIDTH,
+		.max_width = W5_MAX_ENC_PIC_WIDTH,
+		.step_width = W5_ENC_RAW_STEP_WIDTH,
+		.min_height = W5_MIN_ENC_PIC_HEIGHT,
+		.max_height = W5_MAX_ENC_PIC_HEIGHT,
+		.step_height = W5_ENC_RAW_STEP_HEIGHT,
+	},
+};
+
 static const struct vpu_format enc_fmt_list[FMT_TYPES][MAX_FMTS] = {
 	[VPU_FMT_TYPE_CODEC] = {
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_HEVC,
-			.max_width = W5_MAX_ENC_PIC_WIDTH,
-			.min_width = W5_MIN_ENC_PIC_WIDTH,
-			.max_height = W5_MAX_ENC_PIC_HEIGHT,
-			.min_height = W5_MIN_ENC_PIC_HEIGHT,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_CODEC],
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_H264,
-			.max_width = W5_MAX_ENC_PIC_WIDTH,
-			.min_width = W5_MIN_ENC_PIC_WIDTH,
-			.max_height = W5_MAX_ENC_PIC_HEIGHT,
-			.min_height = W5_MIN_ENC_PIC_HEIGHT,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_CODEC],
 		},
 	},
 	[VPU_FMT_TYPE_RAW] = {
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV420,
-			.max_width = W5_MAX_ENC_PIC_WIDTH,
-			.min_width = W5_MIN_ENC_PIC_WIDTH,
-			.max_height = W5_MAX_ENC_PIC_HEIGHT,
-			.min_height = W5_MIN_ENC_PIC_HEIGHT,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_NV12,
-			.max_width = W5_MAX_ENC_PIC_WIDTH,
-			.min_width = W5_MIN_ENC_PIC_WIDTH,
-			.max_height = W5_MAX_ENC_PIC_HEIGHT,
-			.min_height = W5_MIN_ENC_PIC_HEIGHT,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_NV21,
-			.max_width = W5_MAX_ENC_PIC_WIDTH,
-			.min_width = W5_MIN_ENC_PIC_WIDTH,
-			.max_height = W5_MAX_ENC_PIC_HEIGHT,
-			.min_height = W5_MIN_ENC_PIC_HEIGHT,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV420M,
-			.max_width = W5_MAX_ENC_PIC_WIDTH,
-			.min_width = W5_MIN_ENC_PIC_WIDTH,
-			.max_height = W5_MAX_ENC_PIC_HEIGHT,
-			.min_height = W5_MIN_ENC_PIC_HEIGHT,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_NV12M,
-			.max_width = W5_MAX_ENC_PIC_WIDTH,
-			.min_width = W5_MIN_ENC_PIC_WIDTH,
-			.max_height = W5_MAX_ENC_PIC_HEIGHT,
-			.min_height = W5_MIN_ENC_PIC_HEIGHT,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
 		},
 		{
 			.v4l2_pix_fmt = V4L2_PIX_FMT_NV21M,
-			.max_width = W5_MAX_ENC_PIC_WIDTH,
-			.min_width = W5_MIN_ENC_PIC_WIDTH,
-			.max_height = W5_MAX_ENC_PIC_HEIGHT,
-			.min_height = W5_MIN_ENC_PIC_HEIGHT,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
+		},
+		{
+			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV422P,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
+		},
+		{
+			.v4l2_pix_fmt = V4L2_PIX_FMT_NV16,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
+		},
+		{
+			.v4l2_pix_fmt = V4L2_PIX_FMT_NV61,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
+		},
+		{
+			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV422M,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
+		},
+		{
+			.v4l2_pix_fmt = V4L2_PIX_FMT_NV16M,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
+		},
+		{
+			.v4l2_pix_fmt = V4L2_PIX_FMT_NV61M,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
+		},
+		{
+			.v4l2_pix_fmt = V4L2_PIX_FMT_YUYV,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
+		},
+		{
+			.v4l2_pix_fmt = V4L2_PIX_FMT_YVYU,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
+		},
+		{
+			.v4l2_pix_fmt = V4L2_PIX_FMT_UYVY,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
+		},
+		{
+			.v4l2_pix_fmt = V4L2_PIX_FMT_VYUY,
+			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
 		},
 	}
 };
@@ -105,46 +141,6 @@
 	return -EINVAL;
 }
 
-static void wave5_update_pix_fmt(struct v4l2_pix_format_mplane *pix_mp, unsigned int width,
-				 unsigned int height)
-{
-	switch (pix_mp->pixelformat) {
-	case V4L2_PIX_FMT_YUV420:
-	case V4L2_PIX_FMT_NV12:
-	case V4L2_PIX_FMT_NV21:
-		pix_mp->width = width;
-		pix_mp->height = height;
-		pix_mp->plane_fmt[0].bytesperline = round_up(width, 32);
-		pix_mp->plane_fmt[0].sizeimage = round_up(width, 32) * height * 3 / 2;
-		break;
-	case V4L2_PIX_FMT_YUV420M:
-		pix_mp->width = width;
-		pix_mp->height = height;
-		pix_mp->plane_fmt[0].bytesperline = round_up(width, 32);
-		pix_mp->plane_fmt[0].sizeimage = round_up(width, 32) * height;
-		pix_mp->plane_fmt[1].bytesperline = round_up(width, 32) / 2;
-		pix_mp->plane_fmt[1].sizeimage = round_up(width, 32) * height / 4;
-		pix_mp->plane_fmt[2].bytesperline = round_up(width, 32) / 2;
-		pix_mp->plane_fmt[2].sizeimage = round_up(width, 32) * height / 4;
-		break;
-	case V4L2_PIX_FMT_NV12M:
-	case V4L2_PIX_FMT_NV21M:
-		pix_mp->width = width;
-		pix_mp->height = height;
-		pix_mp->plane_fmt[0].bytesperline = round_up(width, 32);
-		pix_mp->plane_fmt[0].sizeimage = round_up(width, 32) * height;
-		pix_mp->plane_fmt[1].bytesperline = round_up(width, 32);
-		pix_mp->plane_fmt[1].sizeimage = round_up(width, 32) * height / 2;
-		break;
-	default:
-		pix_mp->width = width;
-		pix_mp->height = height;
-		pix_mp->plane_fmt[0].bytesperline = 0;
-		pix_mp->plane_fmt[0].sizeimage = width * height / 8 * 3;
-		break;
-	}
-}
-
 static int start_encode(struct vpu_instance *inst, u32 *fail_res)
 {
 	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
@@ -153,13 +149,50 @@
 	struct vb2_v4l2_buffer *dst_buf;
 	struct frame_buffer frame_buf;
 	struct enc_param pic_param;
-	u32 stride = ALIGN(inst->dst_fmt.width, 32);
-	u32 luma_size = (stride * inst->dst_fmt.height);
-	u32 chroma_size = ((stride / 2) * (inst->dst_fmt.height / 2));
+	const struct v4l2_format_info *info;
+	u32 stride = inst->src_fmt.plane_fmt[0].bytesperline;
+	u32 luma_size = 0;
+	u32 chroma_size = 0;
 
 	memset(&pic_param, 0, sizeof(struct enc_param));
 	memset(&frame_buf, 0, sizeof(struct frame_buffer));
 
+	if (inst->change_param_flags) {
+		struct enc_output_info enc_output_info;
+
+		wave5_vpu_enc_change_param(inst, NULL);
+		inst->change_param_flags = 0;
+		if (wave5_vpu_wait_interrupt(inst, VPU_ENC_TIMEOUT) < 0) {
+			dev_dbg(inst->dev->dev, "%s: wave5_vpu_wait_interrupt failed\n", __func__);
+			return -EINVAL;
+		}
+
+		ret = wave5_vpu_enc_get_output_info(inst, &enc_output_info);
+		if (ret) {
+			dev_dbg(inst->dev->dev,
+				"%s: vpu_enc_get_output_info fail: %d  reason: %u | info: %u\n",
+				__func__, ret, enc_output_info.error_reason, enc_output_info.warn_info);
+			return -EINVAL;
+		}
+
+		if (enc_output_info.recon_frame_index == RECON_IDX_FLAG_CHANGE_PARAM)
+			dev_dbg(inst->dev->dev, "%s: the change param done\n", __func__);
+		else
+			return -EINVAL;
+	}
+
+	info = v4l2_format_info(inst->src_fmt.pixelformat);
+	if (!info)
+		return -EINVAL;
+
+	if (info->mem_planes == 1) {
+		luma_size = stride * inst->dst_fmt.height;
+		chroma_size = luma_size / (info->hdiv * info->vdiv);
+	} else {
+		luma_size = inst->src_fmt.plane_fmt[0].sizeimage;
+		chroma_size = inst->src_fmt.plane_fmt[1].sizeimage;
+	}
+
 	dst_buf = v4l2_m2m_next_dst_buf(m2m_ctx);
 	if (!dst_buf) {
 		dev_dbg(inst->dev->dev, "%s: No destination buffer found\n", __func__);
@@ -205,6 +238,11 @@
 	pic_param.source_frame = &frame_buf;
 	pic_param.code_option.implicit_header_encode = 1;
 	pic_param.code_option.encode_aud = inst->encode_aud;
+	if (inst->enc_param.forced_idr_pictype_enable) {
+		pic_param.force_pic_type = 3;  /* IDR Frame */
+		pic_param.force_pictype_enable = 1;
+		inst->enc_param.forced_idr_pictype_enable = 0;
+	}
 	ret = wave5_vpu_enc_start_one_frame(inst, &pic_param, fail_res);
 	if (ret) {
 		if (*fail_res == WAVE5_SYSERR_QUEUEING_FAIL)
@@ -317,11 +355,16 @@
 		dst_buf->vb2_buf.timestamp = inst->timestamp;
 		dst_buf->field = V4L2_FIELD_NONE;
 		if (enc_output_info.pic_type == PIC_TYPE_I) {
-			if (enc_output_info.enc_vcl_nut == 19 ||
-			    enc_output_info.enc_vcl_nut == 20)
+			if (inst->std == W_HEVC_ENC &&
+				(enc_output_info.enc_vcl_nut == 19 ||
+				enc_output_info.enc_vcl_nut == 20)) {
 				dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
-			else
+			} else if (inst->std == W_AVC_ENC &&
+				enc_output_info.enc_vcl_nut == 5) {
+				dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
+			} else {
 				dst_buf->flags |= V4L2_BUF_FLAG_PFRAME;
+			}
 		} else if (enc_output_info.pic_type == PIC_TYPE_P) {
 			dst_buf->flags |= V4L2_BUF_FLAG_PFRAME;
 		} else if (enc_output_info.pic_type == PIC_TYPE_B) {
@@ -359,13 +402,8 @@
 			return -EINVAL;
 	}
 
-	fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
-	fsize->stepwise.min_width = vpu_fmt->min_width;
-	fsize->stepwise.max_width = vpu_fmt->max_width;
-	fsize->stepwise.step_width = 1;
-	fsize->stepwise.min_height = vpu_fmt->min_height;
-	fsize->stepwise.max_height = vpu_fmt->max_height;
-	fsize->stepwise.step_height = 1;
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise = enc_frmsize[VPU_FMT_TYPE_CODEC];
 
 	return 0;
 }
@@ -390,7 +428,9 @@
 static int wave5_vpu_enc_try_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
 {
 	struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+	const struct v4l2_frmsize_stepwise *frmsize;
 	const struct vpu_format *vpu_fmt;
+	int width, height;
 
 	dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n",
 		__func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height,
@@ -398,20 +438,21 @@
 
 	vpu_fmt = wave5_find_vpu_fmt(f->fmt.pix_mp.pixelformat, enc_fmt_list[VPU_FMT_TYPE_CODEC]);
 	if (!vpu_fmt) {
+		width = inst->dst_fmt.width;
+		height = inst->dst_fmt.height;
 		f->fmt.pix_mp.pixelformat = inst->dst_fmt.pixelformat;
-		f->fmt.pix_mp.num_planes = inst->dst_fmt.num_planes;
-		wave5_update_pix_fmt(&f->fmt.pix_mp, inst->dst_fmt.width, inst->dst_fmt.height);
+		frmsize = &enc_frmsize[VPU_FMT_TYPE_CODEC];
 	} else {
-		int width = clamp(f->fmt.pix_mp.width, vpu_fmt->min_width, vpu_fmt->max_width);
-		int height = clamp(f->fmt.pix_mp.height, vpu_fmt->min_height, vpu_fmt->max_height);
-
+		width = f->fmt.pix_mp.width;
+		height = f->fmt.pix_mp.height;
 		f->fmt.pix_mp.pixelformat = vpu_fmt->v4l2_pix_fmt;
-		f->fmt.pix_mp.num_planes = 1;
-		wave5_update_pix_fmt(&f->fmt.pix_mp, width, height);
+		frmsize = vpu_fmt->v4l2_frmsize;
 	}
 
-	f->fmt.pix_mp.flags = 0;
-	f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+	wave5_update_pix_fmt(&f->fmt.pix_mp, VPU_FMT_TYPE_CODEC,
+					     width,
+					     height,
+					     frmsize);
 	f->fmt.pix_mp.colorspace = inst->colorspace;
 	f->fmt.pix_mp.ycbcr_enc = inst->ycbcr_enc;
 	f->fmt.pix_mp.quantization = inst->quantization;
@@ -498,7 +539,9 @@
 static int wave5_vpu_enc_try_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
 {
 	struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+	const struct v4l2_frmsize_stepwise *frmsize;
 	const struct vpu_format *vpu_fmt;
+	int width, height;
 
 	dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n",
 		__func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height,
@@ -506,21 +549,21 @@
 
 	vpu_fmt = wave5_find_vpu_fmt(f->fmt.pix_mp.pixelformat, enc_fmt_list[VPU_FMT_TYPE_RAW]);
 	if (!vpu_fmt) {
+		width = inst->src_fmt.width;
+		height = inst->src_fmt.height;
 		f->fmt.pix_mp.pixelformat = inst->src_fmt.pixelformat;
-		f->fmt.pix_mp.num_planes = inst->src_fmt.num_planes;
-		wave5_update_pix_fmt(&f->fmt.pix_mp, inst->src_fmt.width, inst->src_fmt.height);
+		frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW];
 	} else {
-		int width = clamp(f->fmt.pix_mp.width, vpu_fmt->min_width, vpu_fmt->max_width);
-		int height = clamp(f->fmt.pix_mp.height, vpu_fmt->min_height, vpu_fmt->max_height);
-		const struct v4l2_format_info *info = v4l2_format_info(vpu_fmt->v4l2_pix_fmt);
-
+		width = f->fmt.pix_mp.width;
+		height = f->fmt.pix_mp.height;
 		f->fmt.pix_mp.pixelformat = vpu_fmt->v4l2_pix_fmt;
-		f->fmt.pix_mp.num_planes = info->mem_planes;
-		wave5_update_pix_fmt(&f->fmt.pix_mp, width, height);
+		frmsize = vpu_fmt->v4l2_frmsize;
 	}
 
-	f->fmt.pix_mp.flags = 0;
-	f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+	wave5_update_pix_fmt(&f->fmt.pix_mp, VPU_FMT_TYPE_RAW,
+					     width,
+					     height,
+					     frmsize);
 
 	return 0;
 }
@@ -528,6 +571,8 @@
 static int wave5_vpu_enc_s_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
 {
 	struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+	const struct vpu_format *vpu_fmt;
+	const struct v4l2_format_info *info;
 	int i, ret;
 
 	dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n",
@@ -549,16 +594,20 @@
 		inst->src_fmt.plane_fmt[i].sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage;
 	}
 
-	if (inst->src_fmt.pixelformat == V4L2_PIX_FMT_NV12 ||
-	    inst->src_fmt.pixelformat == V4L2_PIX_FMT_NV12M) {
-		inst->cbcr_interleave = true;
-		inst->nv21 = false;
-	} else if (inst->src_fmt.pixelformat == V4L2_PIX_FMT_NV21 ||
-		   inst->src_fmt.pixelformat == V4L2_PIX_FMT_NV21M) {
-		inst->cbcr_interleave = true;
+	info = v4l2_format_info(inst->src_fmt.pixelformat);
+	if (!info)
+		return -EINVAL;
+
+	inst->cbcr_interleave = (info->comp_planes == 2) ? true : false;
+
+	switch (inst->src_fmt.pixelformat) {
+	case V4L2_PIX_FMT_NV21:
+	case V4L2_PIX_FMT_NV21M:
+	case V4L2_PIX_FMT_NV61:
+	case V4L2_PIX_FMT_NV61M:
 		inst->nv21 = true;
-	} else {
-		inst->cbcr_interleave = false;
+		break;
+	default:
 		inst->nv21 = false;
 	}
 
@@ -567,7 +616,16 @@
 	inst->quantization = f->fmt.pix_mp.quantization;
 	inst->xfer_func = f->fmt.pix_mp.xfer_func;
 
-	wave5_update_pix_fmt(&inst->dst_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height);
+	vpu_fmt = wave5_find_vpu_fmt(inst->dst_fmt.pixelformat, enc_fmt_list[VPU_FMT_TYPE_CODEC]);
+	if (!vpu_fmt)
+		return -EINVAL;
+
+	wave5_update_pix_fmt(&inst->dst_fmt, VPU_FMT_TYPE_CODEC,
+					     f->fmt.pix_mp.width,
+					     f->fmt.pix_mp.height,
+					     vpu_fmt->v4l2_frmsize);
+	inst->conf_win.width = inst->dst_fmt.width;
+	inst->conf_win.height = inst->dst_fmt.height;
 
 	return 0;
 }
@@ -583,12 +641,17 @@
 	switch (s->target) {
 	case V4L2_SEL_TGT_CROP_DEFAULT:
 	case V4L2_SEL_TGT_CROP_BOUNDS:
-	case V4L2_SEL_TGT_CROP:
 		s->r.left = 0;
 		s->r.top = 0;
 		s->r.width = inst->dst_fmt.width;
 		s->r.height = inst->dst_fmt.height;
 		break;
+	case V4L2_SEL_TGT_CROP:
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = inst->conf_win.width;
+		s->r.height = inst->conf_win.height;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -611,8 +674,10 @@
 
 	s->r.left = 0;
 	s->r.top = 0;
-	s->r.width = inst->src_fmt.width;
-	s->r.height = inst->src_fmt.height;
+	s->r.width = min(s->r.width, inst->dst_fmt.width);
+	s->r.height = min(s->r.height, inst->dst_fmt.height);
+
+	inst->conf_win = s->r;
 
 	return 0;
 }
@@ -767,8 +832,13 @@
 		}
 		break;
 	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		if (inst->state == VPU_INST_STATE_PIC_RUN)
+			inst->change_param_flags |= W5_ENC_CHANGE_PARAM_RC_TARGET_RATE;
 		inst->bit_rate = ctrl->val;
 		break;
+	case V4L2_CID_MPEG_VIDEO_BACKGROUND_DETECTION:
+		inst->enc_param.bg_detection = ctrl->val;
+		break;
 	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
 		inst->enc_param.avc_idr_period = ctrl->val;
 		break;
@@ -925,6 +995,8 @@
 		case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
 			inst->enc_param.profile = H264_PROFILE_BP;
 			inst->bit_depth = 8;
+			if (ctrl->val == V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)
+				inst->enc_param.constraint_set1_flag = 1;
 			break;
 		case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
 			inst->enc_param.profile = H264_PROFILE_MP;
@@ -1061,6 +1133,12 @@
 	case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
 		inst->enc_param.entropy_coding_mode = ctrl->val;
 		break;
+	case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR:
+		inst->enc_param.forced_idr_header_enable = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
+		inst->enc_param.forced_idr_pictype_enable = 1;
+		break;
 	case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
 		break;
 	default:
@@ -1125,13 +1203,40 @@
 	v4l2_m2m_buf_queue(m2m_ctx, vbuf);
 }
 
-static void wave5_set_enc_openparam(struct enc_open_param *open_param,
+static int wave5_set_enc_openparam(struct enc_open_param *open_param,
 				    struct vpu_instance *inst)
 {
 	struct enc_wave_param input = inst->enc_param;
+	const struct v4l2_format_info *info;
 	u32 num_ctu_row = ALIGN(inst->dst_fmt.height, 64) / 64;
 	u32 num_mb_row = ALIGN(inst->dst_fmt.height, 16) / 16;
 
+	info = v4l2_format_info(inst->src_fmt.pixelformat);
+	if (!info)
+		return -EINVAL;
+
+	if (info->hdiv == 2 && info->vdiv == 1)
+		open_param->src_format = FORMAT_422;
+	else
+		open_param->src_format = FORMAT_420;
+
+	switch (info->format) {
+	case V4L2_PIX_FMT_YUYV:
+		open_param->packed_format = PACKED_YUYV;
+		break;
+	case V4L2_PIX_FMT_YVYU:
+		open_param->packed_format = PACKED_YVYU;
+		break;
+	case V4L2_PIX_FMT_UYVY:
+		open_param->packed_format = PACKED_UYVY;
+		break;
+	case V4L2_PIX_FMT_VYUY:
+		open_param->packed_format = PACKED_VYUY;
+		break;
+	default:
+		break;
+	}
+
 	open_param->wave_param.gop_preset_idx = PRESET_IDX_IPP_SINGLE;
 	open_param->wave_param.hvs_qp_scale = 2;
 	open_param->wave_param.hvs_max_delta_qp = 10;
@@ -1147,8 +1252,8 @@
 	open_param->wave_param.lambda_scaling_enable = 1;
 
 	open_param->line_buf_int_en = true;
-	open_param->pic_width = inst->dst_fmt.width;
-	open_param->pic_height = inst->dst_fmt.height;
+	open_param->pic_width = inst->conf_win.width;
+	open_param->pic_height = inst->conf_win.height;
 	open_param->frame_rate_info = inst->frame_rate;
 	open_param->rc_enable = inst->rc_enable;
 	if (inst->rc_enable) {
@@ -1181,14 +1286,17 @@
 	open_param->wave_param.beta_offset_div2 = input.beta_offset_div2;
 	open_param->wave_param.decoding_refresh_type = input.decoding_refresh_type;
 	open_param->wave_param.intra_period = input.intra_period;
+	open_param->wave_param.bg_detection = input.bg_detection;
 	if (inst->std == W_HEVC_ENC) {
 		if (input.intra_period == 0) {
 			open_param->wave_param.decoding_refresh_type = DEC_REFRESH_TYPE_IDR;
 			open_param->wave_param.intra_period = input.avc_idr_period;
 		}
-	} else {
+	} else if (inst->std == W_AVC_ENC) {
+		open_param->wave_param.constraint_set1_flag = input.constraint_set1_flag;
 		open_param->wave_param.avc_idr_period = input.avc_idr_period;
 	}
+
 	open_param->wave_param.entropy_coding_mode = input.entropy_coding_mode;
 	open_param->wave_param.lossless_enable = input.lossless_enable;
 	open_param->wave_param.const_intra_pred_flag = input.const_intra_pred_flag;
@@ -1219,6 +1327,9 @@
 		else
 			open_param->wave_param.intra_refresh_arg = num_ctu_row;
 	}
+	open_param->wave_param.forced_idr_header_enable = input.forced_idr_header_enable;
+
+	return 0;
 }
 
 static int initialize_sequence(struct vpu_instance *inst)
@@ -1306,6 +1417,7 @@
 	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
 	int ret = 0;
 
+	pm_runtime_resume_and_get(inst->dev->dev);
 	v4l2_m2m_update_start_streaming_state(m2m_ctx, q);
 
 	if (inst->state == VPU_INST_STATE_NONE && q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
@@ -1313,7 +1425,12 @@
 
 		memset(&open_param, 0, sizeof(struct enc_open_param));
 
-		wave5_set_enc_openparam(&open_param, inst);
+		ret = wave5_set_enc_openparam(&open_param, inst);
+		if (ret) {
+			dev_dbg(inst->dev->dev, "%s: wave5_set_enc_openparam, fail: %d\n",
+				__func__, ret);
+			goto return_buffers;
+		}
 
 		ret = wave5_vpu_enc_open(inst, &open_param);
 		if (ret) {
@@ -1360,9 +1477,13 @@
 	if (ret)
 		goto return_buffers;
 
+	pm_runtime_mark_last_busy(inst->dev->dev);
+	pm_runtime_put_autosuspend(inst->dev->dev);
 	return 0;
 return_buffers:
 	wave5_return_bufs(q, VB2_BUF_STATE_QUEUED);
+	pm_runtime_mark_last_busy(inst->dev->dev);
+	pm_runtime_put_autosuspend(inst->dev->dev);
 	return ret;
 }
 
@@ -1404,6 +1525,7 @@
 	 */
 
 	dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type);
+	pm_runtime_resume_and_get(inst->dev->dev);
 
 	if (wave5_vpu_both_queues_are_streaming(inst))
 		switch_state(inst, VPU_INST_STATE_STOP);
@@ -1428,6 +1550,9 @@
 		streamoff_output(inst, q);
 	else
 		streamoff_capture(inst, q);
+
+	pm_runtime_mark_last_busy(inst->dev->dev);
+	pm_runtime_put_autosuspend(inst->dev->dev);
 }
 
 static const struct vb2_ops wave5_vpu_enc_vb2_ops = {
@@ -1442,20 +1567,17 @@
 static void wave5_set_default_format(struct v4l2_pix_format_mplane *src_fmt,
 				     struct v4l2_pix_format_mplane *dst_fmt)
 {
-	unsigned int src_pix_fmt = enc_fmt_list[VPU_FMT_TYPE_RAW][0].v4l2_pix_fmt;
-	const struct v4l2_format_info *src_fmt_info = v4l2_format_info(src_pix_fmt);
-
-	src_fmt->pixelformat = src_pix_fmt;
-	src_fmt->field = V4L2_FIELD_NONE;
-	src_fmt->flags = 0;
-	src_fmt->num_planes = src_fmt_info->mem_planes;
-	wave5_update_pix_fmt(src_fmt, 416, 240);
+	src_fmt->pixelformat = enc_fmt_list[VPU_FMT_TYPE_RAW][0].v4l2_pix_fmt;
+	wave5_update_pix_fmt(src_fmt, VPU_FMT_TYPE_RAW,
+				      W5_DEF_ENC_PIC_WIDTH,
+				      W5_DEF_ENC_PIC_HEIGHT,
+				      &enc_frmsize[VPU_FMT_TYPE_RAW]);
 
 	dst_fmt->pixelformat = enc_fmt_list[VPU_FMT_TYPE_CODEC][0].v4l2_pix_fmt;
-	dst_fmt->field = V4L2_FIELD_NONE;
-	dst_fmt->flags = 0;
-	dst_fmt->num_planes = 1;
-	wave5_update_pix_fmt(dst_fmt, 416, 240);
+	wave5_update_pix_fmt(dst_fmt, VPU_FMT_TYPE_CODEC,
+				      W5_DEF_ENC_PIC_WIDTH,
+				      W5_DEF_ENC_PIC_HEIGHT,
+				      &enc_frmsize[VPU_FMT_TYPE_CODEC]);
 }
 
 static int wave5_vpu_enc_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
@@ -1474,6 +1596,7 @@
 	u32 fail_res = 0;
 	int ret = 0;
 
+	pm_runtime_resume_and_get(inst->dev->dev);
 	switch (inst->state) {
 	case VPU_INST_STATE_PIC_RUN:
 		ret = start_encode(inst, &fail_res);
@@ -1487,6 +1610,8 @@
 			break;
 		}
 		dev_dbg(inst->dev->dev, "%s: leave with active job", __func__);
+		pm_runtime_mark_last_busy(inst->dev->dev);
+		pm_runtime_put_autosuspend(inst->dev->dev);
 		return;
 	default:
 		WARN(1, "Execution of a job in state %s is invalid.\n",
@@ -1494,6 +1619,8 @@
 		break;
 	}
 	dev_dbg(inst->dev->dev, "%s: leave and finish job", __func__);
+	pm_runtime_mark_last_busy(inst->dev->dev);
+	pm_runtime_put_autosuspend(inst->dev->dev);
 	v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
 }
 
@@ -1647,7 +1774,7 @@
 			  -6, 6, 1, 0);
 	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
 			  V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM,
-			  0, 1, 1, 1);
+			  0, 1, 1, 0);
 	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
 			  V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION,
 			  0, 1, 1, 0);
@@ -1665,6 +1792,9 @@
 			  V4L2_CID_MPEG_VIDEO_AU_DELIMITER,
 			  0, 1, 1, 1);
 	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_BACKGROUND_DETECTION,
+			  0, 1, 1, 0);
+	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
 			  V4L2_CID_HFLIP,
 			  0, 1, 1, 0);
 	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
@@ -1701,6 +1831,12 @@
 			  0, 1, 1, 0);
 	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
 			  V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 1);
+	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR,
+			  0, 1, 1, 0);
+	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME,
+			  0, 0, 0, 0);
 
 	if (v4l2_ctrl_hdl->error) {
 		ret = -ENODEV;
@@ -1711,6 +1847,8 @@
 	v4l2_ctrl_handler_setup(v4l2_ctrl_hdl);
 
 	wave5_set_default_format(&inst->src_fmt, &inst->dst_fmt);
+	inst->conf_win.width = inst->dst_fmt.width;
+	inst->conf_win.height = inst->dst_fmt.height;
 	inst->colorspace = V4L2_COLORSPACE_REC709;
 	inst->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
 	inst->quantization = V4L2_QUANTIZATION_DEFAULT;
@@ -1732,10 +1870,6 @@
 	if (ret)
 		goto cleanup_inst;
 
-	if (dev->irq < 0 && !hrtimer_active(&dev->hrtimer) && list_empty(&dev->instances))
-		hrtimer_start(&dev->hrtimer, ns_to_ktime(dev->vpu_poll_interval * NSEC_PER_MSEC),
-			      HRTIMER_MODE_REL_PINNED);
-
 	list_add_tail(&inst->list, &dev->instances);
 
 	mutex_unlock(&dev->dev_lock);
diff -Naur --no-dereference a/drivers/media/platform/chips-media/wave5/wave5-vpu.h b/drivers/media/platform/chips-media/wave5/wave5-vpu.h
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu.h	2025-10-23 09:30:40.285462207 -0400
@@ -38,10 +38,7 @@
 
 struct vpu_format {
 	unsigned int v4l2_pix_fmt;
-	unsigned int max_width;
-	unsigned int min_width;
-	unsigned int max_height;
-	unsigned int min_height;
+	const struct v4l2_frmsize_stepwise *v4l2_frmsize;
 };
 
 static inline struct vpu_instance *wave5_to_vpu_inst(struct v4l2_fh *vfh)
diff -Naur --no-dereference a/drivers/media/platform/imagination/e5010-jpeg-enc.c b/drivers/media/platform/imagination/e5010-jpeg-enc.c
--- a/drivers/media/platform/imagination/e5010-jpeg-enc.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/imagination/e5010-jpeg-enc.c	2025-10-23 09:30:40.285462207 -0400
@@ -454,6 +454,7 @@
 
 	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
 	fsize->stepwise = fmt->frmsize;
+	fsize->stepwise.step_width = JPEG_STEP_WIDTH;
 	fsize->reserved[0] = 0;
 	fsize->reserved[1] = 0;
 
diff -Naur --no-dereference a/drivers/media/platform/imagination/e5010-jpeg-enc.h b/drivers/media/platform/imagination/e5010-jpeg-enc.h
--- a/drivers/media/platform/imagination/e5010-jpeg-enc.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/imagination/e5010-jpeg-enc.h	2025-10-23 09:30:40.285462207 -0400
@@ -23,6 +23,7 @@
 #define DEFAULT_HEIGHT			480
 #define E5010_MODULE_NAME		"e5010"
 #define JPEG_MAX_BYTES_PER_PIXEL	2
+#define JPEG_STEP_WIDTH			16
 
 /* JPEG marker definitions */
 #define START_OF_IMAGE			0xFFD8
diff -Naur --no-dereference a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
--- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c	2025-10-23 09:30:40.285462207 -0400
@@ -13,6 +13,8 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/suspend.h>
 
 #include <media/mipi-csi2.h>
 #include <media/v4l2-device.h>
@@ -25,21 +27,26 @@
 #define SHIM_CNTL			0x10
 #define SHIM_CNTL_PIX_RST		BIT(0)
 
-#define SHIM_DMACNTX			0x20
+#define SHIM_DMACNTX(i)			(0x20 + ((i) * 0x20))
 #define SHIM_DMACNTX_EN			BIT(31)
 #define SHIM_DMACNTX_YUV422		GENMASK(27, 26)
+#define SHIM_DMACNTX_DUAL_PCK_CFG	BIT(24)
 #define SHIM_DMACNTX_SIZE		GENMASK(21, 20)
+#define SHIM_DMACNTX_VC			GENMASK(9, 6)
 #define SHIM_DMACNTX_FMT		GENMASK(5, 0)
 #define SHIM_DMACNTX_YUV422_MODE_11	3
 #define SHIM_DMACNTX_SIZE_8		0
 #define SHIM_DMACNTX_SIZE_16		1
 #define SHIM_DMACNTX_SIZE_32		2
 
-#define SHIM_PSI_CFG0			0x24
+#define SHIM_PSI_CFG0(i)		(0x24 + ((i) * 0x20))
 #define SHIM_PSI_CFG0_SRC_TAG		GENMASK(15, 0)
 #define SHIM_PSI_CFG0_DST_TAG		GENMASK(31, 16)
 
+#define TI_CSI2RX_MAX_PIX_PER_CLK	4
 #define PSIL_WORD_SIZE_BYTES		16
+#define TI_CSI2RX_MAX_CTX		32
+
 /*
  * There are no hard limits on the width or height. The DMA engine can handle
  * all sizes. The max width and height are arbitrary numbers for this driver.
@@ -49,8 +56,13 @@
 #define MAX_WIDTH_BYTES			SZ_16K
 #define MAX_HEIGHT_LINES		SZ_16K
 
-#define DRAIN_TIMEOUT_MS		50
+#define TI_CSI2RX_PAD_SINK		0
+#define TI_CSI2RX_PAD_FIRST_SOURCE	1
+#define TI_CSI2RX_MAX_SOURCE_PADS	TI_CSI2RX_MAX_CTX
+#define TI_CSI2RX_MAX_PADS		(1 + TI_CSI2RX_MAX_SOURCE_PADS)
+
 #define DRAIN_BUFFER_SIZE		SZ_32K
+#define DRAIN_TIMEOUT_MS		250
 
 struct ti_csi2rx_fmt {
 	u32				fourcc;	/* Four character code. */
@@ -64,12 +76,11 @@
 	/* Common v4l2 buffer. Must be first. */
 	struct vb2_v4l2_buffer		vb;
 	struct list_head		list;
-	struct ti_csi2rx_dev		*csi;
+	struct ti_csi2rx_ctx		*ctx;
 };
 
 enum ti_csi2rx_dma_state {
 	TI_CSI2RX_DMA_STOPPED,	/* Streaming not started yet. */
-	TI_CSI2RX_DMA_IDLE,	/* Streaming but no pending DMA operation. */
 	TI_CSI2RX_DMA_ACTIVE,	/* Streaming and pending DMA operation. */
 };
 
@@ -84,29 +95,47 @@
 	 * Queue of buffers submitted to DMA engine.
 	 */
 	struct list_head		submitted;
-	/* Buffer to drain stale data from PSI-L endpoint */
-	struct {
-		void			*vaddr;
-		dma_addr_t		paddr;
-		size_t			len;
-	} drain;
+};
+
+struct ti_csi2rx_dev;
+
+struct ti_csi2rx_ctx {
+	struct ti_csi2rx_dev		*csi;
+	struct video_device		vdev;
+	struct vb2_queue		vidq;
+	struct mutex			mutex; /* To serialize ioctls. */
+	struct v4l2_format		v_fmt;
+	struct ti_csi2rx_dma		dma;
+	struct media_pad		pad;
+	u32				sequence;
+	u32				idx;
+	u32				vc;
+	u32				stream;
 };
 
 struct ti_csi2rx_dev {
 	struct device			*dev;
 	void __iomem			*shim;
+	struct mutex			mutex; /* To serialize ioctls. */
+	unsigned int			enable_count;
+	unsigned int			num_ctx;
 	struct v4l2_device		v4l2_dev;
-	struct video_device		vdev;
 	struct media_device		mdev;
 	struct media_pipeline		pipe;
-	struct media_pad		pad;
+	struct media_pad		pads[TI_CSI2RX_MAX_PADS];
 	struct v4l2_async_notifier	notifier;
 	struct v4l2_subdev		*source;
-	struct vb2_queue		vidq;
-	struct mutex			mutex; /* To serialize ioctls. */
-	struct v4l2_format		v_fmt;
-	struct ti_csi2rx_dma		dma;
-	u32				sequence;
+	struct v4l2_subdev		subdev;
+	struct ti_csi2rx_ctx		ctx[TI_CSI2RX_MAX_CTX];
+	struct notifier_block		pm_notifier;
+	u8				pix_per_clk;
+	/* Buffer to drain stale data from PSI-L endpoint */
+	struct {
+		void			*vaddr;
+		dma_addr_t		paddr;
+		size_t			len;
+	} drain;
+	struct completion drain_complete;
 };
 
 static const struct ti_csi2rx_fmt ti_csi2rx_formats[] = {
@@ -189,12 +218,90 @@
 		.bpp			= 16,
 		.size			= SHIM_DMACNTX_SIZE_16,
 	}, {
+		.fourcc			= V4L2_PIX_FMT_SRGGI10,
+		.code			= MEDIA_BUS_FMT_SRGGI10_1X10,
+		.csi_dt			= MIPI_CSI2_DT_RAW10,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_SGRIG10,
+		.code			= MEDIA_BUS_FMT_SGRIG10_1X10,
+		.csi_dt			= MIPI_CSI2_DT_RAW10,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_SBGGI10,
+		.code			= MEDIA_BUS_FMT_SBGGI10_1X10,
+		.csi_dt			= MIPI_CSI2_DT_RAW10,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_SGBIG10,
+		.code			= MEDIA_BUS_FMT_SGBIG10_1X10,
+		.csi_dt			= MIPI_CSI2_DT_RAW10,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_SGIRG10,
+		.code			= MEDIA_BUS_FMT_SGIRG10_1X10,
+		.csi_dt			= MIPI_CSI2_DT_RAW10,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_SIGGR10,
+		.code			= MEDIA_BUS_FMT_SIGGR10_1X10,
+		.csi_dt			= MIPI_CSI2_DT_RAW10,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_SGIBG10,
+		.code			= MEDIA_BUS_FMT_SGIBG10_1X10,
+		.csi_dt			= MIPI_CSI2_DT_RAW10,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_SIGGB10,
+		.code			= MEDIA_BUS_FMT_SIGGB10_1X10,
+		.csi_dt			= MIPI_CSI2_DT_RAW10,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_SBGGR12,
+		.code			= MEDIA_BUS_FMT_SBGGR12_1X12,
+		.csi_dt			= MIPI_CSI2_DT_RAW12,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_SGBRG12,
+		.code			= MEDIA_BUS_FMT_SGBRG12_1X12,
+		.csi_dt			= MIPI_CSI2_DT_RAW12,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_SGRBG12,
+		.code			= MEDIA_BUS_FMT_SGRBG12_1X12,
+		.csi_dt			= MIPI_CSI2_DT_RAW12,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_SRGGB12,
+		.code			= MEDIA_BUS_FMT_SRGGB12_1X12,
+		.csi_dt			= MIPI_CSI2_DT_RAW12,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
 		.fourcc			= V4L2_PIX_FMT_RGB565X,
 		.code			= MEDIA_BUS_FMT_RGB565_1X16,
 		.csi_dt			= MIPI_CSI2_DT_RGB565,
 		.bpp			= 16,
 		.size			= SHIM_DMACNTX_SIZE_16,
 	}, {
+		.fourcc			= V4L2_PIX_FMT_Y10,
+		.code			= MEDIA_BUS_FMT_Y10_1X10,
+		.csi_dt			= MIPI_CSI2_DT_RAW10,
+		.bpp			= 16,
+		.size			= SHIM_DMACNTX_SIZE_16,
+	}, {
 		.fourcc			= V4L2_PIX_FMT_XBGR32,
 		.code			= MEDIA_BUS_FMT_RGB888_1X24,
 		.csi_dt			= MIPI_CSI2_DT_RGB888,
@@ -211,10 +318,17 @@
 	/* More formats can be supported but they are not listed for now. */
 };
 
+extern int cdns_csi2rx_negotiate_ppc(struct v4l2_subdev *subdev,
+				     unsigned int pad, u8 *ppc);
+
 /* Forward declaration needed by ti_csi2rx_dma_callback. */
-static int ti_csi2rx_start_dma(struct ti_csi2rx_dev *csi,
+static int ti_csi2rx_start_dma(struct ti_csi2rx_ctx *ctx,
 			       struct ti_csi2rx_buffer *buf);
 
+/* Forward declarations needed by ti_csi2rx_drain_callback. */
+static int ti_csi2rx_drain_dma(struct ti_csi2rx_ctx *ctx);
+static int ti_csi2rx_dma_submit_pending(struct ti_csi2rx_ctx *ctx);
+
 static const struct ti_csi2rx_fmt *find_format_by_fourcc(u32 pixelformat)
 {
 	unsigned int i;
@@ -302,7 +416,7 @@
 static int ti_csi2rx_g_fmt_vid_cap(struct file *file, void *prov,
 				   struct v4l2_format *f)
 {
-	struct ti_csi2rx_dev *csi = video_drvdata(file);
+	struct ti_csi2rx_ctx *csi = video_drvdata(file);
 
 	*f = csi->v_fmt;
 
@@ -333,7 +447,7 @@
 static int ti_csi2rx_s_fmt_vid_cap(struct file *file, void *priv,
 				   struct v4l2_format *f)
 {
-	struct ti_csi2rx_dev *csi = video_drvdata(file);
+	struct ti_csi2rx_ctx *csi = video_drvdata(file);
 	struct vb2_queue *q = &csi->vidq;
 	int ret;
 
@@ -419,25 +533,48 @@
 static int csi_async_notifier_complete(struct v4l2_async_notifier *notifier)
 {
 	struct ti_csi2rx_dev *csi = dev_get_drvdata(notifier->v4l2_dev->dev);
-	struct video_device *vdev = &csi->vdev;
-	int ret;
+	int ret, i;
 
-	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+	/* Create link from source to subdev */
+	ret = v4l2_create_fwnode_links_to_pad(csi->source,
+					      &csi->pads[TI_CSI2RX_PAD_SINK],
+					      MEDIA_LNK_FL_IMMUTABLE |
+					      MEDIA_LNK_FL_ENABLED);
 	if (ret)
 		return ret;
 
-	ret = v4l2_create_fwnode_links_to_pad(csi->source, &csi->pad,
-					      MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
-
-	if (ret) {
-		video_unregister_device(vdev);
-		return ret;
+	/* Create and link video nodes for all DMA contexts */
+	for (i = 0; i < csi->num_ctx; i++) {
+		struct ti_csi2rx_ctx *ctx = &csi->ctx[i];
+		struct video_device *vdev = &ctx->vdev;
+
+		ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+		if (ret)
+			goto unregister_dev;
+
+		ret = media_create_pad_link(&csi->subdev.entity,
+					    TI_CSI2RX_PAD_FIRST_SOURCE + ctx->idx,
+					    &vdev->entity, 0,
+					    MEDIA_LNK_FL_IMMUTABLE |
+					    MEDIA_LNK_FL_ENABLED);
+		if (ret) {
+			video_unregister_device(vdev);
+			goto unregister_dev;
+		}
 	}
 
 	ret = v4l2_device_register_subdev_nodes(&csi->v4l2_dev);
 	if (ret)
-		video_unregister_device(vdev);
+		goto unregister_dev;
 
+	return 0;
+
+unregister_dev:
+	i--;
+	for (; i >= 0; i--) {
+		media_entity_remove_links(&csi->ctx[i].vdev.entity);
+		video_unregister_device(&csi->ctx[i].vdev);
+	}
 	return ret;
 }
 
@@ -483,16 +620,45 @@
 	return 0;
 }
 
-static void ti_csi2rx_setup_shim(struct ti_csi2rx_dev *csi)
+/* Request maximum possible pixels per clock from the bridge */
+static void ti_csi2rx_request_max_ppc(struct ti_csi2rx_dev *csi)
 {
+	struct media_pad *pad;
+	int ret;
+	u8 ppc = TI_CSI2RX_MAX_PIX_PER_CLK;
+
+	pad = media_entity_remote_source_pad_unique(&csi->subdev.entity);
+	if (!pad)
+		return;
+
+	ret = cdns_csi2rx_negotiate_ppc(csi->source, pad->index, &ppc);
+	if (ret) {
+		dev_warn(csi->dev, "NUM_PIXELS negotiation failed: %d\n", ret);
+		csi->pix_per_clk = 1;
+	} else {
+		csi->pix_per_clk = ppc;
+	}
+}
+
+static void ti_csi2rx_setup_shim(struct ti_csi2rx_ctx *ctx)
+{
+	struct ti_csi2rx_dev *csi = ctx->csi;
 	const struct ti_csi2rx_fmt *fmt;
 	unsigned int reg;
 
-	fmt = find_format_by_fourcc(csi->v_fmt.fmt.pix.pixelformat);
+	fmt = find_format_by_fourcc(ctx->v_fmt.fmt.pix.pixelformat);
 
-	/* De-assert the pixel interface reset. */
-	reg = SHIM_CNTL_PIX_RST;
-	writel(reg, csi->shim + SHIM_CNTL);
+	/*
+	 * De-assert the pixel interface reset. Negotiate pixel count before
+	 * starting first stream on source
+	 */
+	mutex_lock(&csi->mutex);
+	if (!csi->enable_count) {
+		reg = SHIM_CNTL_PIX_RST;
+		writel(reg, csi->shim + SHIM_CNTL);
+		ti_csi2rx_request_max_ppc(csi);
+	}
+	mutex_unlock(&csi->mutex);
 
 	reg = SHIM_DMACNTX_EN;
 	reg |= FIELD_PREP(SHIM_DMACNTX_FMT, fmt->csi_dt);
@@ -522,26 +688,55 @@
 	case V4L2_PIX_FMT_YVYU:
 		reg |= FIELD_PREP(SHIM_DMACNTX_YUV422,
 				  SHIM_DMACNTX_YUV422_MODE_11);
+		/* Multiple pixels are handled differently for packed YUV */
+		if (csi->pix_per_clk == 2)
+			reg |= SHIM_DMACNTX_DUAL_PCK_CFG;
+		reg |= FIELD_PREP(SHIM_DMACNTX_SIZE, fmt->size);
 		break;
 	default:
-		/* Ignore if not YUV 4:2:2 */
+		/* By default we change the shift size for multiple pixels */
+		reg |= FIELD_PREP(SHIM_DMACNTX_SIZE,
+				  fmt->size + (csi->pix_per_clk >> 1));
 		break;
 	}
 
-	reg |= FIELD_PREP(SHIM_DMACNTX_SIZE, fmt->size);
+	reg |= FIELD_PREP(SHIM_DMACNTX_VC, ctx->vc);
 
-	writel(reg, csi->shim + SHIM_DMACNTX);
+	writel(reg, csi->shim + SHIM_DMACNTX(ctx->idx));
 
 	reg = FIELD_PREP(SHIM_PSI_CFG0_SRC_TAG, 0) |
 	      FIELD_PREP(SHIM_PSI_CFG0_DST_TAG, 0);
-	writel(reg, csi->shim + SHIM_PSI_CFG0);
+	writel(reg, csi->shim + SHIM_PSI_CFG0(ctx->idx));
 }
 
 static void ti_csi2rx_drain_callback(void *param)
 {
-	struct completion *drain_complete = param;
+	struct ti_csi2rx_ctx *ctx = param;
+	struct ti_csi2rx_dev *csi = ctx->csi;
+	struct ti_csi2rx_dma *dma = &ctx->dma;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dma->lock, flags);
 
-	complete(drain_complete);
+	if (dma->state == TI_CSI2RX_DMA_STOPPED) {
+		writel(0, csi->shim + SHIM_DMACNTX(ctx->idx));
+		complete(&csi->drain_complete);
+
+		spin_unlock_irqrestore(&dma->lock, flags);
+		return;
+	}
+
+	/*
+	 * If dma->queue is empty, it signals no buffer has arrived from
+	 * user space, so, queue more transaction to drain dma
+	 */
+	if (list_empty(&dma->queue)) {
+		if (ti_csi2rx_drain_dma(ctx))
+			dev_warn(ctx->csi->dev, "DMA drain failed\n");
+	} else {
+		ti_csi2rx_dma_submit_pending(ctx);
+	}
+	spin_unlock_irqrestore(&dma->lock, flags);
 }
 
 /*
@@ -555,17 +750,15 @@
  * To prevent that stale data corrupting the subsequent transactions, it is
  * required to issue DMA requests to drain it out.
  */
-static int ti_csi2rx_drain_dma(struct ti_csi2rx_dev *csi)
+static int ti_csi2rx_drain_dma(struct ti_csi2rx_ctx *ctx)
 {
+	struct ti_csi2rx_dev *csi = ctx->csi;
 	struct dma_async_tx_descriptor *desc;
-	struct completion drain_complete;
 	dma_cookie_t cookie;
 	int ret;
 
-	init_completion(&drain_complete);
-
-	desc = dmaengine_prep_slave_single(csi->dma.chan, csi->dma.drain.paddr,
-					   csi->dma.drain.len, DMA_DEV_TO_MEM,
+	desc = dmaengine_prep_slave_single(ctx->dma.chan, csi->drain.paddr,
+					   csi->drain.len, DMA_DEV_TO_MEM,
 					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 	if (!desc) {
 		ret = -EIO;
@@ -573,31 +766,45 @@
 	}
 
 	desc->callback = ti_csi2rx_drain_callback;
-	desc->callback_param = &drain_complete;
+	desc->callback_param = ctx;
 
 	cookie = dmaengine_submit(desc);
 	ret = dma_submit_error(cookie);
 	if (ret)
 		goto out;
 
-	dma_async_issue_pending(csi->dma.chan);
+	dma_async_issue_pending(ctx->dma.chan);
 
-	if (!wait_for_completion_timeout(&drain_complete,
-					 msecs_to_jiffies(DRAIN_TIMEOUT_MS))) {
-		dmaengine_terminate_sync(csi->dma.chan);
-		dev_dbg(csi->dev, "DMA transfer timed out for drain buffer\n");
-		ret = -ETIMEDOUT;
-		goto out;
-	}
 out:
 	return ret;
 }
 
+static int ti_csi2rx_dma_submit_pending(struct ti_csi2rx_ctx *ctx)
+{
+	struct ti_csi2rx_dma *dma = &ctx->dma;
+	struct ti_csi2rx_buffer *buf;
+	int ret = 0;
+
+	/* If there are more buffers to process then start their transfer. */
+	while (!list_empty(&dma->queue)) {
+		buf = list_entry(dma->queue.next, struct ti_csi2rx_buffer, list);
+		ret = ti_csi2rx_start_dma(ctx, buf);
+		if (ret) {
+			dev_err(ctx->csi->dev,
+				"Failed to queue the next buffer for DMA\n");
+			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+			break;
+		}
+		list_move_tail(&buf->list, &dma->submitted);
+	}
+	return ret;
+}
+
 static void ti_csi2rx_dma_callback(void *param)
 {
 	struct ti_csi2rx_buffer *buf = param;
-	struct ti_csi2rx_dev *csi = buf->csi;
-	struct ti_csi2rx_dma *dma = &csi->dma;
+	struct ti_csi2rx_ctx *ctx = buf->ctx;
+	struct ti_csi2rx_dma *dma = &ctx->dma;
 	unsigned long flags;
 
 	/*
@@ -605,7 +812,7 @@
 	 * hardware monitor registers.
 	 */
 	buf->vb.vb2_buf.timestamp = ktime_get_ns();
-	buf->vb.sequence = csi->sequence++;
+	buf->vb.sequence = ctx->sequence++;
 
 	spin_lock_irqsave(&dma->lock, flags);
 
@@ -613,35 +820,27 @@
 	vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
 	list_del(&buf->list);
 
-	/* If there are more buffers to process then start their transfer. */
-	while (!list_empty(&dma->queue)) {
-		buf = list_entry(dma->queue.next, struct ti_csi2rx_buffer, list);
+	ti_csi2rx_dma_submit_pending(ctx);
 
-		if (ti_csi2rx_start_dma(csi, buf)) {
-			dev_err(csi->dev, "Failed to queue the next buffer for DMA\n");
-			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-		} else {
-			list_move_tail(&buf->list, &dma->submitted);
-		}
+	if (list_empty(&dma->submitted)) {
+		if (ti_csi2rx_drain_dma(ctx))
+			dev_warn(ctx->csi->dev,
+				"DMA drain failed on one of the transactions\n");
 	}
-
-	if (list_empty(&dma->submitted))
-		dma->state = TI_CSI2RX_DMA_IDLE;
-
 	spin_unlock_irqrestore(&dma->lock, flags);
 }
 
-static int ti_csi2rx_start_dma(struct ti_csi2rx_dev *csi,
+static int ti_csi2rx_start_dma(struct ti_csi2rx_ctx *ctx,
 			       struct ti_csi2rx_buffer *buf)
 {
 	unsigned long addr;
 	struct dma_async_tx_descriptor *desc;
-	size_t len = csi->v_fmt.fmt.pix.sizeimage;
+	size_t len = ctx->v_fmt.fmt.pix.sizeimage;
 	dma_cookie_t cookie;
 	int ret = 0;
 
 	addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
-	desc = dmaengine_prep_slave_single(csi->dma.chan, addr, len,
+	desc = dmaengine_prep_slave_single(ctx->dma.chan, addr, len,
 					   DMA_DEV_TO_MEM,
 					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 	if (!desc)
@@ -655,23 +854,26 @@
 	if (ret)
 		return ret;
 
-	dma_async_issue_pending(csi->dma.chan);
+	dma_async_issue_pending(ctx->dma.chan);
 
 	return 0;
 }
 
-static void ti_csi2rx_stop_dma(struct ti_csi2rx_dev *csi)
+static void ti_csi2rx_stop_dma(struct ti_csi2rx_ctx *ctx)
 {
-	struct ti_csi2rx_dma *dma = &csi->dma;
+	struct ti_csi2rx_dma *dma = &ctx->dma;
+	struct ti_csi2rx_dev *csi = ctx->csi;
 	enum ti_csi2rx_dma_state state;
 	unsigned long flags;
 	int ret;
 
 	spin_lock_irqsave(&dma->lock, flags);
-	state = csi->dma.state;
+	state = ctx->dma.state;
 	dma->state = TI_CSI2RX_DMA_STOPPED;
 	spin_unlock_irqrestore(&dma->lock, flags);
 
+	init_completion(&csi->drain_complete);
+
 	if (state != TI_CSI2RX_DMA_STOPPED) {
 		/*
 		 * Normal DMA termination does not clean up pending data on
@@ -679,30 +881,34 @@
 		 * is stopped, as the module-level pixel reset cannot be
 		 * enforced before terminating DMA.
 		 */
-		ret = ti_csi2rx_drain_dma(csi);
-		if (ret && ret != -ETIMEDOUT)
-			dev_warn(csi->dev,
+		ret = ti_csi2rx_drain_dma(ctx);
+		if (ret)
+			dev_warn(ctx->csi->dev,
 				 "Failed to drain DMA. Next frame might be bogus\n");
 	}
 
-	ret = dmaengine_terminate_sync(csi->dma.chan);
+	if (!wait_for_completion_timeout(&csi->drain_complete,
+					 msecs_to_jiffies(DRAIN_TIMEOUT_MS)))
+		dev_dbg(csi->dev, "DMA transfer timed out for drain buffer\n");
+
+	ret = dmaengine_terminate_sync(ctx->dma.chan);
 	if (ret)
-		dev_err(csi->dev, "Failed to stop DMA: %d\n", ret);
+		dev_err(ctx->csi->dev, "Failed to stop DMA: %d\n", ret);
 }
 
-static void ti_csi2rx_cleanup_buffers(struct ti_csi2rx_dev *csi,
+static void ti_csi2rx_cleanup_buffers(struct ti_csi2rx_ctx *ctx,
 				      enum vb2_buffer_state state)
 {
-	struct ti_csi2rx_dma *dma = &csi->dma;
+	struct ti_csi2rx_dma *dma = &ctx->dma;
 	struct ti_csi2rx_buffer *buf, *tmp;
 	unsigned long flags;
 
 	spin_lock_irqsave(&dma->lock, flags);
-	list_for_each_entry_safe(buf, tmp, &csi->dma.queue, list) {
+	list_for_each_entry_safe(buf, tmp, &ctx->dma.queue, list) {
 		list_del(&buf->list);
 		vb2_buffer_done(&buf->vb.vb2_buf, state);
 	}
-	list_for_each_entry_safe(buf, tmp, &csi->dma.submitted, list) {
+	list_for_each_entry_safe(buf, tmp, &ctx->dma.submitted, list) {
 		list_del(&buf->list);
 		vb2_buffer_done(&buf->vb.vb2_buf, state);
 	}
@@ -713,8 +919,8 @@
 				 unsigned int *nplanes, unsigned int sizes[],
 				 struct device *alloc_devs[])
 {
-	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(q);
-	unsigned int size = csi->v_fmt.fmt.pix.sizeimage;
+	struct ti_csi2rx_ctx *ctx = vb2_get_drv_priv(q);
+	unsigned int size = ctx->v_fmt.fmt.pix.sizeimage;
 
 	if (*nplanes) {
 		if (sizes[0] < size)
@@ -730,11 +936,11 @@
 
 static int ti_csi2rx_buffer_prepare(struct vb2_buffer *vb)
 {
-	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vb->vb2_queue);
-	unsigned long size = csi->v_fmt.fmt.pix.sizeimage;
+	struct ti_csi2rx_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned long size = ctx->v_fmt.fmt.pix.sizeimage;
 
 	if (vb2_plane_size(vb, 0) < size) {
-		dev_err(csi->dev, "Data will not fit into plane\n");
+		dev_err(ctx->csi->dev, "Data will not fit into plane\n");
 		return -EINVAL;
 	}
 
@@ -744,69 +950,61 @@
 
 static void ti_csi2rx_buffer_queue(struct vb2_buffer *vb)
 {
-	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vb->vb2_queue);
+	struct ti_csi2rx_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 	struct ti_csi2rx_buffer *buf;
-	struct ti_csi2rx_dma *dma = &csi->dma;
-	bool restart_dma = false;
+	struct ti_csi2rx_dma *dma = &ctx->dma;
 	unsigned long flags = 0;
-	int ret;
 
 	buf = container_of(vb, struct ti_csi2rx_buffer, vb.vb2_buf);
-	buf->csi = csi;
+	buf->ctx = ctx;
 
 	spin_lock_irqsave(&dma->lock, flags);
-	/*
-	 * Usually the DMA callback takes care of queueing the pending buffers.
-	 * But if DMA has stalled due to lack of buffers, restart it now.
-	 */
-	if (dma->state == TI_CSI2RX_DMA_IDLE) {
-		/*
-		 * Do not restart DMA with the lock held because
-		 * ti_csi2rx_drain_dma() might block for completion.
-		 * There won't be a race on queueing DMA anyway since the
-		 * callback is not being fired.
-		 */
-		restart_dma = true;
-		dma->state = TI_CSI2RX_DMA_ACTIVE;
-	} else {
-		list_add_tail(&buf->list, &dma->queue);
-	}
+	list_add_tail(&buf->list, &dma->queue);
 	spin_unlock_irqrestore(&dma->lock, flags);
+}
 
-	if (restart_dma) {
-		/*
-		 * Once frames start dropping, some data gets stuck in the DMA
-		 * pipeline somewhere. So the first DMA transfer after frame
-		 * drops gives a partial frame. This is obviously not useful to
-		 * the application and will only confuse it. Issue a DMA
-		 * transaction to drain that up.
-		 */
-		ret = ti_csi2rx_drain_dma(csi);
-		if (ret && ret != -ETIMEDOUT)
-			dev_warn(csi->dev,
-				 "Failed to drain DMA. Next frame might be bogus\n");
+static int ti_csi2rx_get_vc(struct ti_csi2rx_ctx *ctx)
+{
+	struct ti_csi2rx_dev *csi = ctx->csi;
+	struct v4l2_mbus_frame_desc fd;
+	struct media_pad *pad;
+	int ret, i;
+
+	pad = media_entity_remote_pad_unique(&csi->subdev.entity, MEDIA_PAD_FL_SOURCE);
+	if (!pad)
+		return -ENODEV;
 
-		spin_lock_irqsave(&dma->lock, flags);
-		ret = ti_csi2rx_start_dma(csi, buf);
-		if (ret) {
-			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-			dma->state = TI_CSI2RX_DMA_IDLE;
-			spin_unlock_irqrestore(&dma->lock, flags);
-			dev_err(csi->dev, "Failed to start DMA: %d\n", ret);
-		} else {
-			list_add_tail(&buf->list, &dma->submitted);
-			spin_unlock_irqrestore(&dma->lock, flags);
-		}
+	ret = v4l2_subdev_call(csi->source, pad, get_frame_desc, pad->index,
+			       &fd);
+	if (ret)
+		return ret;
+
+	if (fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2)
+		return -EINVAL;
+
+	for (i = 0; i < fd.num_entries; i++) {
+		if (ctx->stream == fd.entry[i].stream)
+			return fd.entry[i].bus.csi2.vc;
 	}
+
+	return -ENODEV;
 }
 
 static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
-	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vq);
-	struct ti_csi2rx_dma *dma = &csi->dma;
-	struct ti_csi2rx_buffer *buf;
+	struct ti_csi2rx_ctx *ctx = vb2_get_drv_priv(vq);
+	struct ti_csi2rx_dev *csi = ctx->csi;
+	struct ti_csi2rx_dma *dma = &ctx->dma;
+	struct v4l2_subdev_krouting *routing;
+	struct v4l2_subdev_route *route = NULL, *r;
+	struct media_pad *remote_pad;
 	unsigned long flags;
 	int ret = 0;
+	struct v4l2_subdev_state *state;
+
+	ret = pm_runtime_resume_and_get(csi->dev);
+	if (ret)
+		return ret;
 
 	spin_lock_irqsave(&dma->lock, flags);
 	if (list_empty(&dma->queue))
@@ -815,61 +1013,114 @@
 	if (ret)
 		return ret;
 
-	ret = video_device_pipeline_start(&csi->vdev, &csi->pipe);
+	ret = video_device_pipeline_start(&ctx->vdev, &csi->pipe);
 	if (ret)
 		goto err;
 
-	ti_csi2rx_setup_shim(csi);
+	remote_pad = media_entity_remote_source_pad_unique(ctx->pad.entity);
+	if (!remote_pad) {
+		ret = -ENODEV;
+		goto err;
+	}
+
+	state = v4l2_subdev_lock_and_get_active_state(&csi->subdev);
+
+	routing = &state->routing;
+
+	/* Find the stream to process. */
+	for_each_active_route(routing, r) {
+
+		if (!(r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))
+			continue;
+
+		if (r->source_pad != remote_pad->index)
+			continue;
+
+		route = r;
+		break;
+	}
+
+	if (!route) {
+		ret = -ENODEV;
+		v4l2_subdev_unlock_state(state);
+		goto err;
+	}
+
+	ctx->stream = route->sink_stream;
 
-	csi->sequence = 0;
+	v4l2_subdev_unlock_state(state);
+
+	ret = ti_csi2rx_get_vc(ctx);
+	if (ret == -ENOIOCTLCMD)
+		ctx->vc = 0;
+	else if (ret < 0)
+		goto err;
+	else
+		ctx->vc = ret;
+
+	ti_csi2rx_setup_shim(ctx);
+
+	ctx->sequence = 0;
 
 	spin_lock_irqsave(&dma->lock, flags);
-	buf = list_entry(dma->queue.next, struct ti_csi2rx_buffer, list);
 
-	ret = ti_csi2rx_start_dma(csi, buf);
+	ret = ti_csi2rx_dma_submit_pending(ctx);
 	if (ret) {
-		dev_err(csi->dev, "Failed to start DMA: %d\n", ret);
 		spin_unlock_irqrestore(&dma->lock, flags);
-		goto err_pipeline;
+		goto err_dma;
 	}
 
-	list_move_tail(&buf->list, &dma->submitted);
 	dma->state = TI_CSI2RX_DMA_ACTIVE;
 	spin_unlock_irqrestore(&dma->lock, flags);
 
-	ret = v4l2_subdev_call(csi->source, video, s_stream, 1);
+	/* Start stream 0, we don't allow multiple streams on the source pad */
+	ret = v4l2_subdev_enable_streams(&csi->subdev,
+					 TI_CSI2RX_PAD_FIRST_SOURCE + ctx->idx,
+					 BIT(0));
 	if (ret)
 		goto err_dma;
 
 	return 0;
 
 err_dma:
-	ti_csi2rx_stop_dma(csi);
-err_pipeline:
-	video_device_pipeline_stop(&csi->vdev);
+	ti_csi2rx_stop_dma(ctx);
+	video_device_pipeline_stop(&ctx->vdev);
 	writel(0, csi->shim + SHIM_CNTL);
-	writel(0, csi->shim + SHIM_DMACNTX);
+	writel(0, csi->shim + SHIM_DMACNTX(ctx->idx));
 err:
-	ti_csi2rx_cleanup_buffers(csi, VB2_BUF_STATE_QUEUED);
+	ti_csi2rx_cleanup_buffers(ctx, VB2_BUF_STATE_QUEUED);
+	pm_runtime_put(csi->dev);
+
 	return ret;
 }
 
 static void ti_csi2rx_stop_streaming(struct vb2_queue *vq)
 {
-	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vq);
+	struct ti_csi2rx_ctx *ctx = vb2_get_drv_priv(vq);
+	struct ti_csi2rx_dev *csi = ctx->csi;
 	int ret;
 
-	video_device_pipeline_stop(&csi->vdev);
+	mutex_lock(&csi->mutex);
+	/* assert pixel reset to prevent stale data */
+	if (csi->enable_count == 1) {
+		writel(0, csi->shim + SHIM_DMACNTX(ctx->idx));
+		writel(0, csi->shim + SHIM_CNTL);
+	}
 
-	writel(0, csi->shim + SHIM_CNTL);
-	writel(0, csi->shim + SHIM_DMACNTX);
+	video_device_pipeline_stop(&ctx->vdev);
+	ti_csi2rx_stop_dma(ctx);
+
+	ret = v4l2_subdev_disable_streams(&csi->subdev,
+					  TI_CSI2RX_PAD_FIRST_SOURCE + ctx->idx,
+					  BIT(0));
 
-	ret = v4l2_subdev_call(csi->source, video, s_stream, 0);
 	if (ret)
 		dev_err(csi->dev, "Failed to stop subdev stream\n");
 
-	ti_csi2rx_stop_dma(csi);
-	ti_csi2rx_cleanup_buffers(csi, VB2_BUF_STATE_ERROR);
+	mutex_unlock(&csi->mutex);
+
+	ti_csi2rx_cleanup_buffers(ctx, VB2_BUF_STATE_ERROR);
+	pm_runtime_put(csi->dev);
 }
 
 static const struct vb2_ops csi_vb2_qops = {
@@ -882,27 +1133,228 @@
 	.wait_finish = vb2_ops_wait_finish,
 };
 
-static int ti_csi2rx_init_vb2q(struct ti_csi2rx_dev *csi)
+static inline struct ti_csi2rx_dev *to_csi2rx_dev(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct ti_csi2rx_dev, subdev);
+}
+
+static int ti_csi2rx_sd_set_fmt(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *state,
+				struct v4l2_subdev_format *format)
+{
+	struct v4l2_mbus_framefmt *fmt;
+
+	/* No transcoding, don't allow setting source fmt */
+	if (format->pad > TI_CSI2RX_PAD_SINK)
+		return v4l2_subdev_get_fmt(sd, state, format);
+
+	if (!find_format_by_code(format->format.code))
+		format->format.code = ti_csi2rx_formats[0].code;
+
+	format->format.field = V4L2_FIELD_NONE;
+
+	fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);
+	*fmt = format->format;
+
+	fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
+							   format->stream);
+	if (!fmt)
+		return -EINVAL;
+
+	*fmt = format->format;
+
+	return 0;
+}
+
+static int _ti_csi2rx_sd_set_routing(struct v4l2_subdev *sd,
+				     struct v4l2_subdev_state *state,
+				     struct v4l2_subdev_krouting *routing)
 {
-	struct vb2_queue *q = &csi->vidq;
+	int ret;
+
+	const struct v4l2_mbus_framefmt format = {
+		.width = 640,
+		.height = 480,
+		.code = MEDIA_BUS_FMT_UYVY8_1X16,
+		.field = V4L2_FIELD_NONE,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.ycbcr_enc = V4L2_YCBCR_ENC_601,
+		.quantization = V4L2_QUANTIZATION_LIM_RANGE,
+		.xfer_func = V4L2_XFER_FUNC_SRGB,
+	};
+
+	ret = v4l2_subdev_routing_validate(sd, routing,
+					   V4L2_SUBDEV_ROUTING_ONLY_1_TO_1 |
+					   V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING);
+
+	if (ret)
+		return ret;
+
+	/* Only stream ID 0 allowed on source pads */
+	for (unsigned int i = 0; i < routing->num_routes; ++i) {
+		const struct v4l2_subdev_route *route = &routing->routes[i];
+
+		if (route->source_stream != 0)
+			return -EINVAL;
+	}
+
+	ret = v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);
+
+	return ret;
+}
+
+static int ti_csi2rx_sd_set_routing(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_state *state,
+				    enum v4l2_subdev_format_whence which,
+				    struct v4l2_subdev_krouting *routing)
+{
+	struct ti_csi2rx_dev *csi = to_csi2rx_dev(sd);
+
+	if (csi->enable_count > 0)
+		return -EBUSY;
+
+	return _ti_csi2rx_sd_set_routing(sd, state, routing);
+}
+
+static int ti_csi2rx_sd_init_state(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_route routes[] = { {
+		.sink_pad = 0,
+		.sink_stream = 0,
+		.source_pad = TI_CSI2RX_PAD_FIRST_SOURCE,
+		.source_stream = 0,
+		.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+	} };
+
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = 1,
+		.routes = routes,
+	};
+
+	/* Initialize routing to single route to the fist source pad */
+	return _ti_csi2rx_sd_set_routing(sd, state, &routing);
+}
+
+static int ti_csi2rx_sd_enable_streams(struct v4l2_subdev *sd,
+				       struct v4l2_subdev_state *state,
+				       u32 pad, u64 streams_mask)
+{
+	struct ti_csi2rx_dev *csi = to_csi2rx_dev(sd);
+	struct media_pad *remote_pad;
+	u64 sink_streams;
+	int ret = 0;
+
+	remote_pad = media_entity_remote_source_pad_unique(&csi->subdev.entity);
+	if (!remote_pad)
+		return -ENODEV;
+	sink_streams = v4l2_subdev_state_xlate_streams(state, pad,
+						       TI_CSI2RX_PAD_SINK,
+						       &streams_mask);
+
+	ret = v4l2_subdev_enable_streams(csi->source, remote_pad->index,
+					 sink_streams);
+	if (ret)
+		return ret;
+
+	mutex_lock(&csi->mutex);
+	csi->enable_count++;
+	mutex_unlock(&csi->mutex);
+
+	return 0;
+}
+
+static int ti_csi2rx_sd_disable_streams(struct v4l2_subdev *sd,
+					struct v4l2_subdev_state *state,
+					u32 pad, u64 streams_mask)
+{
+	struct ti_csi2rx_dev *csi = to_csi2rx_dev(sd);
+	struct media_pad *remote_pad;
+	u64 sink_streams;
+	int ret = 0;
+
+	remote_pad = media_entity_remote_source_pad_unique(&csi->subdev.entity);
+	if (!remote_pad)
+		return -ENODEV;
+	sink_streams = v4l2_subdev_state_xlate_streams(state, pad,
+						       TI_CSI2RX_PAD_SINK,
+						       &streams_mask);
+
+	if (csi->enable_count == 0)
+		return -EINVAL;
+
+	ret = v4l2_subdev_disable_streams(csi->source, remote_pad->index,
+					  sink_streams);
+	if (!ret)
+		--csi->enable_count;
+
+	return 0;
+}
+
+static const struct v4l2_subdev_pad_ops ti_csi2rx_subdev_pad_ops = {
+	.set_routing = ti_csi2rx_sd_set_routing,
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = ti_csi2rx_sd_set_fmt,
+	.enable_streams = ti_csi2rx_sd_enable_streams,
+	.disable_streams = ti_csi2rx_sd_disable_streams,
+};
+
+static const struct v4l2_subdev_ops ti_csi2rx_subdev_ops = {
+	.pad = &ti_csi2rx_subdev_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops ti_csi2rx_internal_ops = {
+	.init_state = ti_csi2rx_sd_init_state,
+};
+
+static void ti_csi2rx_cleanup_v4l2(struct ti_csi2rx_dev *csi)
+{
+	v4l2_subdev_cleanup(&csi->subdev);
+	media_device_unregister(&csi->mdev);
+	v4l2_device_unregister(&csi->v4l2_dev);
+	media_device_cleanup(&csi->mdev);
+}
+
+static void ti_csi2rx_cleanup_notifier(struct ti_csi2rx_dev *csi)
+{
+	v4l2_async_nf_unregister(&csi->notifier);
+	v4l2_async_nf_cleanup(&csi->notifier);
+}
+
+static void ti_csi2rx_cleanup_ctx(struct ti_csi2rx_ctx *ctx)
+{
+	if (!pm_runtime_status_suspended(ctx->csi->dev))
+		dma_release_channel(ctx->dma.chan);
+
+	vb2_queue_release(&ctx->vidq);
+
+	video_unregister_device(&ctx->vdev);
+
+	mutex_destroy(&ctx->mutex);
+}
+
+static int ti_csi2rx_init_vb2q(struct ti_csi2rx_ctx *ctx)
+{
+	struct vb2_queue *q = &ctx->vidq;
 	int ret;
 
 	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	q->io_modes = VB2_MMAP | VB2_DMABUF;
-	q->drv_priv = csi;
+	q->drv_priv = ctx;
 	q->buf_struct_size = sizeof(struct ti_csi2rx_buffer);
 	q->ops = &csi_vb2_qops;
 	q->mem_ops = &vb2_dma_contig_memops;
 	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-	q->dev = dmaengine_get_dma_device(csi->dma.chan);
-	q->lock = &csi->mutex;
+	q->dev = dmaengine_get_dma_device(ctx->dma.chan);
+	q->lock = &ctx->mutex;
 	q->min_queued_buffers = 1;
+	q->allow_cache_hints = 1;
 
 	ret = vb2_queue_init(q);
 	if (ret)
 		return ret;
 
-	csi->vdev.queue = q;
+	ctx->vdev.queue = q;
 
 	return 0;
 }
@@ -911,19 +1363,28 @@
 {
 	struct media_entity *entity = link->sink->entity;
 	struct video_device *vdev = media_entity_to_video_device(entity);
-	struct ti_csi2rx_dev *csi = container_of(vdev, struct ti_csi2rx_dev, vdev);
-	struct v4l2_pix_format *csi_fmt = &csi->v_fmt.fmt.pix;
+	struct ti_csi2rx_ctx *ctx = container_of(vdev, struct ti_csi2rx_ctx, vdev);
+	struct ti_csi2rx_dev *csi = ctx->csi;
+	struct v4l2_pix_format *csi_fmt = &ctx->v_fmt.fmt.pix;
 	struct v4l2_subdev_format source_fmt = {
 		.which	= V4L2_SUBDEV_FORMAT_ACTIVE,
 		.pad	= link->source->index,
+		.stream = 0,
 	};
+	struct v4l2_subdev_state *state;
 	const struct ti_csi2rx_fmt *ti_fmt;
 	int ret;
 
-	ret = v4l2_subdev_call_state_active(csi->source, pad,
-					    get_fmt, &source_fmt);
-	if (ret)
-		return ret;
+	state = v4l2_subdev_lock_and_get_active_state(&csi->subdev);
+	ret = v4l2_subdev_call(&csi->subdev, pad, get_fmt, state, &source_fmt);
+	v4l2_subdev_unlock_state(state);
+
+	if (ret) {
+		dev_dbg(csi->dev,
+			"Skipping validation as no format present on \"%s\":%u:0\n",
+			link->source->entity->name, link->source->index);
+		return 0;
+	}
 
 	if (source_fmt.format.width != csi_fmt->width) {
 		dev_dbg(csi->dev, "Width does not match (source %u, sink %u)\n",
@@ -953,8 +1414,9 @@
 
 	if (ti_fmt->fourcc != csi_fmt->pixelformat) {
 		dev_dbg(csi->dev,
-			"Cannot transform source fmt 0x%x to sink fmt 0x%x\n",
-			ti_fmt->fourcc, csi_fmt->pixelformat);
+			"Cannot transform \"%s\":%u format %p4cc to %p4cc\n",
+			link->source->entity->name, link->source->index,
+			&ti_fmt->fourcc, &csi_fmt->pixelformat);
 		return -EPIPE;
 	}
 
@@ -965,47 +1427,106 @@
 	.link_validate = ti_csi2rx_link_validate,
 };
 
-static int ti_csi2rx_init_dma(struct ti_csi2rx_dev *csi)
+static const struct media_entity_operations ti_csi2rx_subdev_entity_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
+static int ti_csi2rx_init_dma(struct ti_csi2rx_ctx *ctx)
 {
 	struct dma_slave_config cfg = {
 		.src_addr_width = DMA_SLAVE_BUSWIDTH_16_BYTES,
 	};
+	char name[32];
 	int ret;
 
-	INIT_LIST_HEAD(&csi->dma.queue);
-	INIT_LIST_HEAD(&csi->dma.submitted);
-	spin_lock_init(&csi->dma.lock);
-
-	csi->dma.state = TI_CSI2RX_DMA_STOPPED;
-
-	csi->dma.chan = dma_request_chan(csi->dev, "rx0");
-	if (IS_ERR(csi->dma.chan))
-		return PTR_ERR(csi->dma.chan);
+	snprintf(name, sizeof(name), "rx%u", ctx->idx);
+	ctx->dma.chan = dma_request_chan(ctx->csi->dev, name);
+	if (IS_ERR(ctx->dma.chan))
+		return PTR_ERR(ctx->dma.chan);
 
-	ret = dmaengine_slave_config(csi->dma.chan, &cfg);
+	ret = dmaengine_slave_config(ctx->dma.chan, &cfg);
 	if (ret) {
-		dma_release_channel(csi->dma.chan);
+		dma_release_channel(ctx->dma.chan);
 		return ret;
 	}
 
-	csi->dma.drain.len = DRAIN_BUFFER_SIZE;
-	csi->dma.drain.vaddr = dma_alloc_coherent(csi->dev, csi->dma.drain.len,
-						  &csi->dma.drain.paddr,
-						  GFP_KERNEL);
-	if (!csi->dma.drain.vaddr)
-		return -ENOMEM;
-
 	return 0;
 }
 
 static int ti_csi2rx_v4l2_init(struct ti_csi2rx_dev *csi)
 {
 	struct media_device *mdev = &csi->mdev;
-	struct video_device *vdev = &csi->vdev;
+	struct v4l2_subdev *sd = &csi->subdev;
+	int ret;
+
+	mdev->dev = csi->dev;
+	mdev->hw_revision = 1;
+	strscpy(mdev->model, "TI-CSI2RX", sizeof(mdev->model));
+
+	media_device_init(mdev);
+
+	csi->v4l2_dev.mdev = mdev;
+
+	ret = v4l2_device_register(csi->dev, &csi->v4l2_dev);
+	if (ret)
+		goto cleanup_media;
+
+	ret = media_device_register(mdev);
+	if (ret)
+		goto unregister_v4l2;
+
+	v4l2_subdev_init(sd, &ti_csi2rx_subdev_ops);
+	sd->internal_ops = &ti_csi2rx_internal_ops;
+	sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+	sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
+	strscpy(sd->name, dev_name(csi->dev), sizeof(sd->name));
+	sd->dev = csi->dev;
+	sd->entity.ops = &ti_csi2rx_subdev_entity_ops;
+
+	csi->pads[TI_CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+
+	for (unsigned int i = TI_CSI2RX_PAD_FIRST_SOURCE;
+	     i < TI_CSI2RX_PAD_FIRST_SOURCE + csi->num_ctx; i++)
+		csi->pads[i].flags = MEDIA_PAD_FL_SOURCE;
+
+	ret = media_entity_pads_init(&sd->entity,
+				     TI_CSI2RX_PAD_FIRST_SOURCE + csi->num_ctx,
+				     csi->pads);
+	if (ret)
+		goto unregister_media;
+
+	ret = v4l2_subdev_init_finalize(sd);
+	if (ret)
+		goto unregister_media;
+
+	ret = v4l2_device_register_subdev(&csi->v4l2_dev, sd);
+	if (ret)
+		goto cleanup_subdev;
+
+	return 0;
+
+cleanup_subdev:
+	v4l2_subdev_cleanup(sd);
+unregister_media:
+	media_device_unregister(mdev);
+unregister_v4l2:
+	v4l2_device_unregister(&csi->v4l2_dev);
+cleanup_media:
+	media_device_cleanup(mdev);
+
+	return ret;
+}
+
+static int ti_csi2rx_init_ctx(struct ti_csi2rx_ctx *ctx)
+{
+	struct ti_csi2rx_dev *csi = ctx->csi;
+	struct video_device *vdev = &ctx->vdev;
 	const struct ti_csi2rx_fmt *fmt;
-	struct v4l2_pix_format *pix_fmt = &csi->v_fmt.fmt.pix;
+	struct v4l2_pix_format *pix_fmt = &ctx->v_fmt.fmt.pix;
 	int ret;
 
+	mutex_init(&ctx->mutex);
+
 	fmt = find_format_by_fourcc(V4L2_PIX_FMT_UYVY);
 	if (!fmt)
 		return -EINVAL;
@@ -1018,15 +1539,16 @@
 	pix_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE,
 	pix_fmt->xfer_func = V4L2_XFER_FUNC_SRGB,
 
-	ti_csi2rx_fill_fmt(fmt, &csi->v_fmt);
-
-	mdev->dev = csi->dev;
-	mdev->hw_revision = 1;
-	strscpy(mdev->model, "TI-CSI2RX", sizeof(mdev->model));
+	ti_csi2rx_fill_fmt(fmt, &ctx->v_fmt);
 
-	media_device_init(mdev);
+	ctx->pad.flags = MEDIA_PAD_FL_SINK;
+	vdev->entity.ops = &ti_csi2rx_video_entity_ops;
+	ret = media_entity_pads_init(&ctx->vdev.entity, 1, &ctx->pad);
+	if (ret)
+		return ret;
 
-	strscpy(vdev->name, TI_CSI2RX_MODULE_NAME, sizeof(vdev->name));
+	snprintf(vdev->name, sizeof(vdev->name), "%s context %u",
+		 dev_name(csi->dev), ctx->idx);
 	vdev->v4l2_dev = &csi->v4l2_dev;
 	vdev->vfl_dir = VFL_DIR_RX;
 	vdev->fops = &csi_fops;
@@ -1034,61 +1556,187 @@
 	vdev->release = video_device_release_empty;
 	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
 			    V4L2_CAP_IO_MC;
-	vdev->lock = &csi->mutex;
-	video_set_drvdata(vdev, csi);
+	vdev->lock = &ctx->mutex;
+	video_set_drvdata(vdev, ctx);
 
-	csi->pad.flags = MEDIA_PAD_FL_SINK;
-	vdev->entity.ops = &ti_csi2rx_video_entity_ops;
-	ret = media_entity_pads_init(&csi->vdev.entity, 1, &csi->pad);
+	INIT_LIST_HEAD(&ctx->dma.queue);
+	INIT_LIST_HEAD(&ctx->dma.submitted);
+	spin_lock_init(&ctx->dma.lock);
+	ctx->dma.state = TI_CSI2RX_DMA_STOPPED;
+
+	ret = ti_csi2rx_init_dma(ctx);
 	if (ret)
 		return ret;
 
-	csi->v4l2_dev.mdev = mdev;
-
-	ret = v4l2_device_register(csi->dev, &csi->v4l2_dev);
+	ret = ti_csi2rx_init_vb2q(ctx);
 	if (ret)
-		return ret;
+		goto cleanup_dma;
 
-	ret = media_device_register(mdev);
-	if (ret) {
-		v4l2_device_unregister(&csi->v4l2_dev);
-		media_device_cleanup(mdev);
-		return ret;
+	return 0;
+
+cleanup_dma:
+	dma_release_channel(ctx->dma.chan);
+	return ret;
+}
+
+#ifdef CONFIG_PM
+static int ti_csi2rx_suspend(struct device *dev)
+{
+	struct ti_csi2rx_dev *csi = dev_get_drvdata(dev);
+	enum ti_csi2rx_dma_state state;
+	struct ti_csi2rx_ctx *ctx;
+	struct ti_csi2rx_dma *dma;
+	unsigned long flags = 0;
+	int i, ret = 0;
+
+	/* If device was not in use we can simply suspend */
+	if (pm_runtime_status_suspended(dev))
+		return 0;
+
+	/*
+	 * If device is running, assert the pixel reset to cleanly stop any
+	 * on-going streams before we suspend.
+	 */
+	writel(0, csi->shim + SHIM_CNTL);
+
+	for (i = 0; i < csi->num_ctx; i++) {
+		ctx = &csi->ctx[i];
+		dma = &ctx->dma;
+
+		spin_lock_irqsave(&dma->lock, flags);
+		state = dma->state;
+		spin_unlock_irqrestore(&dma->lock, flags);
+
+		if (state != TI_CSI2RX_DMA_STOPPED) {
+			/* Disable source */
+			ret = v4l2_subdev_disable_streams(&csi->subdev,
+							  TI_CSI2RX_PAD_FIRST_SOURCE + ctx->idx,
+							  BIT(0));
+			if (ret)
+				dev_err(csi->dev, "Failed to stop subdev stream\n");
+		}
+
+		/* Stop any on-going streams */
+		writel(0, csi->shim + SHIM_DMACNTX(ctx->idx));
+
+		/* Drain DMA */
+		ti_csi2rx_drain_dma(ctx);
+
+		/* Terminate DMA */
+		ret = dmaengine_terminate_sync(ctx->dma.chan);
+		if (ret)
+			dev_err(csi->dev, "Failed to stop DMA\n");
 	}
 
-	return 0;
+	return ret;
 }
 
-static void ti_csi2rx_cleanup_dma(struct ti_csi2rx_dev *csi)
+static int ti_csi2rx_resume(struct device *dev)
 {
-	dma_free_coherent(csi->dev, csi->dma.drain.len,
-			  csi->dma.drain.vaddr, csi->dma.drain.paddr);
-	csi->dma.drain.vaddr = NULL;
-	dma_release_channel(csi->dma.chan);
+	struct ti_csi2rx_dev *csi = dev_get_drvdata(dev);
+	struct ti_csi2rx_ctx *ctx;
+	struct ti_csi2rx_dma *dma;
+	struct ti_csi2rx_buffer *buf;
+	unsigned long flags = 0;
+	unsigned int reg;
+	int i, ret = 0;
+
+	/* If device was not in use, we can simply wakeup */
+	if (pm_runtime_status_suspended(dev))
+		return 0;
+
+	/* If device was in use before, restore all the running streams */
+	reg = SHIM_CNTL_PIX_RST;
+	writel(reg, csi->shim + SHIM_CNTL);
+
+	for (i = 0; i < csi->num_ctx; i++) {
+		ctx = &csi->ctx[i];
+		dma = &ctx->dma;
+		spin_lock_irqsave(&dma->lock, flags);
+		if (dma->state != TI_CSI2RX_DMA_STOPPED) {
+			/* Re-submit all previously submitted buffers to DMA */
+			list_for_each_entry(buf, &ctx->dma.submitted, list) {
+				ti_csi2rx_start_dma(ctx, buf);
+			}
+			spin_unlock_irqrestore(&dma->lock, flags);
+
+			/* Restore stream config */
+			ti_csi2rx_setup_shim(ctx);
+
+			ret = v4l2_subdev_enable_streams(&csi->subdev,
+							 TI_CSI2RX_PAD_FIRST_SOURCE + ctx->idx,
+							 BIT(0));
+			if (ret)
+				dev_err(ctx->csi->dev, "Failed to start subdev\n");
+		} else {
+			spin_unlock_irqrestore(&dma->lock, flags);
+		}
+	}
+
+	return ret;
 }
 
-static void ti_csi2rx_cleanup_v4l2(struct ti_csi2rx_dev *csi)
+static int ti_csi2rx_runtime_suspend(struct device *dev)
 {
-	media_device_unregister(&csi->mdev);
-	v4l2_device_unregister(&csi->v4l2_dev);
-	media_device_cleanup(&csi->mdev);
+	struct ti_csi2rx_dev *csi = dev_get_drvdata(dev);
+	int i;
+
+	if (csi->enable_count != 0)
+		return -EBUSY;
+
+	for (i = 0; i < csi->num_ctx; i++)
+		dma_release_channel(csi->ctx[i].dma.chan);
+
+	return 0;
 }
 
-static void ti_csi2rx_cleanup_subdev(struct ti_csi2rx_dev *csi)
+static int ti_csi2rx_runtime_resume(struct device *dev)
 {
-	v4l2_async_nf_unregister(&csi->notifier);
-	v4l2_async_nf_cleanup(&csi->notifier);
+	struct ti_csi2rx_dev *csi = dev_get_drvdata(dev);
+	int ret, i;
+
+	for (i = 0; i < csi->num_ctx; i++) {
+		ret = ti_csi2rx_init_dma(&csi->ctx[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
-static void ti_csi2rx_cleanup_vb2q(struct ti_csi2rx_dev *csi)
+static int ti_csi2rx_pm_notifier(struct notifier_block *nb, unsigned long action,
+			  void *data)
 {
-	vb2_queue_release(&csi->vidq);
+	struct ti_csi2rx_dev *csi =
+		container_of(nb, struct ti_csi2rx_dev, pm_notifier);
+
+	switch (action) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_SUSPEND_PREPARE:
+	case PM_RESTORE_PREPARE:
+		ti_csi2rx_suspend(csi->dev);
+		break;
+	case PM_POST_SUSPEND:
+	case PM_POST_HIBERNATION:
+	case PM_POST_RESTORE:
+		ti_csi2rx_resume(csi->dev);
+		break;
+	}
+
+	return NOTIFY_DONE;
 }
 
+static const struct dev_pm_ops ti_csi2rx_pm_ops = {
+	SET_RUNTIME_PM_OPS(ti_csi2rx_runtime_suspend, ti_csi2rx_runtime_resume,
+			   NULL)
+};
+#endif /* CONFIG_PM */
+
 static int ti_csi2rx_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
 	struct ti_csi2rx_dev *csi;
-	int ret;
+	int ret, i, count;
 
 	csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL);
 	if (!csi)
@@ -1097,62 +1745,103 @@
 	csi->dev = &pdev->dev;
 	platform_set_drvdata(pdev, csi);
 
-	mutex_init(&csi->mutex);
 	csi->shim = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(csi->shim)) {
 		ret = PTR_ERR(csi->shim);
-		goto err_mutex;
+		return ret;
 	}
 
-	ret = ti_csi2rx_init_dma(csi);
-	if (ret)
-		goto err_mutex;
+	csi->drain.len = DRAIN_BUFFER_SIZE;
+	csi->drain.vaddr = dma_alloc_coherent(csi->dev, csi->drain.len,
+					      &csi->drain.paddr,
+					      GFP_KERNEL);
+	if (!csi->drain.vaddr)
+		return -ENOMEM;
 
-	ret = ti_csi2rx_v4l2_init(csi);
-	if (ret)
-		goto err_dma;
+	/* Only use as many contexts as the number of DMA channels allocated. */
+	count = of_property_count_strings(np, "dma-names");
+	if (count < 0) {
+		dev_err(csi->dev, "Failed to get DMA channel count: %d\n",
+			count);
+		return count;
+	}
+
+	csi->num_ctx = count;
+	if (csi->num_ctx > TI_CSI2RX_MAX_CTX) {
+		dev_warn(csi->dev,
+			 "%u DMA channels passed. Maximum is %u. Ignoring the rest.\n",
+			 csi->num_ctx, TI_CSI2RX_MAX_CTX);
+		csi->num_ctx = TI_CSI2RX_MAX_CTX;
+	}
+
+	mutex_init(&csi->mutex);
 
-	ret = ti_csi2rx_init_vb2q(csi);
+	ret = ti_csi2rx_v4l2_init(csi);
 	if (ret)
 		goto err_v4l2;
 
+	for (i = 0; i < csi->num_ctx; i++) {
+		csi->ctx[i].idx = i;
+		csi->ctx[i].csi = csi;
+		ret = ti_csi2rx_init_ctx(&csi->ctx[i]);
+		if (ret)
+			goto err_ctx;
+	}
+
 	ret = ti_csi2rx_notifier_register(csi);
 	if (ret)
-		goto err_vb2q;
+		goto err_ctx;
 
 	ret = of_platform_populate(csi->dev->of_node, NULL, NULL, csi->dev);
 	if (ret) {
 		dev_err(csi->dev, "Failed to create children: %d\n", ret);
-		goto err_subdev;
+		goto err_notifier;
 	}
 
+	csi->pm_notifier.notifier_call = ti_csi2rx_pm_notifier;
+	ret = register_pm_notifier(&csi->pm_notifier);
+	if (ret) {
+		dev_err(csi->dev, "Failed to create PM notifier: %d\n", ret);
+		goto err_notifier;
+	}
+
+	pm_runtime_set_active(csi->dev);
+	pm_runtime_enable(csi->dev);
+	pm_request_idle(csi->dev);
+
 	return 0;
 
-err_subdev:
-	ti_csi2rx_cleanup_subdev(csi);
-err_vb2q:
-	ti_csi2rx_cleanup_vb2q(csi);
-err_v4l2:
+err_notifier:
+	ti_csi2rx_cleanup_notifier(csi);
+err_ctx:
+	i--;
+	for (; i >= 0; i--)
+		ti_csi2rx_cleanup_ctx(&csi->ctx[i]);
 	ti_csi2rx_cleanup_v4l2(csi);
-err_dma:
-	ti_csi2rx_cleanup_dma(csi);
-err_mutex:
+err_v4l2:
 	mutex_destroy(&csi->mutex);
+	dma_free_coherent(csi->dev, csi->drain.len, csi->drain.vaddr,
+			  csi->drain.paddr);
 	return ret;
 }
 
 static void ti_csi2rx_remove(struct platform_device *pdev)
 {
 	struct ti_csi2rx_dev *csi = platform_get_drvdata(pdev);
+	unsigned int i;
 
-	video_unregister_device(&csi->vdev);
+	for (i = 0; i < csi->num_ctx; i++)
+		ti_csi2rx_cleanup_ctx(&csi->ctx[i]);
 
-	ti_csi2rx_cleanup_vb2q(csi);
-	ti_csi2rx_cleanup_subdev(csi);
+	unregister_pm_notifier(&csi->pm_notifier);
+	ti_csi2rx_cleanup_notifier(csi);
 	ti_csi2rx_cleanup_v4l2(csi);
-	ti_csi2rx_cleanup_dma(csi);
-
 	mutex_destroy(&csi->mutex);
+	dma_free_coherent(csi->dev, csi->drain.len, csi->drain.vaddr,
+			  csi->drain.paddr);
+
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
 }
 
 static const struct of_device_id ti_csi2rx_of_match[] = {
@@ -1165,8 +1854,11 @@
 	.probe = ti_csi2rx_probe,
 	.remove_new = ti_csi2rx_remove,
 	.driver = {
-		.name = TI_CSI2RX_MODULE_NAME,
-		.of_match_table = ti_csi2rx_of_match,
+		.name		= TI_CSI2RX_MODULE_NAME,
+		.of_match_table	= ti_csi2rx_of_match,
+#ifdef CONFIG_PM
+		.pm		= &ti_csi2rx_pm_ops,
+#endif
 	},
 };
 
diff -Naur --no-dereference a/drivers/media/platform/ti/Kconfig b/drivers/media/platform/ti/Kconfig
--- a/drivers/media/platform/ti/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/ti/Kconfig	2025-10-23 09:30:40.285462207 -0400
@@ -41,6 +41,19 @@
 	  default. Note that this behavior can be overridden via
 	  module parameter 'mc_api'.
 
+config VIDEO_TI_VIP
+        tristate "TI Video Input Port"
+        default n
+        depends on VIDEO_DEV && SOC_DRA7XX
+        depends on HAS_DMA
+        select VIDEOBUF2_DMA_CONTIG
+        select VIDEO_TI_VPDMA
+        select VIDEO_TI_SC
+        select VIDEO_TI_CSC
+        help
+        Driver support for VIP module on certain TI SoC's
+        VIP = Video Input Port.
+
 # Mem2mem drivers
 
 config VIDEO_TI_VPE
diff -Naur --no-dereference a/drivers/media/platform/ti/vpe/Makefile b/drivers/media/platform/ti/vpe/Makefile
--- a/drivers/media/platform/ti/vpe/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/platform/ti/vpe/Makefile	2025-10-23 09:30:40.285462207 -0400
@@ -3,10 +3,12 @@
 obj-$(CONFIG_VIDEO_TI_VPDMA) += ti-vpdma.o
 obj-$(CONFIG_VIDEO_TI_SC) += ti-sc.o
 obj-$(CONFIG_VIDEO_TI_CSC) += ti-csc.o
+obj-$(CONFIG_VIDEO_TI_VIP) += ti-vip.o
 
 ti-vpe-y := vpe.o
 ti-vpdma-y := vpdma.o
 ti-sc-y := sc.o
 ti-csc-y := csc.o
+ti-vip-y := vip.o
 
 ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG
diff -Naur --no-dereference a/drivers/media/platform/ti/vpe/vip.c b/drivers/media/platform/ti/vpe/vip.c
--- a/drivers/media/platform/ti/vpe/vip.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/media/platform/ti/vpe/vip.c	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,3962 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI VIP capture driver
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated -  http://www.ti.com/
+ * David Griego, <dagriego@biglakesoftware.com>
+ * Dale Farnsworth, <dale@farnsworth.org>
+ * Yemike Abhilash Chandra, <y-abhilashchandra@ti.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/pm_runtime.h>
+#include <linux/sched.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#include <linux/pinctrl/consumer.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+
+#include "vip.h"
+
+#define VIP_MODULE_NAME "vip"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-8)");
+
+/*
+ * Minimum and maximum frame sizes
+ */
+#define MIN_W		128
+#define MIN_H		128
+#define MAX_W		2048
+#define MAX_H		1536
+
+/*
+ * Required alignments
+ */
+#define S_ALIGN		0 /* multiple of 1 */
+#define H_ALIGN		1 /* multiple of 2 */
+#define W_ALIGN		1 /* multiple of 2 */
+#define L_ALIGN		7 /* multiple of 128, line stride, 16 bytes */
+
+/*
+ * Need a descriptor entry for each of up to 15 outputs,
+ * and up to 2 control transfers.
+ */
+#define VIP_DESC_LIST_SIZE	(17 * sizeof(struct vpdma_dtd))
+
+#define CTRL_CORE_SMA_SW_1      0x534
+
+/*
+ * port flag bits
+ */
+#define FLAG_INTERLACED	BIT(4)
+#define FLAG_MULT_PORT		BIT(6)
+#define FLAG_MULT_ANC		BIT(7)
+
+#define VIP_VPDMA_FIFO_SIZE	2
+#define VIP_DROPQ_SIZE		3
+
+/*
+ * Define indices into the srce_info tables
+ */
+
+#define VIP_SRCE_MULT_PORT	0
+#define VIP_SRCE_MULT_ANC	1
+#define VIP_SRCE_LUMA		2
+#define VIP_SRCE_CHROMA	3
+#define VIP_SRCE_RGB		4
+
+#define reg_read(dev, offset) ioread32((dev)->base + (offset))
+#define reg_write(dev, offset, val) iowrite32((val), (dev)->base + (offset))
+
+#define GET_OFFSET_TOP(port, obj, reg)	\
+	((obj)->res->start - (port)->dev->res->start + (reg))
+
+#define VIP_SET_MMR_ADB_HDR(port, hdr, regs, offset_a)	\
+	VPDMA_SET_MMR_ADB_HDR((port)->mmr_adb, vip_mmr_adb, hdr, regs, offset_a)
+
+/*
+ * These represent the module resets bit for slice 1
+ * Upon detecting slice2 we simply left shift by 1
+ */
+#define VIP_DP_RST	BIT(16)
+#define VIP_CSC_RST	BIT(20)
+#define VIP_SC_RST	BIT(22)
+
+#define VIP_PARSER_PORT(p)		(VIP_PARSER_PORTA_0 + ((p) * 0x8U))
+#define VIP_PARSER_EXTRA_PORT(p)	(VIP_PARSER_PORTA_1 + ((p) * 0x8U))
+#define VIP_PARSER_CROP_H_PORT(p) \
+		(VIP_PARSER_PORTA_EXTRA4 + ((p) * 0x10U))
+#define VIP_PARSER_CROP_V_PORT(p) \
+		(VIP_PARSER_PORTA_EXTRA5 + ((p) * 0x10U))
+#define VIP_PARSER_STOP_IMM_PORT(p)	(VIP_PARSER_PORTA_EXTRA6 + ((p) * 0x4U))
+
+#define PARSER_IRQ_MASK (VIP_PORTA_OUTPUT_FIFO_YUV | \
+			 VIP_PORTB_OUTPUT_FIFO_YUV)
+
+/*
+ * The srce_info structure contains per-srce data.
+ */
+struct vip_srce_info {
+	u8	base_channel;	/* the VPDMA channel number */
+	u8	vb_index;	/* input frame f, f-1, f-2 index */
+	u8	vb_part;	/* identifies section of co-planar formats */
+};
+
+static struct vip_srce_info srce_info[5] = {
+	[VIP_SRCE_MULT_PORT] = {
+		.base_channel	= VIP1_CHAN_NUM_MULT_PORT_A_SRC0,
+		.vb_index	= 0,
+		.vb_part	= VIP_CHROMA,
+	},
+	[VIP_SRCE_MULT_ANC] = {
+		.base_channel	= VIP1_CHAN_NUM_MULT_ANC_A_SRC0,
+		.vb_index	= 0,
+		.vb_part	= VIP_LUMA,
+	},
+	[VIP_SRCE_LUMA] = {
+		.base_channel	= VIP1_CHAN_NUM_PORT_A_LUMA,
+		.vb_index	= 1,
+		.vb_part	= VIP_LUMA,
+	},
+	[VIP_SRCE_CHROMA] = {
+		.base_channel	= VIP1_CHAN_NUM_PORT_A_CHROMA,
+		.vb_index	= 1,
+		.vb_part	= VIP_CHROMA,
+	},
+	[VIP_SRCE_RGB] = {
+		.base_channel	= VIP1_CHAN_NUM_PORT_A_RGB,
+		.vb_part	= VIP_LUMA,
+	},
+};
+
+static struct vip_fmt vip_formats[VIP_MAX_ACTIVE_FMT] = {
+	{
+		.fourcc		= V4L2_PIX_FMT_NV12,
+		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+		.coplanar	= 1,
+		.vpdma_fmt	= { &vpdma_yuv_fmts[VPDMA_DATA_FMT_Y420],
+				    &vpdma_yuv_fmts[VPDMA_DATA_FMT_C420],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_UYVY,
+		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CBY422],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_YUYV,
+		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_yuv_fmts[VPDMA_DATA_FMT_YCB422],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_VYUY,
+		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CRY422],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_YVYU,
+		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_yuv_fmts[VPDMA_DATA_FMT_YCR422],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_RGB24,
+		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGB24],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_RGB32,
+		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ARGB32],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_BGR24,
+		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_rgb_fmts[VPDMA_DATA_FMT_BGR24],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_BGR32,
+		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ABGR32],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_RGB24,
+		.code		= MEDIA_BUS_FMT_RGB888_1X24,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGB24],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_RGB32,
+		.code		= MEDIA_BUS_FMT_ARGB8888_1X32,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ARGB32],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_SBGGR8,
+		.code		= MEDIA_BUS_FMT_SBGGR8_1X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_raw_fmts[VPDMA_DATA_FMT_RAW8],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_SGBRG8,
+		.code		= MEDIA_BUS_FMT_SGBRG8_1X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_raw_fmts[VPDMA_DATA_FMT_RAW8],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_SGRBG8,
+		.code		= MEDIA_BUS_FMT_SGRBG8_1X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_raw_fmts[VPDMA_DATA_FMT_RAW8],
+				  },
+	},
+	{
+		.fourcc		= V4L2_PIX_FMT_SRGGB8,
+		.code		= MEDIA_BUS_FMT_SRGGB8_1X8,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_raw_fmts[VPDMA_DATA_FMT_RAW8],
+				  },
+	},
+	{
+		/* V4L2 currently only defines one 16 bit variant */
+		.fourcc		= V4L2_PIX_FMT_SBGGR16,
+		.code		= MEDIA_BUS_FMT_SBGGR16_1X16,
+		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_raw_fmts[VPDMA_DATA_FMT_RAW16],
+				  },
+	},
+};
+
+/*
+ * DMA address/data block for the shadow registers
+ */
+struct vip_mmr_adb {
+	struct vpdma_adb_hdr	sc_hdr0;
+	u32			sc_regs0[7];
+	u32			sc_pad0[1];
+	struct vpdma_adb_hdr	sc_hdr8;
+	u32			sc_regs8[6];
+	u32			sc_pad8[2];
+	struct vpdma_adb_hdr	sc_hdr17;
+	u32			sc_regs17[9];
+	u32			sc_pad17[3];
+	struct vpdma_adb_hdr	csc_hdr;
+	u32			csc_regs[6];
+	u32			csc_pad[2];
+};
+
+/*
+ * Function prototype declarations
+ */
+static int alloc_port(struct vip_dev *, int);
+static void free_port(struct vip_port *);
+static int vip_setup_parser(struct vip_port *port);
+static int vip_setup_scaler(struct vip_stream *stream);
+static void vip_enable_parser(struct vip_port *port, bool on);
+static void vip_reset_parser(struct vip_port *port, bool on);
+static void vip_parser_stop_imm(struct vip_port *port, bool on);
+static void stop_dma(struct vip_stream *stream, bool clear_list);
+static int vip_load_vpdma_list_fifo(struct vip_stream *stream);
+static inline bool is_scaler_available(struct vip_port *port);
+static inline bool allocate_scaler(struct vip_port *port);
+static inline void free_scaler(struct vip_port *port);
+static bool is_csc_available(struct vip_port *port);
+static bool allocate_csc(struct vip_port *port,
+			 enum vip_csc_state csc_direction);
+static void free_csc(struct vip_port *port);
+
+/* initialize  v4l2_format_info member in vip_formats array */
+static void vip_init_format_info(struct device *dev)
+{
+	struct vip_fmt *fmt;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vip_formats); i++) {
+		fmt = &vip_formats[i];
+		fmt->finfo = v4l2_format_info(fmt->fourcc);
+	}
+}
+
+/*  Print Four-character-code (FOURCC) */
+static char *fourcc_to_str(u32 fmt)
+{
+	static char code[5];
+
+	code[0] = (unsigned char)(fmt & 0xff);
+	code[1] = (unsigned char)((fmt >> 8) & 0xff);
+	code[2] = (unsigned char)((fmt >> 16) & 0xff);
+	code[3] = (unsigned char)((fmt >> 24) & 0xff);
+	code[4] = '\0';
+
+	return code;
+}
+
+/*
+ * Find our format description corresponding to the passed v4l2_format
+ */
+static struct vip_fmt *find_port_format_by_pix(struct vip_port *port,
+					       u32 pixelformat)
+{
+	struct vip_fmt *fmt;
+	unsigned int index;
+
+	for (index = 0; index < port->num_active_fmt; index++) {
+		fmt = port->active_fmt[index];
+		if (fmt->fourcc == pixelformat)
+			return fmt;
+	}
+
+	return NULL;
+}
+
+static struct vip_fmt *find_port_format_by_code(struct vip_port *port,
+						u32 code)
+{
+	struct vip_fmt *fmt;
+	unsigned int index;
+
+	for (index = 0; index < port->num_active_fmt; index++) {
+		fmt = port->active_fmt[index];
+		if (fmt->code == code)
+			return fmt;
+	}
+
+	return NULL;
+}
+
+inline struct vip_port *notifier_to_vip_port(struct v4l2_async_notifier *n)
+{
+	return container_of(n, struct vip_port, notifier);
+}
+
+static bool vip_is_mbuscode_yuv(u32 code)
+{
+	return ((code & 0xff00) == 0x2000);
+}
+
+static bool vip_is_mbuscode_rgb(u32 code)
+{
+	return ((code & 0xff00) == 0x1000);
+}
+
+static bool vip_is_mbuscode_raw(u32 code)
+{
+	return ((code & 0xff00) == 0x3000);
+}
+
+/*
+ * This is not an accurate conversion but it is only used to
+ * assess if color conversion is needed.
+ */
+static u32 vip_mbus_code_to_fourcc(u32 code)
+{
+	if (vip_is_mbuscode_rgb(code))
+		return V4L2_PIX_FMT_RGB24;
+
+	if (vip_is_mbuscode_yuv(code))
+		return V4L2_PIX_FMT_UYVY;
+
+	return V4L2_PIX_FMT_SBGGR8;
+}
+
+static enum vip_csc_state
+vip_csc_direction(u32 src_code, const struct v4l2_format_info *dfinfo)
+{
+	if (vip_is_mbuscode_yuv(src_code) && v4l2_is_format_rgb(dfinfo))
+		return VIP_CSC_Y2R;
+	else if (vip_is_mbuscode_rgb(src_code) && v4l2_is_format_yuv(dfinfo))
+		return VIP_CSC_R2Y;
+	else
+		return VIP_CSC_NA;
+}
+
+/*
+ * Insert a masked field into a 32-bit field
+ */
+static void insert_field(u32 *valp, u32 field, u32 mask, int shift)
+{
+	u32 val = *valp;
+
+	val &= ~(mask << shift);
+	val |= (field & mask) << shift;
+	*valp = val;
+}
+
+/*
+ * Set the headers for all of the address/data block structures.
+ */
+static void init_adb_hdrs(struct vip_port *port)
+{
+	VIP_SET_MMR_ADB_HDR(port, sc_hdr0, sc_regs0,
+			    GET_OFFSET_TOP(port, port->dev->sc, CFG_SC0));
+	VIP_SET_MMR_ADB_HDR(port, sc_hdr8, sc_regs8,
+			    GET_OFFSET_TOP(port, port->dev->sc, CFG_SC8));
+	VIP_SET_MMR_ADB_HDR(port, sc_hdr17, sc_regs17,
+			    GET_OFFSET_TOP(port, port->dev->sc, CFG_SC17));
+	VIP_SET_MMR_ADB_HDR(port, csc_hdr, csc_regs,
+			    GET_OFFSET_TOP(port, port->dev->csc, CSC_CSC00));
+
+};
+
+static void vip_module_toggle(struct vip_dev *dev, uint32_t module, bool on)
+{
+	u32 val = 0;
+
+	val = reg_read(dev, VIP_CLK_RESET);
+
+	if (dev->slice_id == VIP_SLICE2)
+		module <<= 1;
+
+	if (on)
+		val |= module;
+	else
+		val &= ~module;
+
+	reg_write(dev, VIP_CLK_RESET, val);
+}
+
+/*
+ * Enable or disable the VIP clocks
+ */
+static void vip_set_clock_enable(struct vip_dev *dev, bool on)
+{
+	u32 val = 0;
+
+	val = reg_read(dev, VIP_CLK_ENABLE);
+	if (on) {
+		val |= VIP_VPDMA_CLK_ENABLE;
+		if (dev->slice_id == VIP_SLICE1)
+			val |= VIP_VIP1_DATA_PATH_CLK_ENABLE;
+		else
+			val |= VIP_VIP2_DATA_PATH_CLK_ENABLE;
+	} else {
+		if (dev->slice_id == VIP_SLICE1)
+			val &= ~VIP_VIP1_DATA_PATH_CLK_ENABLE;
+		else
+			val &= ~VIP_VIP2_DATA_PATH_CLK_ENABLE;
+
+		/* Both VIP are disabled then shutdown VPDMA also */
+		if (!(val & (VIP_VIP1_DATA_PATH_CLK_ENABLE |
+			     VIP_VIP2_DATA_PATH_CLK_ENABLE)))
+			val = 0;
+	}
+
+	reg_write(dev, VIP_CLK_ENABLE, val);
+}
+
+/* This helper function is used to enable the clock early on to
+ * enable vpdma firmware loading before the slice device are created
+ */
+static void vip_shared_set_clock_enable(struct vip_shared *shared, bool on)
+{
+	u32 val = 0;
+
+	val = VIP_VIP1_DATA_PATH_CLK_ENABLE | VIP_VPDMA_CLK_ENABLE;
+
+	reg_write(shared, VIP_CLK_ENABLE, val);
+}
+
+static void vip_top_reset(struct vip_dev *dev)
+{
+	u32 val = 0;
+
+	val = reg_read(dev, VIP_CLK_RESET);
+
+	if (dev->slice_id == VIP_SLICE1)
+		insert_field(&val, 1, VIP_DATA_PATH_CLK_RESET_MASK,
+			     VIP_VIP1_DATA_PATH_RESET_SHIFT);
+	else
+		insert_field(&val, 1, VIP_DATA_PATH_CLK_RESET_MASK,
+			     VIP_VIP2_DATA_PATH_RESET_SHIFT);
+
+	reg_write(dev, VIP_CLK_RESET, val);
+
+	usleep_range(200, 250);
+
+	val = reg_read(dev, VIP_CLK_RESET);
+
+	if (dev->slice_id == VIP_SLICE1)
+		insert_field(&val, 0, VIP_DATA_PATH_CLK_RESET_MASK,
+			     VIP_VIP1_DATA_PATH_RESET_SHIFT);
+	else
+		insert_field(&val, 0, VIP_DATA_PATH_CLK_RESET_MASK,
+			     VIP_VIP2_DATA_PATH_RESET_SHIFT);
+	reg_write(dev, VIP_CLK_RESET, val);
+}
+
+static void vip_top_vpdma_reset(struct vip_shared *shared)
+{
+	u32 val;
+
+	val = reg_read(shared, VIP_CLK_RESET);
+	insert_field(&val, 1, VIP_VPDMA_CLK_RESET_MASK,
+		     VIP_VPDMA_CLK_RESET_SHIFT);
+	reg_write(shared, VIP_CLK_RESET, val);
+
+	usleep_range(200, 250);
+
+	val = reg_read(shared, VIP_CLK_RESET);
+	insert_field(&val, 0, VIP_VPDMA_CLK_RESET_MASK,
+		     VIP_VPDMA_CLK_RESET_SHIFT);
+	reg_write(shared, VIP_CLK_RESET, val);
+}
+
+static void vip_set_pclk_invert(struct vip_port *port)
+{
+	u32 offset;
+	/*
+	 * When the VIP parser is configured to so that the pixel clock
+	 * is to be sampled at falling edge, the pixel clock needs to be
+	 * inverted before it is given to the VIP module. This is done
+	 * by setting a bit in the CTRL_CORE_SMA_SW1 register.
+	 */
+
+	if (port->dev->instance_id == VIP_INSTANCE1) {
+		offset = 0 + 2 * port->port_id + port->dev->slice_id;
+	} else if (port->dev->instance_id == VIP_INSTANCE2) {
+		offset = 4 + 2 * port->port_id + port->dev->slice_id;
+	} else if (port->dev->instance_id == VIP_INSTANCE3) {
+		offset = 10 - port->dev->slice_id;
+	} else {
+		v4l2_err(port, "%s: VIP instance id out of range...\n",
+			 __func__);
+		return;
+	}
+
+	if (port->dev->syscon_pol)
+		regmap_update_bits(port->dev->syscon_pol,
+				   port->dev->syscon_pol_offset,
+				   1 << offset, 1 << offset);
+}
+
+static void vip_set_data_interface(struct vip_port *port,
+				   enum data_interface_modes mode)
+{
+	u32 val = 0;
+
+	insert_field(&val, mode, VIP_DATA_INTERFACE_MODE_MASK,
+		     VIP_DATA_INTERFACE_MODE_SHFT);
+
+	reg_write(port->dev->parser, VIP_PARSER_MAIN_CFG, val);
+}
+
+static void vip_set_slice_path(struct vip_dev *dev,
+			       enum data_path_select data_path, u32 path_val)
+{
+	u32 val = 0;
+	int data_path_reg;
+
+	data_path_reg = VIP_VIP1_DATA_PATH_SELECT + 4 * dev->slice_id;
+
+	switch (data_path) {
+	case ALL_FIELDS_DATA_SELECT:
+		val |= path_val;
+		break;
+	case VIP_CSC_SRC_DATA_SELECT:
+		insert_field(&val, path_val, VIP_CSC_SRC_SELECT_MASK,
+			     VIP_CSC_SRC_SELECT_SHFT);
+		break;
+	case VIP_SC_SRC_DATA_SELECT:
+		insert_field(&val, path_val, VIP_SC_SRC_SELECT_MASK,
+			     VIP_SC_SRC_SELECT_SHFT);
+		break;
+	case VIP_RGB_SRC_DATA_SELECT:
+		val |= (path_val) ? VIP_RGB_SRC_SELECT : 0;
+		break;
+	case VIP_RGB_OUT_LO_DATA_SELECT:
+		val |= (path_val) ? VIP_RGB_OUT_LO_SRC_SELECT : 0;
+		break;
+	case VIP_RGB_OUT_HI_DATA_SELECT:
+		val |= (path_val) ? VIP_RGB_OUT_HI_SRC_SELECT : 0;
+		break;
+	case VIP_CHR_DS_1_SRC_DATA_SELECT:
+		insert_field(&val, path_val, VIP_DS1_SRC_SELECT_MASK,
+			     VIP_DS1_SRC_SELECT_SHFT);
+		break;
+	case VIP_CHR_DS_2_SRC_DATA_SELECT:
+		insert_field(&val, path_val, VIP_DS2_SRC_SELECT_MASK,
+			     VIP_DS2_SRC_SELECT_SHFT);
+		break;
+	case VIP_MULTI_CHANNEL_DATA_SELECT:
+		val |= (path_val) ? VIP_MULTI_CHANNEL_SELECT : 0;
+		break;
+	case VIP_CHR_DS_1_DATA_BYPASS:
+		val |= (path_val) ? VIP_DS1_BYPASS : 0;
+		break;
+	case VIP_CHR_DS_2_DATA_BYPASS:
+		val |= (path_val) ? VIP_DS2_BYPASS : 0;
+		break;
+	default:
+		v4l2_err(dev, "%s: data_path 0x%x is not valid\n",
+			 __func__, data_path);
+		return;
+	}
+	insert_field(&val, data_path, VIP_DATAPATH_SELECT_MASK,
+		     VIP_DATAPATH_SELECT_SHFT);
+	reg_write(dev, data_path_reg, val);
+	v4l2_dbg(3, debug, dev, "%s: DATA_PATH_SELECT(%08X): %08X\n", __func__,
+		 data_path_reg, reg_read(dev, data_path_reg));
+}
+
+/*
+ * Return the vip_stream structure for a given struct file
+ */
+static inline struct vip_stream *file2stream(struct file *file)
+{
+	return video_drvdata(file);
+}
+
+/*
+ * Append a destination descriptor to the current descriptor list,
+ * setting up dma to the given srce.
+ */
+static int add_out_dtd(struct vip_stream *stream, int srce_type)
+{
+	struct vip_port *port = stream->port;
+	struct vip_dev *dev = port->dev;
+	struct vip_srce_info *sinfo = &srce_info[srce_type];
+	struct v4l2_rect *c_rect = &port->c_rect;
+	struct vip_fmt *fmt = port->fmt;
+	int channel, plane = 0;
+	int max_width, max_height;
+	dma_addr_t dma_addr = 0;
+	u32 flags;
+	u32 width = stream->width;
+
+	channel = sinfo->base_channel;
+
+	switch (srce_type) {
+	case VIP_SRCE_MULT_PORT:
+	case VIP_SRCE_MULT_ANC:
+		if (port->port_id == VIP_PORTB)
+			channel += VIP_CHAN_MULT_PORTB_OFFSET;
+		channel += stream->stream_id;
+		flags = 0;
+		break;
+	case VIP_SRCE_CHROMA:
+		plane = 1;
+		fallthrough;
+	case VIP_SRCE_LUMA:
+		if (port->port_id == VIP_PORTB) {
+			if (port->scaler && !port->fmt->coplanar)
+				/*
+				 * In this case Port A Chroma channel
+				 * is used to carry Port B scaled YUV422
+				 */
+				channel += 1;
+			else
+				channel += VIP_CHAN_YUV_PORTB_OFFSET;
+		}
+		flags = port->flags;
+		break;
+	case VIP_SRCE_RGB:
+		if (port->port_id == VIP_PORTB ||
+		    (port->port_id == VIP_PORTA &&
+		     port->csc == VIP_CSC_NA &&
+		     v4l2_is_format_rgb(port->fmt->finfo)))
+			/*
+			 * RGB sensor only connect to Y_LO
+			 * channel i.e. port B channel.
+			 */
+			channel += VIP_CHAN_RGB_PORTB_OFFSET;
+		flags = port->flags;
+		break;
+	default:
+		v4l2_err(stream, "%s: srce_type 0x%x is not valid\n",
+			 __func__, srce_type);
+		return -1;
+	}
+
+	if (dev->slice_id == VIP_SLICE2)
+		channel += VIP_CHAN_VIP2_OFFSET;
+
+	if (port->fmt->vpdma_fmt[0] == &vpdma_raw_fmts[VPDMA_DATA_FMT_RAW8]) {
+		/*
+		 * Special case since we are faking a YUV422 16bit format
+		 * to have the vpdma perform the needed byte swap
+		 * we need to adjust the pixel width accordingly
+		 * otherwise the parser will attempt to collect more pixels
+		 * then available and the vpdma transfer will exceed the
+		 * allocated frame buffer.
+		 */
+		width >>= 1;
+		v4l2_dbg(1, debug, stream, "%s: 8 bit raw detected, adjusting width to %d\n",
+			 __func__, width);
+	}
+
+	/*
+	 * Use VPDMA_MAX_SIZE1 or VPDMA_MAX_SIZE2 register for slice0/1
+	 */
+
+	if (dev->slice_id == VIP_SLICE1) {
+		vpdma_set_max_size(dev->shared->vpdma, VPDMA_MAX_SIZE1,
+				   width, stream->height);
+
+		max_width = MAX_OUT_WIDTH_REG1;
+		max_height = MAX_OUT_HEIGHT_REG1;
+	} else if (dev->slice_id == VIP_SLICE2) {
+		vpdma_set_max_size(dev->shared->vpdma, VPDMA_MAX_SIZE2,
+				   width, stream->height);
+
+		max_width = MAX_OUT_WIDTH_REG2;
+		max_height = MAX_OUT_HEIGHT_REG2;
+	}
+
+	/*
+	 * Mark this channel to be cleared while cleaning up resources
+	 * This will make sure that an abort descriptor for this channel
+	 * would be submitted to VPDMA causing any ongoing  transaction to be
+	 * aborted and cleanup the VPDMA FSM for this channel
+	 */
+	stream->vpdma_channels[channel] = 1;
+
+	vpdma_rawchan_add_out_dtd(&stream->desc_list, c_rect->width,
+				  stream->bytesperline, c_rect,
+				  fmt->vpdma_fmt[plane], dma_addr,
+				  max_width, max_height, channel, flags);
+	return 0;
+}
+
+/*
+ * add_stream_dtds - prepares and starts DMA for pending transfers
+ */
+static void add_stream_dtds(struct vip_stream *stream)
+{
+	struct vip_port *port = stream->port;
+	int srce_type;
+
+	if (port->flags & FLAG_MULT_PORT)
+		srce_type = VIP_SRCE_MULT_PORT;
+	else if (port->flags & FLAG_MULT_ANC)
+		srce_type = VIP_SRCE_MULT_ANC;
+	else if (v4l2_is_format_rgb(port->fmt->finfo))
+		srce_type = VIP_SRCE_RGB;
+	else
+		srce_type = VIP_SRCE_LUMA;
+
+	add_out_dtd(stream, srce_type);
+
+	if (srce_type == VIP_SRCE_LUMA && port->fmt->coplanar)
+		add_out_dtd(stream, VIP_SRCE_CHROMA);
+}
+
+static void enable_irqs(struct vip_dev *dev, int irq_num, int list_num)
+{
+	struct vip_parser_data *parser = dev->parser;
+	u32 reg_addr = VIP_INT0_ENABLE0_SET +
+			VIP_INTC_INTX_OFFSET * irq_num;
+	u32 irq_val = (1 << (list_num * 2)) |
+		      (VIP_VIP1_PARSER_INT << (irq_num * 1));
+
+	/* Enable Parser Interrupt */
+	reg_write(parser, VIP_PARSER_FIQ_MASK, ~PARSER_IRQ_MASK);
+
+	reg_write(dev->shared, reg_addr, irq_val);
+
+	vpdma_enable_list_complete_irq(dev->shared->vpdma,
+				       irq_num, list_num, true);
+}
+
+static void disable_irqs(struct vip_dev *dev, int irq_num, int list_num)
+{
+	struct vip_parser_data *parser = dev->parser;
+	u32 reg_addr = VIP_INT0_ENABLE0_CLR +
+			VIP_INTC_INTX_OFFSET * irq_num;
+	u32 irq_val = (1 << (list_num * 2)) |
+		      (VIP_VIP1_PARSER_INT << (irq_num * 1));
+
+	/* Disable all Parser Interrupt */
+	reg_write(parser, VIP_PARSER_FIQ_MASK, 0xffffffff);
+
+	reg_write(dev->shared, reg_addr, irq_val);
+
+	vpdma_enable_list_complete_irq(dev->shared->vpdma,
+				       irq_num, list_num, false);
+}
+
+static void clear_irqs(struct vip_dev *dev, int irq_num, int list_num)
+{
+	struct vip_parser_data *parser = dev->parser;
+	u32 reg_addr = VIP_INT0_STATUS0_CLR +
+			VIP_INTC_INTX_OFFSET * irq_num;
+	u32 irq_val = (1 << (list_num * 2)) |
+		      (VIP_VIP1_PARSER_INT << (irq_num * 1));
+
+	/* Clear all Parser Interrupt */
+	reg_write(parser, VIP_PARSER_FIQ_CLR, 0xffffffff);
+	reg_write(parser, VIP_PARSER_FIQ_CLR, 0x0);
+
+	reg_write(dev->shared, reg_addr, irq_val);
+
+	vpdma_clear_list_stat(dev->shared->vpdma, irq_num, dev->slice_id);
+}
+
+static void populate_desc_list(struct vip_stream *stream)
+{
+	struct vip_port *port = stream->port;
+	struct vip_dev *dev = port->dev;
+	unsigned int list_length;
+
+	stream->desc_next = stream->desc_list.buf.addr;
+	add_stream_dtds(stream);
+
+	list_length = stream->desc_next - stream->desc_list.buf.addr;
+	vpdma_map_desc_buf(dev->shared->vpdma, &stream->desc_list.buf);
+}
+
+/*
+ * start_dma - adds descriptors to the dma list and submits them.
+ * Should be called after a new vb is queued and on a vpdma list
+ * completion interrupt.
+ */
+static void start_dma(struct vip_stream *stream, struct vip_buffer *buf)
+{
+	struct vip_dev *dev = stream->port->dev;
+	struct vpdma_data *vpdma = dev->shared->vpdma;
+	int list_num = stream->list_num;
+	dma_addr_t dma_addr;
+	int drop_data;
+
+	if (vpdma_list_busy(vpdma, list_num)) {
+		v4l2_err(stream, "vpdma list busy, cannot post\n");
+		return;				/* nothing to do */
+	}
+
+	if (buf) {
+		dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+		drop_data = 0;
+		v4l2_dbg(4, debug, stream, "%s: vb2 buf idx:%d, dma_addr:%pad\n",
+			 __func__, buf->vb.vb2_buf.index, &dma_addr);
+	} else {
+		dma_addr = 0;
+		drop_data = 1;
+		v4l2_dbg(4, debug, stream, "%s: dropped\n", __func__);
+	}
+
+	vpdma_update_dma_addr(dev->shared->vpdma, &stream->desc_list,
+			      dma_addr, stream->write_desc, drop_data, 0);
+
+	if (stream->port->fmt->coplanar) {
+		dma_addr += stream->bytesperline * stream->height;
+		vpdma_update_dma_addr(dev->shared->vpdma, &stream->desc_list,
+				      dma_addr, stream->write_desc + 1,
+				      drop_data, 1);
+	}
+
+	vpdma_submit_descs(dev->shared->vpdma,
+			   &stream->desc_list, stream->list_num);
+}
+
+static void vip_schedule_next_buffer(struct vip_stream *stream)
+{
+	struct vip_dev *dev = stream->port->dev;
+	struct vip_buffer *buf;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->slock, flags);
+	if (list_empty(&stream->vidq)) {
+		v4l2_dbg(4, debug, stream, "Dropping frame\n");
+		if (list_empty(&stream->dropq)) {
+			v4l2_err(stream, "No dropq buffer left!");
+			spin_unlock_irqrestore(&dev->slock, flags);
+			return;
+		}
+		buf = list_entry(stream->dropq.next,
+				 struct vip_buffer, list);
+
+		buf->drop = true;
+		list_move_tail(&buf->list, &stream->post_bufs);
+		buf = NULL;
+	} else {
+		buf = list_entry(stream->vidq.next,
+				 struct vip_buffer, list);
+		buf->drop = false;
+		list_move_tail(&buf->list, &stream->post_bufs);
+		v4l2_dbg(4, debug, stream, "added next buffer\n");
+	}
+
+	spin_unlock_irqrestore(&dev->slock, flags);
+	start_dma(stream, buf);
+}
+
+static void vip_process_buffer_complete(struct vip_stream *stream)
+{
+	struct vip_dev *dev = stream->port->dev;
+	struct vip_buffer *buf;
+	struct vb2_v4l2_buffer *vb = NULL;
+	unsigned long flags, fld;
+
+	buf = list_first_entry(&stream->post_bufs, struct vip_buffer, list);
+
+	if (stream->port->flags & FLAG_INTERLACED) {
+		vpdma_unmap_desc_buf(dev->shared->vpdma,
+				     &stream->desc_list.buf);
+
+		fld = dtd_get_field(stream->write_desc);
+		stream->field = fld ? V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP;
+
+		vpdma_map_desc_buf(dev->shared->vpdma, &stream->desc_list.buf);
+	}
+
+	if (buf) {
+		v4l2_dbg(4, debug, stream, "vip buffer complete 0x%x, 0x%x\n",
+			 (unsigned int)buf, buf->drop);
+
+		vb = &buf->vb;
+		vb->field = stream->field;
+		vb->sequence = stream->sequence;
+		vb->vb2_buf.timestamp = ktime_get_ns();
+
+		if (buf->drop) {
+			spin_lock_irqsave(&dev->slock, flags);
+			list_move_tail(&buf->list, &stream->dropq);
+			spin_unlock_irqrestore(&dev->slock, flags);
+		} else {
+			spin_lock_irqsave(&dev->slock, flags);
+			list_del(&buf->list);
+			spin_unlock_irqrestore(&dev->slock, flags);
+			vb2_buffer_done(&vb->vb2_buf, VB2_BUF_STATE_DONE);
+		}
+	} else {
+		v4l2_err(stream, "%s: buf is null!!!\n", __func__);
+		return;
+	}
+
+	stream->sequence++;
+}
+
+static int vip_reset_vpdma(struct vip_stream *stream)
+{
+	struct vip_port *port = stream->port;
+	struct vip_dev *dev = port->dev;
+	struct vip_buffer *buf;
+	unsigned long flags;
+
+	stop_dma(stream, false);
+
+	spin_lock_irqsave(&dev->slock, flags);
+	/* requeue all active buffers in the opposite order */
+	while (!list_empty(&stream->post_bufs)) {
+		buf = list_last_entry(&stream->post_bufs,
+				      struct vip_buffer, list);
+		list_del(&buf->list);
+		if (buf->drop == 1) {
+			list_add_tail(&buf->list, &stream->dropq);
+			v4l2_dbg(4, debug, stream, "requeueing drop buffer on dropq\n");
+		} else {
+			list_add(&buf->list, &stream->vidq);
+			v4l2_dbg(4, debug, stream, "requeueing vb2 buf idx:%d on vidq\n",
+				 buf->vb.vb2_buf.index);
+		}
+	}
+	spin_unlock_irqrestore(&dev->slock, flags);
+
+	/* Make sure the desc_list is unmapped */
+	vpdma_unmap_desc_buf(dev->shared->vpdma, &stream->desc_list.buf);
+
+	return 0;
+}
+
+static void vip_overflow_recovery_work(struct work_struct *work)
+{
+	struct vip_stream *stream = container_of(work, struct vip_stream,
+						 recovery_work);
+	struct vip_port *port = stream->port;
+	struct vip_dev *dev = port->dev;
+
+	v4l2_err(stream, "%s: Port %c\n", __func__,
+		 port->port_id == VIP_PORTA ? 'A' : 'B');
+
+	disable_irqs(dev, dev->slice_id, stream->list_num);
+	clear_irqs(dev, dev->slice_id, stream->list_num);
+
+	/* 1.	Set VIP_XTRA6_PORT_A[31:16] YUV_SRCNUM_STOP_IMMEDIATELY */
+	/* 2.	Set VIP_XTRA6_PORT_A[15:0] ANC_SRCNUM_STOP_IMMEDIATELY */
+	vip_parser_stop_imm(port, 1);
+
+	/* 3.	Clear VIP_PORT_A[8] ENABLE */
+	/*
+	 * 4.	Set VIP_PORT_A[7] CLR_ASYNC_FIFO_RD
+	 *      Set VIP_PORT_A[6] CLR_ASYNC_FIFO_WR
+	 */
+	vip_enable_parser(port, false);
+
+	/* 5.	Set VIP_PORT_A[23] SW_RESET */
+	vip_reset_parser(port, 1);
+
+	/*
+	 * 6.	Reset other VIP modules
+	 *	For each module used downstream of VIP_PARSER, write 1 to the
+	 *      bit location of the VIP_CLKC_RST register which is connected
+	 *      to VIP_PARSER
+	 */
+	vip_module_toggle(dev, VIP_DP_RST, true);
+
+	usleep_range(200, 250);
+
+	/*
+	 * 7.	Abort VPDMA channels
+	 *	Write to list attribute to stop list 0
+	 *	Write to list address register location of abort list
+	 *	Write to list attribute register list 0 and size of abort list
+	 */
+	vip_reset_vpdma(stream);
+
+	/* 8.	Clear VIP_PORT_A[23] SW_RESET */
+	vip_reset_parser(port, 0);
+
+	/*
+	 * 9.	Un-reset other VIP modules
+	 *	For each module used downstream of VIP_PARSER, write 0 to
+	 *	the bit location of the VIP_CLKC_RST register which is
+	 *	connected to VIP_PARSER
+	 */
+	vip_module_toggle(dev, VIP_DP_RST, false);
+
+	/* 10.	(Delay) */
+	/* 11.	SC coeff downloaded (if VIP_SCALER is being used) */
+	vip_setup_scaler(stream);
+
+	/* 12.	(Delay) */
+		/* the above are not needed here yet */
+
+	populate_desc_list(stream);
+	stream->num_recovery++;
+	if (stream->num_recovery < 5) {
+		/* Reload the vpdma */
+		vip_load_vpdma_list_fifo(stream);
+
+		enable_irqs(dev, dev->slice_id, stream->list_num);
+		vip_schedule_next_buffer(stream);
+
+		/* 13.	Clear VIP_XTRA6_PORT_A[31:16] YUV_SRCNUM_STOP_IMM */
+		/* 14.	Clear VIP_XTRA6_PORT_A[15:0] ANC_SRCNUM_STOP_IMM */
+
+		vip_parser_stop_imm(port, 0);
+
+		/* 15.	Set VIP_PORT_A[8] ENABLE */
+		/*
+		 * 16.	Clear VIP_PORT_A[7] CLR_ASYNC_FIFO_RD
+		 *	Clear VIP_PORT_A[6] CLR_ASYNC_FIFO_WR
+		 */
+		vip_enable_parser(port, true);
+	} else {
+		v4l2_err(stream, "%s: num_recovery limit exceeded leaving disabled\n",
+			 __func__);
+	}
+}
+
+static void handle_parser_irqs(struct vip_dev *dev)
+{
+	struct vip_parser_data *parser = dev->parser;
+	struct vip_port *porta = dev->ports[VIP_PORTA];
+	struct vip_port *portb = dev->ports[VIP_PORTB];
+	struct vip_stream *stream = NULL;
+	u32 irq_stat = reg_read(parser, VIP_PARSER_FIQ_STATUS);
+	int i;
+
+	v4l2_dbg(3, debug, dev, "%s: FIQ_STATUS: 0x%08x\n", __func__, irq_stat);
+
+	/* Clear all Parser Interrupt */
+	reg_write(parser, VIP_PARSER_FIQ_CLR, irq_stat);
+	reg_write(parser, VIP_PARSER_FIQ_CLR, 0x0);
+
+	#ifdef DEBUG
+	if (irq_stat & VIP_PORTA_VDET)
+		v4l2_dbg(3, debug, dev, "VIP_PORTA_VDET\n");
+	if (irq_stat & VIP_PORTB_VDET)
+		v4l2_dbg(3, debug, dev, "VIP_PORTB_VDET\n");
+	if (irq_stat & VIP_PORTA_ASYNC_FIFO_OF)
+		v4l2_err(dev, "VIP_PORTA_ASYNC_FIFO_OF\n");
+	if (irq_stat & VIP_PORTB_ASYNC_FIFO_OF)
+		v4l2_err(dev, "VIP_PORTB_ASYNC_FIFO_OF\n");
+	if (irq_stat & VIP_PORTA_OUTPUT_FIFO_YUV)
+		v4l2_err(dev, "VIP_PORTA_OUTPUT_FIFO_YUV\n");
+	if (irq_stat & VIP_PORTA_OUTPUT_FIFO_ANC)
+		v4l2_err(dev, "VIP_PORTA_OUTPUT_FIFO_ANC\n");
+	if (irq_stat & VIP_PORTB_OUTPUT_FIFO_YUV)
+		v4l2_err(dev, "VIP_PORTB_OUTPUT_FIFO_YUV\n");
+	if (irq_stat & VIP_PORTB_OUTPUT_FIFO_ANC)
+		v4l2_err(dev, "VIP_PORTB_OUTPUT_FIFO_ANC\n");
+	if (irq_stat & VIP_PORTA_CONN)
+		v4l2_dbg(3, debug, dev, "VIP_PORTA_CONN\n");
+	if (irq_stat & VIP_PORTA_DISCONN)
+		v4l2_dbg(3, debug, dev, "VIP_PORTA_DISCONN\n");
+	if (irq_stat & VIP_PORTB_CONN)
+		v4l2_dbg(3, debug, dev, "VIP_PORTB_CONN\n");
+	if (irq_stat & VIP_PORTB_DISCONN)
+		v4l2_dbg(3, debug, dev, "VIP_PORTB_DISCONN\n");
+	if (irq_stat & VIP_PORTA_SRC0_SIZE)
+		v4l2_dbg(3, debug, dev, "VIP_PORTA_SRC0_SIZE\n");
+	if (irq_stat & VIP_PORTB_SRC0_SIZE)
+		v4l2_dbg(3, debug, dev, "VIP_PORTB_SRC0_SIZE\n");
+	if (irq_stat & VIP_PORTA_YUV_PROTO_VIOLATION)
+		v4l2_dbg(3, debug, dev, "VIP_PORTA_YUV_PROTO_VIOLATION\n");
+	if (irq_stat & VIP_PORTA_ANC_PROTO_VIOLATION)
+		v4l2_dbg(3, debug, dev, "VIP_PORTA_ANC_PROTO_VIOLATION\n");
+	if (irq_stat & VIP_PORTB_YUV_PROTO_VIOLATION)
+		v4l2_dbg(3, debug, dev, "VIP_PORTB_YUV_PROTO_VIOLATION\n");
+	if (irq_stat & VIP_PORTB_ANC_PROTO_VIOLATION)
+		v4l2_dbg(3, debug, dev, "VIP_PORTB_ANC_PROTO_VIOLATION\n");
+	if (irq_stat & VIP_PORTA_CFG_DISABLE_COMPLETE)
+		v4l2_dbg(3, debug, dev, "VIP_PORTA_CFG_DISABLE_COMPLETE\n");
+	if (irq_stat & VIP_PORTB_CFG_DISABLE_COMPLETE)
+		v4l2_dbg(3, debug, dev, "VIP_PORTB_CFG_DISABLE_COMPLETE\n");
+	#endif
+
+	if (irq_stat & (VIP_PORTA_ASYNC_FIFO_OF |
+			VIP_PORTA_OUTPUT_FIFO_YUV |
+			VIP_PORTA_OUTPUT_FIFO_ANC)) {
+		for (i = 0; i < VIP_CAP_STREAMS_PER_PORT; i++) {
+			if (porta->cap_streams[i] &&
+			    porta->cap_streams[i]->port->port_id ==
+			    porta->port_id) {
+				stream = porta->cap_streams[i];
+				break;
+			}
+		}
+		if (stream) {
+			disable_irqs(dev, dev->slice_id,
+				     stream->list_num);
+			schedule_work(&stream->recovery_work);
+			return;
+		}
+	}
+	if (irq_stat & (VIP_PORTB_ASYNC_FIFO_OF |
+			VIP_PORTB_OUTPUT_FIFO_YUV |
+			VIP_PORTB_OUTPUT_FIFO_ANC)) {
+		for (i = 0; i < VIP_CAP_STREAMS_PER_PORT; i++) {
+			if (portb->cap_streams[i] &&
+			    portb->cap_streams[i]->port->port_id ==
+			    portb->port_id) {
+				stream = portb->cap_streams[i];
+				break;
+			}
+		}
+		if (stream) {
+			disable_irqs(dev, dev->slice_id,
+				     stream->list_num);
+			schedule_work(&stream->recovery_work);
+			return;
+		}
+	}
+}
+
+static irqreturn_t vip_irq(int irq_vip, void *data)
+{
+	struct vip_dev *dev = (struct vip_dev *)data;
+	struct vpdma_data *vpdma;
+	struct vip_stream *stream;
+	int list_num;
+	int irq_num = dev->slice_id;
+	u32 irqst, irqst_saved, reg_addr;
+
+	if (!dev->shared)
+		return IRQ_HANDLED;
+
+	vpdma = dev->shared->vpdma;
+	reg_addr = VIP_INT0_STATUS0 +
+			VIP_INTC_INTX_OFFSET * irq_num;
+	irqst_saved = reg_read(dev->shared, reg_addr);
+	irqst = irqst_saved;
+
+	v4l2_dbg(8, debug, dev, "IRQ %d VIP_INT%d_STATUS0 0x%x\n",
+		 irq_vip, irq_num, irqst);
+	if (irqst) {
+		if (irqst & (VIP_VIP1_PARSER_INT << (irq_num * 1))) {
+			irqst &= ~(VIP_VIP1_PARSER_INT << (irq_num * 1));
+			handle_parser_irqs(dev);
+		}
+
+		for (list_num = 0; irqst && (list_num < 8);  list_num++) {
+			/* Check for LIST_COMPLETE IRQ */
+			if (!(irqst & (1 << list_num * 2)))
+				continue;
+
+			v4l2_dbg(8, debug, dev, "IRQ %d: handling LIST%d_COMPLETE\n",
+				 irq_num, list_num);
+
+			stream = vpdma_hwlist_get_priv(vpdma, list_num);
+			if (!stream || stream->list_num != list_num) {
+				v4l2_err(dev, "IRQ occurred for unused list");
+				continue;
+			}
+
+			vpdma_clear_list_stat(vpdma, irq_num, list_num);
+
+			vip_process_buffer_complete(stream);
+
+			vip_schedule_next_buffer(stream);
+
+			irqst &= ~((1 << list_num * 2));
+		}
+	}
+
+	/* Acknowledge that we are done with all interrupts */
+	reg_write(dev->shared, VIP_INTC_E0I, 1 << irq_num);
+
+	/* Clear handled events from status register */
+	reg_addr = VIP_INT0_STATUS0_CLR +
+		   VIP_INTC_INTX_OFFSET * irq_num;
+	reg_write(dev->shared, reg_addr, irqst_saved);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * video ioctls
+ */
+static int vip_querycap(struct file *file, void *priv,
+			struct v4l2_capability *cap)
+{
+	struct vip_stream *stream = file2stream(file);
+	struct vip_port *port = stream->port;
+	struct vip_dev *dev = port->dev;
+	u32 vin_id = 1 + ((dev->instance_id - 1) * 2) + dev->slice_id;
+
+	strscpy(cap->driver, VIP_MODULE_NAME, sizeof(cap->driver));
+	strscpy(cap->card, VIP_MODULE_NAME, sizeof(cap->card));
+
+	snprintf(cap->bus_info, sizeof(cap->bus_info),
+		 "platform:vip%1d:vin%1d%c:stream%1d", dev->instance_id, vin_id,
+		 port->port_id == VIP_PORTA ? 'a' : 'b', stream->stream_id);
+	return 0;
+}
+
+static int vip_enuminput(struct file *file, void *priv,
+			 struct v4l2_input *inp)
+{
+	struct vip_stream *stream = file2stream(file);
+
+	if (inp->index)
+		return -EINVAL;
+
+	inp->type = V4L2_INPUT_TYPE_CAMERA;
+	inp->std = stream->vfd->tvnorms;
+	sprintf(inp->name, "camera %u", stream->vfd->num);
+
+	return 0;
+}
+
+static int vip_g_input(struct file *file, void *priv, unsigned int *i)
+{
+	*i = 0;
+	return 0;
+}
+
+static int vip_s_input(struct file *file, void *priv, unsigned int i)
+{
+	if (i != 0)
+		return -EINVAL;
+	return 0;
+}
+
+static int vip_querystd(struct file *file, void *fh, v4l2_std_id *std)
+{
+	struct vip_stream *stream = file2stream(file);
+	struct vip_port *port = stream->port;
+
+	*std = stream->vfd->tvnorms;
+	v4l2_subdev_call(port->subdev, video, querystd, std);
+	v4l2_dbg(1, debug, stream, "querystd: 0x%lx\n", (unsigned long)*std);
+	return 0;
+}
+
+static int vip_g_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+	struct vip_stream *stream = file2stream(file);
+	struct vip_port *port = stream->port;
+
+	*std = stream->vfd->tvnorms;
+	v4l2_subdev_call(port->subdev, video, g_std_output, std);
+	v4l2_dbg(1, debug, stream, "g_std: 0x%lx\n", (unsigned long)*std);
+
+	return 0;
+}
+
+static int vip_s_std(struct file *file, void *fh, v4l2_std_id std)
+{
+	struct vip_stream *stream = file2stream(file);
+	struct vip_port *port = stream->port;
+
+	v4l2_dbg(1, debug, stream, "s_std: 0x%lx\n", (unsigned long)std);
+
+	if (!(std & stream->vfd->tvnorms)) {
+		v4l2_dbg(1, debug, stream, "s_std after check: 0x%lx\n",
+			 (unsigned long)std);
+		return -EINVAL;
+	}
+
+	v4l2_subdev_call(port->subdev, video, s_std_output, std);
+	return 0;
+}
+
+static int vip_enum_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_fmtdesc *f)
+{
+	struct vip_stream *stream = file2stream(file);
+	struct vip_port *port = stream->port;
+	struct vip_fmt *fmt;
+
+	v4l2_dbg(3, debug, stream, "enum_fmt index:%d\n", f->index);
+	if (f->index >= port->num_active_fmt)
+		return -EINVAL;
+
+	fmt = port->active_fmt[f->index];
+
+	f->pixelformat = fmt->fourcc;
+	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	v4l2_dbg(3, debug, stream, "enum_fmt fourcc:%s\n",
+		 fourcc_to_str(f->pixelformat));
+
+	return 0;
+}
+
+static int vip_enum_framesizes(struct file *file, void *priv,
+			       struct v4l2_frmsizeenum *f)
+{
+	struct vip_stream *stream = file2stream(file);
+	struct vip_port *port = stream->port;
+	struct vip_fmt *fmt;
+	int ret;
+	struct v4l2_subdev_frame_size_enum fse = {
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+		.pad = 0,
+	};
+
+	fmt = find_port_format_by_pix(port, f->pixel_format);
+	if (!fmt)
+		return -EINVAL;
+
+	fse.index = f->index;
+	fse.code = fmt->code;
+	ret = v4l2_subdev_call(port->subdev, pad, enum_frame_size, NULL, &fse);
+	if (ret)
+		return -EINVAL;
+
+	v4l2_dbg(1, debug, stream, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n",
+		 __func__, fse.index, fse.code, fse.min_width, fse.max_width,
+		 fse.min_height, fse.max_height);
+
+	f->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+	f->discrete.width = fse.max_width;
+	f->discrete.height = fse.max_height;
+
+	return 0;
+}
+
+static int vip_enum_frameintervals(struct file *file, void *priv,
+				   struct v4l2_frmivalenum *f)
+{
+	struct vip_stream *stream = file2stream(file);
+	struct vip_port *port = stream->port;
+	struct vip_fmt *fmt;
+	struct v4l2_subdev_frame_interval_enum fie = {
+		.index = f->index,
+		.width = f->width,
+		.height = f->height,
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+	};
+	int ret;
+
+	fmt = find_port_format_by_pix(port, f->pixel_format);
+	if (!fmt)
+		return -EINVAL;
+
+	fie.code = fmt->code;
+	ret = v4l2_subdev_call(port->subdev, pad, enum_frame_interval,
+			       NULL, &fie);
+	if (ret)
+		return ret;
+	f->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+	f->discrete = fie.interval;
+
+	return 0;
+}
+
+static int vip_g_parm(struct file *file, void *priv,
+		      struct v4l2_streamparm *parm)
+{
+	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	parm->parm.capture.capability   = V4L2_CAP_TIMEPERFRAME;
+	parm->parm.capture.timeperframe.numerator = 1;
+	parm->parm.capture.timeperframe.denominator = 30;
+	parm->parm.capture.readbuffers  = 4;
+	return 0;
+}
+
+static int vip_s_parm(struct file *file, void *priv,
+		      struct v4l2_streamparm *parm)
+{
+	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	parm->parm.capture.timeperframe.numerator = 1;
+	parm->parm.capture.timeperframe.denominator = 30;
+	parm->parm.capture.readbuffers  = 4;
+
+	return 0;
+}
+
+static int vip_calc_format_size(struct vip_port *port,
+				struct vip_fmt *fmt,
+				struct v4l2_format *f)
+{
+	enum v4l2_field *field;
+	unsigned int stride;
+
+	if (!fmt) {
+		v4l2_dbg(2, debug, port,
+			 "no vip_fmt format provided!\n");
+		return -EINVAL;
+	}
+
+	field = &f->fmt.pix.field;
+	if (*field == V4L2_FIELD_ANY)
+		*field = V4L2_FIELD_NONE;
+	else if (V4L2_FIELD_NONE != *field && V4L2_FIELD_ALTERNATE != *field)
+		return -EINVAL;
+
+	v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W, W_ALIGN,
+			      &f->fmt.pix.height, MIN_H, MAX_H, H_ALIGN,
+			      S_ALIGN);
+
+	stride = f->fmt.pix.width * (fmt->vpdma_fmt[0]->depth >> 3);
+	if (stride > f->fmt.pix.bytesperline)
+		f->fmt.pix.bytesperline = stride;
+	f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline,
+					VPDMA_STRIDE_ALIGN);
+
+	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+	if (fmt->coplanar) {
+		f->fmt.pix.sizeimage += f->fmt.pix.height *
+					f->fmt.pix.bytesperline *
+					fmt->vpdma_fmt[VIP_CHROMA]->depth >> 3;
+	}
+
+	f->fmt.pix.colorspace = fmt->colorspace;
+	f->fmt.pix.priv = 0;
+
+	v4l2_dbg(3, debug, port, "calc_format_size: fourcc:%s size: %dx%d bpl:%d img_size:%d\n",
+		 fourcc_to_str(f->fmt.pix.pixelformat),
+		 f->fmt.pix.width, f->fmt.pix.height,
+		 f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
+
+	return 0;
+}
+
+static inline bool vip_is_size_dma_aligned(u32 bpp, u32 width)
+{
+	return ((width * bpp) == ALIGN(width * bpp, VPDMA_STRIDE_ALIGN));
+}
+
+static int vip_try_fmt_vid_cap(struct file *file, void *priv,
+			       struct v4l2_format *f)
+{
+	struct vip_stream *stream = file2stream(file);
+	struct vip_port *port = stream->port;
+	struct vip_fmt *fmt;
+	u32 best_width, best_height, largest_width, largest_height;
+	int ret, found;
+	enum vip_csc_state csc_direction;
+	struct v4l2_subdev_frame_size_enum fse = {
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+		.pad = 0,
+	};
+
+	v4l2_dbg(3, debug, stream, "try_fmt fourcc:%s size: %dx%d\n",
+		 fourcc_to_str(f->fmt.pix.pixelformat),
+		 f->fmt.pix.width, f->fmt.pix.height);
+
+	fmt = find_port_format_by_pix(port, f->fmt.pix.pixelformat);
+	if (!fmt) {
+		v4l2_dbg(2, debug, stream,
+			 "Fourcc format (0x%08x) not found.\n",
+			 f->fmt.pix.pixelformat);
+
+		/* Just get the first one enumerated */
+		fmt = port->active_fmt[0];
+		f->fmt.pix.pixelformat = fmt->fourcc;
+	}
+
+	csc_direction =  vip_csc_direction(fmt->code, fmt->finfo);
+	if (csc_direction != VIP_CSC_NA) {
+		if (!is_csc_available(port)) {
+			v4l2_dbg(2, debug, stream,
+				 "CSC not available for Fourcc format (0x%08x).\n",
+				 f->fmt.pix.pixelformat);
+
+			/* Just get the first one enumerated */
+			fmt = port->active_fmt[0];
+			f->fmt.pix.pixelformat = fmt->fourcc;
+			/* re-evaluate the csc_direction here */
+			csc_direction =  vip_csc_direction(fmt->code,
+							   fmt->finfo);
+		} else {
+			v4l2_dbg(3, debug, stream, "CSC active on Port %c: going %s\n",
+				 port->port_id == VIP_PORTA ? 'A' : 'B',
+				 (csc_direction == VIP_CSC_Y2R) ? "Y2R" : "R2Y");
+		}
+	}
+
+	/*
+	 * Given that sensors might support multiple mbus code we need
+	 * to use the one that matches the requested pixel format
+	 */
+	port->try_mbus_framefmt = port->mbus_framefmt;
+	port->try_mbus_framefmt.code = fmt->code;
+
+	/* check for/find a valid width/height */
+	ret = 0;
+	found = false;
+	best_width = 0;
+	best_height = 0;
+	largest_width = 0;
+	largest_height = 0;
+
+	fse.code = fmt->code;
+	for (fse.index = 0; ; fse.index++) {
+		u32 bpp = fmt->vpdma_fmt[0]->depth >> 3;
+
+		ret = v4l2_subdev_call(port->subdev, pad,
+				       enum_frame_size, NULL, &fse);
+		if (ret)
+			break;
+
+		v4l2_dbg(3, debug, stream, "try_fmt loop:%d fourcc:%s size: %dx%d\n",
+			 fse.index, fourcc_to_str(f->fmt.pix.pixelformat),
+			 fse.max_width, fse.max_height);
+
+		if (!vip_is_size_dma_aligned(bpp, fse.max_width))
+			continue;
+
+		if (fse.max_width >= largest_width &&
+		    fse.max_height >= largest_height) {
+			v4l2_dbg(3, debug, stream, "try_fmt loop:%d found new larger: %dx%d\n",
+				 fse.index, fse.max_width, fse.max_height);
+			largest_width = fse.max_width;
+			largest_height = fse.max_height;
+		}
+
+		if (fse.max_width >= f->fmt.pix.width &&
+		    fse.max_height >= f->fmt.pix.height) {
+			v4l2_dbg(3, debug, stream, "try_fmt loop:%d found at least larger: %dx%d\n",
+				 fse.index, fse.max_width, fse.max_height);
+
+			if (!best_width ||
+			    ((abs(best_width - f->fmt.pix.width) >=
+			      abs(fse.max_width - f->fmt.pix.width)) &&
+			     (abs(best_height - f->fmt.pix.height) >=
+			      abs(fse.max_height - f->fmt.pix.height)))) {
+				best_width = fse.max_width;
+				best_height = fse.max_height;
+				v4l2_dbg(3, debug, stream, "try_fmt loop:%d found new best: %dx%d\n",
+					 fse.index, fse.max_width,
+					 fse.max_height);
+			}
+		}
+
+		if (f->fmt.pix.width == fse.max_width &&
+		    f->fmt.pix.height == fse.max_height) {
+			found = true;
+			v4l2_dbg(3, debug, stream, "try_fmt loop:%d found direct match: %dx%d\n",
+				 fse.index, fse.max_width,
+				 fse.max_height);
+			break;
+		}
+
+		if (f->fmt.pix.width >= fse.min_width &&
+		    f->fmt.pix.width <= fse.max_width &&
+		    f->fmt.pix.height >= fse.min_height &&
+		    f->fmt.pix.height <= fse.max_height) {
+			found = true;
+			v4l2_dbg(3, debug, stream, "try_fmt loop:%d found direct range match: %dx%d\n",
+				 fse.index, fse.max_width,
+				 fse.max_height);
+			break;
+		}
+	}
+
+	if (found) {
+		port->try_mbus_framefmt.width = f->fmt.pix.width;
+		port->try_mbus_framefmt.height = f->fmt.pix.height;
+		/* No need to check for scaling */
+		goto calc_size;
+	} else if (f->fmt.pix.width > largest_width) {
+		port->try_mbus_framefmt.width = largest_width;
+		port->try_mbus_framefmt.height = largest_height;
+	} else if (best_width) {
+		port->try_mbus_framefmt.width = best_width;
+		port->try_mbus_framefmt.height = best_height;
+	} else {
+		/* use existing values as default */
+	}
+
+	v4l2_dbg(3, debug, stream, "try_fmt best subdev size: %dx%d\n",
+		 port->try_mbus_framefmt.width,
+		 port->try_mbus_framefmt.height);
+
+	if (is_scaler_available(port) &&
+	    csc_direction != VIP_CSC_Y2R &&
+	    !vip_is_mbuscode_raw(fmt->code) &&
+	    f->fmt.pix.height <= port->try_mbus_framefmt.height &&
+	    port->try_mbus_framefmt.height <= SC_MAX_PIXEL_HEIGHT &&
+	    port->try_mbus_framefmt.width <= SC_MAX_PIXEL_WIDTH) {
+		/*
+		 * Scaler is only accessible if the dst colorspace is YUV.
+		 * As the input to the scaler must be in YUV mode only.
+		 *
+		 * Scaling up is allowed only horizontally.
+		 */
+		unsigned int hratio, vratio, width_align, height_align;
+		u32 bpp = fmt->vpdma_fmt[0]->depth >> 3;
+
+		v4l2_dbg(3, debug, stream, "Scaler active on Port %c: requesting %dx%d\n",
+			 port->port_id == VIP_PORTA ? 'A' : 'B',
+			 f->fmt.pix.width, f->fmt.pix.height);
+
+		/* Just make sure everything is properly aligned */
+		width_align = ALIGN(f->fmt.pix.width * bpp, VPDMA_STRIDE_ALIGN);
+		width_align /= bpp;
+		height_align = ALIGN(f->fmt.pix.height, 2);
+
+		f->fmt.pix.width = width_align;
+		f->fmt.pix.height = height_align;
+
+		hratio = f->fmt.pix.width * 1000 /
+			 port->try_mbus_framefmt.width;
+		vratio = f->fmt.pix.height * 1000 /
+			 port->try_mbus_framefmt.height;
+		if (hratio < 125) {
+			f->fmt.pix.width = port->try_mbus_framefmt.width / 8;
+			v4l2_dbg(3, debug, stream, "Horizontal scaling ratio out of range adjusting -> %d\n",
+				 f->fmt.pix.width);
+		}
+
+		if (vratio < 188) {
+			f->fmt.pix.height = port->try_mbus_framefmt.height / 4;
+			v4l2_dbg(3, debug, stream, "Vertical scaling ratio out of range adjusting -> %d\n",
+				 f->fmt.pix.height);
+		}
+		v4l2_dbg(3, debug, stream, "Scaler: got %dx%d\n",
+			 f->fmt.pix.width, f->fmt.pix.height);
+	} else {
+		/* use existing values as default */
+		f->fmt.pix.width = port->try_mbus_framefmt.width;
+		f->fmt.pix.height = port->try_mbus_framefmt.height;
+	}
+
+calc_size:
+	/* That we have a fmt calculate imagesize and bytesperline */
+	return vip_calc_format_size(port, fmt, f);
+}
+
+static int vip_g_fmt_vid_cap(struct file *file, void *priv,
+			     struct v4l2_format *f)
+{
+	struct vip_stream *stream = file2stream(file);
+	struct vip_port *port = stream->port;
+	struct vip_fmt *fmt = port->fmt;
+
+	/* Use last known values or defaults */
+	f->fmt.pix.width	= stream->width;
+	f->fmt.pix.height	= stream->height;
+	f->fmt.pix.pixelformat	= port->fmt->fourcc;
+	f->fmt.pix.field	= stream->sup_field;
+	f->fmt.pix.colorspace	= port->fmt->colorspace;
+	f->fmt.pix.bytesperline	= stream->bytesperline;
+	f->fmt.pix.sizeimage	= stream->sizeimage;
+
+	v4l2_dbg(3, debug, stream,
+		 "g_fmt fourcc:%s code: %04x size: %dx%d bpl:%d img_size:%d\n",
+		 fourcc_to_str(f->fmt.pix.pixelformat),
+		 fmt->code,
+		 f->fmt.pix.width, f->fmt.pix.height,
+		 f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
+	v4l2_dbg(3, debug, stream, "g_fmt vpdma data type: 0x%02X\n",
+		 port->fmt->vpdma_fmt[0]->data_type);
+
+	return 0;
+}
+
+static int vip_s_fmt_vid_cap(struct file *file, void *priv,
+			     struct v4l2_format *f)
+{
+	struct vip_stream *stream = file2stream(file);
+	struct vip_port *port = stream->port;
+	struct v4l2_subdev_format sfmt;
+	struct v4l2_mbus_framefmt *mf;
+	enum vip_csc_state csc_direction;
+	int ret;
+
+	v4l2_dbg(3, debug, stream, "s_fmt input fourcc:%s size: %dx%d bpl:%d img_size:%d\n",
+		 fourcc_to_str(f->fmt.pix.pixelformat),
+		 f->fmt.pix.width, f->fmt.pix.height,
+		 f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
+
+	ret = vip_try_fmt_vid_cap(file, priv, f);
+	if (ret)
+		return ret;
+
+	v4l2_dbg(3, debug, stream, "s_fmt try_fmt fourcc:%s size: %dx%d bpl:%d img_size:%d\n",
+		 fourcc_to_str(f->fmt.pix.pixelformat),
+		 f->fmt.pix.width, f->fmt.pix.height,
+		 f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
+
+	if (vb2_is_busy(&stream->vb_vidq)) {
+		v4l2_err(stream, "%s queue busy\n", __func__);
+		return -EBUSY;
+	}
+
+	/*
+	 * Check if we need the scaler or not
+	 *
+	 * Since on previous S_FMT call the scaler might have been
+	 * allocated if it is not needed in this instance we will
+	 * attempt to free it just in case.
+	 *
+	 * free_scaler() is harmless unless the current port
+	 * allocated it.
+	 */
+	if (f->fmt.pix.width == port->try_mbus_framefmt.width &&
+	    f->fmt.pix.height == port->try_mbus_framefmt.height)
+		free_scaler(port);
+	else
+		allocate_scaler(port);
+
+	port->fmt = find_port_format_by_pix(port,
+					    f->fmt.pix.pixelformat);
+	stream->width		= f->fmt.pix.width;
+	stream->height		= f->fmt.pix.height;
+	stream->bytesperline	= f->fmt.pix.bytesperline;
+	stream->sizeimage	= f->fmt.pix.sizeimage;
+	stream->sup_field	= f->fmt.pix.field;
+
+	port->c_rect.left	= 0;
+	port->c_rect.top	= 0;
+	port->c_rect.width	= stream->width;
+	port->c_rect.height	= stream->height;
+
+	/*
+	 * Check if we need the csc unit or not
+	 *
+	 * Since on previous S_FMT call, the csc might have been
+	 * allocated if it is not needed in this instance we will
+	 * attempt to free it just in case.
+	 *
+	 * free_csc() is harmless unless the current port
+	 * allocated it.
+	 */
+	csc_direction =  vip_csc_direction(port->fmt->code, port->fmt->finfo);
+	if (csc_direction == VIP_CSC_NA)
+		free_csc(port);
+	else
+		allocate_csc(port, csc_direction);
+
+	if (stream->sup_field == V4L2_FIELD_ALTERNATE)
+		port->flags |= FLAG_INTERLACED;
+	else
+		port->flags &= ~FLAG_INTERLACED;
+
+	v4l2_dbg(3, debug, stream, "s_fmt fourcc:%s size: %dx%d bpl:%d img_size:%d\n",
+		 fourcc_to_str(f->fmt.pix.pixelformat),
+		 f->fmt.pix.width, f->fmt.pix.height,
+		 f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
+
+	memset(&sfmt, 0, sizeof(sfmt));
+	mf = &sfmt.format;
+	v4l2_fill_mbus_format(mf, &f->fmt.pix, port->fmt->code);
+	/* Make sure to use the subdev size found in the try_fmt */
+	mf->width = port->try_mbus_framefmt.width;
+	mf->height = port->try_mbus_framefmt.height;
+
+	v4l2_dbg(3, debug, stream, "s_fmt pix_to_mbus mbus_code: %04X size: %dx%d\n",
+		 mf->code,
+		 mf->width, mf->height);
+
+	sfmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	sfmt.pad = 0;
+	ret = v4l2_subdev_call(port->subdev, pad, set_fmt, NULL, &sfmt);
+	if (ret) {
+		v4l2_dbg(1, debug, stream, "set_fmt failed in subdev\n");
+		return ret;
+	}
+
+	/* Save it */
+	port->mbus_framefmt = *mf;
+
+	v4l2_dbg(3, debug, stream, "s_fmt subdev fmt mbus_code: %04X size: %dx%d\n",
+		 port->mbus_framefmt.code,
+		 port->mbus_framefmt.width, port->mbus_framefmt.height);
+	v4l2_dbg(3, debug, stream, "s_fmt vpdma data type: 0x%02X\n",
+		 port->fmt->vpdma_fmt[0]->data_type);
+
+	return 0;
+}
+
+/*
+ * Does the exact opposite of set_fmt_params
+ * It makes sure the DataPath register is sane after tear down
+ */
+static void unset_fmt_params(struct vip_stream *stream)
+{
+	struct vip_dev *dev = stream->port->dev;
+	struct vip_port *port = stream->port;
+
+	stream->sequence = 0;
+	stream->field = V4L2_FIELD_TOP;
+
+	if (port->csc == VIP_CSC_Y2R) {
+		if (port->port_id == VIP_PORTA) {
+			vip_set_slice_path(dev, VIP_CSC_SRC_DATA_SELECT, 0);
+			vip_set_slice_path(dev,
+					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_RGB_SRC_DATA_SELECT, 0);
+		} else {
+			vip_set_slice_path(dev, VIP_CSC_SRC_DATA_SELECT, 0);
+			vip_set_slice_path(dev,
+					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
+		}
+		/* We are done */
+		return;
+	} else if (port->csc == VIP_CSC_R2Y) {
+		if (port->scaler && port->fmt->coplanar) {
+			if (port->port_id == VIP_PORTA) {
+				vip_set_slice_path(dev,
+						   VIP_CSC_SRC_DATA_SELECT, 0);
+				vip_set_slice_path(dev,
+						   VIP_SC_SRC_DATA_SELECT, 0);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_SRC_DATA_SELECT,
+						   0);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_DATA_BYPASS, 0);
+				vip_set_slice_path(dev,
+						   VIP_RGB_OUT_HI_DATA_SELECT,
+						   0);
+			}
+		} else if (port->scaler) {
+			if (port->port_id == VIP_PORTA) {
+				vip_set_slice_path(dev,
+						   VIP_CSC_SRC_DATA_SELECT, 0);
+				vip_set_slice_path(dev,
+						   VIP_SC_SRC_DATA_SELECT, 0);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_SRC_DATA_SELECT,
+						   0);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_DATA_BYPASS, 0);
+				vip_set_slice_path(dev,
+						   VIP_RGB_OUT_HI_DATA_SELECT,
+						   0);
+			}
+		} else if (port->fmt->coplanar) {
+			if (port->port_id == VIP_PORTA) {
+				vip_set_slice_path(dev,
+						   VIP_CSC_SRC_DATA_SELECT, 0);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_SRC_DATA_SELECT,
+						   0);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_DATA_BYPASS, 0);
+				vip_set_slice_path(dev,
+						   VIP_RGB_OUT_HI_DATA_SELECT,
+						   0);
+			}
+		} else {
+			if (port->port_id == VIP_PORTA) {
+				vip_set_slice_path(dev,
+						   VIP_CSC_SRC_DATA_SELECT, 0);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_SRC_DATA_SELECT,
+						   0);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_DATA_BYPASS, 0);
+				vip_set_slice_path(dev,
+						   VIP_RGB_OUT_HI_DATA_SELECT,
+						   0);
+			}
+		}
+		/* We are done */
+		return;
+	} else if (v4l2_is_format_rgb(port->fmt->finfo)) {
+		if (port->port_id == VIP_PORTA) {
+			vip_set_slice_path(dev,
+					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
+		}
+		/* We are done */
+		return;
+	}
+
+	if (port->scaler && port->fmt->coplanar) {
+		if (port->port_id == VIP_PORTA) {
+			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 0);
+			vip_set_slice_path(dev,
+					   VIP_CHR_DS_1_SRC_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
+		} else {
+			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 0);
+			vip_set_slice_path(dev,
+					   VIP_CHR_DS_2_SRC_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
+			vip_set_slice_path(dev,
+					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
+		}
+	} else if (port->scaler) {
+		if (port->port_id == VIP_PORTA) {
+			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 0);
+			vip_set_slice_path(dev,
+					   VIP_CHR_DS_1_SRC_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
+		} else {
+			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 0);
+			vip_set_slice_path(dev,
+					   VIP_CHR_DS_2_SRC_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
+			vip_set_slice_path(dev, VIP_CHR_DS_2_DATA_BYPASS, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
+		}
+	} else if (port->fmt->coplanar) {
+		if (port->port_id == VIP_PORTA) {
+			vip_set_slice_path(dev,
+					   VIP_CHR_DS_1_SRC_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
+		} else {
+			vip_set_slice_path(dev,
+					   VIP_CHR_DS_2_SRC_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_CHR_DS_2_DATA_BYPASS, 0);
+			vip_set_slice_path(dev,
+					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
+		}
+	} else {
+		/*
+		 * We undo all data path setting except for the multi
+		 * stream case.
+		 * Because we cannot disrupt other on-going capture if only
+		 * one stream is terminated the other might still be going
+		 */
+		vip_set_slice_path(dev, VIP_MULTI_CHANNEL_DATA_SELECT, 1);
+		vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
+	}
+}
+
+/*
+ * Set the registers that are modified when the video format changes.
+ */
+static void set_fmt_params(struct vip_stream *stream)
+{
+	struct vip_dev *dev = stream->port->dev;
+	struct vip_port *port = stream->port;
+
+	stream->sequence = 0;
+	stream->field = V4L2_FIELD_TOP;
+
+	if (port->csc == VIP_CSC_Y2R) {
+		port->flags &= ~FLAG_MULT_PORT;
+		/* Set alpha component in background color */
+		vpdma_set_bg_color(dev->shared->vpdma,
+				   (struct vpdma_data_format *)
+				   port->fmt->vpdma_fmt[0],
+				   0xff);
+		if (port->port_id == VIP_PORTA) {
+			/*
+			 * Input A: YUV422
+			 * Output: Y_UP/UV_UP: RGB
+			 * CSC_SRC_SELECT       = 1
+			 * RGB_OUT_HI_SELECT    = 1
+			 * RGB_SRC_SELECT       = 1
+			 * MULTI_CHANNEL_SELECT = 0
+			 */
+			vip_set_slice_path(dev, VIP_CSC_SRC_DATA_SELECT, 1);
+			vip_set_slice_path(dev,
+					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 1);
+			vip_set_slice_path(dev, VIP_RGB_SRC_DATA_SELECT, 1);
+		} else {
+			/*
+			 * Input B: YUV422
+			 * Output: Y_UP/UV_UP: RGB
+			 * CSC_SRC_SELECT       = 2
+			 * RGB_OUT_LO_SELECT    = 1
+			 * MULTI_CHANNEL_SELECT = 0
+			 */
+			vip_set_slice_path(dev, VIP_CSC_SRC_DATA_SELECT, 2);
+			vip_set_slice_path(dev,
+					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 1);
+		}
+		/* We are done */
+		return;
+	} else if (port->csc == VIP_CSC_R2Y) {
+		port->flags &= ~FLAG_MULT_PORT;
+		if (port->scaler && port->fmt->coplanar) {
+			if (port->port_id == VIP_PORTA) {
+				/*
+				 * Input A: RGB
+				 * Output: Y_UP/UV_UP: Scaled YUV420
+				 * CSC_SRC_SELECT       = 4
+				 * SC_SRC_SELECT        = 1
+				 * CHR_DS_1_SRC_SELECT  = 1
+				 * CHR_DS_1_BYPASS      = 0
+				 * RGB_OUT_HI_SELECT    = 0
+				 */
+				vip_set_slice_path(dev,
+						   VIP_CSC_SRC_DATA_SELECT, 4);
+				vip_set_slice_path(dev,
+						   VIP_SC_SRC_DATA_SELECT, 1);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_SRC_DATA_SELECT,
+						   1);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_DATA_BYPASS, 0);
+				vip_set_slice_path(dev,
+						   VIP_RGB_OUT_HI_DATA_SELECT,
+						   0);
+			} else {
+				v4l2_err(stream, "RGB sensor can only be on Port A\n");
+			}
+		} else if (port->scaler) {
+			if (port->port_id == VIP_PORTA) {
+				/*
+				 * Input A: RGB
+				 * Output: Y_UP: Scaled YUV422
+				 * CSC_SRC_SELECT       = 4
+				 * SC_SRC_SELECT        = 1
+				 * CHR_DS_1_SRC_SELECT  = 1
+				 * CHR_DS_1_BYPASS      = 1
+				 * RGB_OUT_HI_SELECT    = 0
+				 */
+				vip_set_slice_path(dev,
+						   VIP_CSC_SRC_DATA_SELECT, 4);
+				vip_set_slice_path(dev,
+						   VIP_SC_SRC_DATA_SELECT, 1);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_SRC_DATA_SELECT,
+						   1);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_DATA_BYPASS, 1);
+				vip_set_slice_path(dev,
+						   VIP_RGB_OUT_HI_DATA_SELECT,
+						   0);
+			} else {
+				v4l2_err(stream, "RGB sensor can only be on Port A\n");
+			}
+		} else if (port->fmt->coplanar) {
+			if (port->port_id == VIP_PORTA) {
+				/*
+				 * Input A: RGB
+				 * Output: Y_UP/UV_UP: YUV420
+				 * CSC_SRC_SELECT       = 4
+				 * CHR_DS_1_SRC_SELECT  = 2
+				 * CHR_DS_1_BYPASS      = 0
+				 * RGB_OUT_HI_SELECT    = 0
+				 */
+				vip_set_slice_path(dev,
+						   VIP_CSC_SRC_DATA_SELECT, 4);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_SRC_DATA_SELECT,
+						   2);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_DATA_BYPASS, 0);
+				vip_set_slice_path(dev,
+						   VIP_RGB_OUT_HI_DATA_SELECT,
+						   0);
+			} else {
+				v4l2_err(stream, "RGB sensor can only be on Port A\n");
+			}
+		} else {
+			if (port->port_id == VIP_PORTA) {
+				/*
+				 * Input A: RGB
+				 * Output: Y_UP/UV_UP: YUV420
+				 * CSC_SRC_SELECT       = 4
+				 * CHR_DS_1_SRC_SELECT  = 2
+				 * CHR_DS_1_BYPASS      = 1
+				 * RGB_OUT_HI_SELECT    = 0
+				 */
+				vip_set_slice_path(dev,
+						   VIP_CSC_SRC_DATA_SELECT, 4);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_SRC_DATA_SELECT,
+						   2);
+				vip_set_slice_path(dev,
+						   VIP_CHR_DS_1_DATA_BYPASS, 1);
+				vip_set_slice_path(dev,
+						   VIP_RGB_OUT_HI_DATA_SELECT,
+						   0);
+			} else {
+				v4l2_err(stream, "RGB sensor can only be on Port A\n");
+			}
+		}
+		/* We are done */
+		return;
+	} else if (v4l2_is_format_rgb(port->fmt->finfo)) {
+		port->flags &= ~FLAG_MULT_PORT;
+		/* Set alpha component in background color */
+		vpdma_set_bg_color(dev->shared->vpdma,
+				   (struct vpdma_data_format *)
+				   port->fmt->vpdma_fmt[0],
+				   0xff);
+		if (port->port_id == VIP_PORTA) {
+			/*
+			 * Input A: RGB
+			 * Output: Y_LO/UV_LO: RGB
+			 * RGB_OUT_LO_SELECT    = 1
+			 * MULTI_CHANNEL_SELECT = 1
+			 */
+			vip_set_slice_path(dev,
+					   VIP_MULTI_CHANNEL_DATA_SELECT, 1);
+			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 1);
+		} else {
+			v4l2_err(stream, "RGB sensor can only be on Port A\n");
+		}
+		/* We are done */
+		return;
+	}
+
+	if (port->scaler && port->fmt->coplanar) {
+		port->flags &= ~FLAG_MULT_PORT;
+		if (port->port_id == VIP_PORTA) {
+			/*
+			 * Input A: YUV422
+			 * Output: Y_UP/UV_UP: Scaled YUV420
+			 * SC_SRC_SELECT        = 2
+			 * CHR_DS_1_SRC_SELECT  = 1
+			 * CHR_DS_1_BYPASS      = 0
+			 * RGB_OUT_HI_SELECT    = 0
+			 */
+			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 2);
+			vip_set_slice_path(dev,
+					   VIP_CHR_DS_1_SRC_DATA_SELECT, 1);
+			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
+		} else {
+			/*
+			 * Input B: YUV422
+			 * Output: Y_LO/UV_LO: Scaled YUV420
+			 * SC_SRC_SELECT        = 3
+			 * CHR_DS_2_SRC_SELECT  = 1
+			 * RGB_OUT_LO_SELECT    = 0
+			 * MULTI_CHANNEL_SELECT = 0
+			 */
+			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 3);
+			vip_set_slice_path(dev,
+					   VIP_CHR_DS_2_SRC_DATA_SELECT, 1);
+			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
+			vip_set_slice_path(dev,
+					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
+		}
+	} else if (port->scaler) {
+		port->flags &= ~FLAG_MULT_PORT;
+		if (port->port_id == VIP_PORTA) {
+			/*
+			 * Input A: YUV422
+			 * Output: Y_UP: Scaled YUV422
+			 * SC_SRC_SELECT        = 2
+			 * CHR_DS_1_SRC_SELECT  = 1
+			 * CHR_DS_1_BYPASS      = 1
+			 * RGB_OUT_HI_SELECT    = 0
+			 */
+			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 2);
+			vip_set_slice_path(dev,
+					   VIP_CHR_DS_1_SRC_DATA_SELECT, 1);
+			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 1);
+			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
+		} else {
+			/*
+			 * Input B: YUV422
+			 * Output: UV_UP: Scaled YUV422
+			 * SC_SRC_SELECT        = 3
+			 * CHR_DS_2_SRC_SELECT  = 1
+			 * CHR_DS_1_BYPASS      = 1
+			 * CHR_DS_2_BYPASS      = 1
+			 * RGB_OUT_HI_SELECT    = 0
+			 */
+			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 3);
+			vip_set_slice_path(dev,
+					   VIP_CHR_DS_2_SRC_DATA_SELECT, 1);
+			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 1);
+			vip_set_slice_path(dev, VIP_CHR_DS_2_DATA_BYPASS, 1);
+			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
+		}
+	} else if (port->fmt->coplanar) {
+		port->flags &= ~FLAG_MULT_PORT;
+		if (port->port_id == VIP_PORTA) {
+			/*
+			 * Input A: YUV422
+			 * Output: Y_UP/UV_UP: YUV420
+			 * CHR_DS_1_SRC_SELECT  = 3
+			 * CHR_DS_1_BYPASS      = 0
+			 * RGB_OUT_HI_SELECT    = 0
+			 */
+			vip_set_slice_path(dev,
+					   VIP_CHR_DS_1_SRC_DATA_SELECT, 3);
+			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
+		} else {
+			/*
+			 * Input B: YUV422
+			 * Output: Y_LO/UV_LO: YUV420
+			 * CHR_DS_2_SRC_SELECT  = 4
+			 * CHR_DS_2_BYPASS      = 0
+			 * RGB_OUT_LO_SELECT    = 0
+			 * MULTI_CHANNEL_SELECT = 0
+			 */
+			vip_set_slice_path(dev,
+					   VIP_CHR_DS_2_SRC_DATA_SELECT, 4);
+			vip_set_slice_path(dev, VIP_CHR_DS_2_DATA_BYPASS, 0);
+			vip_set_slice_path(dev,
+					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
+			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
+		}
+	} else {
+		port->flags |= FLAG_MULT_PORT;
+		/*
+		 * Input A/B: YUV422
+		 * Output: Y_LO: YUV422 - UV_LO: YUV422
+		 * MULTI_CHANNEL_SELECT = 1
+		 * RGB_OUT_LO_SELECT    = 0
+		 */
+		vip_set_slice_path(dev, VIP_MULTI_CHANNEL_DATA_SELECT, 1);
+		vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
+	}
+}
+
+static int vip_g_selection(struct file *file, void *fh,
+			   struct v4l2_selection *s)
+{
+	struct vip_stream *stream = file2stream(file);
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = stream->width;
+		s->r.height = stream->height;
+		return 0;
+
+	case V4L2_SEL_TGT_COMPOSE:
+	case V4L2_SEL_TGT_CROP:
+		s->r = stream->port->c_rect;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
+{
+	if (a->left < b->left || a->top < b->top)
+		return 0;
+	if (a->left + a->width > b->left + b->width)
+		return 0;
+	if (a->top + a->height > b->top + b->height)
+		return 0;
+
+	return 1;
+}
+
+static int vip_s_selection(struct file *file, void *fh,
+			   struct v4l2_selection *s)
+{
+	struct vip_stream *stream = file2stream(file);
+	struct v4l2_rect r = s->r;
+
+	v4l_bound_align_image(&r.width, 0, stream->width, 0,
+			      &r.height, 0, stream->height, 0, 0);
+
+	r.left = clamp_t(unsigned int, r.left, 0, stream->width - r.width);
+	r.top  = clamp_t(unsigned int, r.top, 0, stream->height - r.height);
+
+	if (s->flags & V4L2_SEL_FLAG_LE && !enclosed_rectangle(&r, &s->r))
+		return -ERANGE;
+
+	if (s->flags & V4L2_SEL_FLAG_GE && !enclosed_rectangle(&s->r, &r))
+		return -ERANGE;
+
+	s->r = r;
+	stream->port->c_rect = r;
+
+	v4l2_dbg(1, debug, stream, "cropped (%d,%d)/%dx%d of %dx%d\n",
+		 r.left, r.top, r.width, r.height,
+		 stream->width, stream->height);
+
+	return 0;
+}
+
+static long vip_ioctl_default(struct file *file, void *fh, bool valid_prio,
+			      unsigned int cmd, void *arg)
+{
+	struct vip_stream *stream = file2stream(file);
+
+	if (!valid_prio) {
+		v4l2_err(stream, "%s device busy\n", __func__);
+		return -EBUSY;
+	}
+
+	switch (cmd) {
+	default:
+		return -ENOTTY;
+	}
+}
+
+static const struct v4l2_ioctl_ops vip_ioctl_ops = {
+	.vidioc_querycap	= vip_querycap,
+	.vidioc_enum_input	= vip_enuminput,
+	.vidioc_g_input		= vip_g_input,
+	.vidioc_s_input		= vip_s_input,
+
+	.vidioc_querystd	= vip_querystd,
+	.vidioc_g_std		= vip_g_std,
+	.vidioc_s_std		= vip_s_std,
+
+	.vidioc_enum_fmt_vid_cap = vip_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap	= vip_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap	= vip_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap	= vip_s_fmt_vid_cap,
+
+	.vidioc_enum_frameintervals	= vip_enum_frameintervals,
+	.vidioc_enum_framesizes		= vip_enum_framesizes,
+	.vidioc_s_parm			= vip_s_parm,
+	.vidioc_g_parm			= vip_g_parm,
+	.vidioc_g_selection	= vip_g_selection,
+	.vidioc_s_selection	= vip_s_selection,
+	.vidioc_reqbufs		= vb2_ioctl_reqbufs,
+	.vidioc_create_bufs	= vb2_ioctl_create_bufs,
+	.vidioc_prepare_buf	= vb2_ioctl_prepare_buf,
+	.vidioc_querybuf	= vb2_ioctl_querybuf,
+	.vidioc_qbuf		= vb2_ioctl_qbuf,
+	.vidioc_dqbuf		= vb2_ioctl_dqbuf,
+	.vidioc_expbuf		= vb2_ioctl_expbuf,
+
+	.vidioc_streamon	= vb2_ioctl_streamon,
+	.vidioc_streamoff	= vb2_ioctl_streamoff,
+	.vidioc_log_status	= v4l2_ctrl_log_status,
+	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+	.vidioc_default		= vip_ioctl_default,
+};
+
+/*
+ * Videobuf operations
+ */
+static int vip_queue_setup(struct vb2_queue *vq,
+			   unsigned int *nbuffers, unsigned int *nplanes,
+			   unsigned int sizes[], struct device *alloc_devs[])
+{
+	struct vip_stream *stream = vb2_get_drv_priv(vq);
+	unsigned int size = stream->sizeimage;
+
+	if (vq->max_num_buffers + *nbuffers < 3)
+		*nbuffers = 3 - vq->max_num_buffers;
+
+	if (*nplanes) {
+		if (sizes[0] < size)
+			return -EINVAL;
+		size = sizes[0];
+	}
+
+	*nplanes = 1;
+	sizes[0] = size;
+
+	v4l2_dbg(1, debug, stream, "get %d buffer(s) of size %d each.\n",
+		 *nbuffers, sizes[0]);
+
+	return 0;
+}
+
+static int vip_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vip_stream *stream = vb2_get_drv_priv(vb->vb2_queue);
+
+	if (vb2_plane_size(vb, 0) < stream->sizeimage) {
+		v4l2_dbg(1, debug, stream,
+			 "%s data will not fit into plane (%lu < %lu)\n",
+			 __func__, vb2_plane_size(vb, 0),
+			(long)stream->sizeimage);
+		return -EINVAL;
+	}
+
+	vb2_set_plane_payload(vb, 0, stream->sizeimage);
+
+	return 0;
+}
+
+static void vip_buf_queue(struct vb2_buffer *vb)
+{
+	struct vip_stream *stream = vb2_get_drv_priv(vb->vb2_queue);
+	struct vip_dev *dev = stream->port->dev;
+	struct vip_buffer *buf = container_of(vb, struct vip_buffer,
+					      vb.vb2_buf);
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->slock, flags);
+	list_add_tail(&buf->list, &stream->vidq);
+	spin_unlock_irqrestore(&dev->slock, flags);
+}
+
+static int vip_setup_scaler(struct vip_stream *stream)
+{
+	struct vip_port *port = stream->port;
+	struct vip_dev *dev = port->dev;
+	struct sc_data *sc = dev->sc;
+	struct csc_data *csc = dev->csc;
+	struct vpdma_data *vpdma = dev->shared->vpdma;
+	struct vip_mmr_adb *mmr_adb = port->mmr_adb.addr;
+	int list_num = stream->list_num;
+	int timeout = 500;
+	struct v4l2_format dst_f;
+	struct v4l2_format src_f;
+
+	memset(&src_f, 0, sizeof(src_f));
+	src_f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	v4l2_fill_pix_format(&src_f.fmt.pix, &port->mbus_framefmt);
+	src_f.fmt.pix.pixelformat = vip_mbus_code_to_fourcc(port->fmt->code);
+
+	dst_f = src_f;
+	dst_f.fmt.pix.pixelformat = port->fmt->fourcc;
+	dst_f.fmt.pix.width = stream->width;
+	dst_f.fmt.pix.height = stream->height;
+
+	/* if scaler not associated with this port then skip */
+	if (port->scaler) {
+		sc_set_hs_coeffs(sc, port->sc_coeff_h.addr,
+				 port->mbus_framefmt.width,
+				 port->c_rect.width);
+		sc_set_vs_coeffs(sc, port->sc_coeff_v.addr,
+				 port->mbus_framefmt.height,
+				 port->c_rect.height);
+		sc_config_scaler(sc, &mmr_adb->sc_regs0[0],
+				 &mmr_adb->sc_regs8[0], &mmr_adb->sc_regs17[0],
+				 port->mbus_framefmt.width,
+				 port->mbus_framefmt.height,
+				 port->c_rect.width,
+				 port->c_rect.height);
+		port->load_mmrs = true;
+	}
+
+	/* if csc not associated with this port then skip */
+	if (port->csc) {
+		csc_set_coeff(csc, &mmr_adb->csc_regs[0],
+			      &src_f, &dst_f);
+
+		port->load_mmrs = true;
+	}
+
+	/* If coeff are already loaded then skip */
+	if (!sc->load_coeff_v && !sc->load_coeff_h && !port->load_mmrs)
+		return 0;
+
+	if (vpdma_list_busy(vpdma, list_num)) {
+		v4l2_dbg(3, debug, stream, "%s: List %d is busy\n",
+			 __func__, list_num);
+	}
+
+	/* Make sure we start with a clean list */
+	vpdma_reset_desc_list(&stream->desc_list);
+
+	/* config descriptors */
+	if (port->load_mmrs) {
+		vpdma_map_desc_buf(vpdma, &port->mmr_adb);
+		vpdma_add_cfd_adb(&stream->desc_list, CFD_MMR_CLIENT,
+				  &port->mmr_adb);
+
+		port->load_mmrs = false;
+		v4l2_dbg(3, debug, stream, "Added mmr_adb config desc\n");
+	}
+
+	if (sc->loaded_coeff_h != port->sc_coeff_h.dma_addr ||
+	    sc->load_coeff_h) {
+		vpdma_map_desc_buf(vpdma, &port->sc_coeff_h);
+		vpdma_add_cfd_block(&stream->desc_list,
+				    VIP_SLICE1_CFD_SC_CLIENT + dev->slice_id,
+				    &port->sc_coeff_h, 0);
+
+		sc->loaded_coeff_h = port->sc_coeff_h.dma_addr;
+		sc->load_coeff_h = false;
+		v4l2_dbg(3, debug, stream, "Added sc_coeff_h config desc\n");
+	}
+
+	if (sc->loaded_coeff_v != port->sc_coeff_v.dma_addr ||
+	    sc->load_coeff_v) {
+		vpdma_map_desc_buf(vpdma, &port->sc_coeff_v);
+		vpdma_add_cfd_block(&stream->desc_list,
+				    VIP_SLICE1_CFD_SC_CLIENT + dev->slice_id,
+				    &port->sc_coeff_v, SC_COEF_SRAM_SIZE >> 4);
+
+		sc->loaded_coeff_v = port->sc_coeff_v.dma_addr;
+		sc->load_coeff_v = false;
+		v4l2_dbg(3, debug, stream, "Added sc_coeff_v config desc\n");
+	}
+	v4l2_dbg(3, debug, stream, "CFD_SC_CLIENT %d slice_id: %d\n",
+		 VIP_SLICE1_CFD_SC_CLIENT + dev->slice_id, dev->slice_id);
+
+	vpdma_map_desc_buf(vpdma, &stream->desc_list.buf);
+	v4l2_dbg(3, debug, stream, "Submitting desc on list# %d\n", list_num);
+	vpdma_submit_descs(vpdma, &stream->desc_list, list_num);
+
+	while (vpdma_list_busy(vpdma, list_num) && timeout--)
+		usleep_range(1000, 1100);
+
+	vpdma_unmap_desc_buf(dev->shared->vpdma, &port->mmr_adb);
+	vpdma_unmap_desc_buf(dev->shared->vpdma, &port->sc_coeff_h);
+	vpdma_unmap_desc_buf(dev->shared->vpdma, &port->sc_coeff_v);
+	vpdma_unmap_desc_buf(dev->shared->vpdma, &stream->desc_list.buf);
+
+	vpdma_reset_desc_list(&stream->desc_list);
+
+	if (timeout <= 0) {
+		v4l2_err(stream, "Timed out setting up scaler through VPDMA list\n");
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static int vip_load_vpdma_list_fifo(struct vip_stream *stream)
+{
+	struct vip_port *port = stream->port;
+	struct vip_dev *dev = port->dev;
+	struct vpdma_data *vpdma = dev->shared->vpdma;
+	int list_num = stream->list_num;
+	struct vip_buffer *buf;
+	unsigned long flags;
+	int timeout, i;
+
+	if (vpdma_list_busy(dev->shared->vpdma, stream->list_num))
+		return -EBUSY;
+
+	for (i = 0; i < VIP_VPDMA_FIFO_SIZE; i++) {
+		spin_lock_irqsave(&dev->slock, flags);
+		if (list_empty(&stream->vidq)) {
+			v4l2_err(stream, "No buffer left!");
+			spin_unlock_irqrestore(&dev->slock, flags);
+			return -EINVAL;
+		}
+
+		buf = list_entry(stream->vidq.next,
+				 struct vip_buffer, list);
+		buf->drop = false;
+
+		list_move_tail(&buf->list, &stream->post_bufs);
+		spin_unlock_irqrestore(&dev->slock, flags);
+
+		v4l2_dbg(2, debug, stream, "%s: start_dma vb2 buf idx:%d\n",
+			 __func__, buf->vb.vb2_buf.index);
+		start_dma(stream, buf);
+
+		timeout = 500;
+		while (vpdma_list_busy(vpdma, list_num) && timeout--)
+			usleep_range(1000, 1100);
+
+		if (timeout <= 0) {
+			v4l2_err(stream, "Timed out loading VPDMA list fifo\n");
+			return -EBUSY;
+		}
+	}
+	return 0;
+}
+
+static int vip_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct vip_stream *stream = vb2_get_drv_priv(vq);
+	struct vip_port *port = stream->port;
+	struct vip_dev *dev = port->dev;
+	int ret;
+
+	vip_setup_scaler(stream);
+
+	/*
+	 * Make sure the scaler is configured before the datapath is
+	 * enabled. The scaler can only load the coefficient
+	 * parameters when it is idle. If the scaler path is enabled
+	 * and video data is being received then the VPDMA transfer will
+	 * stall indefinetely.
+	 */
+	set_fmt_params(stream);
+	vip_setup_parser(port);
+
+	if (port->subdev) {
+		ret = v4l2_subdev_call(port->subdev, video, s_stream, 1);
+		if (ret) {
+			v4l2_dbg(1, debug, stream, "stream on failed in subdev\n");
+			return ret;
+		}
+	}
+
+	stream->sequence = 0;
+	stream->field = V4L2_FIELD_TOP;
+	populate_desc_list(stream);
+
+	ret = vip_load_vpdma_list_fifo(stream);
+	if (ret)
+		return ret;
+
+	stream->num_recovery = 0;
+
+	clear_irqs(dev, dev->slice_id, stream->list_num);
+	enable_irqs(dev, dev->slice_id, stream->list_num);
+	vip_schedule_next_buffer(stream);
+	vip_parser_stop_imm(port, false);
+	vip_enable_parser(port, true);
+
+	return 0;
+}
+
+/*
+ * Abort streaming and wait for last buffer
+ */
+static void vip_stop_streaming(struct vb2_queue *vq)
+{
+	struct vip_stream *stream = vb2_get_drv_priv(vq);
+	struct vip_port *port = stream->port;
+	struct vip_dev *dev = port->dev;
+	struct vip_buffer *buf;
+	int ret;
+
+	vip_parser_stop_imm(port, true);
+	vip_enable_parser(port, false);
+	unset_fmt_params(stream);
+
+	disable_irqs(dev, dev->slice_id, stream->list_num);
+	clear_irqs(dev, dev->slice_id, stream->list_num);
+
+	if (port->subdev) {
+		ret = v4l2_subdev_call(port->subdev, video, s_stream, 0);
+		if (ret)
+			v4l2_dbg(1, debug, stream, "stream on failed in subdev\n");
+	}
+
+	stop_dma(stream, true);
+
+	/* release all active buffers */
+	while (!list_empty(&stream->post_bufs)) {
+		buf = list_entry(stream->post_bufs.next,
+				 struct vip_buffer, list);
+		list_del(&buf->list);
+		if (buf->drop == 1)
+			list_add_tail(&buf->list, &stream->dropq);
+		else
+			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+	}
+	while (!list_empty(&stream->vidq)) {
+		buf = list_entry(stream->vidq.next, struct vip_buffer, list);
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+	}
+
+	if (!vb2_is_streaming(vq))
+		return;
+
+	vpdma_unmap_desc_buf(dev->shared->vpdma, &stream->desc_list.buf);
+	vpdma_reset_desc_list(&stream->desc_list);
+}
+
+static const struct vb2_ops vip_video_qops = {
+	.queue_setup		= vip_queue_setup,
+	.buf_prepare		= vip_buf_prepare,
+	.buf_queue		= vip_buf_queue,
+	.start_streaming	= vip_start_streaming,
+	.stop_streaming		= vip_stop_streaming,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+static int vip_init_dev(struct vip_dev *dev)
+{
+	if (dev->num_ports != 0)
+		goto done;
+
+	vip_set_clock_enable(dev, 1);
+	vip_module_toggle(dev, VIP_SC_RST, false);
+	vip_module_toggle(dev, VIP_CSC_RST, false);
+done:
+	dev->num_ports++;
+
+	return 0;
+}
+
+static inline bool is_scaler_available(struct vip_port *port)
+{
+	if (port->endpoint.bus_type == V4L2_MBUS_PARALLEL)
+		if (port->dev->sc_assigned == VIP_NOT_ASSIGNED ||
+		    port->dev->sc_assigned == port->port_id)
+			return true;
+	return false;
+}
+
+static inline bool allocate_scaler(struct vip_port *port)
+{
+	if (is_scaler_available(port)) {
+		if (port->dev->sc_assigned == VIP_NOT_ASSIGNED ||
+		    port->dev->sc_assigned == port->port_id) {
+			port->dev->sc_assigned = port->port_id;
+			port->scaler = true;
+			return true;
+		}
+	}
+	return false;
+}
+
+static inline void free_scaler(struct vip_port *port)
+{
+	if (port->dev->sc_assigned == port->port_id) {
+		port->dev->sc_assigned = VIP_NOT_ASSIGNED;
+		port->scaler = false;
+	}
+}
+
+static bool is_csc_available(struct vip_port *port)
+{
+	if (port->endpoint.bus_type == V4L2_MBUS_PARALLEL)
+		if (port->dev->csc_assigned == VIP_NOT_ASSIGNED ||
+		    port->dev->csc_assigned == port->port_id)
+			return true;
+	return false;
+}
+
+static bool allocate_csc(struct vip_port *port,
+			 enum vip_csc_state csc_direction)
+{
+	/* Is CSC needed? */
+	if (csc_direction != VIP_CSC_NA) {
+		if (is_csc_available(port)) {
+			port->dev->csc_assigned = port->port_id;
+			port->csc = csc_direction;
+			v4l2_dbg(1, debug, port, "%s: csc allocated: dir: %d\n",
+				 __func__, csc_direction);
+			return true;
+		}
+	}
+	return false;
+}
+
+static void free_csc(struct vip_port *port)
+{
+	if (port->dev->csc_assigned == port->port_id) {
+		port->dev->csc_assigned = VIP_NOT_ASSIGNED;
+		port->csc = VIP_CSC_NA;
+		v4l2_dbg(1, debug, port, "%s: csc freed\n",
+			 __func__);
+	}
+}
+
+static int vip_init_port(struct vip_port *port)
+{
+	int ret;
+	struct vip_fmt *fmt;
+	struct v4l2_subdev_format sd_fmt = {
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+		.pad = 0,
+	};
+	struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
+
+	if (port->num_streams != 0)
+		goto done;
+
+	ret = vip_init_dev(port->dev);
+	if (ret)
+		goto done;
+
+	/* Get subdevice current frame format */
+	ret = v4l2_subdev_call(port->subdev, pad, get_fmt, NULL, &sd_fmt);
+	if (ret)
+		v4l2_dbg(1, debug, port, "init_port get_fmt failed in subdev: (%d)\n",
+			 ret);
+
+	/* try to find one that matches */
+	fmt = find_port_format_by_code(port, mbus_fmt->code);
+	if (!fmt) {
+		v4l2_dbg(1, debug, port, "subdev default mbus_fmt %04x is not matched.\n",
+			 mbus_fmt->code);
+		/* if all else fails just pick the first one */
+		fmt = port->active_fmt[0];
+
+		mbus_fmt->code = fmt->code;
+		sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+		sd_fmt.pad = 0;
+		ret = v4l2_subdev_call(port->subdev, pad, set_fmt,
+				       NULL, &sd_fmt);
+		if (ret)
+			v4l2_dbg(1, debug, port, "init_port set_fmt failed in subdev: (%d)\n",
+				 ret);
+	}
+
+	/* Assign current format */
+	port->fmt = fmt;
+	port->mbus_framefmt = *mbus_fmt;
+
+	v4l2_dbg(3, debug, port, "%s: g_mbus_fmt subdev mbus_code: %04X fourcc:%s size: %dx%d\n",
+		 __func__, fmt->code,
+		fourcc_to_str(fmt->fourcc),
+		mbus_fmt->width, mbus_fmt->height);
+
+	if (mbus_fmt->field == V4L2_FIELD_ALTERNATE)
+		port->flags |= FLAG_INTERLACED;
+	else
+		port->flags &= ~FLAG_INTERLACED;
+
+	port->c_rect.left	= 0;
+	port->c_rect.top	= 0;
+	port->c_rect.width	= mbus_fmt->width;
+	port->c_rect.height	= mbus_fmt->height;
+
+	ret = vpdma_alloc_desc_buf(&port->sc_coeff_h, SC_COEF_SRAM_SIZE);
+	if (ret != 0)
+		return ret;
+
+	ret = vpdma_alloc_desc_buf(&port->sc_coeff_v, SC_COEF_SRAM_SIZE);
+	if (ret != 0)
+		goto free_sc_h;
+
+	ret = vpdma_alloc_desc_buf(&port->mmr_adb, sizeof(struct vip_mmr_adb));
+	if (ret != 0)
+		goto free_sc_v;
+
+	init_adb_hdrs(port);
+
+	vip_enable_parser(port, false);
+done:
+	port->num_streams++;
+	return 0;
+
+free_sc_v:
+	vpdma_free_desc_buf(&port->sc_coeff_v);
+free_sc_h:
+	vpdma_free_desc_buf(&port->sc_coeff_h);
+	return ret;
+}
+
+static int vip_init_stream(struct vip_stream *stream)
+{
+	struct vip_port *port = stream->port;
+	struct vip_fmt *fmt;
+	struct v4l2_mbus_framefmt *mbus_fmt;
+	struct v4l2_format f;
+	int ret;
+
+	ret = vip_init_port(port);
+	if (ret != 0)
+		return ret;
+
+	fmt = port->fmt;
+	mbus_fmt = &port->mbus_framefmt;
+
+	memset(&f, 0, sizeof(f));
+
+	/* Properly calculate the sizeimage and bytesperline values. */
+	v4l2_fill_pix_format(&f.fmt.pix, mbus_fmt);
+	f.fmt.pix.pixelformat = fmt->fourcc;
+	ret = vip_calc_format_size(port, fmt, &f);
+	if (ret)
+		return ret;
+
+	stream->width = f.fmt.pix.width;
+	stream->height = f.fmt.pix.height;
+	stream->sup_field = f.fmt.pix.field;
+	stream->bytesperline = f.fmt.pix.bytesperline;
+	stream->sizeimage = f.fmt.pix.sizeimage;
+
+	v4l2_dbg(3, debug, stream, "init_stream fourcc:%s size: %dx%d bpl:%d img_size:%d\n",
+		 fourcc_to_str(f.fmt.pix.pixelformat),
+		 f.fmt.pix.width, f.fmt.pix.height,
+		 f.fmt.pix.bytesperline, f.fmt.pix.sizeimage);
+	v4l2_dbg(3, debug, stream, "init_stream vpdma data type: 0x%02X\n",
+		 port->fmt->vpdma_fmt[0]->data_type);
+
+	ret = vpdma_create_desc_list(&stream->desc_list, VIP_DESC_LIST_SIZE,
+				     VPDMA_LIST_TYPE_NORMAL);
+
+	if (ret != 0)
+		return ret;
+
+	stream->write_desc = (struct vpdma_dtd *)stream->desc_list.buf.addr
+				+ 15;
+
+	v4l2_dbg(1, debug, stream, "%s: stream instance %pa\n",
+		 __func__, &stream);
+
+	return 0;
+}
+
+static void vip_release_dev(struct vip_dev *dev)
+{
+	/*
+	 * On last close, disable clocks to conserve power
+	 */
+
+	if (--dev->num_ports == 0) {
+		/* reset the scaler module */
+		vip_module_toggle(dev, VIP_SC_RST, true);
+		vip_module_toggle(dev, VIP_CSC_RST, true);
+		vip_set_clock_enable(dev, 0);
+	}
+}
+
+static int vip_set_crop_parser(struct vip_port *port)
+{
+	struct vip_dev *dev = port->dev;
+	struct vip_parser_data *parser = dev->parser;
+	u32 hcrop = 0, vcrop = 0;
+	u32 width = port->mbus_framefmt.width;
+
+	if (port->fmt->vpdma_fmt[0] == &vpdma_raw_fmts[VPDMA_DATA_FMT_RAW8]) {
+		/*
+		 * Special case since we are faking a YUV422 16bit format
+		 * to have the vpdma perform the needed byte swap
+		 * we need to adjust the pixel width accordingly
+		 * otherwise the parser will attempt to collect more pixels
+		 * then available and the vpdma transfer will exceed the
+		 * allocated frame buffer.
+		 */
+		width >>= 1;
+		v4l2_dbg(1, debug, port, "%s: 8 bit raw detected, adjusting width to %d\n",
+			 __func__, width);
+	}
+
+	/*
+	 * Set Parser Crop parameters to source size otherwise
+	 * scaler and colorspace converter will yield garbage.
+	 */
+	hcrop = VIP_ACT_BYPASS;
+	insert_field(&hcrop, 0, VIP_ACT_SKIP_NUMPIX_MASK,
+		     VIP_ACT_SKIP_NUMPIX_SHFT);
+	insert_field(&hcrop, width,
+		     VIP_ACT_USE_NUMPIX_MASK, VIP_ACT_USE_NUMPIX_SHFT);
+	reg_write(parser, VIP_PARSER_CROP_H_PORT(port->port_id), hcrop);
+
+	insert_field(&vcrop, 0, VIP_ACT_SKIP_NUMLINES_MASK,
+		     VIP_ACT_SKIP_NUMLINES_SHFT);
+	insert_field(&vcrop, port->mbus_framefmt.height,
+		     VIP_ACT_USE_NUMLINES_MASK, VIP_ACT_USE_NUMLINES_SHFT);
+	reg_write(parser, VIP_PARSER_CROP_V_PORT(port->port_id), vcrop);
+
+	return 0;
+}
+
+static int vip_setup_parser(struct vip_port *port)
+{
+	struct vip_dev *dev = port->dev;
+	struct vip_parser_data *parser = dev->parser;
+	struct v4l2_fwnode_endpoint *endpoint = &port->endpoint;
+	struct vip_bt656_bus *bt656_ep = &port->bt656_endpoint;
+	int iface, sync_type;
+	u32 flags = 0, config0;
+
+	/* Reset the port */
+	vip_reset_parser(port, true);
+	usleep_range(200, 250);
+	vip_reset_parser(port, false);
+
+	config0 = reg_read(parser, VIP_PARSER_PORT(port->port_id));
+
+	if (endpoint->bus_type == V4L2_MBUS_BT656) {
+		flags = endpoint->bus.parallel.flags;
+		iface = DUAL_8B_INTERFACE;
+
+		/*
+		 * Ideally, this should come from subdev
+		 * port->fmt can be anything once CSC is enabled
+		 */
+		if (vip_is_mbuscode_rgb(port->fmt->code)) {
+			sync_type = EMBEDDED_SYNC_SINGLE_RGB_OR_YUV444;
+		} else {
+			switch (bt656_ep->num_channels) {
+			case 4:
+				sync_type = EMBEDDED_SYNC_4X_MULTIPLEXED_YUV422;
+				break;
+			case 2:
+				sync_type = EMBEDDED_SYNC_2X_MULTIPLEXED_YUV422;
+				break;
+			case 1:
+				sync_type = EMBEDDED_SYNC_SINGLE_YUV422;
+				break;
+			default:
+				sync_type =
+				EMBEDDED_SYNC_LINE_MULTIPLEXED_YUV422;
+			}
+			if (bt656_ep->pixmux == 0)
+				sync_type =
+				EMBEDDED_SYNC_LINE_MULTIPLEXED_YUV422;
+		}
+
+	} else if (endpoint->bus_type == V4L2_MBUS_PARALLEL) {
+		flags = endpoint->bus.parallel.flags;
+
+		switch (endpoint->bus.parallel.bus_width) {
+		case 24:
+			iface = SINGLE_24B_INTERFACE;
+		break;
+		case 16:
+			iface = SINGLE_16B_INTERFACE;
+		break;
+		case 8:
+		default:
+			iface = DUAL_8B_INTERFACE;
+		}
+
+		if (vip_is_mbuscode_rgb(port->fmt->code))
+			sync_type = DISCRETE_SYNC_SINGLE_RGB_24B;
+		else
+			sync_type = DISCRETE_SYNC_SINGLE_YUV422;
+
+		if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+			config0 |= VIP_HSYNC_POLARITY;
+		else if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
+			config0 &= ~VIP_HSYNC_POLARITY;
+
+		if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
+			config0 |= VIP_VSYNC_POLARITY;
+		else if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+			config0 &= ~VIP_VSYNC_POLARITY;
+
+		config0 &= ~VIP_USE_ACTVID_HSYNC_ONLY;
+		config0 |= VIP_ACTVID_POLARITY;
+		config0 |= VIP_DISCRETE_BASIC_MODE;
+
+	} else {
+		v4l2_err(port, "Device doesn't support CSI2");
+		return -EINVAL;
+	}
+
+	if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) {
+		vip_set_pclk_invert(port);
+		config0 |= VIP_PIXCLK_EDGE_POLARITY;
+	} else {
+		config0 &= ~VIP_PIXCLK_EDGE_POLARITY;
+	}
+
+	config0 |= ((sync_type & VIP_SYNC_TYPE_MASK) << VIP_SYNC_TYPE_SHFT);
+
+	reg_write(parser, VIP_PARSER_PORT(port->port_id), config0);
+
+	vip_set_data_interface(port, iface);
+	vip_set_crop_parser(port);
+
+	return 0;
+}
+
+static void vip_enable_parser(struct vip_port *port, bool on)
+{
+	u32 config0;
+	struct vip_dev *dev = port->dev;
+	struct vip_parser_data *parser = dev->parser;
+
+	config0 = reg_read(parser, VIP_PARSER_PORT(port->port_id));
+
+	if (on) {
+		config0 |= VIP_PORT_ENABLE;
+		config0 &= ~(VIP_ASYNC_FIFO_RD | VIP_ASYNC_FIFO_WR);
+	} else {
+		config0 &= ~VIP_PORT_ENABLE;
+		config0 |= (VIP_ASYNC_FIFO_RD | VIP_ASYNC_FIFO_WR);
+	}
+	reg_write(parser, VIP_PARSER_PORT(port->port_id), config0);
+}
+
+static void vip_reset_parser(struct vip_port *port, bool on)
+{
+	u32 config0;
+	struct vip_dev *dev = port->dev;
+	struct vip_parser_data *parser = dev->parser;
+
+	config0 = reg_read(parser, VIP_PARSER_PORT(port->port_id));
+
+	if (on)
+		config0 |= VIP_SW_RESET;
+	else
+		config0 &= ~VIP_SW_RESET;
+
+	reg_write(parser, VIP_PARSER_PORT(port->port_id), config0);
+}
+
+static void vip_parser_stop_imm(struct vip_port *port, bool on)
+{
+	u32 config0;
+	struct vip_dev *dev = port->dev;
+	struct vip_parser_data *parser = dev->parser;
+
+	config0 = reg_read(parser, VIP_PARSER_STOP_IMM_PORT(port->port_id));
+
+	if (on)
+		config0 = 0xffffffff;
+	else
+		config0 = 0;
+
+	reg_write(parser, VIP_PARSER_STOP_IMM_PORT(port->port_id), config0);
+}
+
+static void vip_release_stream(struct vip_stream *stream)
+{
+	struct vip_dev *dev = stream->port->dev;
+
+	v4l2_dbg(1, debug, stream, "%s: stream instance %pa\n",
+		 __func__, &stream);
+
+	vpdma_unmap_desc_buf(dev->shared->vpdma, &stream->desc_list.buf);
+	vpdma_free_desc_buf(&stream->desc_list.buf);
+	vpdma_free_desc_list(&stream->desc_list);
+}
+
+static void vip_release_port(struct vip_port *port)
+{
+	v4l2_dbg(1, debug, port, "%s: port instance %pa\n",
+		 __func__, &port);
+
+	vpdma_free_desc_buf(&port->mmr_adb);
+	vpdma_free_desc_buf(&port->sc_coeff_h);
+	vpdma_free_desc_buf(&port->sc_coeff_v);
+}
+
+static void stop_dma(struct vip_stream *stream, bool clear_list)
+{
+	struct vip_dev *dev = stream->port->dev;
+	int ch, size = 0;
+
+	/* Create a list of channels to be cleared */
+	for (ch = 0; ch < VPDMA_MAX_CHANNELS; ch++) {
+		if (stream->vpdma_channels[ch] == 1) {
+			stream->vpdma_channels_to_abort[size++] = ch;
+			v4l2_dbg(2, debug, stream, "Clear channel no: %d\n", ch);
+		}
+	}
+
+	/* Clear all the used channels for the list */
+	vpdma_list_cleanup(dev->shared->vpdma, stream->list_num,
+			   stream->vpdma_channels_to_abort, size);
+
+	if (clear_list)
+		for (ch = 0; ch < VPDMA_MAX_CHANNELS; ch++)
+			stream->vpdma_channels[ch] = 0;
+}
+
+static int vip_open(struct file *file)
+{
+	struct vip_stream *stream = video_drvdata(file);
+	struct vip_port *port = stream->port;
+	struct vip_dev *dev = port->dev;
+	int ret = 0;
+
+	mutex_lock(&dev->mutex);
+
+	ret = v4l2_fh_open(file);
+	if (ret) {
+		v4l2_err(stream, "v4l2_fh_open failed\n");
+		goto unlock;
+	}
+
+	/*
+	 * If this is the first open file.
+	 * Then initialize hw module.
+	 */
+	if (!v4l2_fh_is_singular_file(file))
+		goto unlock;
+
+	if (vip_init_stream(stream))
+		ret = -ENODEV;
+unlock:
+	mutex_unlock(&dev->mutex);
+	return ret;
+}
+
+static int vip_release(struct file *file)
+{
+	struct vip_stream *stream = video_drvdata(file);
+	struct vip_port *port = stream->port;
+	struct vip_dev *dev = port->dev;
+	bool fh_singular;
+	int ret;
+
+	mutex_lock(&dev->mutex);
+
+	/* Save the singular status before we call the clean-up helper */
+	fh_singular = v4l2_fh_is_singular_file(file);
+
+	/* the release helper will cleanup any on-going streaming */
+	ret = _vb2_fop_release(file, NULL);
+
+	free_csc(port);
+	free_scaler(port);
+
+	/*
+	 * If this is the last open file.
+	 * Then de-initialize hw module.
+	 */
+	if (fh_singular) {
+		vip_release_stream(stream);
+
+		if (--port->num_streams == 0) {
+			vip_release_port(port);
+			vip_release_dev(port->dev);
+		}
+	}
+
+	mutex_unlock(&dev->mutex);
+
+	return ret;
+}
+
+/*
+ * File operations
+ */
+static const struct v4l2_file_operations vip_fops = {
+	.owner		= THIS_MODULE,
+	.open		= vip_open,
+	.release	= vip_release,
+	.read		= vb2_fop_read,
+	.poll		= vb2_fop_poll,
+	.unlocked_ioctl	= video_ioctl2,
+	.mmap		= vb2_fop_mmap,
+};
+
+static struct video_device vip_videodev = {
+	.name		= VIP_MODULE_NAME,
+	.fops		= &vip_fops,
+	.ioctl_ops	= &vip_ioctl_ops,
+	.minor		= -1,
+	.release	= video_device_release,
+	.tvnorms	= V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+	.device_caps	= V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
+			  V4L2_CAP_READWRITE,
+};
+
+static int alloc_stream(struct vip_port *port, int stream_id, int vfl_type)
+{
+	struct vip_stream *stream;
+	struct vip_dev *dev = port->dev;
+	struct vb2_queue *q;
+	struct video_device *vfd;
+	struct vip_buffer *buf;
+	struct list_head *pos, *tmp;
+	int ret, i;
+	u32 vin_id;
+
+	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
+	if (!stream)
+		return -ENOMEM;
+
+	stream->port = port;
+	stream->stream_id = stream_id;
+	stream->vfl_type = vfl_type;
+	port->cap_streams[stream_id] = stream;
+
+	vin_id = 1 + ((dev->instance_id - 1) * 2) + dev->slice_id;
+	snprintf(stream->name, sizeof(stream->name), "vin%d%c-%d",
+		 vin_id, (port->port_id == VIP_PORTA) ? 'a' : 'b', stream_id);
+
+	stream->list_num = vpdma_hwlist_alloc(dev->shared->vpdma, stream);
+	if (stream->list_num < 0) {
+		v4l2_err(stream, "Could not get VPDMA hwlist");
+		ret = -ENODEV;
+		goto do_free_stream;
+	}
+
+	INIT_LIST_HEAD(&stream->post_bufs);
+
+	/*
+	 * Initialize queue
+	 */
+	q = &stream->vb_vidq;
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
+	q->drv_priv = stream;
+	q->buf_struct_size = sizeof(struct vip_buffer);
+	q->ops = &vip_video_qops;
+	q->mem_ops = &vb2_dma_contig_memops;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &dev->mutex;
+	q->min_reqbufs_allocation = 3;
+	q->dev = dev->v4l2_dev->dev;
+
+	ret = vb2_queue_init(q);
+	if (ret)
+		goto do_free_hwlist;
+
+	INIT_WORK(&stream->recovery_work, vip_overflow_recovery_work);
+
+	INIT_LIST_HEAD(&stream->vidq);
+
+	/* Allocate/populate Drop queue entries */
+	INIT_LIST_HEAD(&stream->dropq);
+	for (i = 0; i < VIP_DROPQ_SIZE; i++) {
+		buf = kzalloc(sizeof(*buf), GFP_ATOMIC);
+		if (!buf) {
+			ret = -ENOMEM;
+			goto do_free_dropq;
+		}
+		buf->drop = true;
+		list_add(&buf->list, &stream->dropq);
+	}
+
+	vfd = video_device_alloc();
+	if (!vfd)
+		goto do_free_dropq;
+	*vfd = vip_videodev;
+	vfd->v4l2_dev = dev->v4l2_dev;
+	vfd->queue = q;
+
+	vfd->lock = &dev->mutex;
+	video_set_drvdata(vfd, stream);
+
+	ret = video_register_device(vfd, vfl_type, -1);
+	if (ret) {
+		v4l2_err(stream, "Failed to register video device\n");
+		goto do_free_vfd;
+	}
+
+	stream->vfd = vfd;
+
+	v4l2_info(stream, "device registered as %s\n",
+		  video_device_node_name(vfd));
+	return 0;
+
+do_free_vfd:
+	video_device_release(vfd);
+do_free_dropq:
+	list_for_each_safe(pos, tmp, &stream->dropq) {
+		buf = list_entry(pos,
+				 struct vip_buffer, list);
+		v4l2_dbg(1, debug, dev, "dropq buffer\n");
+		list_del(pos);
+		kfree(buf);
+	}
+do_free_hwlist:
+	vpdma_hwlist_release(dev->shared->vpdma, stream->list_num);
+do_free_stream:
+	kfree(stream);
+	return ret;
+}
+
+static void free_stream(struct vip_stream *stream)
+{
+	struct vip_dev *dev;
+	struct vip_buffer *buf;
+	struct list_head *pos, *q;
+
+	if (!stream)
+		return;
+
+	dev = stream->port->dev;
+	/* Free up the Drop queue */
+	list_for_each_safe(pos, q, &stream->dropq) {
+		buf = list_entry(pos,
+				 struct vip_buffer, list);
+		v4l2_dbg(1, debug, stream, "dropq buffer\n");
+		list_del(pos);
+		kfree(buf);
+	}
+
+	video_unregister_device(stream->vfd);
+	vpdma_hwlist_release(dev->shared->vpdma, stream->list_num);
+	stream->port->cap_streams[stream->stream_id] = NULL;
+	kfree(stream);
+}
+
+static int get_subdev_active_format(struct vip_port *port,
+				    struct v4l2_subdev *subdev)
+{
+	struct vip_fmt *fmt;
+	struct v4l2_subdev_mbus_code_enum mbus_code;
+	int ret = 0;
+	unsigned int k, i, j;
+	enum vip_csc_state csc;
+
+	/* Enumerate sub device formats and enable all matching local formats */
+	port->num_active_fmt = 0;
+	for (k = 0, i = 0; (ret != -EINVAL); k++) {
+		memset(&mbus_code, 0, sizeof(mbus_code));
+		mbus_code.index = k;
+		mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+		ret = v4l2_subdev_call(subdev, pad, enum_mbus_code,
+				       NULL, &mbus_code);
+		if (ret)
+			continue;
+
+		v4l2_dbg(2, debug, port,
+			 "subdev %s: code: %04x idx: %d\n",
+			 subdev->name, mbus_code.code, k);
+
+		for (j = 0; j < ARRAY_SIZE(vip_formats); j++) {
+			fmt = &vip_formats[j];
+			if (mbus_code.code != fmt->code)
+				continue;
+
+			/*
+			 * When the port is configured for BT656
+			 * then none of the downstream unit can be used.
+			 * So here we need to skip all format requiring
+			 * either CSC or CHR_DS
+			 */
+			csc = vip_csc_direction(fmt->code, fmt->finfo);
+			if (port->endpoint.bus_type == V4L2_MBUS_BT656 &&
+			    (csc != VIP_CSC_NA || fmt->coplanar))
+				continue;
+
+			port->active_fmt[i] = fmt;
+			v4l2_dbg(2, debug, port,
+				 "matched fourcc: %s: code: %04x idx: %d\n",
+				 fourcc_to_str(fmt->fourcc), fmt->code, i);
+			port->num_active_fmt = ++i;
+		}
+	}
+
+	if (i == 0) {
+		v4l2_err(port, "No suitable format reported by subdev %s\n",
+			 subdev->name);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int alloc_port(struct vip_dev *dev, int id)
+{
+	struct vip_port *port;
+	u32 vin_id;
+
+	if (dev->ports[id])
+		return -EINVAL;
+
+	port = devm_kzalloc(&dev->pdev->dev, sizeof(*port), GFP_KERNEL);
+	if (!port)
+		return -ENOMEM;
+
+	dev->ports[id] = port;
+	port->dev = dev;
+	port->port_id = id;
+	vin_id = 1 + ((dev->instance_id - 1) * 2) + dev->slice_id;
+	snprintf(port->name, sizeof(port->name),
+		 "vin%d%c", vin_id, (id == VIP_PORTA) ? 'a' : 'b');
+	port->num_streams = 0;
+	return 0;
+}
+
+static void free_port(struct vip_port *port)
+{
+	if (!port)
+		return;
+
+	v4l2_async_nf_unregister(&port->notifier);
+	v4l2_async_nf_cleanup(&port->notifier);
+	free_stream(port->cap_streams[0]);
+}
+
+static int get_field(u32 value, u32 mask, int shift)
+{
+	return (value & (mask << shift)) >> shift;
+}
+
+static int vip_probe_complete(struct platform_device *pdev);
+static void vip_vpdma_fw_cb(struct platform_device *pdev)
+{
+	dev_info(&pdev->dev, "VPDMA firmware loaded\n");
+
+	if (pdev->dev.of_node)
+		vip_probe_complete(pdev);
+}
+
+static int vip_create_streams(struct vip_port *port,
+			      struct v4l2_subdev *subdev)
+{
+	struct v4l2_mbus_config_parallel *bus;
+	struct vip_bt656_bus *bt656_ep;
+	int i;
+
+	for (i = 0; i < VIP_CAP_STREAMS_PER_PORT; i++)
+		free_stream(port->cap_streams[i]);
+
+	if (get_subdev_active_format(port, subdev))
+		return -ENODEV;
+
+	port->subdev = subdev;
+
+	if (port->endpoint.bus_type == V4L2_MBUS_PARALLEL) {
+		port->flags |= FLAG_MULT_PORT;
+		port->num_streams_configured = 1;
+		alloc_stream(port, 0, VFL_TYPE_VIDEO);
+	} else if (port->endpoint.bus_type == V4L2_MBUS_BT656) {
+		port->flags |= FLAG_MULT_PORT;
+		bus = &port->endpoint.bus.parallel;
+		bt656_ep = &port->bt656_endpoint;
+		port->num_streams_configured = bt656_ep->num_channels;
+		for (i = 0; i < bt656_ep->num_channels; i++) {
+			if (bt656_ep->channels[i] >= 16)
+				continue;
+			alloc_stream(port, bt656_ep->channels[i], VFL_TYPE_VIDEO);
+		}
+	}
+	return 0;
+}
+
+static int vip_async_bound(struct v4l2_async_notifier *notifier,
+			   struct v4l2_subdev *subdev,
+			   struct v4l2_async_connection *asd)
+{
+	struct vip_port *port = notifier_to_vip_port(notifier);
+	int ret;
+
+	if (port->subdev) {
+		v4l2_info(port, "Rejecting subdev %s (Already set!!)",
+			  subdev->name);
+		return 0;
+	}
+
+	v4l2_info(port, "Port %c: Using subdev %s for capture\n",
+		  port->port_id == VIP_PORTA ? 'A' : 'B', subdev->name);
+
+	ret = vip_create_streams(port, subdev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int vip_async_complete(struct v4l2_async_notifier *notifier)
+{
+	return 0;
+}
+
+static const struct v4l2_async_notifier_operations vip_async_ops = {
+	.bound = vip_async_bound,
+	.complete = vip_async_complete,
+};
+
+static struct fwnode_handle *
+fwnode_graph_get_next_endpoint_by_regs(const struct fwnode_handle *fwnode,
+				       int port_reg, int reg)
+{
+	return of_fwnode_handle(of_graph_get_endpoint_by_regs(to_of_node(fwnode),
+							      port_reg, reg));
+}
+
+static int vip_register_subdev_notif(struct vip_port *port,
+				     struct fwnode_handle *ep)
+{
+	struct v4l2_async_notifier *notifier = &port->notifier;
+	struct fwnode_handle *subdev;
+	struct v4l2_fwnode_endpoint *vep;
+	struct vip_bt656_bus *bt656_vep;
+	struct v4l2_async_connection *asd;
+	int ret, rval;
+
+	vep = &port->endpoint;
+	bt656_vep = &port->bt656_endpoint;
+
+	subdev = fwnode_graph_get_remote_port_parent(ep);
+	if (!subdev) {
+		v4l2_dbg(3, debug, port, "can't get remote parent\n");
+		return -EINVAL;
+	}
+
+	ret = v4l2_fwnode_endpoint_parse(ep, vep);
+	if (ret) {
+		v4l2_dbg(3, debug, port, "Failed to parse endpoint:\n");
+		fwnode_handle_put(subdev);
+		return -EINVAL;
+	}
+
+	if (vep->bus_type == V4L2_MBUS_BT656) {
+		if (fwnode_property_present(ep, "ti,vip-pixel-mux"))
+			bt656_vep->pixmux = 1;
+		else
+			bt656_vep->pixmux = 0;
+		v4l2_dbg(3, debug, port, "ti,vip-pixel-mux %u\n", bt656_vep->pixmux);
+
+		bt656_vep->num_channels = 0;
+		rval = fwnode_property_read_u8_array(ep, "ti,vip-channels",
+						     NULL, 0);
+		if (rval > 0) {
+			bt656_vep->num_channels =
+				min_t(int, ARRAY_SIZE(bt656_vep->channels),
+				      rval);
+
+			fwnode_property_read_u8_array(ep, "ti,vip-channels",
+						      bt656_vep->channels,
+						      bt656_vep->num_channels);
+		}
+		v4l2_dbg(3, debug, port, "ti,vip-channels %u\n", bt656_vep->num_channels);
+	}
+
+	v4l2_async_nf_init(notifier, &port->dev->shared->v4l2_dev);
+
+	asd = v4l2_async_nf_add_fwnode(notifier, subdev, struct v4l2_async_connection);
+	if (IS_ERR(asd)) {
+		v4l2_dbg(1, debug, port, "Error adding asd\n");
+		fwnode_handle_put(subdev);
+		v4l2_async_nf_cleanup(notifier);
+		return -EINVAL;
+	}
+
+	notifier->ops = &vip_async_ops;
+	ret = v4l2_async_nf_register(notifier);
+	if (ret) {
+		v4l2_dbg(1, debug, port, "Error registering async notifier\n");
+		v4l2_async_nf_cleanup(notifier);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int vip_endpoint_scan(struct platform_device *pdev)
+{
+	struct device_node *parent = pdev->dev.of_node;
+	struct device_node *ep = NULL;
+	int count = 0, p;
+
+	for (p = 0; p < (VIP_NUM_PORTS * VIP_NUM_SLICES); p++) {
+		ep = of_graph_get_endpoint_by_regs(parent, p, 0);
+		if (!ep)
+			continue;
+
+		count++;
+		of_node_put(ep);
+	}
+
+	return count;
+}
+
+static int vip_probe_complete(struct platform_device *pdev)
+{
+	struct vip_shared *shared = platform_get_drvdata(pdev);
+	struct regmap *syscon_pol = NULL;
+	u32 syscon_pol_offset = 0;
+	struct vip_port *port;
+	struct vip_dev *dev;
+	struct device_node *parent = pdev->dev.of_node;
+	struct fwnode_handle *ep = NULL;
+	int ret, slice_id, port_id, p;
+
+	if (parent && of_property_read_bool(parent, "ti,vip-clk-polarity")) {
+		syscon_pol = syscon_regmap_lookup_by_phandle(parent,
+							     "ti,vip-clk-polarity");
+		if (IS_ERR(syscon_pol)) {
+			dev_err(&pdev->dev, "failed to get ti,vip-clk-polarity regmap\n");
+			return PTR_ERR(syscon_pol);
+		}
+
+		if (of_property_read_u32_index(parent, "ti,vip-clk-polarity",
+					       1, &syscon_pol_offset)) {
+			dev_err(&pdev->dev, "failed to get ti,vip-clk-polarity offset\n");
+			return -EINVAL;
+		}
+	}
+
+	for (p = 0; p < (VIP_NUM_PORTS * VIP_NUM_SLICES); p++) {
+		ep = fwnode_graph_get_next_endpoint_by_regs(of_fwnode_handle(parent),
+							    p, 0);
+		if (!ep)
+			continue;
+
+		switch (p) {
+		case 0:
+			slice_id = VIP_SLICE1;	port_id = VIP_PORTA;
+			break;
+		case 1:
+			slice_id = VIP_SLICE2;	port_id = VIP_PORTA;
+			break;
+		case 2:
+			slice_id = VIP_SLICE1;	port_id = VIP_PORTB;
+			break;
+		case 3:
+			slice_id = VIP_SLICE2;	port_id = VIP_PORTB;
+			break;
+		default:
+			dev_err(&pdev->dev, "Unknown port reg=<%d>\n", p);
+			continue;
+		}
+
+		ret = alloc_port(shared->devs[slice_id], port_id);
+		if (ret < 0)
+			continue;
+
+		dev = shared->devs[slice_id];
+		dev->syscon_pol = syscon_pol;
+		dev->syscon_pol_offset = syscon_pol_offset;
+		port = dev->ports[port_id];
+
+		vip_register_subdev_notif(port, ep);
+		fwnode_handle_put(ep);
+	}
+	return 0;
+}
+
+static int vip_probe_slice(struct platform_device *pdev, int slice, int instance_id)
+{
+	struct vip_shared *shared = platform_get_drvdata(pdev);
+	struct vip_dev *dev;
+	struct vip_parser_data *parser;
+	u32 vin_id;
+	int ret;
+
+	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->instance_id = instance_id;
+	vin_id = 1 + ((dev->instance_id - 1) * 2) + slice;
+	snprintf(dev->name, sizeof(dev->name), "vin%d", vin_id);
+
+	dev->irq = platform_get_irq(pdev, slice);
+	if (dev->irq < 0)
+		return dev->irq;
+
+	ret = devm_request_irq(&pdev->dev, dev->irq, vip_irq,
+			       0, dev->name, dev);
+	if (ret < 0)
+		return -ENOMEM;
+
+	spin_lock_init(&dev->slock);
+	mutex_init(&dev->mutex);
+
+	dev->slice_id = slice;
+	dev->pdev = pdev;
+	dev->res = shared->res;
+	dev->base = shared->base;
+	dev->v4l2_dev = &shared->v4l2_dev;
+
+	dev->shared = shared;
+	shared->devs[slice] = dev;
+
+	vip_top_reset(dev);
+	vip_set_slice_path(dev, VIP_MULTI_CHANNEL_DATA_SELECT, 1);
+
+	parser = devm_kzalloc(&pdev->dev, sizeof(*dev->parser), GFP_KERNEL);
+	if (!parser)
+		return PTR_ERR(parser);
+
+	parser->res = platform_get_resource_byname(pdev,
+						   IORESOURCE_MEM,
+						   (slice == 0) ?
+						   "parser0" :
+						   "parser1");
+	parser->base = devm_ioremap_resource(&pdev->dev, parser->res);
+	if (IS_ERR(parser->base))
+		return PTR_ERR(parser->base);
+
+	parser->pdev = pdev;
+	dev->parser = parser;
+
+	dev->sc_assigned = VIP_NOT_ASSIGNED;
+	dev->sc = sc_create(pdev, (slice == 0) ? "sc0" : "sc1");
+	if (IS_ERR(dev->sc))
+		return PTR_ERR(dev->sc);
+
+	dev->csc_assigned = VIP_NOT_ASSIGNED;
+	dev->csc = csc_create(pdev, (slice == 0) ? "csc0" : "csc1");
+	if (IS_ERR(dev->sc))
+		return PTR_ERR(dev->sc);
+
+	return 0;
+}
+
+static int vip_probe(struct platform_device *pdev)
+{
+	struct vip_shared *shared;
+	struct pinctrl *pinctrl;
+	int ret, slice = VIP_SLICE1;
+	int instance_id;
+	u32 tmp, pid;
+	const char *label;
+
+	if (!of_property_read_string(pdev->dev.of_node, "label", &label)) {
+		if (strcmp(label, "vip1") == 0)
+			instance_id = 1;
+		else if (strcmp(label, "vip2") == 0)
+			instance_id = 2;
+		else if (strcmp(label, "vip3") == 0)
+			instance_id = 3;
+	} else {
+		dev_err(&pdev->dev, "%s: VIP instance id out of range...\n",
+			__func__);
+		return -ENODEV;
+	}
+
+	/* If there are no endpoint defined there is nothing to do */
+	if (!vip_endpoint_scan(pdev)) {
+		dev_err(&pdev->dev, "%s: No sensor", __func__);
+		return -ENODEV;
+	}
+
+	ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+	if (ret) {
+		dev_err(&pdev->dev,
+			"32-bit consistent DMA enable failed\n");
+		return ret;
+	}
+
+	shared = devm_kzalloc(&pdev->dev, sizeof(*shared), GFP_KERNEL);
+	if (!shared)
+		return -ENOMEM;
+
+	shared->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vip");
+	shared->base = devm_ioremap_resource(&pdev->dev, shared->res);
+	if (IS_ERR(shared->base))
+		return PTR_ERR(shared->base);
+
+	vip_init_format_info(&pdev->dev);
+
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+
+	pm_runtime_enable(&pdev->dev);
+
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret)
+		goto err_runtime_disable;
+
+	/* Make sure H/W module has the right functionality */
+	pid = reg_read(shared, VIP_PID);
+	tmp = get_field(pid, VIP_PID_FUNC_MASK, VIP_PID_FUNC_SHIFT);
+
+	if (tmp != VIP_PID_FUNC) {
+		dev_info(&pdev->dev, "vip: unexpected PID function: 0x%x\n",
+			 tmp);
+		ret = -ENODEV;
+		goto err_runtime_put;
+	}
+
+	ret = v4l2_device_register(&pdev->dev, &shared->v4l2_dev);
+	if (ret)
+		goto err_runtime_put;
+
+	/* enable clocks, so the firmware will load properly */
+	vip_shared_set_clock_enable(shared, 1);
+	vip_top_vpdma_reset(shared);
+
+	platform_set_drvdata(pdev, shared);
+
+	v4l2_ctrl_handler_init(&shared->ctrl_handler, 11);
+	shared->v4l2_dev.ctrl_handler = &shared->ctrl_handler;
+
+	for (slice = VIP_SLICE1; slice < VIP_NUM_SLICES; slice++) {
+		ret = vip_probe_slice(pdev, slice, instance_id);
+		if (ret) {
+			dev_err(&pdev->dev, "Creating slice failed");
+			goto err_dev_unreg;
+		}
+	}
+
+	shared->vpdma = &shared->vpdma_data;
+	ret = vpdma_create(pdev, shared->vpdma, vip_vpdma_fw_cb);
+	if (ret) {
+		dev_err(&pdev->dev, "Creating VPDMA failed");
+		goto err_dev_unreg;
+	}
+
+	return 0;
+
+err_dev_unreg:
+	v4l2_ctrl_handler_free(&shared->ctrl_handler);
+	v4l2_device_unregister(&shared->v4l2_dev);
+err_runtime_put:
+	pm_runtime_put_sync(&pdev->dev);
+err_runtime_disable:
+	pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static void vip_remove(struct platform_device *pdev)
+{
+	struct vip_shared *shared = platform_get_drvdata(pdev);
+	struct vip_dev *dev;
+	int slice;
+
+	for (slice = 0; slice < VIP_NUM_SLICES; slice++) {
+		dev = shared->devs[slice];
+		if (!dev)
+			continue;
+
+		free_port(dev->ports[VIP_PORTA]);
+		free_port(dev->ports[VIP_PORTB]);
+	}
+
+	v4l2_ctrl_handler_free(&shared->ctrl_handler);
+
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+}
+
+#if defined(CONFIG_OF)
+static const struct of_device_id vip_of_match[] = {
+	{
+		.compatible = "ti,dra7-vip",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, vip_of_match);
+#endif
+
+static struct platform_driver vip_pdrv = {
+	.probe		= vip_probe,
+	.remove		= vip_remove,
+	.driver		= {
+		.name	= VIP_MODULE_NAME,
+		.of_match_table = of_match_ptr(vip_of_match),
+	},
+};
+
+module_platform_driver(vip_pdrv);
+
+MODULE_DESCRIPTION("TI VIP driver");
+MODULE_AUTHOR("Texas Instruments");
+MODULE_LICENSE("GPL");
diff -Naur --no-dereference a/drivers/media/platform/ti/vpe/vip.h b/drivers/media/platform/ti/vpe/vip.h
--- a/drivers/media/platform/ti/vpe/vip.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/media/platform/ti/vpe/vip.h	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,719 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TI VIP capture driver
+ *
+ * Copyright (C) 2025 Texas Instruments Incorpated - http://www.ti.com/
+ * David Griego, <dagriego@biglakesoftware.com>
+ * Dale Farnsworth, <dale@farnsworth.org>
+ * Yemike Abhilash Chandra, <y-abhilashchandra@ti.com>
+ */
+
+#ifndef __TI_VIP_H
+#define __TI_VIP_H
+
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-memops.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-async.h>
+
+#include "vpdma.h"
+#include "vpdma_priv.h"
+#include "sc.h"
+#include "csc.h"
+
+#define VIP_INSTANCE1	1
+#define VIP_INSTANCE2	2
+#define VIP_INSTANCE3	3
+
+#define VIP_SLICE1	0
+#define VIP_SLICE2	1
+#define VIP_NUM_SLICES	2
+
+/*
+ * Additional client identifiers used for VPDMA configuration descriptors
+ */
+#define VIP_SLICE1_CFD_SC_CLIENT	7
+#define VIP_SLICE2_CFD_SC_CLIENT	8
+
+#define VIP_PORTA	0
+#define VIP_PORTB	1
+#define VIP_NUM_PORTS	2
+
+#define VIP_MAX_PLANES	2
+#define	VIP_LUMA	0
+#define VIP_CHROMA	1
+
+#define VIP_CAP_STREAMS_PER_PORT	16
+#define VIP_VBI_STREAMS_PER_PORT	16
+
+#define VIP_MAX_SUBDEV			5
+/*
+ * This value needs to be at least as large as the number of entry in
+ * vip_formats[].
+ * When vip_formats[] is modified make sure to adjust this value also.
+ */
+#define VIP_MAX_ACTIVE_FMT		16
+/*
+ * Colorspace conversion unit can be in one of 3 modes:
+ * NA  - Not Available on this port
+ * Y2R - Needed for YUV to RGB on this port
+ * R2Y - Needed for RGB to YUV on this port
+ */
+enum vip_csc_state {
+	VIP_CSC_NA = 0,
+	VIP_CSC_Y2R,
+	VIP_CSC_R2Y,
+};
+
+/* buffer for one video frame */
+struct vip_buffer {
+	/* common v4l buffer stuff */
+	struct vb2_v4l2_buffer	vb;
+	struct list_head	list;
+	bool			drop;
+};
+
+/*
+ * struct vip_fmt - VIP media bus format information
+ * @fourcc: V4L2 pixel format FCC identifier
+ * @code: V4L2 media bus format code
+ * @colorspace: V4L2 colorspace identifier
+ * @coplanar: 1 if unpacked Luma and Chroma, 0 otherwise (packed/interleaved)
+ * @vpdma_fmt: VPDMA data format per plane.
+ * @finfo: Cache v4l2_format_info for associated fourcc
+ */
+struct vip_fmt {
+	u32	fourcc;
+	u32	code;
+	u32	colorspace;
+	u8	coplanar;
+	const struct vpdma_data_format *vpdma_fmt[VIP_MAX_PLANES];
+	const struct v4l2_format_info *finfo;
+};
+
+/*
+ * The vip_parser_data structures contains the memory mapped
+ * info to access the parser registers.
+ */
+struct vip_parser_data {
+	void __iomem		*base;
+	struct resource		*res;
+
+	struct platform_device *pdev;
+};
+
+/*
+ * The vip_shared structure contains data that is shared by both
+ * the VIP1 and VIP2 slices.
+ */
+struct vip_shared {
+	struct list_head	list;
+	struct resource		*res;
+	void __iomem		*base;
+	struct vpdma_data	vpdma_data;
+	struct vpdma_data	*vpdma;
+	struct v4l2_device	v4l2_dev;
+	struct vip_dev		*devs[VIP_NUM_SLICES];
+	struct v4l2_ctrl_handler ctrl_handler;
+};
+
+/*
+ * The vip_bt656_bus structure contains vip specific bt656 bus data.
+ */
+struct vip_bt656_bus {
+	unsigned char num_channels;
+	unsigned char pixmux;
+	unsigned char channels[16];
+};
+
+/*
+ * There are two vip_dev structure, one for each vip slice: VIP1 & VIP2.
+ */
+struct vip_dev {
+	struct v4l2_device	*v4l2_dev;
+	struct platform_device *pdev;
+	struct vip_shared	*shared;
+	struct resource		*res;
+	struct regmap		*syscon_pol;
+	u32			syscon_pol_offset;
+	int			instance_id;
+	int			slice_id;
+	int			num_ports;	/* count of open ports */
+	struct mutex		mutex;
+	/* protects access to stream buffer queues */
+	spinlock_t		slock;
+
+	int			irq;
+	void __iomem		*base;
+
+	struct vip_port		*ports[VIP_NUM_PORTS];
+
+	char			name[16];
+	/* parser data handle */
+	struct vip_parser_data	*parser;
+	/* scaler data handle */
+	struct sc_data		*sc;
+	/* scaler port assignation */
+	int			sc_assigned;
+	/* csc data handle */
+	struct csc_data		*csc;
+	/* csc port assignation */
+	int			csc_assigned;
+};
+
+/*
+ * There are two vip_port structures for each vip_dev, one for port A
+ * and one for port B.
+ */
+struct vip_port {
+	struct vip_dev		*dev;
+	int			port_id;
+
+	unsigned int		flags;
+	struct v4l2_rect	c_rect;		/* crop rectangle */
+	struct v4l2_mbus_framefmt mbus_framefmt;
+	struct v4l2_mbus_framefmt try_mbus_framefmt;
+
+	char			name[16];
+	struct vip_fmt		*fmt;		/* current format info */
+	/* Number of channels/streams configured */
+	int			num_streams_configured;
+	int			num_streams;	/* count of open streams */
+	struct vip_stream	*cap_streams[VIP_CAP_STREAMS_PER_PORT];
+
+	struct v4l2_async_notifier notifier;
+	struct v4l2_subdev	*subdev;
+	struct v4l2_fwnode_endpoint endpoint;
+	struct vip_bt656_bus	bt656_endpoint;
+	struct vip_fmt		*active_fmt[VIP_MAX_ACTIVE_FMT];
+	int			num_active_fmt;
+	/* have new shadow reg values */
+	bool			load_mmrs;
+	/* shadow reg addr/data block */
+	struct vpdma_buf	mmr_adb;
+	/* h coeff buffer */
+	struct vpdma_buf	sc_coeff_h;
+	/* v coeff buffer */
+	struct vpdma_buf	sc_coeff_v;
+	/* Show if scaler resource is available on this port */
+	bool			scaler;
+	/* Show the csc resource state on this port */
+	enum vip_csc_state	csc;
+};
+
+/*
+ * When handling multiplexed video, there can be multiple streams for each
+ * port.  The vip_stream structure holds per-stream data.
+ */
+struct vip_stream {
+	struct video_device	*vfd;
+	struct vip_port		*port;
+	int			stream_id;
+	int			list_num;
+	int			vfl_type;
+	char			name[16];
+	struct work_struct	recovery_work;
+	int			num_recovery;
+	enum v4l2_field		field;		/* current field */
+	unsigned int		sequence;	/* current frame/field seq */
+	enum v4l2_field		sup_field;	/* supported field value */
+	unsigned int		width;		/* frame width */
+	unsigned int		height;		/* frame height */
+	unsigned int		bytesperline;	/* bytes per line in memory */
+	unsigned int		sizeimage;	/* image size in memory */
+	struct list_head	vidq;		/* incoming vip_bufs queue */
+	struct list_head	dropq;		/* drop vip_bufs queue */
+	struct list_head	post_bufs;	/* vip_bufs to be DMAed */
+	/* Maintain a list of used channels - Needed for VPDMA cleanup */
+	int			vpdma_channels[VPDMA_MAX_CHANNELS];
+	int			vpdma_channels_to_abort[VPDMA_MAX_CHANNELS];
+	struct vpdma_desc_list	desc_list;	/* DMA descriptor list */
+	struct vpdma_dtd	*write_desc;
+	/* next unused desc_list addr */
+	void			*desc_next;
+	struct vb2_queue	vb_vidq;
+};
+
+/*
+ * VIP Enumerations
+ */
+enum data_path_select {
+	ALL_FIELDS_DATA_SELECT = 0,
+	VIP_CSC_SRC_DATA_SELECT,
+	VIP_SC_SRC_DATA_SELECT,
+	VIP_RGB_SRC_DATA_SELECT,
+	VIP_RGB_OUT_LO_DATA_SELECT,
+	VIP_RGB_OUT_HI_DATA_SELECT,
+	VIP_CHR_DS_1_SRC_DATA_SELECT,
+	VIP_CHR_DS_2_SRC_DATA_SELECT,
+	VIP_MULTI_CHANNEL_DATA_SELECT,
+	VIP_CHR_DS_1_DATA_BYPASS,
+	VIP_CHR_DS_2_DATA_BYPASS,
+};
+
+enum data_interface_modes {
+	SINGLE_24B_INTERFACE = 0,
+	SINGLE_16B_INTERFACE = 1,
+	DUAL_8B_INTERFACE = 2,
+};
+
+enum sync_types {
+	EMBEDDED_SYNC_SINGLE_YUV422 = 0,
+	EMBEDDED_SYNC_2X_MULTIPLEXED_YUV422 = 1,
+	EMBEDDED_SYNC_4X_MULTIPLEXED_YUV422 = 2,
+	EMBEDDED_SYNC_LINE_MULTIPLEXED_YUV422 = 3,
+	DISCRETE_SYNC_SINGLE_YUV422 = 4,
+	EMBEDDED_SYNC_SINGLE_RGB_OR_YUV444 = 5,
+	DISCRETE_SYNC_SINGLE_RGB_24B = 10,
+};
+
+#define VIP_NOT_ASSIGNED	-1
+
+/*
+ * Register offsets and field selectors
+ */
+#define VIP_PID_FUNC			0xf02
+
+#define VIP_PID				0x0000
+#define VIP_PID_MINOR_MASK              0x3f
+#define VIP_PID_MINOR_SHIFT             0
+#define VIP_PID_CUSTOM_MASK             0x03
+#define VIP_PID_CUSTOM_SHIFT            6
+#define VIP_PID_MAJOR_MASK              0x07
+#define VIP_PID_MAJOR_SHIFT             8
+#define VIP_PID_RTL_MASK                0x1f
+#define VIP_PID_RTL_SHIFT               11
+#define VIP_PID_FUNC_MASK               0xfff
+#define VIP_PID_FUNC_SHIFT              16
+#define VIP_PID_SCHEME_MASK             0x03
+#define VIP_PID_SCHEME_SHIFT            30
+
+#define VIP_SYSCONFIG			0x0010
+#define VIP_SYSCONFIG_IDLE_MASK         0x03
+#define VIP_SYSCONFIG_IDLE_SHIFT        2
+#define VIP_SYSCONFIG_STANDBY_MASK      0x03
+#define VIP_SYSCONFIG_STANDBY_SHIFT     4
+#define VIP_FORCE_IDLE_MODE             0
+#define VIP_NO_IDLE_MODE                1
+#define VIP_SMART_IDLE_MODE             2
+#define VIP_SMART_IDLE_WAKEUP_MODE      3
+#define VIP_FORCE_STANDBY_MODE          0
+#define VIP_NO_STANDBY_MODE             1
+#define VIP_SMART_STANDBY_MODE          2
+#define VIP_SMART_STANDBY_WAKEUP_MODE   3
+
+#define VIP_INTC_INTX_OFFSET		0x0020
+
+#define VIP_INT0_STATUS0_RAW_SET	0x0020
+#define VIP_INT0_STATUS0_RAW		VIP_INT0_STATUS0_RAW_SET
+#define VIP_INT0_STATUS0_CLR		0x0028
+#define VIP_INT0_STATUS0		VIP_INT0_STATUS0_CLR
+#define VIP_INT0_ENABLE0_SET		0x0030
+#define VIP_INT0_ENABLE0		VIP_INT0_ENABLE0_SET
+#define VIP_INT0_ENABLE0_CLR		0x0038
+#define VIP_INT0_LIST0_COMPLETE         BIT(0)
+#define VIP_INT0_LIST0_NOTIFY           BIT(1)
+#define VIP_INT0_LIST1_COMPLETE         BIT(2)
+#define VIP_INT0_LIST1_NOTIFY           BIT(3)
+#define VIP_INT0_LIST2_COMPLETE         BIT(4)
+#define VIP_INT0_LIST2_NOTIFY           BIT(5)
+#define VIP_INT0_LIST3_COMPLETE         BIT(6)
+#define VIP_INT0_LIST3_NOTIFY           BIT(7)
+#define VIP_INT0_LIST4_COMPLETE         BIT(8)
+#define VIP_INT0_LIST4_NOTIFY           BIT(9)
+#define VIP_INT0_LIST5_COMPLETE         BIT(10)
+#define VIP_INT0_LIST5_NOTIFY           BIT(11)
+#define VIP_INT0_LIST6_COMPLETE         BIT(12)
+#define VIP_INT0_LIST6_NOTIFY           BIT(13)
+#define VIP_INT0_LIST7_COMPLETE         BIT(14)
+#define VIP_INT0_LIST7_NOTIFY           BIT(15)
+#define VIP_INT0_DESCRIPTOR             BIT(16)
+#define VIP_VIP1_PARSER_INT		BIT(20)
+#define VIP_VIP2_PARSER_INT		BIT(21)
+
+#define VIP_INT0_STATUS1_RAW_SET        0x0024
+#define VIP_INT0_STATUS1_RAW            VIP_INT0_STATUS0_RAW_SET
+#define VIP_INT0_STATUS1_CLR            0x002c
+#define VIP_INT0_STATUS1                VIP_INT0_STATUS0_CLR
+#define VIP_INT0_ENABLE1_SET            0x0034
+#define VIP_INT0_ENABLE1                VIP_INT0_ENABLE0_SET
+#define VIP_INT0_ENABLE1_CLR            0x003c
+#define VIP_INT0_ENABLE1_STAT		0x004c
+#define VIP_INT0_CHANNEL_GROUP0		BIT(0)
+#define VIP_INT0_CHANNEL_GROUP1		BIT(1)
+#define VIP_INT0_CHANNEL_GROUP2		BIT(2)
+#define VIP_INT0_CHANNEL_GROUP3		BIT(3)
+#define VIP_INT0_CHANNEL_GROUP4		BIT(4)
+#define VIP_INT0_CHANNEL_GROUP5		BIT(5)
+#define VIP_INT0_CLIENT			BIT(7)
+#define VIP_VIP1_DS1_UV_ERROR_INT	BIT(22)
+#define VIP_VIP1_DS2_UV_ERROR_INT	BIT(23)
+#define VIP_VIP2_DS1_UV_ERROR_INT	BIT(24)
+#define VIP_VIP2_DS2_UV_ERROR_INT	BIT(25)
+
+#define VIP_INTC_E0I			0x00a0
+
+#define VIP_CLK_ENABLE			0x0100
+#define VIP_VPDMA_CLK_ENABLE		BIT(0)
+#define VIP_VIP1_DATA_PATH_CLK_ENABLE	BIT(16)
+#define VIP_VIP2_DATA_PATH_CLK_ENABLE	BIT(17)
+
+#define VIP_CLK_RESET			0x0104
+#define VIP_VPDMA_RESET			BIT(0)
+#define VIP_VPDMA_CLK_RESET_MASK	0x1
+#define VIP_VPDMA_CLK_RESET_SHIFT	0
+#define VIP_DATA_PATH_CLK_RESET_MASK	0x1
+#define VIP_VIP1_DATA_PATH_RESET_SHIFT	16
+#define VIP_VIP2_DATA_PATH_RESET_SHIFT	17
+#define VIP_VIP1_DATA_PATH_RESET	BIT(16)
+#define VIP_VIP2_DATA_PATH_RESET	BIT(17)
+#define VIP_VIP1_PARSER_RESET		BIT(18)
+#define VIP_VIP2_PARSER_RESET		BIT(19)
+#define VIP_VIP1_CSC_RESET		BIT(20)
+#define VIP_VIP2_CSC_RESET		BIT(21)
+#define VIP_VIP1_SC_RESET		BIT(22)
+#define VIP_VIP2_SC_RESET		BIT(23)
+#define VIP_VIP1_DS1_RESET		BIT(25)
+#define VIP_VIP2_DS1_RESET		BIT(26)
+#define VIP_VIP1_DS2_RESET		BIT(27)
+#define VIP_VIP2_DS2_RESET		BIT(28)
+#define VIP_MAIN_RESET			BIT(31)
+
+#define VIP_VIP1_DATA_PATH_SELECT	0x010c
+#define VIP_VIP2_DATA_PATH_SELECT	0x0110
+#define VIP_CSC_SRC_SELECT_MASK		0x07
+#define VIP_CSC_SRC_SELECT_SHFT		0
+#define VIP_SC_SRC_SELECT_MASK		0x07
+#define VIP_SC_SRC_SELECT_SHFT		3
+#define VIP_RGB_SRC_SELECT		BIT(6)
+#define VIP_RGB_OUT_LO_SRC_SELECT	BIT(7)
+#define VIP_RGB_OUT_HI_SRC_SELECT	BIT(8)
+#define VIP_DS1_SRC_SELECT_MASK		0x07
+#define VIP_DS1_SRC_SELECT_SHFT		9
+#define VIP_DS2_SRC_SELECT_MASK		0x07
+#define VIP_DS2_SRC_SELECT_SHFT		12
+#define VIP_MULTI_CHANNEL_SELECT	BIT(15)
+#define VIP_DS1_BYPASS			BIT(16)
+#define VIP_DS2_BYPASS			BIT(17)
+#define VIP_TESTPORT_B_SELECT		BIT(26)
+#define VIP_TESTPORT_A_SELECT		BIT(27)
+#define VIP_DATAPATH_SELECT_MASK	0x0f
+#define VIP_DATAPATH_SELECT_SHFT	28
+
+#define VIP1_PARSER_REG_OFFSET		0x5500
+#define VIP2_PARSER_REG_OFFSET		0x5a00
+
+#define VIP_PARSER_MAIN_CFG		0x0000
+#define VIP_DATA_INTERFACE_MODE_MASK	0x03
+#define VIP_DATA_INTERFACE_MODE_SHFT	0
+#define VIP_CLIP_BLANK			BIT(4)
+#define VIP_CLIP_ACTIVE			BIT(5)
+
+#define VIP_PARSER_PORTA_0		0x0004
+#define VIP_PARSER_PORTB_0		0x000c
+#define VIP_SYNC_TYPE_MASK		0x0f
+#define VIP_SYNC_TYPE_SHFT		0
+#define VIP_CTRL_CHANNEL_SEL_MASK	0x03
+#define VIP_CTRL_CHANNEL_SEL_SHFT	4
+#define VIP_ASYNC_FIFO_WR		BIT(6)
+#define VIP_ASYNC_FIFO_RD		BIT(7)
+#define VIP_PORT_ENABLE			BIT(8)
+#define VIP_FID_POLARITY		BIT(9)
+#define VIP_PIXCLK_EDGE_POLARITY	BIT(10)
+#define VIP_HSYNC_POLARITY		BIT(11)
+#define VIP_VSYNC_POLARITY		BIT(12)
+#define VIP_ACTVID_POLARITY		BIT(13)
+#define VIP_FID_DETECT_MODE		BIT(14)
+#define VIP_USE_ACTVID_HSYNC_ONLY	BIT(15)
+#define VIP_FID_SKEW_PRECOUNT_MASK	0x3f
+#define VIP_FID_SKEW_PRECOUNT_SHFT	16
+#define VIP_DISCRETE_BASIC_MODE		BIT(22)
+#define VIP_SW_RESET			BIT(23)
+#define VIP_FID_SKEW_POSTCOUNT_MASK	0x3f
+#define VIP_FID_SKEW_POSTCOUNT_SHFT	24
+#define VIP_ANALYZER_2X4X_SRCNUM_POS	BIT(30)
+#define VIP_ANALYZER_FVH_ERR_COR_EN	BIT(31)
+
+#define VIP_PARSER_PORTA_1		0x0008
+#define VIP_PARSER_PORTB_1		0x0010
+#define VIP_SRC0_NUMLINES_MASK		0x0fff
+#define VIP_SRC0_NUMLINES_SHFT		0
+#define VIP_ANC_CHAN_SEL_8B_MASK	0x03
+#define VIP_ANC_CHAN_SEL_8B_SHFT	13
+#define VIP_SRC0_NUMPIX_MASK		0x0fff
+#define VIP_SRC0_NUMPIX_SHFT		16
+#define VIP_REPACK_SEL_MASK		0x07
+#define VIP_REPACK_SEL_SHFT		28
+
+#define VIP_PARSER_FIQ_MASK		0x0014
+#define VIP_PARSER_FIQ_CLR		0x0018
+#define VIP_PARSER_FIQ_STATUS		0x001c
+#define VIP_PORTA_VDET			BIT(0)
+#define VIP_PORTB_VDET			BIT(1)
+#define VIP_PORTA_ASYNC_FIFO_OF		BIT(2)
+#define VIP_PORTB_ASYNC_FIFO_OF		BIT(3)
+#define VIP_PORTA_OUTPUT_FIFO_YUV	BIT(4)
+#define VIP_PORTA_OUTPUT_FIFO_ANC	BIT(6)
+#define VIP_PORTB_OUTPUT_FIFO_YUV	BIT(7)
+#define VIP_PORTB_OUTPUT_FIFO_ANC	BIT(9)
+#define VIP_PORTA_CONN			BIT(10)
+#define VIP_PORTA_DISCONN		BIT(11)
+#define VIP_PORTB_CONN			BIT(12)
+#define VIP_PORTB_DISCONN		BIT(13)
+#define VIP_PORTA_SRC0_SIZE		BIT(14)
+#define VIP_PORTB_SRC0_SIZE		BIT(15)
+#define VIP_PORTA_YUV_PROTO_VIOLATION	BIT(16)
+#define VIP_PORTA_ANC_PROTO_VIOLATION	BIT(17)
+#define VIP_PORTB_YUV_PROTO_VIOLATION	BIT(18)
+#define VIP_PORTB_ANC_PROTO_VIOLATION	BIT(19)
+#define VIP_PORTA_CFG_DISABLE_COMPLETE	BIT(20)
+#define VIP_PORTB_CFG_DISABLE_COMPLETE	BIT(21)
+
+#define VIP_PARSER_PORTA_SOURCE_FID	0x0020
+#define VIP_PARSER_PORTA_ENCODER_FID	0x0024
+#define VIP_PARSER_PORTB_SOURCE_FID	0x0028
+#define VIP_PARSER_PORTB_ENCODER_FID	0x002c
+
+#define VIP_PARSER_PORTA_SRC0_SIZE	0x0030
+#define VIP_PARSER_PORTB_SRC0_SIZE	0x0070
+#define VIP_SOURCE_HEIGHT_MASK		0x0fff
+#define VIP_SOURCE_HEIGHT_SHFT		0
+#define VIP_SOURCE_WIDTH_MASK		0x0fff
+#define VIP_SOURCE_WIDTH_SHFT		16
+
+#define VIP_PARSER_PORTA_VDET_VEC	0x00b0
+#define VIP_PARSER_PORTB_VDET_VEC	0x00b4
+
+#define VIP_PARSER_PORTA_EXTRA2		0x00b8
+#define VIP_PARSER_PORTB_EXTRA2		0x00c8
+#define VIP_ANC_SKIP_NUMPIX_MASK	0x0fff
+#define VIP_ANC_SKIP_NUMPIX_SHFT	0
+#define VIP_ANC_BYPASS			BIT(15)
+#define VIP_ANC_USE_NUMPIX_MASK		0x0fff
+#define VIP_ANC_USE_NUMPIX_SHFT		16
+#define VIP_ANC_TARGET_SRCNUM_MASK	0x0f
+#define VIP_ANC_TARGET_SRCNUM_SHFT	28
+
+#define VIP_PARSER_PORTA_EXTRA3		0x00bc
+#define VIP_PARSER_PORTB_EXTRA3		0x00cc
+#define VIP_ANC_SKIP_NUMLINES_MASK	0x0fff
+#define VIP_ANC_SKIP_NUMLINES_SHFT	0
+#define VIP_ANC_USE_NUMLINES_MASK	0x0fff
+#define VIP_ANC_USE_NUMLINES_SHFT	16
+
+#define VIP_PARSER_PORTA_EXTRA4		0x00c0
+#define VIP_PARSER_PORTB_EXTRA4		0x00d0
+#define VIP_ACT_SKIP_NUMPIX_MASK	0x0fff
+#define VIP_ACT_SKIP_NUMPIX_SHFT	0
+#define VIP_ACT_BYPASS			BIT(15)
+#define VIP_ACT_USE_NUMPIX_MASK		0x0fff
+#define VIP_ACT_USE_NUMPIX_SHFT		16
+#define VIP_ACT_TARGET_SRCNUM_MASK	0x0f
+#define VIP_ACT_TARGET_SRCNUM_SHFT	28
+
+#define VIP_PARSER_PORTA_EXTRA5		0x00c4
+#define VIP_PARSER_PORTB_EXTRA5		0x00d4
+#define VIP_ACT_SKIP_NUMLINES_MASK	0x0fff
+#define VIP_ACT_SKIP_NUMLINES_SHFT	0
+#define VIP_ACT_USE_NUMLINES_MASK	0x0fff
+#define VIP_ACT_USE_NUMLINES_SHFT	16
+
+#define VIP_PARSER_PORTA_EXTRA6		0x00d8
+#define VIP_PARSER_PORTB_EXTRA6		0x00dc
+#define VIP_ANC_SRCNUM_STOP_IMM_SHFT	0
+#define VIP_YUV_SRCNUM_STOP_IMM_SHFT	16
+
+#define VIP_CSC_CSC00			0x0200
+#define VIP_CSC_A0_MASK			0x1fff
+#define VIP_CSC_A0_SHFT			0
+#define VIP_CSC_B0_MASK			0x1fff
+#define VIP_CSC_B0_SHFT			16
+
+#define VIP_CSC_CSC01			0x0204
+#define VIP_CSC_C0_MASK			0x1fff
+#define VIP_CSC_C0_SHFT			0
+#define VIP_CSC_A1_MASK			0x1fff
+#define VIP_CSC_A1_SHFT			16
+
+#define VIP_CSC_CSC02			0x0208
+#define VIP_CSC_B1_MASK			0x1fff
+#define VIP_CSC_B1_SHFT			0
+#define VIP_CSC_C1_MASK			0x1fff
+#define VIP_CSC_C1_SHFT			16
+
+#define VIP_CSC_CSC03			0x020c
+#define VIP_CSC_A2_MASK			0x1fff
+#define VIP_CSC_A2_SHFT			0
+#define VIP_CSC_B2_MASK			0x1fff
+#define VIP_CSC_B2_SHFT			16
+
+#define VIP_CSC_CSC04			0x0210
+#define VIP_CSC_C2_MASK			0x1fff
+#define VIP_CSC_C2_SHFT			0
+#define VIP_CSC_D0_MASK			0x0fff
+#define VIP_CSC_D0_SHFT			16
+
+#define VIP_CSC_CSC05			0x0214
+#define VIP_CSC_D1_MASK			0x0fff
+#define VIP_CSC_D1_SHFT			0
+#define VIP_CSC_D2_MASK			0x0fff
+#define VIP_CSC_D2_SHFT			16
+#define VIP_CSC_BYPASS			BIT(28)
+
+#define VIP_SC_MP_SC0			0x0300
+#define VIP_INTERLACE_O			BIT(0)
+#define VIP_LINEAR			BIT(1)
+#define VIP_SC_BYPASS			BIT(2)
+#define VIP_INVT_FID			BIT(3)
+#define VIP_USE_RAV			BIT(4)
+#define VIP_ENABLE_EV			BIT(5)
+#define VIP_AUTH_HS			BIT(6)
+#define VIP_DCM_2X			BIT(7)
+#define VIP_DCM_4X			BIT(8)
+#define VIP_HP_BYPASS			BIT(9)
+#define VIP_INTERLACE_I			BIT(10)
+#define VIP_ENABLE_SIN2_VER_INTP	BIT(11)
+#define VIP_Y_PK_EN			BIT(14)
+#define VIP_TRIM			BIT(15)
+#define VIP_SELFGEN_FID			BIT(16)
+
+#define VIP_SC_MP_SC1			0x0304
+#define VIP_ROW_ACC_INC_MASK		0x07ffffff
+#define VIP_ROW_ACC_INC_SHFT		0
+
+#define VIP_SC_MP_SC2			0x0308
+#define VIP_ROW_ACC_OFFSET_MASK		0x0fffffff
+#define VIP_ROW_ACC_OFFSET_SHFT		0
+
+#define VIP_SC_MP_SC3			0x030c
+#define VIP_ROW_ACC_OFFSET_B_MASK	0x0fffffff
+#define VIP_ROW_ACC_OFFSET_B_SHFT	0
+
+#define VIP_SC_MP_SC4			0x0310
+#define VIP_TAR_H_MASK			0x07ff
+#define VIP_TAR_H_SHFT			0
+#define VIP_TAR_W_MASK			0x07ff
+#define VIP_TAR_W_SHFT			12
+#define VIP_LIN_ACC_INC_U_MASK		0x07
+#define VIP_LIN_ACC_INC_U_SHFT		24
+#define VIP_NLIN_ACC_INIT_U_MASK	0x07
+#define VIP_NLIN_ACC_INIT_U_SHFT	28
+
+#define VIP_SC_MP_SC5			0x0314
+#define VIP_SRC_H_MASK			0x03ff
+#define VIP_SRC_H_SHFT			0
+#define VIP_SRC_W_MASK			0x07ff
+#define VIP_SRC_W_SHFT			12
+#define VIP_NLIN_ACC_INC_U_MASK		0x07
+#define VIP_NLIN_ACC_INC_U_SHFT		24
+
+#define VIP_SC_MP_SC6			0x0318
+#define VIP_ROW_ACC_INIT_RAV_MASK	0x03ff
+#define VIP_ROW_ACC_INIT_RAV_SHFT	0
+#define VIP_ROW_ACC_INIT_RAV_B_MASK	0x03ff
+#define VIP_ROW_ACC_INIT_RAV_B_SHFT	10
+
+#define VIP_SC_MP_SC8			0x0320
+#define VIP_NLIN_LEFT_MASK		0x07ff
+#define VIP_NLIN_LEFT_SHFT		0
+#define VIP_NLIN_RIGHT_MASK		0x07ff
+#define VIP_NLIN_RIGHT_SHFT		12
+
+#define VIP_SC_MP_SC9			0x0324
+#define VIP_LIN_ACC_INC			VIP_SC_MP_SC9
+
+#define VIP_SC_MP_SC10			0x0328
+#define VIP_NLIN_ACC_INIT		VIP_SC_MP_SC10
+
+#define VIP_SC_MP_SC11			0x032c
+#define VIP_NLIN_ACC_INC		VIP_SC_MP_SC11
+
+#define VIP_SC_MP_SC12			0x0330
+#define VIP_COL_ACC_OFFSET_MASK		0x01ffffff
+#define VIP_COL_ACC_OFFSET_SHFT		0
+
+#define VIP_SC_MP_SC13			0x0334
+#define VIP_SC_FACTOR_RAV_MASK		0x03ff
+#define VIP_SC_FACTOR_RAV_SHFT		0
+#define VIP_CHROMA_INTP_THR_MASK	0x03ff
+#define VIP_CHROMA_INTP_THR_SHFT	12
+#define VIP_DELTA_CHROMA_THR_MASK	0x0f
+#define VIP_DELTA_CHROMA_THR_SHFT	24
+
+#define VIP_SC_MP_SC17			0x0344
+#define VIP_EV_THR_MASK			0x03ff
+#define VIP_EV_THR_SHFT			12
+#define VIP_DELTA_LUMA_THR_MASK		0x0f
+#define VIP_DELTA_LUMA_THR_SHFT		24
+#define VIP_DELTA_EV_THR_MASK		0x0f
+#define VIP_DELTA_EV_THR_SHFT		28
+
+#define VIP_SC_MP_SC18			0x0348
+#define VIP_HS_FACTOR_MASK		0x03ff
+#define VIP_HS_FACTOR_SHFT		0
+#define VIP_CONF_DEFAULT_MASK		0x01ff
+#define VIP_CONF_DEFAULT_SHFT		16
+
+#define VIP_SC_MP_SC19			0x034c
+#define VIP_HPF_COEFF0_MASK		0xff
+#define VIP_HPF_COEFF0_SHFT		0
+#define VIP_HPF_COEFF1_MASK		0xff
+#define VIP_HPF_COEFF1_SHFT		8
+#define VIP_HPF_COEFF2_MASK		0xff
+#define VIP_HPF_COEFF2_SHFT		16
+#define VIP_HPF_COEFF3_MASK		0xff
+#define VIP_HPF_COEFF3_SHFT		23
+
+#define VIP_SC_MP_SC20			0x0350
+#define VIP_HPF_COEFF4_MASK		0xff
+#define VIP_HPF_COEFF4_SHFT		0
+#define VIP_HPF_COEFF5_MASK		0xff
+#define VIP_HPF_COEFF5_SHFT		8
+#define VIP_HPF_NORM_SHFT_MASK		0x07
+#define VIP_HPF_NORM_SHFT_SHFT		16
+#define VIP_NL_LIMIT_MASK		0x1ff
+#define VIP_NL_LIMIT_SHFT		20
+
+#define VIP_SC_MP_SC21			0x0354
+#define VIP_NL_LO_THR_MASK		0x01ff
+#define VIP_NL_LO_THR_SHFT		0
+#define VIP_NL_LO_SLOPE_MASK		0xff
+#define VIP_NL_LO_SLOPE_SHFT		16
+
+#define VIP_SC_MP_SC22			0x0358
+#define VIP_NL_HI_THR_MASK		0x01ff
+#define VIP_NL_HI_THR_SHFT		0
+#define VIP_NL_HI_SLOPE_SH_MASK		0x07
+#define VIP_NL_HI_SLOPE_SH_SHFT		16
+
+#define VIP_SC_MP_SC23			0x035c
+#define VIP_GRADIENT_THR_MASK		0x07ff
+#define VIP_GRADIENT_THR_SHFT		0
+#define VIP_GRADIENT_THR_RANGE_MASK	0x0f
+#define VIP_GRADIENT_THR_RANGE_SHFT	12
+#define VIP_MIN_GY_THR_MASK		0xff
+#define VIP_MIN_GY_THR_SHFT		16
+#define VIP_MIN_GY_THR_RANGE_MASK	0x0f
+#define VIP_MIN_GY_THR_RANGE_SHFT	28
+
+#define VIP_SC_MP_SC24			0x0360
+#define VIP_ORG_H_MASK			0x07ff
+#define VIP_ORG_H_SHFT			0
+#define VIP_ORG_W_MASK			0x07ff
+#define VIP_ORG_W_SHFT			16
+
+#define VIP_SC_MP_SC25			0x0364
+#define VIP_OFF_H_MASK			0x07ff
+#define VIP_OFF_H_SHFT			0
+#define VIP_OFF_W_MASK			0x07ff
+#define VIP_OFF_W_SHFT			16
+
+#define VIP_VPDMA_REG_OFFSET		0xd000
+
+#endif
diff -Naur --no-dereference a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
--- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c	2025-10-23 09:30:40.285462207 -0400
@@ -831,6 +831,7 @@
 	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_IR_EXPOSURE:		return "Exposure, IR";
 
 	/*
 	 * Codec controls
@@ -889,6 +890,7 @@
 	case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY:		return "Display Delay";
 	case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE:	return "Display Delay Enable";
 	case V4L2_CID_MPEG_VIDEO_AU_DELIMITER:			return "Generate Access Unit Delimiters";
+	case V4L2_CID_MPEG_VIDEO_BACKGROUND_DETECTION:		return "Background Detection";
 	case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:		return "H263 I-Frame QP Value";
 	case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:		return "H263 P-Frame QP Value";
 	case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:		return "H263 B-Frame QP Value";
@@ -1155,6 +1157,7 @@
 	case V4L2_CID_TEST_PATTERN_BLUE:	return "Blue Pixel Value";
 	case V4L2_CID_TEST_PATTERN_GREENB:	return "Green (Blue) Pixel Value";
 	case V4L2_CID_NOTIFY_GAINS:		return "Notify Gains";
+	case V4L2_CID_IR_ANALOGUE_GAIN:		return "Analogue Gain, IR";
 
 	/* Image processing controls */
 	/* Keep the order of the 'case's the same as in v4l2-controls.h! */
@@ -1164,6 +1167,7 @@
 	case V4L2_CID_TEST_PATTERN:		return "Test Pattern";
 	case V4L2_CID_DEINTERLACING_MODE:	return "Deinterlacing Mode";
 	case V4L2_CID_DIGITAL_GAIN:		return "Digital Gain";
+	case V4L2_CID_IR_DIGITAL_GAIN:		return "Digital Gain, IR";
 
 	/* DV controls */
 	/* Keep the order of the 'case's the same as in v4l2-controls.h! */
@@ -1291,6 +1295,7 @@
 	case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
 	case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER:
 	case V4L2_CID_MPEG_VIDEO_AU_DELIMITER:
+	case V4L2_CID_MPEG_VIDEO_BACKGROUND_DETECTION:
 	case V4L2_CID_WIDE_DYNAMIC_RANGE:
 	case V4L2_CID_IMAGE_STABILIZATION:
 	case V4L2_CID_RDS_RECEPTION:
diff -Naur --no-dereference a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
--- a/drivers/media/v4l2-core/v4l2-ioctl.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c	2025-10-23 09:30:40.285462207 -0400
@@ -1428,6 +1428,14 @@
 	case V4L2_PIX_FMT_SGBRG16:	descr = "16-bit Bayer GBGB/RGRG"; break;
 	case V4L2_PIX_FMT_SGRBG16:	descr = "16-bit Bayer GRGR/BGBG"; break;
 	case V4L2_PIX_FMT_SRGGB16:	descr = "16-bit Bayer RGRG/GBGB"; break;
+	case V4L2_PIX_FMT_SRGGI10:	descr = "10-bit Bayer RGBG/GIrGIr"; break;
+	case V4L2_PIX_FMT_SGRIG10:	descr = "10-bit Bayer GRGB/IrGIrG"; break;
+	case V4L2_PIX_FMT_SBGGI10:	descr = "10-bit Bayer BGRG/GIrGIr"; break;
+	case V4L2_PIX_FMT_SGBIG10:	descr = "10-bit Bayer GBGR/IrGIrG"; break;
+	case V4L2_PIX_FMT_SGIRG10:	descr = "10-bit Bayer GIrGIr/RGBG"; break;
+	case V4L2_PIX_FMT_SIGGR10:	descr = "10-bit Bayer IrGIrG/GRGB"; break;
+	case V4L2_PIX_FMT_SGIBG10:	descr = "10-bit Bayer GIrGIr/BGRG"; break;
+	case V4L2_PIX_FMT_SIGGB10:	descr = "10-bit Bayer IrGIrG/GBGR"; break;
 	case V4L2_PIX_FMT_SN9C20X_I420:	descr = "GSPCA SN9C20X I420"; break;
 	case V4L2_PIX_FMT_SPCA501:	descr = "GSPCA SPCA501"; break;
 	case V4L2_PIX_FMT_SPCA505:	descr = "GSPCA SPCA505"; break;
diff -Naur --no-dereference a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
--- a/drivers/media/v4l2-core/v4l2-subdev.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/media/v4l2-core/v4l2-subdev.c	2025-10-23 09:30:40.285462207 -0400
@@ -32,7 +32,7 @@
  * 'v4l2_subdev_enable_streams_api' to 1 below.
  */
 
-static bool v4l2_subdev_enable_streams_api;
+static bool v4l2_subdev_enable_streams_api = 1;
 #endif
 
 /*
diff -Naur --no-dereference a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
--- a/drivers/mfd/syscon.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/mfd/syscon.c	2025-10-23 09:30:40.285462207 -0400
@@ -111,6 +111,8 @@
 	syscon_config.reg_stride = reg_io_width;
 	syscon_config.val_bits = reg_io_width * 8;
 	syscon_config.max_register = resource_size(&res) - reg_io_width;
+	if (!syscon_config.max_register)
+		syscon_config.max_register_is_0 = true;
 
 	regmap = regmap_init_mmio(NULL, base, &syscon_config);
 	kfree(syscon_config.name);
@@ -358,6 +360,9 @@
 		return -ENOMEM;
 
 	syscon_config.max_register = resource_size(res) - 4;
+	if (!syscon_config.max_register)
+		syscon_config.max_register_is_0 = true;
+
 	if (pdata)
 		syscon_config.name = pdata->label;
 	syscon->regmap = devm_regmap_init_mmio(dev, base, &syscon_config);
diff -Naur --no-dereference a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
--- a/drivers/mfd/tps65219.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/mfd/tps65219.c	2025-10-23 09:30:40.285462207 -0400
@@ -1,8 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
 //
-// Driver for TPS65219 Integrated Power Management Integrated Chips (PMIC)
+// Driver for TPS65214/TPS65215/TPS65219 Power Management Integrated Chips
 //
 // Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+// Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
 
 #include <linux/i2c.h>
 #include <linux/reboot.h>
@@ -59,6 +60,84 @@
 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_RISING_EDGE_DETECT, "rising"),
 };
 
+static const struct resource tps65214_regulator_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_SCG, "LDO1_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_OC, "LDO1_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_UV, "LDO1_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_SCG, "LDO2_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_OC, "LDO2_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_UV, "LDO2_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_SCG, "BUCK3_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_OC, "BUCK3_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_NEG_OC, "BUCK3_NEG_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_UV, "BUCK3_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_SCG, "BUCK1_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_OC, "BUCK1_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_NEG_OC, "BUCK1_NEG_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_UV, "BUCK1_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_SCG, "BUCK2_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_OC, "BUCK2_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_NEG_OC, "BUCK2_NEG_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_UV, "BUCK2_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV, "BUCK1_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV, "BUCK2_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV, "BUCK3_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV, "LDO1_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65214_INT_LDO2_RV, "LDO2_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV_SD, "BUCK1_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV_SD, "BUCK2_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV_SD, "BUCK3_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65214_INT_LDO1_RV_SD, "LDO1_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV_SD, "LDO2_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_TIMEOUT, "TIMEOUT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_WARM, "SENSOR_2_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_WARM, "SENSOR_1_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_WARM, "SENSOR_0_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_HOT, "SENSOR_2_HOT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_HOT, "SENSOR_1_HOT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_HOT, "SENSOR_0_HOT"),
+};
+
+static const struct resource tps65215_regulator_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO1_SCG, "LDO1_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO1_OC, "LDO1_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO1_UV, "LDO1_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO2_SCG, "LDO2_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO2_OC, "LDO2_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO2_UV, "LDO2_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_SCG, "BUCK3_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_OC, "BUCK3_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_NEG_OC, "BUCK3_NEG_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_UV, "BUCK3_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_SCG, "BUCK1_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_OC, "BUCK1_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_NEG_OC, "BUCK1_NEG_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_UV, "BUCK1_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_SCG, "BUCK2_SCG"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_OC, "BUCK2_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_NEG_OC, "BUCK2_NEG_OC"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_UV, "BUCK2_UV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV, "BUCK1_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV, "BUCK2_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV, "BUCK3_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV, "LDO1_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO2_RV, "LDO2_RV"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV_SD, "BUCK1_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV_SD, "BUCK2_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV_SD, "BUCK3_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV_SD, "LDO1_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO2_RV_SD, "LDO2_RV_SD"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_TIMEOUT, "TIMEOUT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_WARM, "SENSOR_3_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_WARM, "SENSOR_2_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_WARM, "SENSOR_1_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_WARM, "SENSOR_0_WARM"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_HOT, "SENSOR_3_HOT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_HOT, "SENSOR_2_HOT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_HOT, "SENSOR_1_HOT"),
+	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_HOT, "SENSOR_0_HOT"),
+};
+
 static const struct resource tps65219_regulator_resources[] = {
 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_SCG, "LDO3_SCG"),
 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_OC, "LDO3_OC"),
@@ -109,21 +188,24 @@
 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_HOT, "SENSOR_0_HOT"),
 };
 
-static const struct mfd_cell tps65219_cells[] = {
-	{
-		.name = "tps65219-regulator",
-		.resources = tps65219_regulator_resources,
-		.num_resources = ARRAY_SIZE(tps65219_regulator_resources),
-	},
-	{ .name = "tps65219-gpio", },
+static const struct mfd_cell tps65214_cells[] = {
+	MFD_CELL_RES("tps65214-regulator", tps65214_regulator_resources),
+	MFD_CELL_NAME("tps65214-gpio"),
 };
 
-static const struct mfd_cell tps65219_pwrbutton_cell = {
-	.name = "tps65219-pwrbutton",
-	.resources = tps65219_pwrbutton_resources,
-	.num_resources = ARRAY_SIZE(tps65219_pwrbutton_resources),
+static const struct mfd_cell tps65215_cells[] = {
+	MFD_CELL_RES("tps65215-regulator", tps65215_regulator_resources),
+	MFD_CELL_NAME("tps65215-gpio"),
 };
 
+static const struct mfd_cell tps65219_cells[] = {
+	MFD_CELL_RES("tps65219-regulator", tps65219_regulator_resources),
+	MFD_CELL_NAME("tps65219-gpio"),
+};
+
+static const struct mfd_cell tps65219_pwrbutton_cell =
+	MFD_CELL_RES("tps65219-pwrbutton", tps65219_pwrbutton_resources);
+
 static const struct regmap_config tps65219_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
@@ -143,8 +225,19 @@
 static unsigned int bit4_offsets[] = { TPS65219_REG_INT_BUCK_3_POS };	/* Buck 3 */
 static unsigned int bit5_offsets[] = { TPS65219_REG_INT_LDO_1_2_POS };	/* LDO 1-2 */
 static unsigned int bit6_offsets[] = { TPS65219_REG_INT_LDO_3_4_POS };	/* LDO 3-4 */
+static unsigned int tps65215_bit5_offsets[] = { TPS65215_REG_INT_LDO_1_POS };
+static unsigned int tps65215_bit6_offsets[] = { TPS65215_REG_INT_LDO_2_POS };
 static unsigned int bit7_offsets[] = { TPS65219_REG_INT_PB_POS };	/* Power Button */
 
+/* TPS65214 INT_SOURCE bit 6 is 'RESERVED'*/
+static unsigned int tps65214_bit0_offsets[] = { TPS65214_REG_INT_TO_RV_POS };
+static unsigned int tps65214_bit1_offsets[] = { TPS65214_REG_INT_RV_POS };
+static unsigned int tps65214_bit2_offsets[] = { TPS65214_REG_INT_SYS_POS };
+static unsigned int tps65214_bit3_offsets[] = { TPS65214_REG_INT_BUCK_1_2_POS };
+static unsigned int tps65214_bit4_offsets[] = { TPS65214_REG_INT_BUCK_3_POS };
+static unsigned int tps65214_bit5_offsets[] = { TPS65214_REG_INT_LDO_1_2_POS };
+static unsigned int tps65214_bit7_offsets[] = { TPS65214_REG_INT_PB_POS };
+
 static struct regmap_irq_sub_irq_map tps65219_sub_irq_offsets[] = {
 	REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
 	REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
@@ -156,9 +249,112 @@
 	REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
 };
 
+static struct regmap_irq_sub_irq_map tps65215_sub_irq_offsets[] = {
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(tps65215_bit5_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(tps65215_bit6_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
+};
+
+static const struct regmap_irq_sub_irq_map tps65214_sub_irq_offsets[] = {
+	REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit0_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit1_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit2_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit3_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit4_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit5_offsets),
+	REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit7_offsets),
+};
+
 #define TPS65219_REGMAP_IRQ_REG(int_name, register_position) \
 	REGMAP_IRQ_REG(int_name, register_position, int_name##_MASK)
 
+static const struct regmap_irq tps65214_irqs[] = {
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_SCG, TPS65214_REG_INT_LDO_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_OC, TPS65214_REG_INT_LDO_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_UV, TPS65214_REG_INT_LDO_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_SCG, TPS65214_REG_INT_LDO_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_OC, TPS65214_REG_INT_LDO_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_UV, TPS65214_REG_INT_LDO_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_SCG, TPS65214_REG_INT_BUCK_3_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_OC, TPS65214_REG_INT_BUCK_3_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_NEG_OC, TPS65214_REG_INT_BUCK_3_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_UV, TPS65214_REG_INT_BUCK_3_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_SCG, TPS65214_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_OC, TPS65214_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_NEG_OC, TPS65214_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_UV, TPS65214_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_SCG, TPS65214_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_OC, TPS65214_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_NEG_OC, TPS65214_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_UV, TPS65214_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_WARM, TPS65214_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_WARM, TPS65214_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_WARM, TPS65214_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_HOT, TPS65214_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_HOT, TPS65214_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_HOT, TPS65214_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV, TPS65214_REG_INT_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV, TPS65214_REG_INT_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV, TPS65214_REG_INT_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV, TPS65214_REG_INT_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65214_INT_LDO2_RV, TPS65214_REG_INT_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV_SD, TPS65214_REG_INT_TO_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV_SD, TPS65214_REG_INT_TO_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV_SD, TPS65214_REG_INT_TO_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65214_INT_LDO1_RV_SD, TPS65214_REG_INT_TO_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV_SD, TPS65214_REG_INT_TO_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_TIMEOUT, TPS65214_REG_INT_TO_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_FALLING_EDGE_DETECT, TPS65214_REG_INT_PB_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_RISING_EDGE_DETECT, TPS65214_REG_INT_PB_POS),
+};
+
+static const struct regmap_irq tps65215_irqs[] = {
+	TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO1_SCG, TPS65215_REG_INT_LDO_1_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO1_OC, TPS65215_REG_INT_LDO_1_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO1_UV, TPS65215_REG_INT_LDO_1_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO2_SCG, TPS65215_REG_INT_LDO_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO2_OC, TPS65215_REG_INT_LDO_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO2_UV, TPS65215_REG_INT_LDO_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_SCG, TPS65219_REG_INT_BUCK_3_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_OC, TPS65219_REG_INT_BUCK_3_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_NEG_OC, TPS65219_REG_INT_BUCK_3_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_UV, TPS65219_REG_INT_BUCK_3_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_SCG, TPS65219_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_OC, TPS65219_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_NEG_OC, TPS65219_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_UV, TPS65219_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_SCG, TPS65219_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_OC, TPS65219_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_NEG_OC, TPS65219_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_UV, TPS65219_REG_INT_BUCK_1_2_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_WARM, TPS65219_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_WARM, TPS65219_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_WARM, TPS65219_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_WARM, TPS65219_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_HOT, TPS65219_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_HOT, TPS65219_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_HOT, TPS65219_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_HOT, TPS65219_REG_INT_SYS_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV, TPS65219_REG_INT_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV, TPS65219_REG_INT_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV, TPS65219_REG_INT_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV, TPS65219_REG_INT_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO2_RV, TPS65219_REG_INT_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV_SD, TPS65219_REG_INT_TO_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV_SD, TPS65219_REG_INT_TO_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV_SD, TPS65219_REG_INT_TO_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV_SD, TPS65219_REG_INT_TO_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO2_RV_SD, TPS65219_REG_INT_TO_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_TIMEOUT, TPS65219_REG_INT_TO_RV_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_FALLING_EDGE_DETECT, TPS65219_REG_INT_PB_POS),
+	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_RISING_EDGE_DETECT, TPS65219_REG_INT_PB_POS),
+};
+
 static const struct regmap_irq tps65219_irqs[] = {
 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_SCG, TPS65219_REG_INT_LDO_3_4_POS),
 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_OC, TPS65219_REG_INT_LDO_3_4_POS),
@@ -211,6 +407,34 @@
 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_RISING_EDGE_DETECT, TPS65219_REG_INT_PB_POS),
 };
 
+static const struct regmap_irq_chip tps65214_irq_chip = {
+	.name = "tps65214_irq",
+	.main_status = TPS65219_REG_INT_SOURCE,
+	.num_main_regs = 1,
+	.num_main_status_bits = 8,
+	.irqs = tps65214_irqs,
+	.num_irqs = ARRAY_SIZE(tps65214_irqs),
+	.status_base = TPS65214_REG_INT_LDO_1_2,
+	.ack_base = TPS65214_REG_INT_LDO_1_2,
+	.clear_ack = 1,
+	.num_regs = 8,
+	.sub_reg_offsets = tps65214_sub_irq_offsets,
+};
+
+static const struct regmap_irq_chip tps65215_irq_chip = {
+	.name = "tps65215_irq",
+	.main_status = TPS65219_REG_INT_SOURCE,
+	.num_main_regs = 1,
+	.num_main_status_bits = 8,
+	.irqs = tps65215_irqs,
+	.num_irqs = ARRAY_SIZE(tps65215_irqs),
+	.status_base = TPS65215_REG_INT_LDO_2,
+	.ack_base = TPS65215_REG_INT_LDO_2,
+	.clear_ack = 1,
+	.num_regs = 8,
+	.sub_reg_offsets = tps65215_sub_irq_offsets,
+};
+
 static const struct regmap_irq_chip tps65219_irq_chip = {
 	.name = "tps65219_irq",
 	.main_status = TPS65219_REG_INT_SOURCE,
@@ -225,9 +449,35 @@
 	.sub_reg_offsets = tps65219_sub_irq_offsets,
 };
 
+struct tps65219_chip_data {
+	const struct regmap_irq_chip *irq_chip;
+	const struct mfd_cell *cells;
+	int n_cells;
+};
+
+static const struct tps65219_chip_data chip_info_table[] = {
+	[TPS65214] = {
+		.irq_chip = &tps65214_irq_chip,
+		.cells = tps65214_cells,
+		.n_cells = ARRAY_SIZE(tps65214_cells),
+	},
+	[TPS65215] = {
+		.irq_chip = &tps65215_irq_chip,
+		.cells = tps65215_cells,
+		.n_cells = ARRAY_SIZE(tps65215_cells),
+	},
+	[TPS65219] = {
+		.irq_chip = &tps65219_irq_chip,
+		.cells = tps65219_cells,
+		.n_cells = ARRAY_SIZE(tps65219_cells),
+	},
+};
+
 static int tps65219_probe(struct i2c_client *client)
 {
 	struct tps65219 *tps;
+	const struct tps65219_chip_data *pmic;
+	unsigned int chip_id;
 	bool pwr_button;
 	int ret;
 
@@ -238,6 +488,8 @@
 	i2c_set_clientdata(client, tps);
 
 	tps->dev = &client->dev;
+	chip_id = (uintptr_t)i2c_get_match_data(client);
+	pmic = &chip_info_table[chip_id];
 
 	tps->regmap = devm_regmap_init_i2c(client, &tps65219_regmap_config);
 	if (IS_ERR(tps->regmap)) {
@@ -246,14 +498,14 @@
 		return ret;
 	}
 
-	ret = devm_regmap_add_irq_chip(&client->dev, tps->regmap, client->irq,
-				       IRQF_ONESHOT, 0, &tps65219_irq_chip,
+	ret = devm_regmap_add_irq_chip(tps->dev, tps->regmap, client->irq,
+				       IRQF_ONESHOT, 0, pmic->irq_chip,
 				       &tps->irq_data);
 	if (ret)
 		return ret;
 
 	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO,
-				   tps65219_cells, ARRAY_SIZE(tps65219_cells),
+				   pmic->cells, pmic->n_cells,
 				   NULL, 0, regmap_irq_get_domain(tps->irq_data));
 	if (ret) {
 		dev_err(tps->dev, "Failed to add child devices: %d\n", ret);
@@ -291,7 +543,9 @@
 }
 
 static const struct of_device_id of_tps65219_match_table[] = {
-	{ .compatible = "ti,tps65219", },
+	{ .compatible = "ti,tps65214", .data = (void *)TPS65214, },
+	{ .compatible = "ti,tps65215", .data = (void *)TPS65215, },
+	{ .compatible = "ti,tps65219", .data = (void *)TPS65219, },
 	{}
 };
 MODULE_DEVICE_TABLE(of, of_tps65219_match_table);
@@ -306,5 +560,5 @@
 module_i2c_driver(tps65219_driver);
 
 MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");
-MODULE_DESCRIPTION("TPS65219 power management IC driver");
+MODULE_DESCRIPTION("TPS65214/TPS65215/TPS65219 PMIC driver");
 MODULE_LICENSE("GPL");
diff -Naur --no-dereference a/drivers/misc/Kconfig b/drivers/misc/Kconfig
--- a/drivers/misc/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/misc/Kconfig	2025-10-23 09:30:40.285462207 -0400
@@ -457,6 +457,13 @@
 config SRAM_EXEC
 	bool
 
+config SRAM_DMA_HEAP
+	bool "Export on-chip SRAM pools using DMA-Heaps"
+	depends on DMABUF_HEAPS && SRAM
+	help
+	  This driver allows the export of on-chip SRAM marked as both pool
+	  and exportable to userspace using the DMA-Heaps interface.
+
 config DW_XDATA_PCIE
 	depends on PCI
 	tristate "Synopsys DesignWare xData PCIe driver"
diff -Naur --no-dereference a/drivers/misc/Makefile b/drivers/misc/Makefile
--- a/drivers/misc/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/misc/Makefile	2025-10-23 09:30:40.285462207 -0400
@@ -48,6 +48,7 @@
 obj-$(CONFIG_LATTICE_ECP3_CONFIG)	+= lattice-ecp3-config.o
 obj-$(CONFIG_SRAM)		+= sram.o
 obj-$(CONFIG_SRAM_EXEC)		+= sram-exec.o
+obj-$(CONFIG_SRAM_DMA_HEAP)	+= sram-dma-heap.o
 obj-$(CONFIG_GENWQE)		+= genwqe/
 obj-$(CONFIG_ECHO)		+= echo/
 obj-$(CONFIG_CXL_BASE)		+= cxl/
diff -Naur --no-dereference a/drivers/misc/sram.c b/drivers/misc/sram.c
--- a/drivers/misc/sram.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/misc/sram.c	2025-10-23 09:30:40.285462207 -0400
@@ -120,6 +120,12 @@
 		ret = sram_add_pool(sram, block, start, part);
 		if (ret)
 			return ret;
+
+		if (block->export) {
+			ret = sram_add_dma_heap(sram, block, start, part);
+			if (ret)
+				return ret;
+		}
 	}
 	if (block->export) {
 		ret = sram_add_export(sram, block, start, part);
diff -Naur --no-dereference a/drivers/misc/sram-dma-heap.c b/drivers/misc/sram-dma-heap.c
--- a/drivers/misc/sram-dma-heap.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/misc/sram-dma-heap.c	2025-10-23 09:30:40.285462207 -0400
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SRAM DMA-Heap userspace exporter
+ *
+ * Copyright (C) 2019-2023 Texas Instruments Incorporated - https://www.ti.com/
+ *	Andrew Davis <afd@ti.com>
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/genalloc.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/dma-buf.h>
+#include <linux/dma-heap.h>
+
+#include "sram.h"
+
+struct sram_dma_heap {
+	struct dma_heap *heap;
+	struct gen_pool *pool;
+};
+
+struct sram_dma_heap_buffer {
+	struct gen_pool *pool;
+	struct list_head attachments;
+	struct mutex attachments_lock;
+	unsigned long len;
+	void *vaddr;
+	phys_addr_t paddr;
+};
+
+struct dma_heap_attachment {
+	struct device *dev;
+	struct sg_table *table;
+	struct list_head list;
+};
+
+static int dma_heap_attach(struct dma_buf *dmabuf,
+			   struct dma_buf_attachment *attachment)
+{
+	struct sram_dma_heap_buffer *buffer = dmabuf->priv;
+	struct dma_heap_attachment *a;
+	struct sg_table *table;
+
+	a = kzalloc(sizeof(*a), GFP_KERNEL);
+	if (!a)
+		return -ENOMEM;
+
+	table = kmalloc(sizeof(*table), GFP_KERNEL);
+	if (!table) {
+		kfree(a);
+		return -ENOMEM;
+	}
+	if (sg_alloc_table(table, 1, GFP_KERNEL)) {
+		kfree(table);
+		kfree(a);
+		return -ENOMEM;
+	}
+	sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(buffer->paddr)), buffer->len, 0);
+
+	a->table = table;
+	a->dev = attachment->dev;
+	INIT_LIST_HEAD(&a->list);
+
+	attachment->priv = a;
+
+	mutex_lock(&buffer->attachments_lock);
+	list_add(&a->list, &buffer->attachments);
+	mutex_unlock(&buffer->attachments_lock);
+
+	return 0;
+}
+
+static void dma_heap_detatch(struct dma_buf *dmabuf,
+			     struct dma_buf_attachment *attachment)
+{
+	struct sram_dma_heap_buffer *buffer = dmabuf->priv;
+	struct dma_heap_attachment *a = attachment->priv;
+
+	mutex_lock(&buffer->attachments_lock);
+	list_del(&a->list);
+	mutex_unlock(&buffer->attachments_lock);
+
+	sg_free_table(a->table);
+	kfree(a->table);
+	kfree(a);
+}
+
+static struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment *attachment,
+					     enum dma_data_direction direction)
+{
+	struct dma_heap_attachment *a = attachment->priv;
+	struct sg_table *table = a->table;
+
+	/*
+	 * As this heap is backed by uncached SRAM memory we do not need to
+	 * perform any sync operations on the buffer before allowing device
+	 * domain access. For this reason we use SKIP_CPU_SYNC and also do
+	 * not use or provide begin/end_cpu_access() dma-buf functions.
+	 */
+	if (!dma_map_sg_attrs(attachment->dev, table->sgl, table->nents,
+			      direction, DMA_ATTR_SKIP_CPU_SYNC))
+		return ERR_PTR(-ENOMEM);
+
+	return table;
+}
+
+static void dma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
+				   struct sg_table *table,
+				   enum dma_data_direction direction)
+{
+	dma_unmap_sg_attrs(attachment->dev, table->sgl, table->nents,
+			   direction, DMA_ATTR_SKIP_CPU_SYNC);
+}
+
+static void dma_heap_dma_buf_release(struct dma_buf *dmabuf)
+{
+	struct sram_dma_heap_buffer *buffer = dmabuf->priv;
+
+	gen_pool_free(buffer->pool, (unsigned long)buffer->vaddr, buffer->len);
+	kfree(buffer);
+}
+
+static int dma_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
+{
+	struct sram_dma_heap_buffer *buffer = dmabuf->priv;
+	int ret;
+
+	/* SRAM mappings are not cached */
+	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+	ret = vm_iomap_memory(vma, buffer->paddr, buffer->len);
+	if (ret)
+		pr_err("Could not map buffer to userspace\n");
+
+	return ret;
+}
+
+static int dma_heap_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
+{
+	struct sram_dma_heap_buffer *buffer = dmabuf->priv;
+
+	iosys_map_set_vaddr(map, buffer->vaddr);
+
+	return 0;
+}
+
+static const struct dma_buf_ops sram_dma_heap_buf_ops = {
+	.attach = dma_heap_attach,
+	.detach = dma_heap_detatch,
+	.map_dma_buf = dma_heap_map_dma_buf,
+	.unmap_dma_buf = dma_heap_unmap_dma_buf,
+	.release = dma_heap_dma_buf_release,
+	.mmap = dma_heap_mmap,
+	.vmap = dma_heap_vmap,
+};
+
+static struct dma_buf *sram_dma_heap_allocate(struct dma_heap *heap,
+					      unsigned long len,
+					      u32 fd_flags,
+					      u64 heap_flags)
+{
+	struct sram_dma_heap *sram_dma_heap = dma_heap_get_drvdata(heap);
+	struct sram_dma_heap_buffer *buffer;
+
+	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+	struct dma_buf *dmabuf;
+	int ret = 0;
+
+	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
+	if (!buffer)
+		return ERR_PTR(-ENOMEM);
+	buffer->pool = sram_dma_heap->pool;
+	INIT_LIST_HEAD(&buffer->attachments);
+	mutex_init(&buffer->attachments_lock);
+	buffer->len = len;
+
+	buffer->vaddr = (void *)gen_pool_alloc(buffer->pool, buffer->len);
+	if (!buffer->vaddr) {
+		ret = -ENOMEM;
+		goto free_buffer;
+	}
+
+	buffer->paddr = gen_pool_virt_to_phys(buffer->pool, (unsigned long)buffer->vaddr);
+	if (buffer->paddr == -1) {
+		ret = -ENOMEM;
+		goto free_pool;
+	}
+
+	/* create the dmabuf */
+	exp_info.exp_name = dma_heap_get_name(heap);
+	exp_info.ops = &sram_dma_heap_buf_ops;
+	exp_info.size = buffer->len;
+	exp_info.flags = fd_flags;
+	exp_info.priv = buffer;
+	dmabuf = dma_buf_export(&exp_info);
+	if (IS_ERR(dmabuf)) {
+		ret = PTR_ERR(dmabuf);
+		goto free_pool;
+	}
+
+	return dmabuf;
+
+free_pool:
+	gen_pool_free(buffer->pool, (unsigned long)buffer->vaddr, buffer->len);
+free_buffer:
+	kfree(buffer);
+
+	return ERR_PTR(ret);
+}
+
+static struct dma_heap_ops sram_dma_heap_ops = {
+	.allocate = sram_dma_heap_allocate,
+};
+
+int sram_add_dma_heap(struct sram_dev *sram,
+		      struct sram_reserve *block,
+		      phys_addr_t start,
+		      struct sram_partition *part)
+{
+	struct sram_dma_heap *sram_dma_heap;
+	struct dma_heap_export_info exp_info;
+
+	dev_dbg(sram->dev, "Exporting SRAM Heap '%s'\n", block->label);
+
+	sram_dma_heap = kzalloc(sizeof(*sram_dma_heap), GFP_KERNEL);
+	if (!sram_dma_heap)
+		return -ENOMEM;
+	sram_dma_heap->pool = part->pool;
+
+	exp_info.name = kasprintf(GFP_KERNEL, "sram_%s", block->label);
+	exp_info.ops = &sram_dma_heap_ops;
+	exp_info.priv = sram_dma_heap;
+	sram_dma_heap->heap = dma_heap_add(&exp_info);
+	if (IS_ERR(sram_dma_heap->heap)) {
+		int ret = PTR_ERR(sram_dma_heap->heap);
+		kfree(sram_dma_heap);
+		return ret;
+	}
+
+	return 0;
+}
diff -Naur --no-dereference a/drivers/misc/sram.h b/drivers/misc/sram.h
--- a/drivers/misc/sram.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/misc/sram.h	2025-10-23 09:30:40.285462207 -0400
@@ -60,4 +60,20 @@
 	return -ENODEV;
 }
 #endif /* CONFIG_SRAM_EXEC */
+
+#ifdef CONFIG_SRAM_DMA_HEAP
+int sram_add_dma_heap(struct sram_dev *sram,
+		      struct sram_reserve *block,
+		      phys_addr_t start,
+		      struct sram_partition *part);
+#else
+static inline int sram_add_dma_heap(struct sram_dev *sram,
+				    struct sram_reserve *block,
+				    phys_addr_t start,
+				    struct sram_partition *part)
+{
+	return 0;
+}
+#endif /* CONFIG_SRAM_DMA_HEAP */
+
 #endif /* __SRAM_H */
diff -Naur --no-dereference a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c
--- a/drivers/mmc/host/sdhci_am654.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/mmc/host/sdhci_am654.c	2025-10-23 09:30:40.285462207 -0400
@@ -155,6 +155,7 @@
 	u32 tuning_loop;
 
 #define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0)
+#define SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA BIT(1)
 };
 
 struct window {
@@ -166,6 +167,7 @@
 struct sdhci_am654_driver_data {
 	const struct sdhci_pltfm_data *pdata;
 	u32 flags;
+	u32 quirks;
 #define IOMUX_PRESENT	(1 << 0)
 #define FREQSEL_2_BIT	(1 << 1)
 #define STRBSEL_4_BIT	(1 << 2)
@@ -356,6 +358,29 @@
 	sdhci_set_clock(host, clock);
 }
 
+static int sdhci_am654_start_signal_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
+	int ret;
+
+	if ((sdhci_am654->quirks & SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA) &&
+	    ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
+		if (!IS_ERR(mmc->supply.vqmmc)) {
+			ret = mmc_regulator_set_vqmmc(mmc, ios);
+			if (ret < 0) {
+				pr_err("%s: Switching to 1.8V signalling voltage failed,\n",
+				       mmc_hostname(mmc));
+				return -EIO;
+			}
+		}
+		return 0;
+	}
+
+	return sdhci_start_signal_voltage_switch(mmc, ios);
+}
+
 static u8 sdhci_am654_write_power_on(struct sdhci_host *host, u8 val, int reg)
 {
 	writeb(val, host->ioaddr + reg);
@@ -588,7 +613,8 @@
 static const struct sdhci_pltfm_data sdhci_am654_pdata = {
 	.ops = &sdhci_am654_ops,
 	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
-	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
+	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+		   SDHCI_QUIRK2_DISABLE_HW_TIMEOUT,
 };
 
 static const struct sdhci_am654_driver_data sdhci_am654_sr1_drvdata = {
@@ -618,7 +644,8 @@
 static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = {
 	.ops = &sdhci_j721e_8bit_ops,
 	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
-	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
+	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+		   SDHCI_QUIRK2_DISABLE_HW_TIMEOUT,
 };
 
 static const struct sdhci_am654_driver_data sdhci_j721e_8bit_drvdata = {
@@ -642,7 +669,8 @@
 static const struct sdhci_pltfm_data sdhci_j721e_4bit_pdata = {
 	.ops = &sdhci_j721e_4bit_ops,
 	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
-	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
+	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+		   SDHCI_QUIRK2_DISABLE_HW_TIMEOUT,
 };
 
 static const struct sdhci_am654_driver_data sdhci_j721e_4bit_drvdata = {
@@ -650,6 +678,12 @@
 	.flags = IOMUX_PRESENT,
 };
 
+static const struct sdhci_am654_driver_data sdhci_am62_4bit_drvdata = {
+	.pdata = &sdhci_j721e_4bit_pdata,
+	.flags = IOMUX_PRESENT,
+	.quirks = SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA,
+};
+
 static const struct soc_device_attribute sdhci_am654_devices[] = {
 	{ .family = "AM65X",
 	  .revision = "SR1.0",
@@ -872,7 +906,7 @@
 	},
 	{
 		.compatible = "ti,am62-sdhci",
-		.data = &sdhci_j721e_4bit_drvdata,
+		.data = &sdhci_am62_4bit_drvdata,
 	},
 	{ /* sentinel */ }
 };
@@ -906,6 +940,7 @@
 	pltfm_host = sdhci_priv(host);
 	sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 	sdhci_am654->flags = drvdata->flags;
+	sdhci_am654->quirks = drvdata->quirks;
 
 	clk_xin = devm_clk_get(dev, "clk_xin");
 	if (IS_ERR(clk_xin)) {
@@ -940,6 +975,7 @@
 		goto err_pltfm_free;
 	}
 
+	host->mmc_host_ops.start_signal_voltage_switch = sdhci_am654_start_signal_voltage_switch;
 	host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning;
 
 	pm_runtime_get_noresume(dev);
diff -Naur --no-dereference a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
--- a/drivers/mtd/nand/spi/core.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/mtd/nand/spi/core.c	2025-10-23 09:30:40.285462207 -0400
@@ -9,6 +9,8 @@
 
 #define pr_fmt(fmt)	"spi-nand: " fmt
 
+#define PHY_PATTERN_SIZE	0x80
+
 #include <linux/device.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
@@ -20,7 +22,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/spi-mem.h>
 
-static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val)
+int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val)
 {
 	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(reg,
 						      spinand->scratchbuf);
@@ -357,7 +359,7 @@
 		engine_conf->status = status;
 }
 
-static int spinand_write_enable_op(struct spinand_device *spinand)
+int spinand_write_enable_op(struct spinand_device *spinand)
 {
 	struct spi_mem_op op = SPINAND_WR_EN_DIS_OP(true);
 
@@ -1268,6 +1270,7 @@
 		spinand->id.len = 1 + table[i].devid.len;
 		spinand->select_target = table[i].select_target;
 		spinand->set_cont_read = table[i].set_cont_read;
+		spinand->late_init = table[i].late_init;
 
 		op = spinand_select_op_variant(spinand,
 					       info->op_variants.read_cache);
@@ -1352,6 +1355,12 @@
 		return ret;
 	}
 
+	if (spinand->late_init) {
+		ret = spinand->late_init(spinand);
+		if (ret)
+			return ret;
+	}
+
 	/* After power up, all blocks are locked, so unlock them here. */
 	for (i = 0; i < nand->memorg.ntargets; i++) {
 		ret = spinand_select_target(spinand, i);
@@ -1506,7 +1515,13 @@
 {
 	struct spinand_device *spinand;
 	struct mtd_info *mtd;
-	int ret;
+	struct mtd_part *part;
+	struct nand_device *nand;
+	struct nand_pos page_pos;
+	struct nand_page_io_req page_req;
+	struct spi_mem_op read_page_op;
+	int ret, pageoffs;
+	u8 status;
 
 	spinand = devm_kzalloc(&mem->spi->dev, sizeof(*spinand),
 			       GFP_KERNEL);
@@ -1524,10 +1539,39 @@
 	if (ret)
 		return ret;
 
+	nand = spinand_to_nand(spinand);
+
 	ret = mtd_device_register(mtd, NULL, 0);
 	if (ret)
 		goto err_spinand_cleanup;
 
+	list_for_each_entry(part, &mtd->partitions, node) {
+		struct mtd_info *part_info =
+			container_of(part, struct mtd_info, part);
+		if (part_info->name &&
+		    !strcmp(part_info->name, "ospi_nand.phypattern")) {
+			pageoffs = nanddev_offs_to_pos(nand, part->offset, &page_pos);
+			page_req.pos = page_pos;
+
+			read_page_op = *spinand->op_templates.read_cache;
+			read_page_op.addr.val = pageoffs;
+			read_page_op.data.nbytes = PHY_PATTERN_SIZE;
+
+			ret = spinand_load_page_op(spinand, &page_req);
+			if (ret)
+				goto err_spinand_cleanup;
+
+			ret = spinand_wait(spinand,
+					   SPINAND_READ_INITIAL_DELAY_US,
+					   SPINAND_READ_POLL_DELAY_US, &status);
+			if (ret < 0)
+				goto err_spinand_cleanup;
+
+			spinand_ondie_ecc_save_status(nand, status);
+			spi_mem_do_calibration(spinand->spimem, &read_page_op);
+		}
+	}
+
 	return 0;
 
 err_spinand_cleanup:
diff -Naur --no-dereference a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
--- a/drivers/mtd/nand/spi/winbond.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/mtd/nand/spi/winbond.c	2025-10-23 09:30:40.285462207 -0400
@@ -10,6 +10,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/mtd/spinand.h>
+#include <linux/delay.h>
 
 #define SPINAND_MFR_WINBOND		0xEF
 
@@ -17,7 +18,20 @@
 
 #define W25N04KV_STATUS_ECC_5_8_BITFLIPS	(3 << 4)
 
+#define W25N01JW_STATUS_REG4			0xd0
+#define W25N01JW_STATUS_REG4_HS			BIT(2)
+#define W25N01JW_STATUS_REG4_HS_MASK		0xFB
+
+#define W35N01JW_VCR_IO_MODE_ADDR		0x00
+#define W35N01JW_VCR_IO_MODE_ADDR_DEFAULT	0xFF
+#define W35N01JW_VCR_IO_MODE_ADDR_OCTAL_SDR	0xDF
+
+#define W35N01JW_VCR_DUMMY_CLOCK_ADDR		0x01
+#define W35N01JW_VCR_DUMMY_CLOCK_ADDR_DEFAULT	0xFF
+#define W35N01JW_VCR_DUMMY_CLOCK_ADDR_20	0x14
+
 static SPINAND_OP_VARIANTS(read_cache_variants,
+		SPINAND_PAGE_READ_FROM_CACHE_OCTALIO_OP(0, 16, NULL, 0),
 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
 		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
@@ -25,11 +39,22 @@
 		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
 		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
 
+static SPINAND_OP_VARIANTS(phy_read_cache_variants,
+		SPINAND_PAGE_READ_FROM_CACHE_OCTALIO_OP(0, 20, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
 static SPINAND_OP_VARIANTS(write_cache_variants,
+		SPINAND_PROG_LOAD_OCTALIO(true, 0, NULL, 0),
 		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
 		SPINAND_PROG_LOAD(true, 0, NULL, 0));
 
 static SPINAND_OP_VARIANTS(update_cache_variants,
+		SPINAND_PROG_LOAD_OCTALIO(false, 0, NULL, 0),
 		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
 		SPINAND_PROG_LOAD(false, 0, NULL, 0));
 
@@ -112,6 +137,54 @@
 	return 0;
 }
 
+static int w25n01jw_ooblayout_ecc(struct mtd_info *mtd, int section,
+				  struct mtd_oob_region *region)
+{
+	if (section > 3)
+		return -ERANGE;
+
+	region->offset = (16 * section) + 12;
+	region->length = 4;
+
+	return 0;
+}
+
+static int w25n01jw_ooblayout_free(struct mtd_info *mtd, int section,
+				   struct mtd_oob_region *region)
+{
+	if (section > 3)
+		return -ERANGE;
+
+	region->offset = (16 * section) + 2;
+	region->length = 10;
+
+	return 0;
+}
+
+static int w35n01jw_ooblayout_ecc(struct mtd_info *mtd, int section,
+				  struct mtd_oob_region *region)
+{
+	if (section > 7)
+		return -ERANGE;
+
+	region->offset = (16 * section) + 12;
+	region->length = 4;
+
+	return 0;
+}
+
+static int w35n01jw_ooblayout_free(struct mtd_info *mtd, int section,
+				   struct mtd_oob_region *region)
+{
+	if (section > 7)
+		return -ERANGE;
+
+	region->offset = (16 * section) + 2;
+	region->length = 10;
+
+	return 0;
+}
+
 static const struct mtd_ooblayout_ops w25n01kv_ooblayout = {
 	.ecc = w25n01kv_ooblayout_ecc,
 	.free = w25n02kv_ooblayout_free,
@@ -122,6 +195,87 @@
 	.free = w25n02kv_ooblayout_free,
 };
 
+static const struct mtd_ooblayout_ops w25n01jw_ooblayout = {
+	.ecc = w25n01jw_ooblayout_ecc,
+	.free = w25n01jw_ooblayout_free,
+};
+
+static const struct mtd_ooblayout_ops w35n01jw_ooblayout = {
+	.ecc = w35n01jw_ooblayout_ecc,
+	.free = w35n01jw_ooblayout_free,
+};
+
+static int w35n01jw_write_vcr_op(struct spinand_device *spinand, u8 reg, u8 val)
+{
+	int ret;
+	struct spi_mem_op op =
+		SPI_MEM_OP(SPI_MEM_OP_CMD(0x81, 1),
+			   SPI_MEM_OP_ADDR(3, reg, 1),
+			   SPI_MEM_OP_NO_DUMMY,
+			   SPI_MEM_OP_DATA_OUT(1, spinand->scratchbuf, 1));
+
+	*spinand->scratchbuf = val;
+
+	ret = spinand_write_enable_op(spinand);
+	if (ret)
+		return ret;
+
+	ret = spi_mem_exec_op(spinand->spimem, &op);
+	if (ret)
+		return ret;
+
+	/*
+	 * Write VCR operation doesn't set the busy bit in SR, so can't perform
+	 * a status poll. Minimum time of 50ns is needed to complete the write.
+	 * So, give thrice the minimum required delay.
+	 */
+	ndelay(150);
+	return 0;
+}
+
+static int w25n01jw_late_init(struct spinand_device *spinand)
+{
+	u8 *sr4_read;
+	u8 sr4_write;
+	int ret;
+
+	sr4_read = kmalloc(sizeof(u8), GFP_KERNEL);
+	if (!sr4_read)
+		return -ENOMEM;
+
+	ret = spinand_read_reg_op(spinand, W25N01JW_STATUS_REG4, sr4_read);
+	if (ret)
+		return ret;
+
+	*sr4_read &= W25N01JW_STATUS_REG4_HS_MASK;
+	*sr4_read |= W25N01JW_STATUS_REG4_HS;
+
+	sr4_write = *sr4_read;
+
+	ret = spinand_write_reg_op(spinand, W25N01JW_STATUS_REG4, sr4_write);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int w35n01jw_late_init(struct spinand_device *spinand)
+{
+	int ret;
+
+	ret = w35n01jw_write_vcr_op(spinand, W35N01JW_VCR_IO_MODE_ADDR,
+				    W35N01JW_VCR_IO_MODE_ADDR_OCTAL_SDR);
+	if (ret)
+		return ret;
+
+	ret = w35n01jw_write_vcr_op(spinand, W35N01JW_VCR_DUMMY_CLOCK_ADDR,
+				    W35N01JW_VCR_DUMMY_CLOCK_ADDR_20);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static int w25n02kv_ecc_get_status(struct spinand_device *spinand,
 				   u8 status)
 {
@@ -202,11 +356,22 @@
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbc, 0x21),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
 		     NAND_ECCREQ(1, 512),
-		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+		     SPINAND_INFO_OP_VARIANTS(&phy_read_cache_variants,
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
+		     SPINAND_ECCINFO(&w25n01jw_ooblayout, NULL),
+		     SPINAND_LATE_INIT(w25n01jw_late_init)),
+	SPINAND_INFO("W35N01JW",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdc, 0x21),
+		     NAND_MEMORG(1, 4096, 128, 64, 512, 20, 1, 1, 1),
+		     NAND_ECCREQ(1, 512),
+		     SPINAND_INFO_OP_VARIANTS(&phy_read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     0,
+		     SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL),
+		     SPINAND_LATE_INIT(w35n01jw_late_init)),
 	SPINAND_INFO("W25N02JWZEIF",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbf, 0x22),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 2, 1),
diff -Naur --no-dereference a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
--- a/drivers/mtd/spi-nor/core.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/mtd/spi-nor/core.c	2025-10-23 09:30:40.285462207 -0400
@@ -184,6 +184,33 @@
 }
 
 /**
+ * spi_nor_spimem_get_read_op() - return a template for the spi_mem_op used for
+ *                                reading data from the flash via spi-mem.
+ * @nor:        pointer to 'struct spi_nor'
+ *
+ * Return: A template of the 'struct spi_mem_op' for used for reading data from
+ * the flash. The caller is expected to fill in the address, data length, and
+ * the data buffer.
+ */
+static struct spi_mem_op spi_nor_spimem_get_read_op(struct spi_nor *nor)
+{
+	struct spi_mem_op op =
+		SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
+			   SPI_MEM_OP_ADDR(nor->addr_nbytes, 0, 0),
+			   SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
+			   SPI_MEM_OP_DATA_IN(1, NULL, 0));
+
+	spi_nor_spimem_setup_op(nor, &op, nor->read_proto);
+
+	/* convert the dummy cycles to the number of bytes */
+	op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;
+	if (spi_nor_protocol_is_dtr(nor->read_proto))
+		op.dummy.nbytes *= 2;
+
+	return op;
+}
+
+/**
  * spi_nor_spimem_read_data() - read data from flash's memory region via
  *                              spi-mem
  * @nor:        pointer to 'struct spi_nor'
@@ -196,21 +223,14 @@
 static ssize_t spi_nor_spimem_read_data(struct spi_nor *nor, loff_t from,
 					size_t len, u8 *buf)
 {
-	struct spi_mem_op op =
-		SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
-			   SPI_MEM_OP_ADDR(nor->addr_nbytes, from, 0),
-			   SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
-			   SPI_MEM_OP_DATA_IN(len, buf, 0));
+	struct spi_mem_op op = spi_nor_spimem_get_read_op(nor);
 	bool usebouncebuf;
 	ssize_t nbytes;
 	int error;
 
-	spi_nor_spimem_setup_op(nor, &op, nor->read_proto);
-
-	/* convert the dummy cycles to the number of bytes */
-	op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;
-	if (spi_nor_protocol_is_dtr(nor->read_proto))
-		op.dummy.nbytes *= 2;
+	op.addr.val = from;
+	op.data.nbytes = len;
+	op.data.buf.in = buf;
 
 	usebouncebuf = spi_nor_spimem_bounce(nor, &op);
 
@@ -2037,6 +2057,82 @@
 	return info;
 }
 
+/*
+ * On Octal DTR capable flashes like Micron Xcella reads cannot start or
+ * end at an odd address in Octal DTR mode. Extra bytes need to be read
+ * at the start or end to make sure both the start address and length
+ * remain even.
+ */
+static int spi_nor_octal_dtr_read(struct spi_nor *nor, loff_t from, size_t len,
+				  u_char *buf)
+{
+	u_char *tmp_buf;
+	size_t tmp_len;
+	loff_t start, end;
+	int ret, bytes_read;
+
+	if (IS_ALIGNED(from, 2) && IS_ALIGNED(len, 2))
+		return spi_nor_read_data(nor, from, len, buf);
+	else if (IS_ALIGNED(from, 2) && len > PAGE_SIZE)
+		return spi_nor_read_data(nor, from, round_down(len, PAGE_SIZE),
+					 buf);
+
+	tmp_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!tmp_buf)
+		return -ENOMEM;
+
+	start = round_down(from, 2);
+	end = round_up(from + len, 2);
+
+	/*
+	 * Avoid allocating too much memory. The requested read length might be
+	 * quite large. Allocating a buffer just as large (slightly bigger, in
+	 * fact) would put unnecessary memory pressure on the system.
+	 *
+	 * For example if the read is from 3 to 1M, then this will read from 2
+	 * to 4098. The reads from 4098 to 1M will then not need a temporary
+	 * buffer so they can proceed as normal.
+	 */
+	tmp_len = min_t(size_t, end - start, PAGE_SIZE);
+
+	ret = spi_nor_read_data(nor, start, tmp_len, tmp_buf);
+	if (ret == 0) {
+		ret = -EIO;
+		goto out;
+	}
+	if (ret < 0)
+		goto out;
+
+	/*
+	 * More bytes are read than actually requested, but that number can't be
+	 * reported to the calling function or it will confuse its calculations.
+	 * Calculate how many of the _requested_ bytes were read.
+	 */
+	bytes_read = ret;
+
+	if (from != start)
+		ret -= from - start;
+
+	/*
+	 * Only account for extra bytes at the end if they were actually read.
+	 * For example, if the total length was truncated because of temporary
+	 * buffer size limit then the adjustment for the extra bytes at the end
+	 * is not needed.
+	 */
+	if (start + bytes_read == end)
+		ret -= end - (from + len);
+
+	if (ret < 0) {
+		ret = -EIO;
+		goto out;
+	}
+
+	memcpy(buf, tmp_buf + (from - start), ret);
+out:
+	kfree(tmp_buf);
+	return ret;
+}
+
 static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
 			size_t *retlen, u_char *buf)
 {
@@ -2054,7 +2150,11 @@
 	while (len) {
 		loff_t addr = from;
 
-		ret = spi_nor_read_data(nor, addr, len, buf);
+		if (nor->read_proto == SNOR_PROTO_8_8_8_DTR)
+			ret = spi_nor_octal_dtr_read(nor, addr, len, buf);
+		else
+			ret = spi_nor_read_data(nor, addr, len, buf);
+
 		if (ret == 0) {
 			/* We shouldn't see 0-length reads */
 			ret = -EIO;
@@ -2078,6 +2178,71 @@
 }
 
 /*
+ * On Octal DTR capable flashes like Micron Xcella the writes cannot start or
+ * end at an odd address in Octal DTR mode. Extra 0xff bytes need to be appended
+ * or prepended to make sure the start address and end address are even. 0xff is
+ * used because on NOR flashes a program operation can only flip bits from 1 to
+ * 0, not the other way round. 0 to 1 flip needs to happen via erases.
+ */
+static int spi_nor_octal_dtr_write(struct spi_nor *nor, loff_t to, size_t len,
+				   const u8 *buf)
+{
+	u8 *tmp_buf;
+	size_t bytes_written;
+	loff_t start, end;
+	int ret;
+
+	if (IS_ALIGNED(to, 2) && IS_ALIGNED(len, 2))
+		return spi_nor_write_data(nor, to, len, buf);
+
+	tmp_buf = kmalloc(nor->params->page_size, GFP_KERNEL);
+	if (!tmp_buf)
+		return -ENOMEM;
+
+	memset(tmp_buf, 0xff, nor->params->page_size);
+
+	start = round_down(to, 2);
+	end = round_up(to + len, 2);
+
+	memcpy(tmp_buf + (to - start), buf, len);
+
+	ret = spi_nor_write_data(nor, start, end - start, tmp_buf);
+	if (ret == 0) {
+		ret = -EIO;
+		goto out;
+	}
+	if (ret < 0)
+		goto out;
+
+	/*
+	 * More bytes are written than actually requested, but that number can't
+	 * be reported to the calling function or it will confuse its
+	 * calculations. Calculate how many of the _requested_ bytes were
+	 * written.
+	 */
+	bytes_written = ret;
+
+	if (to != start)
+		ret -= to - start;
+
+	/*
+	 * Only account for extra bytes at the end if they were actually
+	 * written. For example, if for some reason the controller could only
+	 * complete a partial write then the adjustment for the extra bytes at
+	 * the end is not needed.
+	 */
+	if (start + bytes_written == end)
+		ret -= end - (to + len);
+
+	if (ret < 0)
+		ret = -EIO;
+
+out:
+	kfree(tmp_buf);
+	return ret;
+}
+
+/*
  * Write an address range to the nor chip.  Data must be written in
  * FLASH_PAGESIZE chunks.  The address range may be any size provided
  * it is within the physical boundaries.
@@ -2113,8 +2278,15 @@
 			goto write_err;
 		}
 
-		ret = spi_nor_write_data(nor, addr, page_remain, buf + i);
+		if (nor->write_proto == SNOR_PROTO_8_8_8_DTR)
+			ret = spi_nor_octal_dtr_write(nor, addr, page_remain,
+						      buf + i);
+		else
+			ret = spi_nor_write_data(nor, addr, page_remain,
+						 buf + i);
+
 		spi_nor_unlock_device(nor);
+
 		if (ret < 0)
 			goto write_err;
 		written = ret;
@@ -3513,28 +3685,10 @@
 static int spi_nor_create_read_dirmap(struct spi_nor *nor)
 {
 	struct spi_mem_dirmap_info info = {
-		.op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
-				      SPI_MEM_OP_ADDR(nor->addr_nbytes, 0, 0),
-				      SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
-				      SPI_MEM_OP_DATA_IN(0, NULL, 0)),
+		.op_tmpl = spi_nor_spimem_get_read_op(nor),
 		.offset = 0,
 		.length = nor->params->size,
 	};
-	struct spi_mem_op *op = &info.op_tmpl;
-
-	spi_nor_spimem_setup_op(nor, op, nor->read_proto);
-
-	/* convert the dummy cycles to the number of bytes */
-	op->dummy.nbytes = (nor->read_dummy * op->dummy.buswidth) / 8;
-	if (spi_nor_protocol_is_dtr(nor->read_proto))
-		op->dummy.nbytes *= 2;
-
-	/*
-	 * Since spi_nor_spimem_setup_op() only sets buswidth when the number
-	 * of data bytes is non-zero, the data buswidth won't be set here. So,
-	 * do it explicitly.
-	 */
-	op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);
 
 	nor->dirmap.rdesc = devm_spi_mem_dirmap_create(nor->dev, nor->spimem,
 						       &info);
@@ -3580,6 +3734,7 @@
 	 * checking what's really supported using spi_mem_supports_op().
 	 */
 	const struct spi_nor_hwcaps hwcaps = { .mask = SNOR_HWCAPS_ALL };
+	struct mtd_part *part;
 	char *flash_name;
 	int ret;
 
@@ -3641,8 +3796,25 @@
 	if (ret)
 		return ret;
 
-	return mtd_device_register(&nor->mtd, data ? data->parts : NULL,
-				   data ? data->nr_parts : 0);
+	ret = mtd_device_register(&nor->mtd, data ? data->parts : NULL,
+				  data ? data->nr_parts : 0);
+	if (ret)
+		return ret;
+
+	list_for_each_entry(part, &nor->mtd.partitions, node) {
+		struct spi_mem_op op;
+		struct mtd_info *part_info = container_of(part,
+							  struct mtd_info, part);
+
+		if (part_info->name &&
+		    !strcmp(part_info->name, "ospi.phypattern")) {
+			op = spi_nor_spimem_get_read_op(nor);
+			op.addr.val = part->offset;
+			spi_mem_do_calibration(nor->spimem, &op);
+		}
+	}
+
+	return 0;
 }
 
 static int spi_nor_remove(struct spi_mem *spimem)
diff -Naur --no-dereference a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
--- a/drivers/mtd/spi-nor/spansion.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/mtd/spi-nor/spansion.c	2025-10-23 09:30:40.285462207 -0400
@@ -222,6 +222,8 @@
 			return ret;
 	}
 
+	nor->params->addr_mode_nbytes = 4;
+
 	/* Read flash ID to make sure the switch was successful. */
 	ret = spi_nor_read_id(nor, nor->addr_nbytes, 3, buf,
 			      SNOR_PROTO_8_8_8_DTR);
@@ -267,6 +269,8 @@
 			return ret;
 	}
 
+	nor->params->addr_mode_nbytes = 3;
+
 	/* Read flash ID to make sure the switch was successful. */
 	ret = spi_nor_read_id(nor, 0, 0, buf, SNOR_PROTO_1_1_1);
 	if (ret) {
diff -Naur --no-dereference a/drivers/mux/mmio.c b/drivers/mux/mmio.c
--- a/drivers/mux/mmio.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/mux/mmio.c	2025-10-23 09:30:40.285462207 -0400
@@ -3,6 +3,7 @@
  * MMIO register bitfield-controlled multiplexer driver
  *
  * Copyright (C) 2017 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
+ * Copyright (C) 2025 Texas Instruments
  */
 
 #include <linux/bitops.h>
@@ -33,10 +34,83 @@
 };
 MODULE_DEVICE_TABLE(of, mux_mmio_dt_ids);
 
+static int reg_mux_get_controllers(const struct device_node *np, char *prop_name)
+{
+	int ret;
+
+	ret = of_property_count_u32_elems(np, prop_name);
+	if (ret == 0 || ret % 2)
+		ret = -EINVAL;
+
+	return ret;
+}
+
+static int reg_mux_get_controllers_extended(const struct device_node *np, char *prop_name)
+{
+	int ret;
+
+	ret = of_property_count_u32_elems(np, prop_name);
+	if (ret == 0 || ret % 3)
+		ret = -EINVAL;
+
+	return ret;
+}
+
+static int reg_mux_parse_dt(const struct device_node *np, bool *mux_reg_masks_state,
+			    int *num_fields)
+{
+	int ret;
+
+	if (of_property_present(np, "mux-reg-masks-state")) {
+		*mux_reg_masks_state = true;
+		ret = reg_mux_get_controllers_extended(np, "mux-reg-masks-state");
+		if (ret < 0)
+			return ret;
+		*num_fields = ret / 3;
+	} else {
+		ret = reg_mux_get_controllers(np, "mux-reg-masks");
+		if (ret < 0)
+			return ret;
+		*num_fields = ret / 2;
+	}
+	return ret;
+}
+
+static int mux_reg_set_parameters(const struct device_node *np, char *prop_name, u32 *reg,
+				  u32 *mask, int index)
+{
+	int ret;
+
+	ret = of_property_read_u32_index(np, prop_name, 2 * index, reg);
+	if (!ret)
+		ret = of_property_read_u32_index(np, prop_name, 2 * index + 1, mask);
+
+	return ret;
+}
+
+static int mux_reg_set_parameters_extended(const struct device_node *np, char *prop_name, u32 *reg,
+					   u32 *mask, u32 *state, int index)
+{
+	int ret;
+
+	ret = of_property_read_u32_index(np, prop_name, 3 * index, reg);
+	if (ret < 0)
+		return ret;
+
+	ret = of_property_read_u32_index(np, prop_name, 3 * index + 1, mask);
+	if (ret < 0)
+		return ret;
+
+	ret = of_property_read_u32_index(np, prop_name, 3 * index + 2, state);
+
+	return ret;
+}
+
 static int mux_mmio_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
+	bool mux_reg_masks_state = false;
 	struct regmap_field **fields;
 	struct mux_chip *mux_chip;
 	struct regmap *regmap;
@@ -59,15 +133,16 @@
 		return dev_err_probe(dev, PTR_ERR(regmap),
 				     "failed to get regmap\n");
 
-	ret = of_property_count_u32_elems(np, "mux-reg-masks");
-	if (ret == 0 || ret % 2)
-		ret = -EINVAL;
+	ret = reg_mux_parse_dt(np, &mux_reg_masks_state, &num_fields);
 	if (ret < 0) {
-		dev_err(dev, "mux-reg-masks property missing or invalid: %d\n",
-			ret);
+		if (mux_reg_masks_state)
+			dev_err(dev, "mux-reg-masks-state property missing or invalid: %d\n",
+				ret);
+		else
+			dev_err(dev, "mux-reg-masks property missing or invalid: %d\n",
+				ret);
 		return ret;
 	}
-	num_fields = ret / 2;
 
 	mux_chip = devm_mux_chip_alloc(dev, num_fields, num_fields *
 				       sizeof(*fields));
@@ -79,19 +154,25 @@
 	for (i = 0; i < num_fields; i++) {
 		struct mux_control *mux = &mux_chip->mux[i];
 		struct reg_field field;
-		s32 idle_state = MUX_IDLE_AS_IS;
+		s32 state, idle_state = MUX_IDLE_AS_IS;
 		u32 reg, mask;
 		int bits;
 
-		ret = of_property_read_u32_index(np, "mux-reg-masks",
-						 2 * i, &reg);
-		if (!ret)
-			ret = of_property_read_u32_index(np, "mux-reg-masks",
-							 2 * i + 1, &mask);
-		if (ret < 0) {
-			dev_err(dev, "bitfield %d: failed to read mux-reg-masks property: %d\n",
-				i, ret);
-			return ret;
+		if (!mux_reg_masks_state) {
+			ret = mux_reg_set_parameters(np, "mux-reg-masks", &reg, &mask, i);
+			if (ret < 0) {
+				dev_err(dev, "bitfield %d: failed to read mux-reg-masks property: %d\n",
+					i, ret);
+				return ret;
+			}
+		} else {
+			ret = mux_reg_set_parameters_extended(np, "mux-reg-masks-state", &reg,
+							      &mask, &state, i);
+			if (ret < 0) {
+				dev_err(dev, "bitfield %d: failed to read custom-states property: %d\n",
+					i, ret);
+				return ret;
+			}
 		}
 
 		field.reg = reg;
@@ -115,16 +196,28 @@
 		bits = 1 + field.msb - field.lsb;
 		mux->states = 1 << bits;
 
-		of_property_read_u32_index(np, "idle-states", i,
-					   (u32 *)&idle_state);
-		if (idle_state != MUX_IDLE_AS_IS) {
-			if (idle_state < 0 || idle_state >= mux->states) {
-				dev_err(dev, "bitfield: %d: out of range idle state %d\n",
-					i, idle_state);
-				return -EINVAL;
+		if (!mux_reg_masks_state) {
+			of_property_read_u32_index(np, "idle-states", i,
+						   (u32 *)&idle_state);
+			if (idle_state != MUX_IDLE_AS_IS) {
+				if (idle_state < 0 || idle_state >= mux->states) {
+					dev_err(dev, "bitfield: %d: out of range idle state %d\n",
+						i, idle_state);
+					return -EINVAL;
+				}
+
+				mux->idle_state = idle_state;
 			}
+		} else {
+			if (state != MUX_IDLE_AS_IS) {
+				if (state < 0 || state >= mux->states) {
+					dev_err(dev, "bitfield: %d: out of range idle state %d\n",
+						i, state);
+					return -EINVAL;
+				}
 
-			mux->idle_state = idle_state;
+				mux->idle_state = state;
+			}
 		}
 	}
 
diff -Naur --no-dereference a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
--- a/drivers/net/can/m_can/m_can.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/can/m_can/m_can.c	2025-10-23 09:30:40.285462207 -0400
@@ -23,6 +23,7 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/reboot.h>
 
 #include "m_can.h"
 
@@ -2215,6 +2216,58 @@
 	return 0;
 }
 
+static void m_can_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct m_can_classdev *cdev = netdev_priv(dev);
+
+	wol->supported = device_can_wakeup(cdev->dev) ? WAKE_PHY : 0;
+	wol->wolopts = device_may_wakeup(cdev->dev) ? WAKE_PHY : 0;
+}
+
+static int m_can_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct m_can_classdev *cdev = netdev_priv(dev);
+	struct pinctrl_state *new_pinctrl_state = NULL;
+	bool wol_enable = !!(wol->wolopts & WAKE_PHY);
+	int ret;
+
+	if (wol->wolopts & ~WAKE_PHY)
+		return -EINVAL;
+
+	if (wol_enable == device_may_wakeup(cdev->dev))
+		return 0;
+
+	ret = device_set_wakeup_enable(cdev->dev, wol_enable);
+	if (ret) {
+		netdev_err(cdev->net, "Failed to set wakeup enable %pE\n",
+			   ERR_PTR(ret));
+		return ret;
+	}
+
+	if (wol_enable)
+		new_pinctrl_state = cdev->pinctrl_state_wakeup;
+	else
+		new_pinctrl_state = cdev->pinctrl_state_default;
+
+	if (IS_ERR_OR_NULL(new_pinctrl_state))
+		return 0;
+
+	ret = pinctrl_select_state(cdev->pinctrl, new_pinctrl_state);
+	if (ret) {
+		netdev_err(cdev->net, "Failed to select pinctrl state %pE\n",
+			   ERR_PTR(ret));
+		goto err_wakeup_enable;
+	}
+
+	return 0;
+
+err_wakeup_enable:
+	/* Revert wakeup enable */
+	device_set_wakeup_enable(cdev->dev, !wol_enable);
+
+	return ret;
+}
+
 static const struct ethtool_ops m_can_ethtool_ops_coalescing = {
 	.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS_IRQ |
 		ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ |
@@ -2224,10 +2277,14 @@
 	.get_ts_info = ethtool_op_get_ts_info,
 	.get_coalesce = m_can_get_coalesce,
 	.set_coalesce = m_can_set_coalesce,
+	.get_wol = m_can_get_wol,
+	.set_wol = m_can_set_wol,
 };
 
 static const struct ethtool_ops m_can_ethtool_ops = {
 	.get_ts_info = ethtool_op_get_ts_info,
+	.get_wol = m_can_get_wol,
+	.set_wol = m_can_set_wol,
 };
 
 static int register_m_can_dev(struct m_can_classdev *cdev)
@@ -2336,6 +2393,59 @@
 }
 EXPORT_SYMBOL_GPL(m_can_class_get_clocks);
 
+static int m_can_class_setup_optional_pinctrl(struct m_can_classdev *class_dev)
+{
+	struct device *dev = class_dev->dev;
+	int ret;
+
+	class_dev->pinctrl = devm_pinctrl_get(dev);
+	if (IS_ERR(class_dev->pinctrl)) {
+		ret = PTR_ERR(class_dev->pinctrl);
+		class_dev->pinctrl = NULL;
+
+		if (ret == -ENODEV)
+			return 0;
+
+		return dev_err_probe(dev, ret, "Failed to get pinctrl\n");
+	}
+
+	class_dev->pinctrl_state_wakeup =
+		pinctrl_lookup_state(class_dev->pinctrl, "wakeup");
+	if (IS_ERR(class_dev->pinctrl_state_wakeup)) {
+		ret = PTR_ERR(class_dev->pinctrl_state_wakeup);
+		class_dev->pinctrl_state_wakeup = NULL;
+
+		if (ret == -ENODEV)
+			return 0;
+
+		return dev_err_probe(dev, ret, "Failed to lookup pinctrl wakeup state\n");
+	}
+
+	class_dev->pinctrl_state_default =
+		pinctrl_lookup_state(class_dev->pinctrl, "default");
+	if (IS_ERR(class_dev->pinctrl_state_default)) {
+		ret = PTR_ERR(class_dev->pinctrl_state_default);
+		return dev_err_probe(dev, ret, "Failed to lookup pinctrl default state\n");
+	}
+
+	return 0;
+}
+
+static int m_can_class_sysoff_handler(struct sys_off_data *data)
+{
+	struct m_can_classdev *cdev = data->cb_data;
+	struct device *dev = data->dev;
+	int ret;
+
+	if (device_may_wakeup(dev) && !IS_ERR(cdev->pinctrl_state_wakeup))
+		ret = pinctrl_select_state(cdev->pinctrl, cdev->pinctrl_state_wakeup);
+
+	if (ret)
+		dev_err(dev, "Failed to select pinctrl state 'wakeup', continuing poweroff\n");
+
+	return NOTIFY_DONE;
+}
+
 struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
 						int sizeof_priv)
 {
@@ -2351,7 +2461,12 @@
 					     sizeof(mram_config_vals) / 4);
 	if (ret) {
 		dev_err(dev, "Could not get Message RAM configuration.");
-		goto out;
+		return ERR_PTR(ret);
+	}
+
+	if (dev->of_node && of_property_read_bool(dev->of_node, "wakeup-source")) {
+		device_set_wakeup_capable(dev, true);
+		device_set_wakeup_enable(dev, true);
 	}
 
 	/* Get TX FIFO size
@@ -2363,7 +2478,7 @@
 	net_dev = alloc_candev(sizeof_priv, tx_fifo_size);
 	if (!net_dev) {
 		dev_err(dev, "Failed to allocate CAN device");
-		goto out;
+		return ERR_PTR(-ENOMEM);
 	}
 
 	class_dev = netdev_priv(net_dev);
@@ -2372,9 +2487,22 @@
 	SET_NETDEV_DEV(net_dev, dev);
 
 	m_can_of_parse_mram(class_dev, mram_config_vals);
+
+	devm_register_sys_off_handler(dev,
+				      SYS_OFF_MODE_POWER_OFF_PREPARE,
+				      SYS_OFF_PRIO_DEFAULT,
+				      m_can_class_sysoff_handler, class_dev);
+
+	ret = m_can_class_setup_optional_pinctrl(class_dev);
+	if (ret)
+		goto err_free_candev;
+
 	spin_lock_init(&class_dev->tx_handling_spinlock);
-out:
 	return class_dev;
+
+err_free_candev:
+	free_candev(net_dev);
+	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(m_can_class_allocate_dev);
 
@@ -2486,7 +2614,10 @@
 		m_can_clk_stop(cdev);
 	}
 
-	pinctrl_pm_select_sleep_state(dev);
+	if (device_may_wakeup(dev) && !IS_ERR(cdev->pinctrl_state_wakeup))
+		pinctrl_select_state(cdev->pinctrl, cdev->pinctrl_state_wakeup);
+	else
+		pinctrl_pm_select_sleep_state(dev);
 
 	cdev->can.state = CAN_STATE_SLEEPING;
 
diff -Naur --no-dereference a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h
--- a/drivers/net/can/m_can/m_can.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/can/m_can/m_can.h	2025-10-23 09:30:40.285462207 -0400
@@ -127,6 +127,10 @@
 	struct mram_cfg mcfg[MRAM_CFG_NUM];
 
 	struct hrtimer hrtimer;
+
+	struct pinctrl *pinctrl;
+	struct pinctrl_state *pinctrl_state_default;
+	struct pinctrl_state *pinctrl_state_wakeup;
 };
 
 struct m_can_classdev *m_can_class_allocate_dev(struct device *dev, int sizeof_priv);
diff -Naur --no-dereference a/drivers/net/can/m_can/m_can_pci.c b/drivers/net/can/m_can/m_can_pci.c
--- a/drivers/net/can/m_can/m_can_pci.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/can/m_can/m_can_pci.c	2025-10-23 09:30:40.285462207 -0400
@@ -111,8 +111,8 @@
 
 	mcan_class = m_can_class_allocate_dev(&pci->dev,
 					      sizeof(struct m_can_pci_priv));
-	if (!mcan_class)
-		return -ENOMEM;
+	if (IS_ERR(mcan_class))
+		return PTR_ERR(mcan_class);
 
 	priv = cdev_to_priv(mcan_class);
 
diff -Naur --no-dereference a/drivers/net/can/m_can/m_can_platform.c b/drivers/net/can/m_can/m_can_platform.c
--- a/drivers/net/can/m_can/m_can_platform.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/can/m_can/m_can_platform.c	2025-10-23 09:30:40.285462207 -0400
@@ -87,8 +87,8 @@
 
 	mcan_class = m_can_class_allocate_dev(&pdev->dev,
 					      sizeof(struct m_can_plat_priv));
-	if (!mcan_class)
-		return -ENOMEM;
+	if (IS_ERR(mcan_class))
+		return PTR_ERR(mcan_class);
 
 	priv = cdev_to_priv(mcan_class);
 
diff -Naur --no-dereference a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c
--- a/drivers/net/can/m_can/tcan4x5x-core.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/can/m_can/tcan4x5x-core.c	2025-10-23 09:30:40.286462238 -0400
@@ -375,8 +375,8 @@
 
 	mcan_class = m_can_class_allocate_dev(&spi->dev,
 					      sizeof(struct tcan4x5x_priv));
-	if (!mcan_class)
-		return -ENOMEM;
+	if (IS_ERR(mcan_class))
+		return PTR_ERR(mcan_class);
 
 	ret = m_can_check_mram_cfg(mcan_class, TCAN4X5X_MRAM_SIZE);
 	if (ret)
diff -Naur --no-dereference a/drivers/net/ethernet/ti/am65-cpsw-ethtool.c b/drivers/net/ethernet/ti/am65-cpsw-ethtool.c
--- a/drivers/net/ethernet/ti/am65-cpsw-ethtool.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/am65-cpsw-ethtool.c	2025-10-23 09:30:40.286462238 -0400
@@ -374,6 +374,8 @@
 static const char am65_cpsw_ethtool_priv_flags[][ETH_GSTRING_LEN] = {
 #define	AM65_CPSW_PRIV_P0_RX_PTYPE_RROBIN	BIT(0)
 	"p0-rx-ptype-rrobin",
+#define AM65_CPSW_PRIV_CUT_THRU			BIT(1)
+	"cut-thru",
 };
 
 static int am65_cpsw_ethtool_op_begin(struct net_device *ndev)
@@ -723,20 +725,25 @@
 static u32 am65_cpsw_get_ethtool_priv_flags(struct net_device *ndev)
 {
 	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
+	struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
 	u32 priv_flags = 0;
 
 	if (common->pf_p0_rx_ptype_rrobin)
 		priv_flags |= AM65_CPSW_PRIV_P0_RX_PTYPE_RROBIN;
 
+	if (port->qos.cut_thru.enable)
+		priv_flags |= AM65_CPSW_PRIV_CUT_THRU;
 	return priv_flags;
 }
 
 static int am65_cpsw_set_ethtool_priv_flags(struct net_device *ndev, u32 flags)
 {
 	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
-	int rrobin;
+	struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
+	int rrobin, cut_thru;
 
 	rrobin = !!(flags & AM65_CPSW_PRIV_P0_RX_PTYPE_RROBIN);
+	cut_thru =  !!(flags & AM65_CPSW_PRIV_CUT_THRU);
 
 	if (common->usage_count)
 		return -EBUSY;
@@ -747,7 +754,18 @@
 		return -EINVAL;
 	}
 
+	if (cut_thru && !(common->pdata.quirks & AM64_CPSW_QUIRK_CUT_THRU)) {
+		netdev_err(ndev, "Cut-Thru not supported\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (cut_thru && common->is_emac_mode) {
+		netdev_err(ndev, "Enable switch mode for cut-thru\n");
+		return -EINVAL;
+	}
+
 	common->pf_p0_rx_ptype_rrobin = rrobin;
+	port->qos.cut_thru.enable = cut_thru;
 
 	return 0;
 }
diff -Naur --no-dereference a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c	2025-10-23 09:30:40.286462238 -0400
@@ -32,6 +32,7 @@
 #include <linux/dma/ti-cppi5.h>
 #include <linux/dma/k3-udma-glue.h>
 #include <net/page_pool/helpers.h>
+#include <net/dsa.h>
 #include <net/switchdev.h>
 
 #include "cpsw_ale.h"
@@ -71,6 +72,8 @@
 #define AM65_CPSW_PORT_REG_RX_PRI_MAP		0x020
 #define AM65_CPSW_PORT_REG_RX_MAXLEN		0x024
 
+#define AM65_CPSW_PORTN_REG_CTL			0x004
+#define AM65_CPSW_PORTN_REG_DSCP_MAP		0x120
 #define AM65_CPSW_PORTN_REG_SA_L		0x308
 #define AM65_CPSW_PORTN_REG_SA_H		0x30c
 #define AM65_CPSW_PORTN_REG_TS_CTL              0x310
@@ -94,6 +97,10 @@
 /* AM65_CPSW_PORT_REG_PRI_CTL */
 #define AM65_CPSW_PORT_REG_PRI_CTL_RX_PTYPE_RROBIN	BIT(8)
 
+/* AM65_CPSW_PN_REG_CTL */
+#define AM65_CPSW_PN_REG_CTL_DSCP_IPV4_EN	BIT(1)
+#define AM65_CPSW_PN_REG_CTL_DSCP_IPV6_EN	BIT(2)
+
 /* AM65_CPSW_PN_TS_CTL register fields */
 #define AM65_CPSW_PN_TS_CTL_TX_ANX_F_EN		BIT(4)
 #define AM65_CPSW_PN_TS_CTL_TX_VLAN_LT1_EN	BIT(5)
@@ -176,6 +183,99 @@
 	writel(mac_lo, slave->port_base + AM65_CPSW_PORTN_REG_SA_L);
 }
 
+#define AM65_CPSW_DSCP_MAX	GENMASK(5, 0)
+#define AM65_CPSW_PRI_MAX	GENMASK(2, 0)
+#define AM65_CPSW_DSCP_PRI_PER_REG	8
+#define AM65_CPSW_DSCP_PRI_SIZE		4	/* in bits */
+static int am65_cpsw_port_set_dscp_map(struct am65_cpsw_port *slave, u8 dscp, u8 pri)
+{
+	int reg_ofs;
+	int bit_ofs;
+	u32 val;
+
+	if (dscp > AM65_CPSW_DSCP_MAX)
+		return -EINVAL;
+
+	if (pri > AM65_CPSW_PRI_MAX)
+		return -EINVAL;
+
+	/* 32-bit register offset to this dscp */
+	reg_ofs = (dscp / AM65_CPSW_DSCP_PRI_PER_REG) * 4;
+	/* bit field offset to this dscp */
+	bit_ofs = AM65_CPSW_DSCP_PRI_SIZE * (dscp % AM65_CPSW_DSCP_PRI_PER_REG);
+
+	val = readl(slave->port_base + AM65_CPSW_PORTN_REG_DSCP_MAP + reg_ofs);
+	val &= ~(AM65_CPSW_PRI_MAX << bit_ofs);	/* clear */
+	val |= pri << bit_ofs;			/* set */
+	writel(val, slave->port_base + AM65_CPSW_PORTN_REG_DSCP_MAP + reg_ofs);
+
+	return 0;
+}
+
+static void am65_cpsw_port_enable_dscp_map(struct am65_cpsw_port *slave)
+{
+	int dscp, pri;
+	u32 val;
+
+	/* Default DSCP to User Priority mapping as per:
+	 * https://datatracker.ietf.org/doc/html/rfc8325#section-4.3
+	 * and
+	 * https://datatracker.ietf.org/doc/html/rfc8622#section-11
+	 */
+	for (dscp = 0; dscp <= AM65_CPSW_DSCP_MAX; dscp++) {
+		switch (dscp) {
+		case 56:	/* CS7 */
+		case 48:	/* CS6 */
+			pri = 7;
+			break;
+		case 46:	/* EF */
+		case 44:	/* VA */
+			pri = 6;
+			break;
+		case 40:	/* CS5 */
+			pri = 5;
+			break;
+		case 34:	/* AF41 */
+		case 36:	/* AF42 */
+		case 38:	/* AF43 */
+		case 32:	/* CS4 */
+		case 26:	/* AF31 */
+		case 28:	/* AF32 */
+		case 30:	/* AF33 */
+		case 24:	/* CS3 */
+			pri = 4;
+			break;
+		case 18:	/* AF21 */
+		case 20:	/* AF22 */
+		case 22:	/* AF23 */
+			pri = 3;
+			break;
+		case 16:	/* CS2 */
+		case 10:	/* AF11 */
+		case 12:	/* AF12 */
+		case 14:	/* AF13 */
+		case 0:		/* DF */
+			pri = 0;
+			break;
+		case 8:		/* CS1 */
+		case 1:		/* LE */
+			pri = 1;
+			break;
+		default:
+			pri = 0;
+			break;
+		}
+
+		am65_cpsw_port_set_dscp_map(slave, dscp, pri);
+	}
+
+	/* enable port IPV4 and IPV6 DSCP for this port */
+	val = readl(slave->port_base + AM65_CPSW_PORTN_REG_CTL);
+	val |= AM65_CPSW_PN_REG_CTL_DSCP_IPV4_EN |
+		AM65_CPSW_PN_REG_CTL_DSCP_IPV6_EN;
+	writel(val, slave->port_base + AM65_CPSW_PORTN_REG_CTL);
+}
+
 static void am65_cpsw_sl_ctl_reset(struct am65_cpsw_port *port)
 {
 	cpsw_sl_reset(port->slave.mac_sl, 100);
@@ -290,7 +390,7 @@
 	cpsw_ale_set_allmulti(common->ale,
 			      ndev->flags & IFF_ALLMULTI, port->port_id);
 
-	port_mask = ALE_PORT_HOST;
+	port_mask = BIT(port->port_id) | ALE_PORT_HOST;
 	/* Clear all mcast from ALE */
 	cpsw_ale_flush_multicast(common->ale, port_mask, -1);
 
@@ -612,7 +712,7 @@
 {
 	struct sk_buff *skb;
 
-	len += AM65_CPSW_HEADROOM;
+	len += AM65_CPSW_HEADROOM + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 
 	skb = build_skb(page_addr, len);
 	if (unlikely(!skb))
@@ -672,7 +772,7 @@
 			     ALE_DEFAULT_THREAD_ID, 0);
 	cpsw_ale_control_set(common->ale, HOST_PORT_NUM,
 			     ALE_DEFAULT_THREAD_ENABLE, 1);
-	/* switch to vlan unaware mode */
+	/* switch to vlan aware mode */
 	cpsw_ale_control_set(common->ale, HOST_PORT_NUM, ALE_VLAN_AWARE, 1);
 	cpsw_ale_control_set(common->ale, HOST_PORT_NUM,
 			     ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
@@ -853,6 +953,7 @@
 
 	phylink_disconnect_phy(port->slave.phylink);
 
+	am65_cpsw_qos_cut_thru_cleanup(port);
 	ret = am65_cpsw_nuss_common_stop(common);
 	if (ret)
 		return ret;
@@ -924,7 +1025,17 @@
 
 	common->usage_count++;
 
+	/* VLAN aware CPSW mode is incompatible with some DSA tagging schemes.
+	 * Therefore disable VLAN_AWARE mode if any of the ports is a DSA Port.
+	 */
+	if (netdev_uses_dsa(ndev)) {
+		reg = readl(common->cpsw_base + AM65_CPSW_REG_CTL);
+		reg &= ~AM65_CPSW_CTL_VLAN_AWARE;
+		writel(reg, common->cpsw_base + AM65_CPSW_REG_CTL);
+	}
+
 	am65_cpsw_port_set_sl_mac(port, ndev->dev_addr);
+	am65_cpsw_port_enable_dscp_map(port);
 
 	if (common->is_emac_mode)
 		am65_cpsw_init_port_emac_ale(port);
@@ -941,6 +1052,7 @@
 	/* restore vlan configurations */
 	vlan_for_each(ndev, cpsw_restore_vlans, port);
 
+	am65_cpsw_qos_cut_thru_init(port);
 	phylink_start(port->slave.phylink);
 
 	return 0;
@@ -2162,7 +2274,7 @@
 	/* enable forwarding */
 	cpsw_ale_control_set(common->ale, port->port_id, ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
 
-	am65_cpsw_qos_link_up(ndev, speed);
+	am65_cpsw_qos_link_up(ndev, speed, duplex);
 	netif_tx_wake_all_queues(ndev);
 }
 
@@ -2194,6 +2306,8 @@
 	for (i = 0; i < common->tx_ch_num; i++) {
 		struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i];
 
+		irq_set_affinity_hint(tx_chn->irq, NULL);
+
 		if (!IS_ERR_OR_NULL(tx_chn->desc_pool))
 			k3_cppi_desc_pool_destroy(tx_chn->desc_pool);
 
@@ -2213,8 +2327,10 @@
 	for (i = 0; i < common->tx_ch_num; i++) {
 		struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i];
 
-		if (tx_chn->irq > 0)
+		if (tx_chn->irq > 0) {
+			irq_set_affinity_hint(tx_chn->irq, NULL);
 			devm_free_irq(dev, tx_chn->irq, tx_chn);
+		}
 
 		netif_napi_del(&tx_chn->napi_tx);
 	}
@@ -2246,6 +2362,7 @@
 				tx_chn->id, tx_chn->irq, ret);
 			goto err;
 		}
+		irq_set_affinity_hint(tx_chn->irq, get_cpu_mask(i % num_online_cpus()));
 	}
 
 	return 0;
@@ -2254,6 +2371,7 @@
 	netif_napi_del(&tx_chn->napi_tx);
 	for (--i; i >= 0; i--) {
 		tx_chn = &common->tx_chns[i];
+		irq_set_affinity_hint(tx_chn->irq, NULL);
 		devm_free_irq(dev, tx_chn->irq, tx_chn);
 		netif_napi_del(&tx_chn->napi_tx);
 	}
@@ -2350,8 +2468,14 @@
 {
 	struct am65_cpsw_common *common = data;
 	struct am65_cpsw_rx_chn *rx_chn;
+	struct am65_cpsw_rx_flow *flows;
+	int i;
 
 	rx_chn = &common->rx_chns;
+	flows = rx_chn->flows;
+
+	for (i = 0; i < common->rx_ch_num_flows; i++)
+		irq_set_affinity_hint(flows[i].irq, NULL);
 
 	if (!IS_ERR_OR_NULL(rx_chn->desc_pool))
 		k3_cppi_desc_pool_destroy(rx_chn->desc_pool);
@@ -2371,8 +2495,11 @@
 	flows = rx_chn->flows;
 
 	for (i = 0; i < common->rx_ch_num_flows; i++) {
-		if (!(flows[i].irq < 0))
+		if (!(flows[i].irq < 0)) {
+			irq_set_affinity_hint(flows[i].irq, NULL);
 			devm_free_irq(dev, flows[i].irq, &flows[i]);
+		}
+
 		netif_napi_del(&flows[i].napi_rx);
 	}
 
@@ -2502,6 +2629,8 @@
 			flow->irq = -EINVAL;
 			goto err_request_irq;
 		}
+
+		irq_set_affinity_hint(flow->irq, get_cpu_mask(cpumask_first(cpu_present_mask)));
 	}
 
 	/* setup classifier to route priorities to flows */
@@ -2515,6 +2644,7 @@
 err_flow:
 	for (--i; i >= 0; i--) {
 		flow = &rx_chn->flows[i];
+		irq_set_affinity_hint(flow->irq, NULL);
 		devm_free_irq(dev, flow->irq, flow);
 		netif_napi_del(&flow->napi_rx);
 	}
@@ -3234,8 +3364,10 @@
 
 			port = am65_ndev_to_port(sl_ndev);
 			port->slave.port_vlan = 0;
-			if (netif_running(sl_ndev))
+			if (netif_running(sl_ndev)) {
 				am65_cpsw_init_port_emac_ale(port);
+				am65_cpsw_qos_cut_thru_cleanup(port);
+			}
 		}
 	}
 	cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_BYPASS, 0);
@@ -3384,6 +3516,10 @@
 	for (i = 0; i < common->port_num; i++) {
 		port = &common->ports[i];
 
+		ret = am65_cpsw_nuss_register_port_debugfs(port);
+		if (ret)
+			goto err_cleanup_ndev;
+
 		if (!port->ndev)
 			continue;
 
@@ -3468,7 +3604,7 @@
 };
 
 static const struct am65_cpsw_pdata am64x_cpswxg_pdata = {
-	.quirks = AM64_CPSW_QUIRK_DMA_RX_TDOWN_IRQ,
+	.quirks = AM64_CPSW_QUIRK_DMA_RX_TDOWN_IRQ | AM64_CPSW_QUIRK_CUT_THRU,
 	.ale_dev_id = "am64-cpswxg",
 	.fdqring_mode = K3_RINGACC_RING_MODE_RING,
 };
@@ -3477,7 +3613,8 @@
 	.quirks = 0,
 	.ale_dev_id = "am64-cpswxg",
 	.fdqring_mode = K3_RINGACC_RING_MODE_RING,
-	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII),
+	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
+		       BIT(PHY_INTERFACE_MODE_USXGMII),
 };
 
 static const struct am65_cpsw_pdata j721e_cpswxg_pdata = {
@@ -3647,10 +3784,16 @@
 	if (ret)
 		goto err_ndevs_clear;
 
-	ret = am65_cpsw_nuss_register_ndevs(common);
+	ret = am65_cpsw_nuss_register_debugfs(common);
 	if (ret)
 		goto err_ndevs_clear;
 
+	ret = am65_cpsw_nuss_register_ndevs(common);
+	if (ret) {
+		am65_cpsw_nuss_unregister_debugfs(common);
+		goto err_ndevs_clear;
+	}
+
 	pm_runtime_put(dev);
 	return 0;
 
diff -Naur --no-dereference a/drivers/net/ethernet/ti/am65-cpsw-nuss.h b/drivers/net/ethernet/ti/am65-cpsw-nuss.h
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.h	2025-10-23 09:30:40.286462238 -0400
@@ -6,6 +6,7 @@
 #ifndef AM65_CPSW_NUSS_H_
 #define AM65_CPSW_NUSS_H_
 
+#include <linux/debugfs.h>
 #include <linux/if_ether.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -55,6 +56,7 @@
 	bool				rx_ts_enabled;
 	struct am65_cpsw_qos		qos;
 	struct devlink_port		devlink_port;
+	struct dentry			*debugfs_port;
 	struct bpf_prog			*xdp_prog;
 	struct xdp_rxq_info		xdp_rxq[AM65_CPSW_MAX_QUEUES];
 	/* Only for suspend resume context */
@@ -121,6 +123,7 @@
 
 #define AM65_CPSW_QUIRK_I2027_NO_TX_CSUM BIT(0)
 #define AM64_CPSW_QUIRK_DMA_RX_TDOWN_IRQ BIT(1)
+#define AM64_CPSW_QUIRK_CUT_THRU	 BIT(2)
 
 struct am65_cpsw_pdata {
 	u32	quirks;
@@ -172,6 +175,7 @@
 	struct am65_cpts	*cpts;
 	int			est_enabled;
 	bool			iet_enabled;
+	unsigned int		cut_thru_enabled;
 
 	bool		is_emac_mode;
 	u16			br_members;
@@ -180,6 +184,8 @@
 	struct net_device *hw_bridge_dev;
 	struct notifier_block am65_cpsw_netdevice_nb;
 	unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN];
+
+	struct dentry		*debugfs_root;
 	/* only for suspend/resume context restore */
 	u32			*ale_context;
 };
@@ -229,4 +235,8 @@
 
 bool am65_cpsw_port_dev_check(const struct net_device *dev);
 
+int am65_cpsw_nuss_register_port_debugfs(struct am65_cpsw_port *port);
+int am65_cpsw_nuss_register_debugfs(struct am65_cpsw_common *common);
+void am65_cpsw_nuss_unregister_debugfs(struct am65_cpsw_common *common);
+
 #endif /* AM65_CPSW_NUSS_H_ */
diff -Naur --no-dereference a/drivers/net/ethernet/ti/am65-cpsw-qos.c b/drivers/net/ethernet/ti/am65-cpsw-qos.c
--- a/drivers/net/ethernet/ti/am65-cpsw-qos.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/am65-cpsw-qos.c	2025-10-23 09:30:40.286462238 -0400
@@ -7,6 +7,7 @@
  * Interspersed Express Traffic (IET - P802.3br/D2.0)
  */
 
+#include <linux/bitfield.h>
 #include <linux/pm_runtime.h>
 #include <linux/math.h>
 #include <linux/math64.h>
@@ -19,6 +20,23 @@
 #include "am65-cpts.h"
 #include "cpsw_ale.h"
 
+#define AM65_CPSW_REG_FREQ			0x05c
+
+#define AM64_CPSW_PN_CUT_THRU			0x3C0
+#define AM64_CPSW_PN_SPEED			0x3C4
+
+/* AM65_CPSW_REG_CTL register fields */
+#define AM64_CPSW_CTL_CUT_THRU_EN		BIT(19)
+
+/* Cut-Thru AM64_CPSW_PN_CUT_THRU */
+#define  AM64_PN_CUT_THRU_TX_PRI		GENMASK(7, 0)
+#define  AM64_PN_CUT_THRU_RX_PRI		GENMASK(15, 8)
+
+/* Cut-Thru AM64_CPSW_PN_SPEED */
+#define  AM64_PN_SPEED_VAL			GENMASK(3, 0)
+#define  AM64_PN_SPEED_AUTO_EN			BIT(8)
+#define  AM64_PN_AUTO_SPEED			GENMASK(15, 12)
+
 #define TO_MBPS(x)	DIV_ROUND_UP((x), BYTES_PER_MBIT)
 
 enum timer_act {
@@ -27,6 +45,9 @@
 	TACT_SKIP_PROG,		/* just buffer can be updated */
 };
 
+/* number of traffic classes (fifos) per port */
+#define AM65_CPSW_PN_TC_NUM			8
+
 static void am65_cpsw_iet_change_preemptible_tcs(struct am65_cpsw_port *port, u8 preemptible_tcs);
 
 static u32
@@ -1295,13 +1316,92 @@
 	}
 }
 
-void am65_cpsw_qos_link_up(struct net_device *ndev, int link_speed)
+static void am65_cpsw_cut_thru_dump(struct am65_cpsw_port *port)
+{
+	struct am65_cpsw_common *common = port->common;
+	u32 contro, cut_thru, speed;
+
+	contro = readl(common->cpsw_base + AM65_CPSW_REG_CTL);
+	cut_thru = readl(port->port_base + AM64_CPSW_PN_CUT_THRU);
+	speed = readl(port->port_base + AM64_CPSW_PN_SPEED);
+	dev_dbg(common->dev,
+		"Port%u: cut_thru dump control:%08x cut_thru:%08x hwspeed:%08x\n",
+		port->port_id, contro, cut_thru, speed);
+}
+
+static u32 am65_cpsw_cut_thru_speed2hw(int link_speed)
+{
+	switch (link_speed) {
+	case SPEED_10:
+		return 1;
+	case SPEED_100:
+		return 2;
+	case SPEED_1000:
+		return 3;
+	default:
+		return 0;
+	}
+}
+
+static void am65_cpsw_cut_thru_link_up(struct am65_cpsw_port *port)
+{
+	struct am65_cpsw_cut_thru *cut_thru = &port->qos.cut_thru;
+	struct am65_cpsw_common *common = port->common;
+	u32 val, speed;
+
+	if (!cut_thru->enable)
+		return;
+
+	writel(AM64_PN_SPEED_AUTO_EN, port->port_base + AM64_CPSW_PN_SPEED);
+	/* barrier */
+	readl(port->port_base + AM64_CPSW_PN_SPEED);
+	/* HW need 15us in 10/100 mode and 3us in 1G mode auto speed detection
+	 * add delay with some margin
+	 */
+	usleep_range(40, 50);
+	val = readl(port->port_base + AM64_CPSW_PN_SPEED);
+	speed = FIELD_GET(AM64_PN_AUTO_SPEED, val);
+	if (!speed) {
+		dev_warn(common->dev,
+			 "Port%u: cut_thru no speed auto detected switch to manual\n",
+			 port->port_id);
+		speed = am65_cpsw_cut_thru_speed2hw(port->qos.link_speed);
+		if (!speed) {
+			dev_err(common->dev,
+				"Port%u: cut_thru speed configuration failed\n",
+				port->port_id);
+			return;
+		}
+		val = FIELD_PREP(AM64_PN_SPEED_VAL, speed);
+		writel(val, port->port_base + AM64_CPSW_PN_SPEED);
+	}
+
+	val = FIELD_PREP(AM64_PN_CUT_THRU_TX_PRI, cut_thru->tx_pri_mask) |
+	      FIELD_PREP(AM64_PN_CUT_THRU_RX_PRI, cut_thru->rx_pri_mask);
+
+	if (port->qos.duplex) {
+		writel(val, port->port_base + AM64_CPSW_PN_CUT_THRU);
+		dev_info(common->dev, "Port%u: Enable cut_thru rx:%08x tx:%08x hwspeed:%u (%08x)\n",
+			 port->port_id,
+			 cut_thru->rx_pri_mask, cut_thru->tx_pri_mask,
+			 speed, val);
+	} else {
+		writel(0, port->port_base + AM64_CPSW_PN_CUT_THRU);
+		dev_info(common->dev, "Port%u: Disable cut_thru duplex=%d\n",
+			 port->port_id, port->qos.duplex);
+	}
+	am65_cpsw_cut_thru_dump(port);
+}
+
+void am65_cpsw_qos_link_up(struct net_device *ndev, int link_speed, int duplex)
 {
 	struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
 
 	port->qos.link_speed = link_speed;
+	port->qos.duplex = duplex;
 	am65_cpsw_tx_pn_shaper_apply(port);
 	am65_cpsw_iet_link_state_update(ndev);
+	am65_cpsw_cut_thru_link_up(port);
 
 	am65_cpsw_est_link_up(ndev, link_speed);
 	port->qos.link_down_time = 0;
@@ -1318,3 +1418,73 @@
 	if (!port->qos.link_down_time)
 		port->qos.link_down_time = ktime_get();
 }
+
+static void am65_cpsw_cut_thru_enable(struct am65_cpsw_common *common)
+{
+	u32 val;
+
+	if (common->cut_thru_enabled) {
+		common->cut_thru_enabled++;
+		return;
+	}
+
+	/* Populate CPSW VBUS freq for auto speed detection */
+	writel(common->bus_freq / 1000000,
+	       common->cpsw_base + AM65_CPSW_REG_FREQ);
+
+	val = readl(common->cpsw_base + AM65_CPSW_REG_CTL);
+	val |= AM64_CPSW_CTL_CUT_THRU_EN;
+	writel(val, common->cpsw_base + AM65_CPSW_REG_CTL);
+	common->cut_thru_enabled++;
+}
+
+void am65_cpsw_qos_cut_thru_init(struct am65_cpsw_port *port)
+{
+	struct am65_cpsw_cut_thru *cut_thru = &port->qos.cut_thru;
+	struct am65_cpsw_common *common = port->common;
+
+	/* Enable cut_thr only if user has enabled priv flag */
+	if (!cut_thru->enable)
+		return;
+
+	if (common->is_emac_mode) {
+		cut_thru->enable = false;
+		dev_info(common->dev, "Disable cut-thru, need Switch mode\n");
+		return;
+	}
+
+	am65_cpsw_cut_thru_enable(common);
+
+	/* en auto speed */
+	writel(AM64_PN_SPEED_AUTO_EN, port->port_base + AM64_CPSW_PN_SPEED);
+	dev_info(common->dev, "Init cut_thru\n");
+	am65_cpsw_cut_thru_dump(port);
+}
+
+static void am65_cpsw_cut_thru_disable(struct am65_cpsw_common *common)
+{
+	u32 val;
+
+	if (--common->cut_thru_enabled)
+		return;
+
+	val = readl(common->cpsw_base + AM65_CPSW_REG_CTL);
+	val &= ~AM64_CPSW_CTL_CUT_THRU_EN;
+	writel(val, common->cpsw_base + AM65_CPSW_REG_CTL);
+}
+
+void am65_cpsw_qos_cut_thru_cleanup(struct am65_cpsw_port *port)
+{
+	struct am65_cpsw_cut_thru *cut_thru = &port->qos.cut_thru;
+	struct am65_cpsw_common *common = port->common;
+
+	if (!cut_thru->enable)
+		return;
+
+	writel(0, port->port_base + AM64_CPSW_PN_CUT_THRU);
+	writel(0, port->port_base + AM64_CPSW_PN_SPEED);
+
+	am65_cpsw_cut_thru_disable(common);
+	dev_info(common->dev, "Cleanup cut_thru\n");
+	am65_cpsw_cut_thru_dump(port);
+}
diff -Naur --no-dereference a/drivers/net/ethernet/ti/am65-cpsw-qos.h b/drivers/net/ethernet/ti/am65-cpsw-qos.h
--- a/drivers/net/ethernet/ti/am65-cpsw-qos.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/am65-cpsw-qos.h	2025-10-23 09:30:40.286462238 -0400
@@ -34,13 +34,21 @@
 	u64 rate_packet_ps;
 };
 
+struct am65_cpsw_cut_thru {
+	unsigned int rx_pri_mask;
+	unsigned int tx_pri_mask;
+	bool enable;
+};
+
 struct am65_cpsw_qos {
 	struct am65_cpsw_est *est_admin;
 	struct am65_cpsw_est *est_oper;
 	ktime_t link_down_time;
 	int link_speed;
+	int duplex;
 	struct am65_cpsw_mqprio mqprio;
 	struct am65_cpsw_iet iet;
+	struct am65_cpsw_cut_thru cut_thru;
 
 	struct am65_cpsw_ale_ratelimit ale_bc_ratelimit;
 	struct am65_cpsw_ale_ratelimit ale_mc_ratelimit;
@@ -96,8 +104,10 @@
 #if IS_ENABLED(CONFIG_TI_AM65_CPSW_QOS)
 int am65_cpsw_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type,
 			       void *type_data);
-void am65_cpsw_qos_link_up(struct net_device *ndev, int link_speed);
+void am65_cpsw_qos_link_up(struct net_device *ndev, int link_speed, int duplex);
 void am65_cpsw_qos_link_down(struct net_device *ndev);
+void am65_cpsw_qos_cut_thru_init(struct am65_cpsw_port *port);
+void am65_cpsw_qos_cut_thru_cleanup(struct am65_cpsw_port *port);
 int am65_cpsw_qos_ndo_tx_p0_set_maxrate(struct net_device *ndev, int queue, u32 rate_mbps);
 void am65_cpsw_qos_tx_p0_rate_init(struct am65_cpsw_common *common);
 void am65_cpsw_iet_commit_preemptible_tcs(struct am65_cpsw_port *port);
@@ -111,12 +121,18 @@
 }
 
 static inline void am65_cpsw_qos_link_up(struct net_device *ndev,
-					 int link_speed)
+					 int link_speed, int duplex)
 { }
 
 static inline void am65_cpsw_qos_link_down(struct net_device *ndev)
 { }
 
+static inline void am65_cpsw_qos_cut_thru_init(struct am65_cpsw_port *port)
+{ }
+
+static inline void am65_cpsw_qos_cut_thru_cleanup(struct am65_cpsw_port *port)
+{ }
+
 static inline int am65_cpsw_qos_ndo_tx_p0_set_maxrate(struct net_device *ndev,
 						      int queue,
 						      u32 rate_mbps)
diff -Naur --no-dereference a/drivers/net/ethernet/ti/am65-debugfs.c b/drivers/net/ethernet/ti/am65-debugfs.c
--- a/drivers/net/ethernet/ti/am65-debugfs.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/ethernet/ti/am65-debugfs.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Texas Instruments K3 AM65 Ethernet debugfs submodule
+ * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include <linux/bitfield.h>
+#include <linux/debugfs.h>
+
+#include "am65-cpsw-nuss.h"
+
+int am65_cpsw_nuss_register_debugfs(struct am65_cpsw_common *common)
+{
+	common->debugfs_root = debugfs_create_dir(dev_name(common->dev), NULL);
+	if (IS_ERR(common->debugfs_root))
+		return PTR_ERR(common->debugfs_root);
+
+	return 0;
+}
+
+void am65_cpsw_nuss_unregister_debugfs(struct am65_cpsw_common *common)
+{
+	debugfs_remove_recursive(common->debugfs_root);
+}
+
+static int
+cut_thru_tx_pri_mask_get(void *data, u64 *val)
+{
+	struct am65_cpsw_port *port = data;
+	struct am65_cpsw_cut_thru *cut_thru;
+	int ret = -EINVAL;
+
+	rtnl_lock();
+	cut_thru = &port->qos.cut_thru;
+	if (port->ndev->reg_state == NETREG_REGISTERED) {
+		*val =  cut_thru->tx_pri_mask;
+		ret = 0;
+	}
+	rtnl_unlock();
+
+	return ret;
+}
+
+static int
+cut_thru_tx_pri_mask_set(void *data, u64 val)
+{
+	struct am65_cpsw_cut_thru *cut_thru;
+	struct am65_cpsw_port *port = data;
+	struct am65_cpsw_common *common;
+	int ret = 0;
+
+	if (val & ~GENMASK(7, 0))
+		return -EINVAL;
+
+	if (!rtnl_trylock())
+		return restart_syscall();
+
+	common = port->common;
+	cut_thru = &port->qos.cut_thru;
+
+	if (cut_thru->enable) {
+		dev_err(common->dev, "Port%u: can't set cut-thru tx_pri_mask while cut-thru enabled\n",
+			port->port_id);
+		ret = -EINVAL;
+		goto err;
+	}
+	cut_thru->tx_pri_mask = val;
+
+err:
+	rtnl_unlock();
+	return ret;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_cut_thru_tx_pri_mask, cut_thru_tx_pri_mask_get,
+			 cut_thru_tx_pri_mask_set, "%llx\n");
+
+static int
+cut_thru_rx_pri_mask_get(void *data, u64 *val)
+{
+	struct am65_cpsw_port *port = data;
+	struct am65_cpsw_cut_thru *cut_thru;
+	int ret = -EINVAL;
+
+	rtnl_lock();
+	cut_thru = &port->qos.cut_thru;
+	if (port->ndev->reg_state == NETREG_REGISTERED) {
+		*val =  cut_thru->rx_pri_mask;
+		ret = 0;
+	}
+	rtnl_unlock();
+
+	return ret;
+}
+
+static int
+cut_thru_rx_pri_mask_set(void *data, u64 val)
+{
+	struct am65_cpsw_cut_thru *cut_thru;
+	struct am65_cpsw_port *port = data;
+	struct am65_cpsw_common *common;
+	int ret = 0;
+
+	if (val & ~GENMASK(7, 0))
+		return -EINVAL;
+
+	if (!rtnl_trylock())
+		return restart_syscall();
+
+	common = port->common;
+	cut_thru = &port->qos.cut_thru;
+
+	if (cut_thru->enable) {
+		dev_err(common->dev, "Port%u: can't set cut-thru rx_pri_mask while cut-thru enabled\n",
+			port->port_id);
+		ret = -EINVAL;
+		goto err;
+	}
+	cut_thru->rx_pri_mask = val;
+
+err:
+	rtnl_unlock();
+	return ret;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_cut_thru_rx_pri_mask, cut_thru_rx_pri_mask_get,
+			 cut_thru_rx_pri_mask_set, "%llx\n");
+
+int am65_cpsw_nuss_register_port_debugfs(struct am65_cpsw_port *port)
+{
+	struct am65_cpsw_common *common = port->common;
+	char dirn[32];
+
+	scnprintf(dirn, sizeof(dirn), "Port%x", port->port_id);
+	port->debugfs_port = debugfs_create_dir(dirn, common->debugfs_root);
+	if (IS_ERR(port->debugfs_port))
+		return PTR_ERR(port->debugfs_port);
+
+	debugfs_create_bool("disabled", 0400,
+			    port->debugfs_port, &port->disabled);
+	if (port->disabled)
+		return 0;
+
+	if (common->pdata.quirks & AM64_CPSW_QUIRK_CUT_THRU) {
+		debugfs_create_file("cut_thru_tx_pri_mask", 0600,
+				    port->debugfs_port,
+				    port, &fops_cut_thru_tx_pri_mask);
+		debugfs_create_file("cut_thru_rx_pri_mask", 0600,
+				    port->debugfs_port,
+				    port, &fops_cut_thru_rx_pri_mask);
+	}
+
+	return 0;
+}
diff -Naur --no-dereference a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
--- a/drivers/net/ethernet/ti/cpsw_ale.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/cpsw_ale.c	2025-10-23 09:30:40.286462238 -0400
@@ -443,14 +443,13 @@
 				      ale->port_mask_bits);
 	if ((mask & port_mask) == 0)
 		return; /* ports dont intersect, not interested */
-	mask &= ~port_mask;
+	mask &= (~port_mask | ALE_PORT_HOST);
 
-	/* free if only remaining port is host port */
-	if (mask)
+	if (mask == 0x0 || mask == ALE_PORT_HOST)
+		cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
+	else
 		cpsw_ale_set_port_mask(ale_entry, mask,
 				       ale->port_mask_bits);
-	else
-		cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
 }
 
 int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid)
diff -Naur --no-dereference a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
--- a/drivers/net/ethernet/ti/cpsw.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/cpsw.c	2025-10-23 09:30:40.286462238 -0400
@@ -684,7 +684,7 @@
 	soft_reset("cpsw", &cpsw->regs->soft_reset);
 	cpsw_ale_start(cpsw->ale);
 
-	/* switch to vlan unaware mode */
+	/* switch to vlan aware mode */
 	cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_VLAN_AWARE,
 			     CPSW_ALE_VLAN_AWARE);
 	control_reg = readl(&cpsw->regs->control);
diff -Naur --no-dereference a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c
--- a/drivers/net/ethernet/ti/cpsw_new.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/cpsw_new.c	2025-10-23 09:30:40.286462238 -0400
@@ -554,7 +554,7 @@
 	soft_reset("cpsw", &cpsw->regs->soft_reset);
 	cpsw_ale_start(cpsw->ale);
 
-	/* switch to vlan unaware mode */
+	/* switch to vlan aware mode */
 	cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_VLAN_AWARE,
 			     CPSW_ALE_VLAN_AWARE);
 	control_reg = readl(&cpsw->regs->control);
diff -Naur --no-dereference a/drivers/net/ethernet/ti/cpsw-proxy-client.c b/drivers/net/ethernet/ti/cpsw-proxy-client.c
--- a/drivers/net/ethernet/ti/cpsw-proxy-client.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/ethernet/ti/cpsw-proxy-client.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,2652 @@
+// SPDX-License-Identifier: GPL-2.0-only or MIT
+/* Texas Instruments CPSW Proxy Client Driver
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/inetdevice.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/kmemleak.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/rpmsg.h>
+#include <linux/sys_soc.h>
+#include <linux/dma/k3-udma-glue.h>
+
+#include "ethfw_abi.h"
+#include "k3-cppi-desc-pool.h"
+
+#define ETHFW_RESPONSE_TIMEOUT_MS	500
+
+#define PS_DATA_SIZE	16
+#define SW_DATA_SIZE	16
+
+#define MAX_TX_DESC	500
+#define MAX_RX_DESC	500
+#define MAX_RX_FLOWS	1
+
+#define MIN_PACKET_SIZE	ETH_ZLEN
+#define MAX_PACKET_SIZE	(VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)
+
+#define MAX_VLAN_ID	4096
+
+#define CHAN_NAME_LEN	128
+
+enum virtual_port_type {
+	VIRT_SWITCH_PORT,
+	VIRT_MAC_ONLY_PORT,
+};
+
+struct cpsw_proxy_req_params {
+	struct message	req_msg;	/* Request message to be filled */
+	u32		token;
+	u32		client_id;
+	u32		request_id;
+	u32		request_type;
+	u32		rx_tx_idx; /* RX or TX Channel index */
+	u32		rx_flow_base; /* RX DMA Flow base */
+	u32		rx_flow_offset; /* RX DMA Flow offset */
+	u32		tx_thread_id; /* PSI-L Thread ID of TX Channel */
+	u32		port_id; /* Virtual Port ID */
+	u16		vlan_id;
+	u8		mac_addr[ETH_ALEN];
+	u8		ipv4_addr[ETHFW_IPV4ADDRLEN];
+};
+
+struct rx_dma_chan {
+	struct virtual_port		*vport;
+	struct device			*dev;
+	struct device			*dma_dev;
+	struct k3_cppi_desc_pool	*desc_pool;
+	struct k3_udma_glue_rx_channel	*rx_chan;
+	struct napi_struct		napi_rx;
+	struct hrtimer			rx_hrtimer;
+	u32				rel_chan_idx;
+	u32				flow_base;
+	u32				flow_offset;
+	u32				thread_id;
+	u32				num_descs;
+	unsigned int			irq;
+	unsigned long			rx_pace_timeout;
+	char				rx_chan_name[CHAN_NAME_LEN];
+	bool				rx_irq_disabled;
+	bool				in_use;
+};
+
+struct tx_dma_chan {
+	struct virtual_port		*vport;
+	struct device			*dev;
+	struct device			*dma_dev;
+	struct k3_cppi_desc_pool	*desc_pool;
+	struct k3_udma_glue_tx_channel	*tx_chan;
+	struct napi_struct		napi_tx;
+	struct hrtimer			tx_hrtimer;
+	u32				rel_chan_idx;
+	u32				thread_id;
+	u32				num_descs;
+	unsigned int			irq;
+	unsigned long			tx_pace_timeout;
+	char				tx_chan_name[CHAN_NAME_LEN];
+	bool				in_use;
+};
+
+struct vport_netdev_stats {
+	u64			tx_packets;
+	u64			tx_bytes;
+	u64			rx_packets;
+	u64			rx_bytes;
+	struct u64_stats_sync	syncp;
+};
+
+struct vport_netdev_priv {
+	struct vport_netdev_stats __percpu	*stats;
+	struct virtual_port			*vport;
+};
+
+struct virtual_port {
+	struct cpsw_proxy_priv		*proxy_priv;
+	struct net_device		*ndev;
+	struct rx_dma_chan		*rx_chans;
+	struct tx_dma_chan		*tx_chans;
+	struct netdev_hw_addr_list	mcast_list;
+	struct netdev_hw_addr_list	vlan_mcast_list[MAX_VLAN_ID];
+	struct workqueue_struct		*vport_wq;
+	struct work_struct		rx_mode_work;
+	struct completion		tdown_complete;
+	struct notifier_block		inetaddr_nb;
+	enum virtual_port_type		port_type;
+	atomic_t			tdown_cnt;
+	u32				port_id;
+	u32				port_token;
+	u32				port_features;
+	u32				num_rx_chan;
+	u32				num_tx_chan;
+	u8				ipv4_addr[ETHFW_IPV4ADDRLEN];
+	u8				mac_addr[ETH_ALEN];
+	bool				mac_in_use;
+};
+
+struct cpsw_proxy_priv {
+	struct rpmsg_device		*rpdev;
+	struct device			*dev;
+	struct device_node		*dma_node;
+	struct virtual_port		*virt_ports;
+	struct cpsw_proxy_req_params	req_params;
+	struct mutex			req_params_mutex; /* Request params mutex */
+	struct message			resp_msg;
+	struct completion		wait_for_response;
+	int				resp_msg_len;
+	u32				vswitch_ports; /* Bitmask of Virtual Switch Port IDs */
+	u32				vmac_ports /* Bitmask of Virtual MAC Only Port IDs */;
+	u32				num_switch_ports;
+	u32				num_mac_ports;
+	u32				num_virt_ports;
+	u32				num_active_tx_chans;
+	u32				num_active_rx_chans;
+};
+
+#define vport_netdev_to_priv(ndev) \
+	((struct vport_netdev_priv *)netdev_priv(ndev))
+#define vport_ndev_to_vport(ndev) \
+	(vport_netdev_to_priv(ndev)->vport)
+
+static int send_request_get_response(struct cpsw_proxy_priv *proxy_priv,
+				     struct message *response);
+static int server_recovery_handler(void *data)
+{
+	struct virtual_port *vport = (struct virtual_port *)data;
+	struct net_device *ndev;
+
+	ndev = vport->ndev;
+	netif_device_attach(ndev);
+	if (!netif_running(ndev)) {
+		rtnl_lock();
+		dev_open(ndev, NULL);
+		rtnl_unlock();
+	}
+
+	return 0;
+}
+
+static int server_error_handler(void *data)
+{
+	struct virtual_port *vport = (struct virtual_port *)data;
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	struct cpsw_proxy_req_params *req_p;
+	struct net_device *ndev;
+	struct message resp_msg;
+	int ret;
+
+	ndev = vport->ndev;
+	netif_device_detach(ndev);
+	if (netif_running(ndev)) {
+		rtnl_lock();
+		dev_close(ndev);
+		rtnl_unlock();
+	}
+
+	mutex_lock(&proxy_priv->req_params_mutex);
+	req_p = &proxy_priv->req_params;
+	req_p->request_type = ETHFW_TEARDOWN_COMPLETE;
+	req_p->token = vport->port_token;
+	ret = send_request_get_response(proxy_priv, &resp_msg);
+	mutex_unlock(&proxy_priv->req_params_mutex);
+
+	if (ret) {
+		dev_err(proxy_priv->dev,
+			"Virt Port: %u teardown completion notify err: %d\n",
+			vport->port_id, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct virtual_port *vport_from_token(struct cpsw_proxy_priv *proxy_priv, u32 token)
+{
+	struct virtual_port *vport;
+	u32 i;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+
+		if (vport->port_token == token)
+			return vport;
+	}
+
+	return NULL;
+}
+
+static int cpsw_proxy_client_cb(struct rpmsg_device *rpdev, void *data,
+				int len, void *priv, u32 src)
+{
+	struct cpsw_proxy_priv *proxy_priv = dev_get_drvdata(&rpdev->dev);
+	struct response_message_header *resp_msg_hdr;
+	struct notify_message_header *notify_msg_hdr;
+	struct message *msg = (struct message *)data;
+	struct task_struct *server_notify_handler;
+	struct cpsw_proxy_req_params *req_params;
+	struct device *dev = &rpdev->dev;
+	struct virtual_port *vport;
+	u32 notify_type, token;
+	u32 msg_type, resp_id;
+
+	dev_dbg(dev, "callback invoked\n");
+	msg_type = msg->msg_hdr.msg_type;
+	switch (msg_type) {
+	case ETHFW_MSG_NOTIFY:
+		notify_msg_hdr = (struct notify_message_header *)msg;
+		notify_type = notify_msg_hdr->notify_type;
+		token = notify_msg_hdr->msg_hdr.token;
+		vport = vport_from_token(proxy_priv, token);
+		if (!vport) {
+			dev_err(dev, "invalid notification received\n");
+			return -EIO;
+		}
+
+		switch (notify_type) {
+		case ETHFW_NOTIFYCLIENT_HWERROR:
+			server_notify_handler = kthread_run(&server_error_handler, vport,
+							    "hwerr_handler");
+			if (IS_ERR(server_notify_handler))
+				return PTR_ERR(server_notify_handler);
+			return 0;
+
+		case ETHFW_NOTIFYCLIENT_RECOVERED:
+			server_notify_handler = kthread_run(&server_recovery_handler, vport,
+							    "recovery_handler");
+			if (IS_ERR(server_notify_handler))
+				return PTR_ERR(server_notify_handler);
+			return 0;
+
+		default:
+			dev_err(dev, "invalid notification received\n");
+			return -EIO;
+		}
+
+	case ETHFW_MSG_RESPONSE:
+		resp_msg_hdr = (struct response_message_header *)msg;
+		resp_id = resp_msg_hdr->response_id;
+		req_params = &proxy_priv->req_params;
+
+		if (unlikely(resp_id == req_params->request_id - 1)) {
+			dev_info(dev, "ignoring late response for request: %u\n",
+				 resp_id);
+			return 0;
+		} else if (unlikely(resp_id != req_params->request_id)) {
+			dev_err(dev, "expected response id: %u but received %u\n",
+				req_params->request_id, resp_id);
+			return -EINVAL;
+		}
+
+		/* Share response */
+		memcpy(&proxy_priv->resp_msg, msg, len);
+		proxy_priv->resp_msg_len = len;
+		complete(&proxy_priv->wait_for_response);
+		return 0;
+
+	default:
+		dev_err(dev, "unsupported message received from EthFw\n");
+		return -EOPNOTSUPP;
+	}
+}
+
+static int create_request_message(struct cpsw_proxy_req_params *req_params)
+{
+	struct mac_register_deregister_request *mac_reg_dereg_req;
+	struct ipv4_deregister_request *ipv4_dereg_req;
+	struct common_request_message *common_req_msg;
+	struct tx_thread_release_request *tx_free_req;
+	struct tx_thread_alloc_request *tx_alloc_req;
+	struct add_multicast_request *mcast_add_req;
+	struct del_multicast_request *mcast_del_req;
+	struct rx_flow_release_request *rx_free_req;
+	struct ipv4_register_request *ipv4_reg_req;
+	struct request_message_header *req_msg_hdr;
+	struct rx_flow_alloc_request *rx_alloc_req;
+	struct message *msg = &req_params->req_msg;
+	struct mac_release_request *mac_free_req;
+	struct vlan_join_leave_request *vlan_req;
+	struct attach_request *attach_req;
+	u32 req_type;
+
+	/* Set message header fields */
+	msg->msg_hdr.token = req_params->token;
+	msg->msg_hdr.client_id = req_params->client_id;
+	msg->msg_hdr.msg_type = ETHFW_MSG_REQUEST;
+
+	req_type = req_params->request_type;
+
+	switch (req_type) {
+	case ETHFW_ALLOC_RX:
+		rx_alloc_req = (struct rx_flow_alloc_request *)msg;
+		req_msg_hdr = &rx_alloc_req->request_msg_hdr;
+		rx_alloc_req->rx_flow_idx = req_params->rx_tx_idx;
+		break;
+
+	case ETHFW_ALLOC_TX:
+		tx_alloc_req = (struct tx_thread_alloc_request *)msg;
+		req_msg_hdr = &tx_alloc_req->request_msg_hdr;
+		tx_alloc_req->tx_chan_idx = req_params->rx_tx_idx;
+		break;
+
+	case ETHFW_VIRT_PORT_ATTACH:
+		attach_req = (struct attach_request *)msg;
+		req_msg_hdr = &attach_req->request_msg_hdr;
+		attach_req->virt_port = req_params->port_id;
+		break;
+
+	case ETHFW_FREE_MAC:
+		mac_free_req = (struct mac_release_request *)msg;
+		req_msg_hdr = &mac_free_req->request_msg_hdr;
+		ether_addr_copy(mac_free_req->mac_addr, req_params->mac_addr);
+		break;
+
+	case ETHFW_FREE_RX:
+		rx_free_req = (struct rx_flow_release_request *)msg;
+		req_msg_hdr = &rx_free_req->request_msg_hdr;
+		rx_free_req->rx_flow_idx_base = req_params->rx_flow_base;
+		rx_free_req->rx_flow_idx_offset = req_params->rx_flow_offset;
+		break;
+
+	case ETHFW_FREE_TX:
+		tx_free_req = (struct tx_thread_release_request *)msg;
+		req_msg_hdr = &tx_free_req->request_msg_hdr;
+		tx_free_req->tx_psil_dest_id = req_params->tx_thread_id;
+		break;
+
+	case ETHFW_IPv4_DEREGISTER:
+		ipv4_dereg_req = (struct ipv4_deregister_request *)msg;
+		req_msg_hdr = &ipv4_dereg_req->request_msg_hdr;
+		memcpy(&ipv4_dereg_req->ipv4_addr, req_params->ipv4_addr,
+		       ETHFW_IPV4ADDRLEN);
+		break;
+
+	case ETHFW_IPv4_REGISTER:
+		ipv4_reg_req = (struct ipv4_register_request *)msg;
+		req_msg_hdr = &ipv4_reg_req->request_msg_hdr;
+		memcpy(&ipv4_reg_req->ipv4_addr, req_params->ipv4_addr,
+		       ETHFW_IPV4ADDRLEN);
+		ether_addr_copy(ipv4_reg_req->mac_addr,
+				req_params->mac_addr);
+		break;
+
+	case ETHFW_MAC_DEREGISTER:
+	case ETHFW_MAC_REGISTER:
+		mac_reg_dereg_req = (struct mac_register_deregister_request *)msg;
+		req_msg_hdr = &mac_reg_dereg_req->request_msg_hdr;
+		ether_addr_copy(mac_reg_dereg_req->mac_addr,
+				req_params->mac_addr);
+		mac_reg_dereg_req->rx_flow_idx_base = req_params->rx_flow_base;
+		mac_reg_dereg_req->rx_flow_idx_offset = req_params->rx_flow_offset;
+		break;
+
+	case ETHFW_MCAST_FILTER_ADD:
+		mcast_add_req = (struct add_multicast_request *)msg;
+		req_msg_hdr = &mcast_add_req->request_msg_hdr;
+		ether_addr_copy(mcast_add_req->mac_addr, req_params->mac_addr);
+		mcast_add_req->vlan_id = req_params->vlan_id;
+		mcast_add_req->rx_flow_idx_base = req_params->rx_flow_base;
+		mcast_add_req->rx_flow_idx_offset = req_params->rx_flow_offset;
+		break;
+
+	case ETHFW_MCAST_FILTER_DEL:
+		mcast_del_req = (struct del_multicast_request *)msg;
+		req_msg_hdr = &mcast_del_req->request_msg_hdr;
+		ether_addr_copy(mcast_del_req->mac_addr, req_params->mac_addr);
+		mcast_del_req->vlan_id = req_params->vlan_id;
+		break;
+
+	case ETHFW_JOIN_VLAN:
+	case ETHFW_LEAVE_VLAN:
+		vlan_req = (struct vlan_join_leave_request *)msg;
+		req_msg_hdr = &vlan_req->request_msg_hdr;
+
+		vlan_req->vid = req_params->vlan_id;
+		ether_addr_copy(vlan_req->mac_addr, req_params->mac_addr);
+		vlan_req->rx_flow_idx_base = req_params->rx_flow_base;
+		vlan_req->rx_flow_idx_offset = req_params->rx_flow_offset;
+		break;
+
+	case ETHFW_ALLOC_MAC:
+	case ETHFW_TEARDOWN_COMPLETE:
+	case ETHFW_VIRT_PORT_DETACH:
+	case ETHFW_VIRT_PORT_INFO:
+	case ETHFW_VIRT_PORT_LINK_STATUS:
+		common_req_msg = (struct common_request_message *)msg;
+		req_msg_hdr = &common_req_msg->request_msg_hdr;
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	/* Set request message header fields */
+	req_msg_hdr->request_id = req_params->request_id;
+	req_msg_hdr->request_type = req_params->request_type;
+
+	return 0;
+}
+
+/* Send a request to EthFw and receive the response for request.
+ * Since the response is received by the callback function, it is
+ * copied to "resp_msg" member of "struct cpsw_proxy_priv" to
+ * allow sharing it with the following function.
+ *
+ * The request parameters within proxy_priv are expected to be set
+ * correctly by the caller. The caller is also expected to acquire
+ * lock before invoking this function, since requests and responses
+ * to/from EthFw are serialized.
+ */
+static int send_request_get_response(struct cpsw_proxy_priv *proxy_priv,
+				     struct message *response)
+{
+	struct cpsw_proxy_req_params *req_params = &proxy_priv->req_params;
+	struct message *send_msg = &req_params->req_msg;
+	struct rpmsg_device *rpdev = proxy_priv->rpdev;
+	struct response_message_header *resp_msg_hdr;
+	struct device *dev = proxy_priv->dev;
+	unsigned long timeout;
+	u32 resp_status;
+	int ret;
+
+	ret = create_request_message(req_params);
+	if (ret) {
+		dev_err(dev, "failed to create request %d\n", ret);
+		goto err;
+	}
+
+	/* Send request and wait for callback function to acknowledge
+	 * receiving the response.
+	 */
+	reinit_completion(&proxy_priv->wait_for_response);
+	ret = rpmsg_send(rpdev->ept, (void *)(send_msg),
+			 sizeof(struct message));
+	if (ret) {
+		dev_err(dev, "failed to send rpmsg\n");
+		goto err;
+	}
+	timeout = msecs_to_jiffies(ETHFW_RESPONSE_TIMEOUT_MS);
+	ret = wait_for_completion_timeout(&proxy_priv->wait_for_response,
+					  timeout);
+	if (!ret) {
+		dev_err(dev, "response timedout\n");
+		ret = -ETIMEDOUT;
+		goto err;
+	}
+
+	/* Store response shared by callback function */
+	memcpy(response, &proxy_priv->resp_msg, proxy_priv->resp_msg_len);
+	resp_msg_hdr = (struct response_message_header *)response;
+	resp_status = resp_msg_hdr->response_status;
+	ret = resp_status;
+
+	/* For all return values other than ETHFW_RES_EFAIL, the caller
+	 * is expected to check the return value to deal with the failure
+	 * accordingly.
+	 */
+	if (unlikely(resp_status == ETHFW_RES_EFAIL)) {
+		dev_err(dev, "bad response status: %d\n", resp_status);
+		ret = -EIO;
+	}
+
+err:
+	req_params->request_id++;
+	return ret;
+}
+
+static int get_virtual_port_info(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct virt_port_info_response *vpi_resp;
+	struct cpsw_proxy_req_params *req_p;
+	struct virtual_port *vport;
+	struct message resp_msg;
+	unsigned int vp_id, i;
+	int ret;
+
+	mutex_lock(&proxy_priv->req_params_mutex);
+	req_p = &proxy_priv->req_params;
+	req_p->request_type = ETHFW_VIRT_PORT_INFO;
+	ret = send_request_get_response(proxy_priv, &resp_msg);
+	mutex_unlock(&proxy_priv->req_params_mutex);
+
+	if (ret) {
+		dev_err(proxy_priv->dev, "failed to get virtual port info\n");
+		return ret;
+	}
+
+	vpi_resp = (struct virt_port_info_response *)&resp_msg;
+	proxy_priv->vswitch_ports = vpi_resp->switch_port_mask;
+	proxy_priv->vmac_ports = vpi_resp->mac_port_mask;
+	/* Number of 1s set in vswitch_ports is the count of switch ports */
+	proxy_priv->num_switch_ports = hweight32(proxy_priv->vswitch_ports);
+	proxy_priv->num_virt_ports = proxy_priv->num_switch_ports;
+	/* Number of 1s set in vmac_ports is the count of mac ports */
+	proxy_priv->num_mac_ports = hweight32(proxy_priv->vmac_ports);
+	proxy_priv->num_virt_ports += proxy_priv->num_mac_ports;
+
+	proxy_priv->virt_ports = devm_kcalloc(proxy_priv->dev,
+					      proxy_priv->num_virt_ports,
+					      sizeof(*proxy_priv->virt_ports),
+					      GFP_KERNEL);
+
+	vp_id = 0;
+	for (i = 0; i < proxy_priv->num_switch_ports; i++) {
+		vport = &proxy_priv->virt_ports[vp_id];
+		vport->proxy_priv = proxy_priv;
+		vport->port_type = VIRT_SWITCH_PORT;
+		/* Port ID is derived from the bit set in the bitmask */
+		vport->port_id = fns(proxy_priv->vswitch_ports, i);
+		vp_id++;
+	}
+
+	for (i = 0; i < proxy_priv->num_mac_ports; i++) {
+		vport = &proxy_priv->virt_ports[vp_id];
+		vport->proxy_priv = proxy_priv;
+		vport->port_type = VIRT_MAC_ONLY_PORT;
+		/* Port ID is derived from the bit set in the bitmask */
+		vport->port_id = fns(proxy_priv->vmac_ports, i);
+		vp_id++;
+	}
+
+	return 0;
+}
+
+static int attach_virtual_ports(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct cpsw_proxy_req_params *req_p;
+	struct attach_response *att_resp;
+	struct rx_dma_chan *rx_chn;
+	struct tx_dma_chan *tx_chn;
+	struct virtual_port *vport;
+	struct message resp_msg;
+	unsigned int i, j;
+	u32 port_id;
+	int ret;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+		port_id = vport->port_id;
+
+		mutex_lock(&proxy_priv->req_params_mutex);
+		req_p = &proxy_priv->req_params;
+		req_p->port_id = port_id;
+		req_p->request_type = ETHFW_VIRT_PORT_ATTACH;
+		ret = send_request_get_response(proxy_priv, &resp_msg);
+		mutex_unlock(&proxy_priv->req_params_mutex);
+
+		if (ret) {
+			dev_err(proxy_priv->dev, "attaching virtual port failed\n");
+			goto err;
+		}
+
+		att_resp = (struct attach_response *)&resp_msg;
+		vport->port_token = att_resp->response_msg_hdr.msg_hdr.token;
+		vport->port_features = att_resp->features;
+		vport->num_tx_chan = att_resp->num_tx_chan;
+		vport->num_rx_chan = att_resp->num_rx_flow;
+
+		vport->rx_chans = devm_kcalloc(proxy_priv->dev,
+					       vport->num_rx_chan,
+					       sizeof(*vport->rx_chans),
+					       GFP_KERNEL);
+		for (j = 0; j < vport->num_rx_chan; j++) {
+			rx_chn = &vport->rx_chans[j];
+			rx_chn->vport = vport;
+			rx_chn->rel_chan_idx = j;
+		}
+
+		vport->tx_chans = devm_kcalloc(proxy_priv->dev,
+					       vport->num_tx_chan,
+					       sizeof(*vport->tx_chans),
+					       GFP_KERNEL);
+		for (j = 0; j < vport->num_tx_chan; j++) {
+			tx_chn = &vport->tx_chans[j];
+			tx_chn->vport = vport;
+			tx_chn->rel_chan_idx = j;
+		}
+	}
+
+	return 0;
+
+err:
+	/* Detach virtual ports which were successfully attached */
+	while (i--) {
+		vport = &proxy_priv->virt_ports[i];
+		port_id = vport->port_id;
+		mutex_lock(&proxy_priv->req_params_mutex);
+		req_p = &proxy_priv->req_params;
+		req_p->request_type = ETHFW_VIRT_PORT_DETACH;
+		req_p->token = vport->port_token;
+		ret = send_request_get_response(proxy_priv, &resp_msg);
+		mutex_unlock(&proxy_priv->req_params_mutex);
+		if (ret)
+			dev_err(proxy_priv->dev, "detaching virtual port %u failed\n", port_id);
+	}
+	return -EIO;
+}
+
+static void free_port_resources(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct cpsw_proxy_req_params *req_p;
+	struct rx_dma_chan *rx_chn;
+	struct tx_dma_chan *tx_chn;
+	struct virtual_port *vport;
+	struct message resp_msg;
+	u32 port_id, i, j;
+	int ret;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+		port_id = vport->port_id;
+
+		/* Free allocated MAC */
+		if (vport->mac_in_use) {
+			mutex_lock(&proxy_priv->req_params_mutex);
+			req_p = &proxy_priv->req_params;
+			req_p->request_type = ETHFW_FREE_MAC;
+			req_p->token = vport->port_token;
+			ether_addr_copy(req_p->mac_addr, vport->mac_addr);
+			ret = send_request_get_response(proxy_priv, &resp_msg);
+			mutex_unlock(&proxy_priv->req_params_mutex);
+			if (ret) {
+				dev_err(proxy_priv->dev,
+					"failed to free MAC Address for port %u err: %d\n",
+					port_id, ret);
+				return;
+			}
+		}
+
+		/* Free TX DMA Channels */
+		for (j = 0; j < vport->num_tx_chan; j++) {
+			tx_chn = &vport->tx_chans[j];
+			if (!tx_chn->in_use)
+				continue;
+			mutex_lock(&proxy_priv->req_params_mutex);
+			req_p = &proxy_priv->req_params;
+			req_p->request_type = ETHFW_FREE_TX;
+			req_p->token = vport->port_token;
+			req_p->tx_thread_id = tx_chn->thread_id;
+			ret = send_request_get_response(proxy_priv, &resp_msg);
+			mutex_unlock(&proxy_priv->req_params_mutex);
+			if (ret) {
+				dev_err(proxy_priv->dev,
+					"failed to free TX Channel for port %u err: %d\n",
+					port_id, ret);
+				return;
+			}
+		}
+
+		/* Free RX DMA Channels */
+		for (j = 0; j < vport->num_rx_chan; j++) {
+			rx_chn = &vport->rx_chans[j];
+			if (!rx_chn->in_use)
+				continue;
+			mutex_lock(&proxy_priv->req_params_mutex);
+			req_p = &proxy_priv->req_params;
+			req_p->request_type = ETHFW_FREE_RX;
+			req_p->token = vport->port_token;
+			req_p->rx_flow_base = rx_chn->flow_base;
+			req_p->rx_flow_offset = rx_chn->flow_offset;
+			ret = send_request_get_response(proxy_priv, &resp_msg);
+			mutex_unlock(&proxy_priv->req_params_mutex);
+			if (ret) {
+				dev_err(proxy_priv->dev,
+					"failed to free RX Channel for port %u err: %d\n",
+					port_id, ret);
+				return;
+			}
+		}
+	}
+}
+
+static int allocate_port_resources(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct tx_thread_alloc_response *tta_resp;
+	struct rx_flow_alloc_response *rfa_resp;
+	struct cpsw_proxy_req_params *req_p;
+	struct mac_alloc_response *ma_resp;
+	struct rx_dma_chan *rx_chn;
+	struct tx_dma_chan *tx_chn;
+	struct virtual_port *vport;
+	struct message resp_msg;
+	u32 port_id, i, j;
+	int ret;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+		port_id = vport->port_id;
+
+		/* Request RX DMA Flow allocation */
+		for (j = 0; j < vport->num_rx_chan; j++) {
+			mutex_lock(&proxy_priv->req_params_mutex);
+			req_p = &proxy_priv->req_params;
+			req_p->request_type = ETHFW_ALLOC_RX;
+			req_p->token = vport->port_token;
+			req_p->rx_tx_idx = j;
+			ret = send_request_get_response(proxy_priv, &resp_msg);
+			mutex_unlock(&proxy_priv->req_params_mutex);
+			if (ret) {
+				dev_err(proxy_priv->dev, "RX Alloc for port %u failed\n", port_id);
+				goto err;
+			}
+
+			rfa_resp = (struct rx_flow_alloc_response *)&resp_msg;
+			rx_chn = &vport->rx_chans[j];
+			rx_chn->flow_base = rfa_resp->rx_flow_idx_base;
+			rx_chn->flow_offset = rfa_resp->rx_flow_idx_offset;
+			rx_chn->thread_id = rfa_resp->rx_psil_src_id;
+			rx_chn->in_use = 1;
+		}
+
+		/* Request TX DMA Channel allocation */
+		for (j = 0; j < vport->num_tx_chan; j++) {
+			mutex_lock(&proxy_priv->req_params_mutex);
+			req_p = &proxy_priv->req_params;
+			req_p->request_type = ETHFW_ALLOC_TX;
+			req_p->token = vport->port_token;
+			req_p->rx_tx_idx = j;
+			ret = send_request_get_response(proxy_priv, &resp_msg);
+			mutex_unlock(&proxy_priv->req_params_mutex);
+			if (ret) {
+				dev_err(proxy_priv->dev, "TX Alloc for port %u failed\n", port_id);
+				goto err;
+			}
+
+			tta_resp = (struct tx_thread_alloc_response *)&resp_msg;
+			tx_chn = &vport->tx_chans[j];
+			tx_chn->thread_id = tta_resp->tx_psil_dest_id;
+			tx_chn->in_use = 1;
+		}
+
+		/* Request MAC allocation */
+		mutex_lock(&proxy_priv->req_params_mutex);
+		req_p = &proxy_priv->req_params;
+		req_p->request_type = ETHFW_ALLOC_MAC;
+		req_p->token = vport->port_token;
+		ret = send_request_get_response(proxy_priv, &resp_msg);
+		mutex_unlock(&proxy_priv->req_params_mutex);
+		if (ret) {
+			dev_err(proxy_priv->dev, "MAC Alloc for port %u failed\n", port_id);
+			goto err;
+		}
+
+		ma_resp = (struct mac_alloc_response *)&resp_msg;
+		ether_addr_copy(vport->mac_addr, ma_resp->mac_addr);
+		vport->mac_in_use = 1;
+	}
+
+	return 0;
+
+err:
+	free_port_resources(proxy_priv);
+	return -EIO;
+}
+
+static void detach_virtual_ports(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct cpsw_proxy_req_params *req_p;
+	struct virtual_port *vport;
+	struct message resp_msg;
+	u32 port_id, i;
+	int ret;
+
+	free_port_resources(proxy_priv);
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+		port_id = vport->port_id;
+		mutex_lock(&proxy_priv->req_params_mutex);
+		req_p = &proxy_priv->req_params;
+		req_p->request_type = ETHFW_VIRT_PORT_DETACH;
+		req_p->token = vport->port_token;
+		ret = send_request_get_response(proxy_priv, &resp_msg);
+		mutex_unlock(&proxy_priv->req_params_mutex);
+		if (ret)
+			dev_err(proxy_priv->dev, "detaching virtual port %u failed\n", port_id);
+	}
+}
+
+static void free_tx_chns(void *data)
+{
+	struct cpsw_proxy_priv *proxy_priv = data;
+	struct tx_dma_chan *tx_chn;
+	struct virtual_port *vport;
+	u32 i, j;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+		for (j = 0; j < vport->num_tx_chan; j++) {
+			tx_chn = &vport->tx_chans[j];
+
+			if (!IS_ERR_OR_NULL(tx_chn->desc_pool))
+				k3_cppi_desc_pool_destroy(tx_chn->desc_pool);
+
+			if (!IS_ERR_OR_NULL(tx_chn->tx_chan))
+				k3_udma_glue_release_tx_chn(tx_chn->tx_chan);
+
+			memset(tx_chn, 0, sizeof(*tx_chn));
+		}
+	}
+}
+
+static int init_tx_chans(struct cpsw_proxy_priv *proxy_priv)
+{
+	u32 max_desc_num = ALIGN(MAX_TX_DESC, MAX_SKB_FRAGS);
+	struct k3_udma_glue_tx_channel_cfg tx_cfg = { 0 };
+	struct device *dev = proxy_priv->dev;
+	u32 hdesc_size, tx_chn_num, i, j;
+	char tx_chn_name[CHAN_NAME_LEN];
+	struct k3_ring_cfg ring_cfg = {
+		.elm_size = K3_RINGACC_RING_ELSIZE_8,
+		.mode = K3_RINGACC_RING_MODE_RING,
+		.flags = 0
+	};
+	struct tx_dma_chan *tx_chn;
+	struct virtual_port *vport;
+	int ret = 0, ret1;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+		init_completion(&vport->tdown_complete);
+
+		for (j = 0; j < vport->num_tx_chan; j++) {
+			tx_chn = &vport->tx_chans[j];
+
+			tx_chn_num = proxy_priv->num_active_tx_chans++;
+			snprintf(tx_chn_name, sizeof(tx_chn_name), "tx%u-virt-port-%u",
+				 tx_chn_num, vport->port_id);
+			strscpy(tx_chn->tx_chan_name, tx_chn_name, sizeof(tx_chn->tx_chan_name));
+
+			hdesc_size = cppi5_hdesc_calc_size(true, PS_DATA_SIZE, SW_DATA_SIZE);
+
+			tx_cfg.swdata_size = SW_DATA_SIZE;
+			tx_cfg.tx_cfg = ring_cfg;
+			tx_cfg.txcq_cfg = ring_cfg;
+			tx_cfg.tx_cfg.size = max_desc_num;
+			tx_cfg.txcq_cfg.size = max_desc_num;
+
+			tx_chn->tx_chan =
+				k3_udma_glue_request_tx_chn_for_thread_id(dev, &tx_cfg,
+									  proxy_priv->dma_node,
+									  tx_chn->thread_id);
+			if (IS_ERR(tx_chn->tx_chan)) {
+				ret = PTR_ERR(tx_chn->tx_chan);
+				dev_err(dev, "Failed to request tx dma channel %d\n", ret);
+				goto err;
+			}
+			tx_chn->dma_dev = k3_udma_glue_tx_get_dma_device(tx_chn->tx_chan);
+
+			tx_chn->dev = dev;
+			tx_chn->num_descs = max_desc_num;
+			tx_chn->desc_pool = k3_cppi_desc_pool_create_name(tx_chn->dma_dev,
+									  tx_chn->num_descs,
+									  hdesc_size,
+									  tx_chn_name);
+			if (IS_ERR(tx_chn->desc_pool)) {
+				ret = PTR_ERR(tx_chn->desc_pool);
+				dev_err(dev, "failed to create tx pool %d\n", ret);
+				goto err;
+			}
+
+			tx_chn->irq = k3_udma_glue_tx_get_irq(tx_chn->tx_chan);
+			if (tx_chn->irq <= 0) {
+				dev_err(dev, "Failed to get tx dma irq %d\n", tx_chn->irq);
+				ret = -ENXIO;
+			}
+		}
+	}
+
+err:
+	ret1 = devm_add_action(dev, free_tx_chns, proxy_priv);
+	if (ret1) {
+		dev_err(dev, "failed to add free_tx_chns action %d", ret1);
+		return ret1;
+	}
+
+	return ret;
+}
+
+static void free_rx_chns(void *data)
+{
+	struct cpsw_proxy_priv *proxy_priv = data;
+	struct rx_dma_chan *rx_chn;
+	struct virtual_port *vport;
+	u32 i, j;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+
+		for (j = 0; j < vport->num_rx_chan; j++) {
+			rx_chn = &vport->rx_chans[j];
+
+			if (!IS_ERR_OR_NULL(rx_chn->desc_pool))
+				k3_cppi_desc_pool_destroy(rx_chn->desc_pool);
+
+			if (!IS_ERR_OR_NULL(rx_chn->rx_chan))
+				k3_udma_glue_release_rx_chn(rx_chn->rx_chan);
+		}
+	}
+}
+
+static int init_rx_chans(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct k3_udma_glue_rx_channel_cfg rx_cfg = {0};
+	struct device *dev = proxy_priv->dev;
+	struct k3_ring_cfg fdqring_cfg = {
+		.elm_size = K3_RINGACC_RING_ELSIZE_8,
+		.mode = K3_RINGACC_RING_MODE_RING,
+		.flags = 0,
+	};
+	struct k3_ring_cfg rxring_cfg = {
+		.elm_size = K3_RINGACC_RING_ELSIZE_8,
+		.mode = K3_RINGACC_RING_MODE_RING,
+		.flags = 0,
+	};
+	struct k3_udma_glue_rx_flow_cfg rx_flow_cfg = {
+		.rx_cfg = rxring_cfg,
+		.rxfdq_cfg = fdqring_cfg,
+		.ring_rxq_id = K3_RINGACC_RING_ID_ANY,
+		.ring_rxfdq0_id = K3_RINGACC_RING_ID_ANY,
+		.src_tag_lo_sel = K3_UDMA_GLUE_SRC_TAG_LO_USE_REMOTE_SRC_TAG,
+	};
+	u32 hdesc_size, rx_chn_num, i, j;
+	u32  max_desc_num = MAX_RX_DESC;
+	char rx_chn_name[CHAN_NAME_LEN];
+	struct rx_dma_chan *rx_chn;
+	struct virtual_port *vport;
+	int ret = 0, ret1;
+
+	hdesc_size = cppi5_hdesc_calc_size(true, PS_DATA_SIZE, SW_DATA_SIZE);
+
+	rx_cfg.swdata_size = SW_DATA_SIZE;
+	rx_cfg.flow_id_num = MAX_RX_FLOWS;
+	rx_cfg.remote = true;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+
+		for (j = 0; j < vport->num_rx_chan; j++) {
+			rx_chn = &vport->rx_chans[j];
+
+			rx_chn_num = proxy_priv->num_active_rx_chans++;
+			snprintf(rx_chn_name, sizeof(rx_chn_name), "rx%u-virt-port-%u", rx_chn_num,
+				 vport->port_id);
+			strscpy(rx_chn->rx_chan_name, rx_chn_name, sizeof(rx_chn->rx_chan_name));
+
+			rx_cfg.flow_id_base = rx_chn->flow_base + rx_chn->flow_offset;
+
+			rx_chn->rx_chan =
+			k3_udma_glue_request_remote_rx_chn_for_thread_id(dev, &rx_cfg,
+									 proxy_priv->dma_node,
+									 rx_chn->thread_id);
+			if (IS_ERR(rx_chn->rx_chan)) {
+				ret = PTR_ERR(rx_chn->rx_chan);
+				dev_err(dev, "Failed to request rx dma channel %d\n", ret);
+				goto err;
+			}
+			rx_chn->dma_dev = k3_udma_glue_rx_get_dma_device(rx_chn->rx_chan);
+
+			/* init all flows */
+			rx_chn->dev = dev;
+			rx_chn->num_descs = max_desc_num;
+			rx_chn->desc_pool = k3_cppi_desc_pool_create_name(rx_chn->dma_dev,
+									  rx_chn->num_descs,
+									  hdesc_size,
+									  rx_chn_name);
+			if (IS_ERR(rx_chn->desc_pool)) {
+				ret = PTR_ERR(rx_chn->desc_pool);
+				dev_err(dev, "Failed to create rx pool %d\n", ret);
+				goto err;
+			}
+
+			rx_flow_cfg.rx_cfg.size = max_desc_num;
+			rx_flow_cfg.rxfdq_cfg.size = max_desc_num;
+			ret = k3_udma_glue_rx_flow_init(rx_chn->rx_chan,
+							0, &rx_flow_cfg);
+			if (ret) {
+				dev_err(dev, "Failed to init rx flow %d\n", ret);
+				goto err;
+			}
+
+			rx_chn->irq = k3_udma_glue_rx_get_irq(rx_chn->rx_chan, 0);
+			if (rx_chn->irq <= 0) {
+				ret = -ENXIO;
+				dev_err(dev, "Failed to get rx dma irq %d\n", rx_chn->irq);
+			}
+		}
+	}
+
+err:
+	ret1 = devm_add_action(dev, free_rx_chns, proxy_priv);
+	if (ret1) {
+		dev_err(dev, "failed to add free_rx_chns action %d", ret1);
+		return ret1;
+	}
+
+	return ret;
+}
+
+static void vport_xmit_free(struct tx_dma_chan *tx_chn, struct cppi5_host_desc_t *desc)
+{
+	struct cppi5_host_desc_t *first_desc, *next_desc;
+	dma_addr_t buf_dma, next_desc_dma;
+	u32 buf_dma_len;
+
+	first_desc = desc;
+	next_desc = first_desc;
+
+	cppi5_hdesc_get_obuf(first_desc, &buf_dma, &buf_dma_len);
+	k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chan, &buf_dma);
+
+	dma_unmap_single(tx_chn->dma_dev, buf_dma, buf_dma_len, DMA_TO_DEVICE);
+
+	next_desc_dma = cppi5_hdesc_get_next_hbdesc(first_desc);
+	k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chan, &next_desc_dma);
+	while (next_desc_dma) {
+		next_desc = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool,
+						       next_desc_dma);
+		cppi5_hdesc_get_obuf(next_desc, &buf_dma, &buf_dma_len);
+		k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chan, &buf_dma);
+
+		dma_unmap_page(tx_chn->dma_dev, buf_dma, buf_dma_len, DMA_TO_DEVICE);
+
+		next_desc_dma = cppi5_hdesc_get_next_hbdesc(next_desc);
+		k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chan, &next_desc_dma);
+
+		k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc);
+	}
+
+	k3_cppi_desc_pool_free(tx_chn->desc_pool, first_desc);
+}
+
+static int tx_compl_packets(struct virtual_port *vport, unsigned int tx_chan_idx,
+			    unsigned int budget, bool *tdown)
+{
+	struct cppi5_host_desc_t *desc_tx;
+	struct netdev_queue *netif_txq;
+	unsigned int total_bytes = 0;
+	struct tx_dma_chan *tx_chn;
+	struct net_device *ndev;
+	struct sk_buff *skb;
+	dma_addr_t desc_dma;
+	int res, num_tx = 0;
+	void **swdata;
+
+	tx_chn = &vport->tx_chans[tx_chan_idx];
+
+	while (budget--) {
+		struct vport_netdev_priv *ndev_priv;
+		struct vport_netdev_stats *stats;
+
+		res = k3_udma_glue_pop_tx_chn(tx_chn->tx_chan, &desc_dma);
+		if (res == -ENODATA)
+			break;
+
+		if (desc_dma & 0x1) {
+			if (atomic_dec_and_test(&vport->tdown_cnt))
+				complete(&vport->tdown_complete);
+			*tdown = true;
+			break;
+		}
+
+		desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool,
+						     desc_dma);
+		swdata = cppi5_hdesc_get_swdata(desc_tx);
+		skb = *(swdata);
+		vport_xmit_free(tx_chn, desc_tx);
+
+		ndev = skb->dev;
+
+		ndev_priv = netdev_priv(ndev);
+		stats = this_cpu_ptr(ndev_priv->stats);
+		u64_stats_update_begin(&stats->syncp);
+		stats->tx_packets++;
+		stats->tx_bytes += skb->len;
+		u64_stats_update_end(&stats->syncp);
+
+		total_bytes += skb->len;
+		napi_consume_skb(skb, budget);
+		num_tx++;
+	}
+
+	if (!num_tx)
+		return 0;
+
+	netif_txq = netdev_get_tx_queue(ndev, tx_chan_idx);
+	netdev_tx_completed_queue(netif_txq, num_tx, total_bytes);
+
+	if (netif_tx_queue_stopped(netif_txq)) {
+		__netif_tx_lock(netif_txq, smp_processor_id());
+		if (netif_running(ndev) &&
+		    (k3_cppi_desc_pool_avail(tx_chn->desc_pool) >=
+		     MAX_SKB_FRAGS))
+			netif_tx_wake_queue(netif_txq);
+
+		__netif_tx_unlock(netif_txq);
+	}
+
+	return num_tx;
+}
+
+static int vport_tx_poll(struct napi_struct *napi_tx, int budget)
+{
+	struct tx_dma_chan *tx_chn = container_of(napi_tx, struct tx_dma_chan,
+							 napi_tx);
+	struct virtual_port *vport = tx_chn->vport;
+	bool tdown = false;
+	int num_tx;
+
+	/* process every unprocessed channel */
+	num_tx = tx_compl_packets(vport, tx_chn->rel_chan_idx, budget, &tdown);
+
+	if (num_tx >= budget)
+		return budget;
+
+	if (napi_complete_done(napi_tx, num_tx)) {
+		if (unlikely(tx_chn->tx_pace_timeout && !tdown)) {
+			hrtimer_start(&tx_chn->tx_hrtimer,
+				      ns_to_ktime(tx_chn->tx_pace_timeout),
+				      HRTIMER_MODE_REL_PINNED);
+		} else {
+			enable_irq(tx_chn->irq);
+		}
+	}
+
+	return 0;
+}
+
+/* RX psdata[2] word format - checksum information */
+#define RX_PSD_CSUM_ERR		BIT(16)
+#define RX_PSD_IS_FRAGMENT	BIT(17)
+#define RX_PSD_IPV6_VALID	BIT(19)
+#define RX_PSD_IPV4_VALID	BIT(20)
+
+static void vport_rx_csum(struct sk_buff *skb, u32 csum_info)
+{
+	/* HW can verify IPv4/IPv6 TCP/UDP packets checksum
+	 * csum information provides in psdata[2] word:
+	 * RX_PSD_CSUM_ERR bit - indicates csum error
+	 * RX_PSD_IPV6_VALID and CPSW_RX_PSD_IPV4_VALID
+	 * bits - indicates IPv4/IPv6 packet
+	 * RX_PSD_IS_FRAGMENT bit - indicates fragmented packet
+	 * RX_PSD_CSUM_ADD has value 0xFFFF for non fragmented packets
+	 * or csum value for fragmented packets if !RX_PSD_CSUM_ERR
+	 */
+	skb_checksum_none_assert(skb);
+
+	if (unlikely(!(skb->dev->features & NETIF_F_RXCSUM)))
+		return;
+
+	if ((csum_info & (RX_PSD_IPV6_VALID |
+			  RX_PSD_IPV4_VALID)) &&
+			  !(csum_info & RX_PSD_CSUM_ERR)) {
+		/* csum for fragmented packets is unsupported */
+		if (!(csum_info & RX_PSD_IS_FRAGMENT))
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+	}
+}
+
+static int vport_rx_push(struct virtual_port *vport, struct sk_buff *skb,
+			 u32 rx_chan_idx)
+{
+	struct rx_dma_chan *rx_chn = &vport->rx_chans[rx_chan_idx];
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	struct device *dev = proxy_priv->dev;
+	struct cppi5_host_desc_t *desc_rx;
+	dma_addr_t desc_dma;
+	dma_addr_t buf_dma;
+	void *swdata;
+
+	desc_rx = k3_cppi_desc_pool_alloc(rx_chn->desc_pool);
+	if (!desc_rx) {
+		dev_err(dev, "Failed to allocate RXFDQ descriptor\n");
+		return -ENOMEM;
+	}
+	desc_dma = k3_cppi_desc_pool_virt2dma(rx_chn->desc_pool, desc_rx);
+
+	buf_dma = dma_map_single(rx_chn->dma_dev, skb->data, MAX_PACKET_SIZE, DMA_FROM_DEVICE);
+	if (unlikely(dma_mapping_error(rx_chn->dma_dev, buf_dma))) {
+		k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
+		dev_err(dev, "Failed to map rx skb buffer\n");
+		return -EINVAL;
+	}
+
+	cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT,
+			 PS_DATA_SIZE);
+	k3_udma_glue_rx_dma_to_cppi5_addr(rx_chn->rx_chan, &buf_dma);
+	cppi5_hdesc_attach_buf(desc_rx, buf_dma, MAX_PACKET_SIZE, buf_dma, MAX_PACKET_SIZE);
+	swdata = cppi5_hdesc_get_swdata(desc_rx);
+	*((void **)swdata) = skb;
+
+	return k3_udma_glue_push_rx_chn(rx_chn->rx_chan, 0, desc_rx, desc_dma);
+}
+
+static int vport_rx_packets(struct virtual_port *vport, u32 rx_chan_idx)
+{
+	struct rx_dma_chan *rx_chn = &vport->rx_chans[rx_chan_idx];
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	u32 buf_dma_len, pkt_len, port_id = 0, csum_info;
+	struct device *dev = proxy_priv->dev;
+	struct vport_netdev_priv *ndev_priv;
+	struct cppi5_host_desc_t *desc_rx;
+	struct vport_netdev_stats *stats;
+	struct sk_buff *skb, *new_skb;
+	dma_addr_t desc_dma, buf_dma;
+	struct net_device *ndev;
+	u32 flow_idx = 0;
+	void **swdata;
+	int ret = 0;
+	u32 *psdata;
+
+	ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chan, flow_idx, &desc_dma);
+	if (ret) {
+		if (ret != -ENODATA)
+			dev_err(dev, "RX: pop chn fail %d\n", ret);
+		return ret;
+	}
+
+	if (desc_dma & 0x1) {
+		dev_dbg(dev, "%s RX tdown flow: %u\n", __func__, flow_idx);
+		return 0;
+	}
+
+	desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma);
+	dev_dbg(dev, "%s flow_idx: %u desc %pad\n",
+		__func__, flow_idx, &desc_dma);
+
+	swdata = cppi5_hdesc_get_swdata(desc_rx);
+	skb = *swdata;
+	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
+	k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chan, &buf_dma);
+	pkt_len = cppi5_hdesc_get_pktlen(desc_rx);
+	cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL);
+	/* read port for dbg */
+	dev_dbg(dev, "%s rx port_id:%d\n", __func__, port_id);
+	ndev = vport->ndev;
+	skb->dev = ndev;
+
+	psdata = cppi5_hdesc_get_psdata(desc_rx);
+	csum_info = psdata[2];
+	dev_dbg(dev, "%s rx csum_info:%#x\n", __func__, csum_info);
+
+	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE);
+
+	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
+
+	if (unlikely(!netif_running(skb->dev))) {
+		dev_kfree_skb_any(skb);
+		return -ENODEV;
+	}
+
+	new_skb = netdev_alloc_skb_ip_align(ndev, MAX_PACKET_SIZE);
+	if (new_skb) {
+		skb_put(skb, pkt_len);
+		skb->protocol = eth_type_trans(skb, ndev);
+		vport_rx_csum(skb, csum_info);
+		napi_gro_receive(&rx_chn->napi_rx, skb);
+
+		ndev_priv = netdev_priv(ndev);
+		stats = this_cpu_ptr(ndev_priv->stats);
+
+		u64_stats_update_begin(&stats->syncp);
+		stats->rx_packets++;
+		stats->rx_bytes += pkt_len;
+		u64_stats_update_end(&stats->syncp);
+		kmemleak_not_leak(new_skb);
+	} else {
+		ndev->stats.rx_dropped++;
+		new_skb = skb;
+	}
+
+	if (netif_dormant(ndev)) {
+		dev_kfree_skb_any(new_skb);
+		ndev->stats.rx_dropped++;
+		return -ENODEV;
+	}
+
+	ret = vport_rx_push(vport, new_skb, rx_chn->rel_chan_idx);
+	if (WARN_ON(ret < 0)) {
+		dev_kfree_skb_any(new_skb);
+		ndev->stats.rx_errors++;
+		ndev->stats.rx_dropped++;
+	}
+
+	return ret;
+}
+
+static int vport_rx_poll(struct napi_struct *napi_rx, int budget)
+{
+	struct rx_dma_chan *rx_chn = container_of(napi_rx, struct rx_dma_chan,
+							 napi_rx);
+	struct virtual_port *vport = rx_chn->vport;
+	int num_rx = 0;
+	int cur_budget;
+	int ret;
+
+	/* process every flow */
+	cur_budget = budget;
+
+	while (cur_budget--) {
+		ret = vport_rx_packets(vport, rx_chn->rel_chan_idx);
+		if (ret)
+			break;
+		num_rx++;
+	}
+
+	if (num_rx < budget && napi_complete_done(napi_rx, num_rx)) {
+		if (rx_chn->rx_irq_disabled) {
+			rx_chn->rx_irq_disabled = false;
+			if (unlikely(rx_chn->rx_pace_timeout)) {
+				hrtimer_start(&rx_chn->rx_hrtimer,
+					      ns_to_ktime(rx_chn->rx_pace_timeout),
+					      HRTIMER_MODE_REL_PINNED);
+			} else {
+				enable_irq(rx_chn->irq);
+			}
+		}
+	}
+
+	return num_rx;
+}
+
+static enum hrtimer_restart vport_tx_timer_cb(struct hrtimer *timer)
+{
+	struct tx_dma_chan *tx_chn = container_of(timer, struct tx_dma_chan, tx_hrtimer);
+
+	enable_irq(tx_chn->irq);
+	return HRTIMER_NORESTART;
+}
+
+static enum hrtimer_restart vport_rx_timer_cb(struct hrtimer *timer)
+{
+	struct rx_dma_chan *rx_chn = container_of(timer, struct rx_dma_chan, rx_hrtimer);
+
+	enable_irq(rx_chn->irq);
+	return HRTIMER_NORESTART;
+}
+
+static u32 vport_get_link(struct net_device *ndev)
+{
+	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	struct port_link_status_response *pls_resp;
+	struct cpsw_proxy_req_params *req_p;
+	struct message resp_msg;
+	bool link_up;
+	int ret;
+
+	if (vport->port_type != VIRT_MAC_ONLY_PORT)
+		return ethtool_op_get_link(ndev);
+
+	mutex_lock(&proxy_priv->req_params_mutex);
+	req_p = &proxy_priv->req_params;
+	req_p->request_type = ETHFW_VIRT_PORT_LINK_STATUS;
+	req_p->token = vport->port_token;
+	ret = send_request_get_response(proxy_priv, &resp_msg);
+	mutex_unlock(&proxy_priv->req_params_mutex);
+	if (ret) {
+		netdev_err(ndev, "failed to get link status\n");
+		/* Assume that link is down if status is unknown */
+		return 0;
+	}
+	pls_resp = (struct port_link_status_response *)&resp_msg;
+	link_up = pls_resp->link_up;
+
+	return link_up;
+}
+
+static int vport_get_coal(struct net_device *ndev, struct ethtool_coalesce *coal,
+			  struct kernel_ethtool_coalesce *kernel_coal,
+			  struct netlink_ext_ack *extack)
+{
+	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+
+	coal->tx_coalesce_usecs = vport->tx_chans[0].tx_pace_timeout / 1000;
+	coal->rx_coalesce_usecs = vport->rx_chans[0].rx_pace_timeout / 1000;
+	return 0;
+}
+
+static int vport_set_coal(struct net_device *ndev, struct ethtool_coalesce *coal,
+			  struct kernel_ethtool_coalesce *kernel_coal,
+			  struct netlink_ext_ack *extack)
+{
+	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	struct device *dev = proxy_priv->dev;
+	u32 i;
+
+	if (coal->tx_coalesce_usecs && coal->tx_coalesce_usecs < 20) {
+		dev_err(dev, "TX coalesce must be at least 20 usecs. Defaulting to 20 usecs\n");
+		coal->tx_coalesce_usecs = 20;
+	}
+
+	if (coal->rx_coalesce_usecs && coal->rx_coalesce_usecs < 20) {
+		dev_err(dev, "RX coalesce must be at least 20 usecs. Defaulting to 20 usecs\n");
+		coal->rx_coalesce_usecs = 20;
+	}
+
+	/* Since it is possible to set pacing values per TX and RX queue, if per queue value is
+	 * not specified, apply it to all available TX and RX queues.
+	 */
+
+	for (i = 0; i < vport->num_tx_chan; i++)
+		vport->tx_chans[i].tx_pace_timeout = coal->tx_coalesce_usecs * 1000;
+
+	for (i = 0; i < vport->num_rx_chan; i++)
+		vport->rx_chans[i].rx_pace_timeout = coal->rx_coalesce_usecs * 1000;
+
+	return 0;
+}
+
+static int vport_get_per_q_coal(struct net_device *ndev, u32 q,
+				struct ethtool_coalesce *coal)
+{
+	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+
+	if (q >= vport->num_tx_chan || q >= vport->num_rx_chan)
+		return -EINVAL;
+
+	coal->tx_coalesce_usecs = vport->tx_chans[q].tx_pace_timeout / 1000;
+	coal->rx_coalesce_usecs = vport->rx_chans[q].rx_pace_timeout / 1000;
+
+	return 0;
+}
+
+static int vport_set_per_q_coal(struct net_device *ndev, u32 q,
+				struct ethtool_coalesce *coal)
+{	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+	struct device *dev = vport->proxy_priv->dev;
+
+	if (q >= vport->num_tx_chan || q >= vport->num_rx_chan)
+		return -EINVAL;
+
+	if (coal->tx_coalesce_usecs && coal->tx_coalesce_usecs < 20) {
+		dev_err(dev, "TX coalesce must be at least 20 usecs. Defaulting to 20 usecs\n");
+		coal->tx_coalesce_usecs = 20;
+	}
+
+	if (coal->rx_coalesce_usecs && coal->rx_coalesce_usecs < 20) {
+		dev_err(dev, "RX coalesce must be at least 20 usecs. Defaulting to 20 usecs\n");
+		coal->rx_coalesce_usecs = 20;
+	}
+
+	vport->tx_chans[q].tx_pace_timeout = coal->tx_coalesce_usecs * 1000;
+	vport->rx_chans[q].rx_pace_timeout = coal->rx_coalesce_usecs * 1000;
+
+	return 0;
+}
+
+const struct ethtool_ops cpsw_proxy_client_ethtool_ops = {
+	.get_link		= vport_get_link,
+	.supported_coalesce_params = ETHTOOL_COALESCE_USECS,
+	.get_coalesce           = vport_get_coal,
+	.set_coalesce           = vport_set_coal,
+	.get_per_queue_coalesce = vport_get_per_q_coal,
+	.set_per_queue_coalesce = vport_set_per_q_coal,
+};
+
+static int register_mac(struct virtual_port *vport)
+{
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	struct rx_dma_chan *rx_chn = &vport->rx_chans[0];
+	struct cpsw_proxy_req_params *req_p;
+	struct message resp_msg;
+	int ret;
+
+	/* Register MAC Address only for RX DMA Channel 0 */
+	mutex_lock(&proxy_priv->req_params_mutex);
+	req_p = &proxy_priv->req_params;
+	req_p->request_type = ETHFW_MAC_REGISTER;
+	req_p->token = vport->port_token;
+	req_p->rx_flow_base = rx_chn->flow_base;
+	req_p->rx_flow_offset = rx_chn->flow_offset;
+	ether_addr_copy(req_p->mac_addr, vport->mac_addr);
+	ret = send_request_get_response(proxy_priv, &resp_msg);
+	mutex_unlock(&proxy_priv->req_params_mutex);
+	if (ret)
+		dev_err(proxy_priv->dev, "failed to register MAC Address\n");
+
+	return ret;
+}
+
+static int deregister_mac(struct virtual_port *vport)
+{
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	struct rx_dma_chan *rx_chn = &vport->rx_chans[0];
+	struct cpsw_proxy_req_params *req_p;
+	struct message resp_msg;
+	int ret;
+
+	mutex_lock(&proxy_priv->req_params_mutex);
+	req_p = &proxy_priv->req_params;
+	req_p->request_type = ETHFW_MAC_DEREGISTER;
+	req_p->token = vport->port_token;
+	req_p->rx_flow_base = rx_chn->flow_base;
+	req_p->rx_flow_offset = rx_chn->flow_offset;
+	ether_addr_copy(req_p->mac_addr, vport->mac_addr);
+	ret = send_request_get_response(proxy_priv, &resp_msg);
+	mutex_unlock(&proxy_priv->req_params_mutex);
+	if (ret)
+		dev_err(proxy_priv->dev, "failed to deregister MAC Address\n");
+
+	return ret;
+}
+
+static void vport_tx_cleanup(void *data, dma_addr_t desc_dma)
+{
+	struct tx_dma_chan *tx_chn = data;
+	struct cppi5_host_desc_t *desc_tx;
+	struct sk_buff *skb;
+	void **swdata;
+
+	desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma);
+	swdata = cppi5_hdesc_get_swdata(desc_tx);
+	skb = *(swdata);
+	vport_xmit_free(tx_chn, desc_tx);
+
+	dev_kfree_skb_any(skb);
+}
+
+static void vport_rx_cleanup(void *data, dma_addr_t desc_dma)
+{
+	struct rx_dma_chan *rx_chn = data;
+	struct cppi5_host_desc_t *desc_rx;
+	struct sk_buff *skb;
+	dma_addr_t buf_dma;
+	u32 buf_dma_len;
+	void **swdata;
+
+	desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma);
+	swdata = cppi5_hdesc_get_swdata(desc_rx);
+	skb = *swdata;
+	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
+	k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chan, &buf_dma);
+
+	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE);
+	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
+
+	dev_kfree_skb_any(skb);
+}
+
+static int vport_add_mcast(struct net_device *ndev, const u8 *addr)
+{
+	struct cpsw_proxy_req_params *req_p;
+	struct cpsw_proxy_priv *proxy_priv;
+	struct net_device *vport_ndev;
+	struct rx_dma_chan *rx_chn;
+	struct virtual_port *vport;
+	struct message resp_msg;
+	int ret;
+
+	if (is_vlan_dev(ndev))
+		vport_ndev = vlan_dev_real_dev(ndev);
+	else
+		vport_ndev = ndev;
+
+	vport = vport_ndev_to_vport(vport_ndev);
+	proxy_priv = vport->proxy_priv;
+	rx_chn = &vport->rx_chans[0];
+
+	mutex_lock(&proxy_priv->req_params_mutex);
+	req_p = &proxy_priv->req_params;
+	req_p->request_type = ETHFW_MCAST_FILTER_ADD;
+	req_p->token = vport->port_token;
+	req_p->vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : ETHFW_DFLT_VLAN;
+	req_p->rx_flow_base = rx_chn->flow_base;
+	req_p->rx_flow_offset = rx_chn->flow_offset;
+	ether_addr_copy(req_p->mac_addr, addr);
+	ret = send_request_get_response(proxy_priv, &resp_msg);
+	mutex_unlock(&proxy_priv->req_params_mutex);
+
+	if (ret == ETHFW_RES_EBADARGS) {
+		dev_info(proxy_priv->dev, "%02x:%02x:%02x:%02x:%02x:%02x is reserved for EthFw\n",
+			 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+
+		return 0;
+	} else if (ret) {
+		dev_err(proxy_priv->dev, "adding %02x:%02x:%02x:%02x:%02x:%02x failed: %d\n",
+			addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], ret);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int vport_del_mcast(struct net_device *ndev, const u8 *addr)
+{
+	struct cpsw_proxy_req_params *req_p;
+	struct cpsw_proxy_priv *proxy_priv;
+	struct net_device *vport_ndev;
+	struct virtual_port *vport;
+	struct message resp_msg;
+	int ret;
+
+	if (is_vlan_dev(ndev))
+		vport_ndev = vlan_dev_real_dev(ndev);
+	else
+		vport_ndev = ndev;
+
+	vport = vport_ndev_to_vport(vport_ndev);
+	proxy_priv = vport->proxy_priv;
+
+	mutex_lock(&proxy_priv->req_params_mutex);
+	req_p = &proxy_priv->req_params;
+	req_p->request_type = ETHFW_MCAST_FILTER_DEL;
+	req_p->token = vport->port_token;
+	req_p->vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : ETHFW_DFLT_VLAN;
+	ether_addr_copy(req_p->mac_addr, addr);
+	ret = send_request_get_response(proxy_priv, &resp_msg);
+	mutex_unlock(&proxy_priv->req_params_mutex);
+
+	if (ret == ETHFW_RES_EBADARGS) {
+		dev_info(proxy_priv->dev, "%02x:%02x:%02x:%02x:%02x:%02x is reserved for EthFw\n",
+			 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+		return 0;
+	} else if (ret) {
+		dev_err(proxy_priv->dev, "deleting %02x:%02x:%02x:%02x:%02x:%02x failed: %d\n",
+			addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], ret);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int vport_update_vlan_mcast(struct net_device *vdev, int vid,
+				   void *args)
+{
+	struct net_device *vport_ndev;
+	struct virtual_port *vport;
+
+	if (!vdev || !vid)
+		return 0;
+
+	vport_ndev = vlan_dev_real_dev(vdev);
+	vport = vport_ndev_to_vport(vport_ndev);
+
+	netif_addr_lock_bh(vdev);
+	__hw_addr_sync_multiple(&vport->vlan_mcast_list[vid], &vdev->mc, vdev->addr_len);
+	netif_addr_unlock_bh(vdev);
+
+	__hw_addr_sync_dev(&vport->vlan_mcast_list[vid], vdev,
+			   vport_add_mcast, vport_del_mcast);
+
+	return 0;
+}
+static void vport_stop(struct virtual_port *vport)
+{
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	struct rx_dma_chan *rx_chn;
+	struct tx_dma_chan *tx_chn;
+	int i;
+
+	/* shutdown tx channels */
+	atomic_set(&vport->tdown_cnt, vport->num_tx_chan);
+	/* ensure new tdown_cnt value is visible */
+	smp_mb__after_atomic();
+	reinit_completion(&vport->tdown_complete);
+
+	for (i = 0; i < vport->num_tx_chan; i++)
+		k3_udma_glue_tdown_tx_chn(vport->tx_chans[i].tx_chan, false);
+
+	i = wait_for_completion_timeout(&vport->tdown_complete, msecs_to_jiffies(1000));
+	if (!i)
+		dev_err(proxy_priv->dev, "tx teardown timeout\n");
+
+	for (i = 0; i < vport->num_tx_chan; i++) {
+		tx_chn = &vport->tx_chans[i];
+		k3_udma_glue_reset_tx_chn(tx_chn->tx_chan, tx_chn, vport_tx_cleanup);
+		k3_udma_glue_disable_tx_chn(tx_chn->tx_chan);
+		napi_disable(&tx_chn->napi_tx);
+		hrtimer_cancel(&tx_chn->tx_hrtimer);
+	}
+
+	for (i = 0; i < vport->num_rx_chan; i++) {
+		rx_chn = &vport->rx_chans[i];
+		k3_udma_glue_rx_flow_disable(rx_chn->rx_chan, 0);
+		/* Need some delay to process RX ring before reset */
+		msleep(100);
+		k3_udma_glue_reset_rx_chn(rx_chn->rx_chan, 0, rx_chn, vport_rx_cleanup,
+					  false);
+		napi_disable(&rx_chn->napi_rx);
+		hrtimer_cancel(&rx_chn->rx_hrtimer);
+	}
+
+	if (vport->port_features & ETHFW_MCAST_FILTERING)
+		cancel_work_sync(&vport->rx_mode_work);
+}
+
+static int vport_open(struct virtual_port *vport, netdev_features_t features)
+{
+	struct rx_dma_chan *rx_chn;
+	struct tx_dma_chan *tx_chn;
+	struct sk_buff *skb;
+	u32 i, j;
+	int ret;
+
+	for (i = 0; i < vport->num_rx_chan; i++) {
+		rx_chn = &vport->rx_chans[i];
+
+		for (j = 0; j < rx_chn->num_descs; j++) {
+			skb = __netdev_alloc_skb_ip_align(NULL, MAX_PACKET_SIZE, GFP_KERNEL);
+			if (!skb)
+				return -ENOMEM;
+
+			ret = vport_rx_push(vport, skb, i);
+			if (ret < 0) {
+				netdev_err(vport->ndev,
+					   "cannot submit skb to rx channel\n");
+				kfree_skb(skb);
+				return ret;
+			}
+			kmemleak_not_leak(skb);
+		}
+
+		ret = k3_udma_glue_rx_flow_enable(rx_chn->rx_chan, 0);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; i < vport->num_tx_chan; i++) {
+		tx_chn = &vport->tx_chans[i];
+		ret = k3_udma_glue_enable_tx_chn(tx_chn->tx_chan);
+		if (ret)
+			return ret;
+		napi_enable(&tx_chn->napi_tx);
+	}
+
+	for (i = 0; i < vport->num_rx_chan; i++) {
+		rx_chn = &vport->rx_chans[i];
+		napi_enable(&rx_chn->napi_rx);
+		if (rx_chn->rx_irq_disabled) {
+			rx_chn->rx_irq_disabled = false;
+			enable_irq(rx_chn->irq);
+		}
+	}
+
+	return 0;
+}
+
+static int vport_ndo_stop(struct net_device *ndev)
+{
+	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	int ret;
+
+	netif_tx_stop_all_queues(ndev);
+	netif_carrier_off(ndev);
+
+	ret = deregister_mac(vport);
+	if (ret)
+		netdev_err(ndev, "failed to deregister MAC for port %u\n",
+			   vport->port_id);
+
+	__dev_mc_unsync(ndev, vport_del_mcast);
+	__hw_addr_init(&vport->mcast_list);
+	vport_stop(vport);
+
+	dev_info(proxy_priv->dev, "stopped port %u on interface %s\n",
+		 vport->port_id, ndev->name);
+
+	return 0;
+}
+
+static int vport_ndo_open(struct net_device *ndev)
+{
+	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	int ret;
+	u32 i;
+
+	ret = netif_set_real_num_tx_queues(ndev, vport->num_tx_chan);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < vport->num_tx_chan; i++)
+		netdev_tx_reset_queue(netdev_get_tx_queue(ndev, i));
+
+	ret = vport_open(vport, ndev->features);
+	if (ret)
+		return ret;
+
+	ret = register_mac(vport);
+	if (ret) {
+		netdev_err(ndev, "failed to register MAC for port: %u\n",
+			   vport->port_id);
+		vport_stop(vport);
+		return -EIO;
+	}
+
+	netif_tx_wake_all_queues(ndev);
+	netif_carrier_on(ndev);
+
+	dev_info(proxy_priv->dev, "started port %u on interface %s\n",
+		 vport->port_id, ndev->name);
+
+	return 0;
+}
+
+static netdev_tx_t vport_ndo_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	struct cppi5_host_desc_t *first_desc, *next_desc, *cur_desc;
+	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	struct device *dev = proxy_priv->dev;
+	struct netdev_queue *netif_txq;
+	dma_addr_t desc_dma, buf_dma;
+	struct tx_dma_chan *tx_chn;
+	void **swdata;
+	int ret, i, q;
+	u32 pkt_len;
+	u32 *psdata;
+
+	/* padding enabled in hw */
+	pkt_len = skb_headlen(skb);
+
+	/* Get Queue / TX DMA Channel for the SKB */
+	q = skb_get_queue_mapping(skb);
+	tx_chn = &vport->tx_chans[q];
+	netif_txq = netdev_get_tx_queue(ndev, q);
+
+	/* Map the linear buffer */
+	buf_dma = dma_map_single(tx_chn->dma_dev, skb->data, pkt_len, DMA_TO_DEVICE);
+	if (unlikely(dma_mapping_error(tx_chn->dma_dev, buf_dma))) {
+		dev_err(dev, "Failed to map tx skb buffer\n");
+		ndev->stats.tx_errors++;
+		goto drop_free_skb;
+	}
+
+	first_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool);
+	if (!first_desc) {
+		dev_dbg(dev, "Failed to allocate descriptor\n");
+		dma_unmap_single(tx_chn->dma_dev, buf_dma, pkt_len, DMA_TO_DEVICE);
+		goto busy_stop_q;
+	}
+
+	cppi5_hdesc_init(first_desc, CPPI5_INFO0_HDESC_EPIB_PRESENT,
+			 PS_DATA_SIZE);
+	cppi5_desc_set_pktids(&first_desc->hdr, 0, 0x3FFF);
+	cppi5_hdesc_set_pkttype(first_desc, 0x7);
+
+	/* For Virtual Switch Ports, ALE will determine the destination.
+	 * For Virtual MAC Ports, a directed packet (ALE Bypass) should
+	 * be sent to the physical MAC Port.
+	 */
+	if (vport->port_type == VIRT_SWITCH_PORT)
+		cppi5_desc_set_tags_ids(&first_desc->hdr, 0, 0);
+	else
+		cppi5_desc_set_tags_ids(&first_desc->hdr, 0, vport->port_id);
+
+	k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chan, &buf_dma);
+	cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len);
+	swdata = cppi5_hdesc_get_swdata(first_desc);
+	*(swdata) = skb;
+	psdata = cppi5_hdesc_get_psdata(first_desc);
+
+	/* HW csum offload if enabled */
+	psdata[2] = 0;
+	if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+		unsigned int cs_start, cs_offset;
+
+		cs_start = skb_transport_offset(skb);
+		cs_offset = cs_start + skb->csum_offset;
+		/* HW numerates bytes starting from 1 */
+		psdata[2] = ((cs_offset + 1) << 24) |
+			    ((cs_start + 1) << 16) | (skb->len - cs_start);
+		dev_dbg(dev, "%s tx psdata:%#x\n", __func__, psdata[2]);
+	}
+
+	if (!skb_is_nonlinear(skb))
+		goto done_tx;
+
+	dev_dbg(dev, "fragmented SKB\n");
+
+	/* Handle the case where skb is fragmented in pages */
+	cur_desc = first_desc;
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+		u32 frag_size = skb_frag_size(frag);
+
+		next_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool);
+		if (!next_desc) {
+			dev_err(dev, "Failed to allocate descriptor\n");
+			goto busy_free_descs;
+		}
+
+		buf_dma = skb_frag_dma_map(tx_chn->dma_dev, frag, 0, frag_size, DMA_TO_DEVICE);
+		if (unlikely(dma_mapping_error(tx_chn->dma_dev, buf_dma))) {
+			dev_err(dev, "Failed to map tx skb page\n");
+			k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc);
+			ndev->stats.tx_errors++;
+			goto drop_free_descs;
+		}
+
+		cppi5_hdesc_reset_hbdesc(next_desc);
+		k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chan, &buf_dma);
+		cppi5_hdesc_attach_buf(next_desc, buf_dma, frag_size, buf_dma, frag_size);
+
+		desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, next_desc);
+		k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chan, &desc_dma);
+		cppi5_hdesc_link_hbdesc(cur_desc, desc_dma);
+
+		pkt_len += frag_size;
+		cur_desc = next_desc;
+	}
+	WARN_ON(pkt_len != skb->len);
+
+done_tx:
+	skb_tx_timestamp(skb);
+
+	/* report bql before sending packet */
+	dev_dbg(dev, "push 0 %d Bytes\n", pkt_len);
+
+	netdev_tx_sent_queue(netif_txq, pkt_len);
+
+	cppi5_hdesc_set_pktlen(first_desc, pkt_len);
+	desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc);
+	ret = k3_udma_glue_push_tx_chn(tx_chn->tx_chan, first_desc, desc_dma);
+	if (ret) {
+		dev_err(dev, "can't push desc %d\n", ret);
+		/* inform bql */
+		netdev_tx_completed_queue(netif_txq, 1, pkt_len);
+		ndev->stats.tx_errors++;
+		goto drop_free_descs;
+	}
+
+	if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) < MAX_SKB_FRAGS) {
+		netif_tx_stop_queue(netif_txq);
+		/* Barrier, so that stop_queue visible to other cpus */
+		smp_mb__after_atomic();
+		dev_dbg(dev, "netif_tx_stop_queue %d\n", q);
+
+		/* re-check for smp */
+		if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) >=
+		    MAX_SKB_FRAGS) {
+			netif_tx_wake_queue(netif_txq);
+			dev_dbg(dev, "netif_tx_wake_queue %d\n", q);
+		}
+	}
+
+	return NETDEV_TX_OK;
+
+drop_free_descs:
+	vport_xmit_free(tx_chn, first_desc);
+drop_free_skb:
+	ndev->stats.tx_dropped++;
+	dev_kfree_skb_any(skb);
+	return NETDEV_TX_OK;
+
+busy_free_descs:
+	vport_xmit_free(tx_chn, first_desc);
+busy_stop_q:
+	netif_tx_stop_queue(netif_txq);
+	return NETDEV_TX_BUSY;
+}
+
+static void vport_ndo_get_stats(struct net_device *ndev,
+				struct rtnl_link_stats64 *stats)
+{
+	struct vport_netdev_priv *ndev_priv = netdev_priv(ndev);
+	unsigned int start;
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		struct vport_netdev_stats *cpu_stats;
+		u64 rx_packets;
+		u64 rx_bytes;
+		u64 tx_packets;
+		u64 tx_bytes;
+
+		cpu_stats = per_cpu_ptr(ndev_priv->stats, cpu);
+		do {
+			start = u64_stats_fetch_begin(&cpu_stats->syncp);
+			rx_packets = cpu_stats->rx_packets;
+			rx_bytes   = cpu_stats->rx_bytes;
+			tx_packets = cpu_stats->tx_packets;
+			tx_bytes   = cpu_stats->tx_bytes;
+		} while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
+
+		stats->rx_packets += rx_packets;
+		stats->rx_bytes   += rx_bytes;
+		stats->tx_packets += tx_packets;
+		stats->tx_bytes   += tx_bytes;
+	}
+
+	stats->rx_errors	= ndev->stats.rx_errors;
+	stats->rx_dropped	= ndev->stats.rx_dropped;
+	stats->tx_dropped	= ndev->stats.tx_dropped;
+}
+
+static void vport_ndo_tx_timeout(struct net_device *ndev, unsigned int txqueue)
+{
+	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+	struct netdev_queue *netif_txq;
+	struct tx_dma_chan *tx_chn;
+	unsigned long trans_start;
+
+	/* process every txq */
+	netif_txq = netdev_get_tx_queue(ndev, txqueue);
+	tx_chn = &vport->tx_chans[txqueue];
+	trans_start = READ_ONCE(netif_txq->trans_start);
+
+	netdev_err(ndev, "txq:%d DRV_XOFF: %d tmo: %u dql_avail:%d free_desc:%zu\n",
+		   txqueue, netif_tx_queue_stopped(netif_txq),
+		   jiffies_to_msecs(jiffies - trans_start),
+		   dql_avail(&netif_txq->dql),
+		   k3_cppi_desc_pool_avail(tx_chn->desc_pool));
+
+	if (netif_tx_queue_stopped(netif_txq)) {
+		/* try to recover if it was stopped by driver */
+		txq_trans_update(netif_txq);
+		netif_tx_wake_queue(netif_txq);
+	}
+}
+
+static void vport_set_rx_mode_work(struct work_struct *work)
+{
+	struct virtual_port *vport = container_of(work, struct virtual_port, rx_mode_work);
+	struct net_device *ndev = vport->ndev;
+
+	if (unlikely(ndev->flags & IFF_PROMISC)) {
+		netdev_err(ndev, "promiscuous mode is not supported\n");
+		return;
+	}
+
+	if (likely(vport->port_features & ETHFW_MCAST_FILTERING)) {
+		netif_addr_lock_bh(ndev);
+		__hw_addr_sync(&vport->mcast_list, &ndev->mc, ndev->addr_len);
+		netif_addr_unlock_bh(ndev);
+
+		__hw_addr_sync_dev(&vport->mcast_list, ndev,
+				   vport_add_mcast, vport_del_mcast);
+
+		if (rtnl_trylock()) {
+			vlan_for_each(ndev, vport_update_vlan_mcast, NULL);
+			rtnl_unlock();
+		}
+	}
+}
+
+static void vport_set_rx_mode(struct net_device *ndev)
+{
+	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+
+	if (vport->port_features & ETHFW_MCAST_FILTERING)
+		queue_work(vport->vport_wq, &vport->rx_mode_work);
+}
+
+static int vport_add_vid(struct net_device *ndev, __be16 proto, u16 vid)
+{
+	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	struct rx_dma_chan *rx_chn = &vport->rx_chans[0];
+	struct cpsw_proxy_req_params *req_p;
+	struct message resp_msg;
+	int ret;
+
+	if (!netif_running(ndev) || !vid)
+		return 0;
+
+	mutex_lock(&proxy_priv->req_params_mutex);
+	req_p = &proxy_priv->req_params;
+	req_p->request_type = ETHFW_JOIN_VLAN;
+	req_p->token = vport->port_token;
+	req_p->vlan_id = vid;
+	req_p->rx_flow_base = rx_chn->flow_base;
+	req_p->rx_flow_offset = rx_chn->flow_offset;
+	ether_addr_copy(req_p->mac_addr, vport->mac_addr);
+	ret = send_request_get_response(proxy_priv, &resp_msg);
+	mutex_unlock(&proxy_priv->req_params_mutex);
+
+	if (ret) {
+		ret = -EINVAL;
+		dev_err(proxy_priv->dev, "failed to add VLAN: %u err: %d\n", vid, ret);
+	}
+
+	__hw_addr_init(&vport->vlan_mcast_list[vid]);
+
+	return ret;
+}
+
+static int vport_free_vlan_mcast(struct net_device *vdev, int vid,
+				 void *args)
+{
+	struct net_device *vport_ndev;
+	struct virtual_port *vport;
+	u16 *target_vid = args;
+
+	if (vid != *target_vid)
+		return 0;
+
+	vport_ndev = vlan_dev_real_dev(vdev);
+	vport = vport_ndev_to_vport(vport_ndev);
+
+	__hw_addr_unsync_dev(&vport->vlan_mcast_list[vid], vdev,
+			     vport_del_mcast);
+
+	return 0;
+}
+
+static int vport_del_vid(struct net_device *ndev, __be16 proto, u16 vid)
+{
+	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	struct rx_dma_chan *rx_chn = &vport->rx_chans[0];
+	struct cpsw_proxy_req_params *req_p;
+	struct message resp_msg;
+	int ret;
+
+	if (!netif_running(ndev) || !vid)
+		return 0;
+
+	if (rtnl_trylock()) {
+		vlan_for_each(ndev, vport_free_vlan_mcast, &vid);
+		rtnl_unlock();
+	}
+
+	mutex_lock(&proxy_priv->req_params_mutex);
+	req_p = &proxy_priv->req_params;
+	req_p->request_type = ETHFW_LEAVE_VLAN;
+	req_p->token = vport->port_token;
+	req_p->vlan_id = vid;
+	req_p->rx_flow_base = rx_chn->flow_base;
+	req_p->rx_flow_offset = rx_chn->flow_offset;
+	ether_addr_copy(req_p->mac_addr, vport->mac_addr);
+	ret = send_request_get_response(proxy_priv, &resp_msg);
+	mutex_unlock(&proxy_priv->req_params_mutex);
+
+	if (ret) {
+		ret = -EINVAL;
+		dev_err(proxy_priv->dev, "failed to delete VLAN: %u err: %d\n", vid, ret);
+	}
+
+	return ret;
+}
+
+static const struct net_device_ops cpsw_proxy_client_netdev_ops = {
+	.ndo_open		= vport_ndo_open,
+	.ndo_stop		= vport_ndo_stop,
+	.ndo_start_xmit		= vport_ndo_xmit,
+	.ndo_get_stats64	= vport_ndo_get_stats,
+	.ndo_tx_timeout		= vport_ndo_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_set_rx_mode	= vport_set_rx_mode,
+	.ndo_vlan_rx_add_vid	= vport_add_vid,
+	.ndo_vlan_rx_kill_vid	= vport_del_vid,
+};
+
+static int init_netdev(struct cpsw_proxy_priv *proxy_priv, struct virtual_port *vport)
+{
+	struct device *dev = proxy_priv->dev;
+	struct vport_netdev_priv *ndev_priv;
+	struct rx_dma_chan *rx_chn;
+	struct tx_dma_chan *tx_chn;
+	int ret = 0;
+	u32 i;
+
+	vport->ndev = devm_alloc_etherdev_mqs(dev, sizeof(struct vport_netdev_priv),
+					      vport->num_tx_chan, vport->num_rx_chan);
+
+	if (!vport->ndev) {
+		dev_err(dev, "error allocating netdev for port %u\n", vport->port_id);
+		return -ENOMEM;
+	}
+
+	ndev_priv = netdev_priv(vport->ndev);
+	ndev_priv->vport = vport;
+	SET_NETDEV_DEV(vport->ndev, dev);
+
+	if (is_valid_ether_addr(vport->mac_addr))
+		eth_hw_addr_set(vport->ndev, vport->mac_addr);
+
+	vport->ndev->min_mtu = MIN_PACKET_SIZE;
+	vport->ndev->max_mtu = MAX_PACKET_SIZE;
+	vport->ndev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM;
+	vport->ndev->features = vport->ndev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER;
+	vport->ndev->vlan_features |= NETIF_F_SG;
+	vport->ndev->netdev_ops = &cpsw_proxy_client_netdev_ops;
+	vport->ndev->ethtool_ops = &cpsw_proxy_client_ethtool_ops;
+
+	ndev_priv->stats = netdev_alloc_pcpu_stats(struct vport_netdev_stats);
+	if (!ndev_priv->stats)
+		return -ENOMEM;
+
+	ret = devm_add_action_or_reset(dev, (void(*)(void *))free_percpu, ndev_priv->stats);
+	if (ret) {
+		dev_err(dev, "failed to add free_percpu action, err: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < vport->num_tx_chan; i++) {
+		tx_chn = &vport->tx_chans[i];
+		netif_napi_add_tx(vport->ndev, &tx_chn->napi_tx, vport_tx_poll);
+		hrtimer_init(&tx_chn->tx_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED);
+		tx_chn->tx_hrtimer.function = &vport_tx_timer_cb;
+	}
+
+	for (i = 0; i < vport->num_rx_chan; i++) {
+		rx_chn = &vport->rx_chans[i];
+		netif_napi_add(vport->ndev, &rx_chn->napi_rx, vport_rx_poll);
+		hrtimer_init(&rx_chn->rx_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED);
+		rx_chn->rx_hrtimer.function = &vport_rx_timer_cb;
+	}
+
+	ret = register_netdev(vport->ndev);
+	if (ret)
+		dev_err(dev, "error registering net device, err: %d\n", ret);
+
+	return ret;
+}
+
+static void unreg_netdevs(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct virtual_port *vport;
+	u32 i;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+		if (vport->ndev)
+			unregister_netdev(vport->ndev);
+	}
+}
+
+static void destroy_vport_wqs(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct virtual_port *vport;
+	u32 i;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+		if (vport->vport_wq)
+			destroy_workqueue(vport->vport_wq);
+	}
+}
+
+static int create_vport_wqs(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct virtual_port *vport;
+	char wq_name[IFNAMSIZ];
+	u32 i;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+		if (!(vport->port_features & ETHFW_MCAST_FILTERING))
+			continue;
+
+		snprintf(wq_name, sizeof(wq_name), "vport_%d", vport->port_id);
+		__hw_addr_init(&vport->mcast_list);
+		INIT_WORK(&vport->rx_mode_work, vport_set_rx_mode_work);
+		vport->vport_wq = create_singlethread_workqueue(wq_name);
+		if (!vport->vport_wq) {
+			dev_err(proxy_priv->dev, "failed to create wq %s\n", wq_name);
+			goto err;
+		}
+	}
+
+	return 0;
+
+err:
+	destroy_vport_wqs(proxy_priv);
+	return -ENOMEM;
+}
+
+static int init_netdevs(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct virtual_port *vport;
+	int ret;
+	u32 i;
+
+	ret = create_vport_wqs(proxy_priv);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+		ret = init_netdev(proxy_priv, vport);
+		if (ret) {
+			dev_err(proxy_priv->dev, "failed to initialize ndev for port %u\n",
+				vport->port_id);
+			goto err;
+		}
+	}
+
+	return 0;
+
+err:
+	unreg_netdevs(proxy_priv);
+	return ret;
+}
+
+static irqreturn_t tx_irq_handler(int irq, void *dev_id)
+{
+	struct tx_dma_chan *tx_chn = dev_id;
+
+	disable_irq_nosync(irq);
+	napi_schedule(&tx_chn->napi_tx);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t rx_irq_handler(int irq, void *dev_id)
+{
+	struct rx_dma_chan *rx_chn = dev_id;
+
+	rx_chn->rx_irq_disabled = true;
+	disable_irq_nosync(irq);
+	napi_schedule(&rx_chn->napi_rx);
+
+	return IRQ_HANDLED;
+}
+
+static int register_dma_irq_handlers(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct device *dev = proxy_priv->dev;
+	struct rx_dma_chan *rx_chn;
+	struct tx_dma_chan *tx_chn;
+	struct virtual_port *vport;
+	u32 i, j;
+	int ret;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+
+		for (j = 0; j < vport->num_tx_chan; j++) {
+			tx_chn = &vport->tx_chans[j];
+
+			ret = devm_request_irq(dev, tx_chn->irq, tx_irq_handler,
+					       IRQF_TRIGGER_HIGH, tx_chn->tx_chan_name, tx_chn);
+			if (ret) {
+				dev_err(dev, "failed to request tx irq: %u, err: %d\n",
+					tx_chn->irq, ret);
+				return ret;
+			}
+		}
+
+		for (j = 0; j < vport->num_rx_chan; j++) {
+			rx_chn = &vport->rx_chans[j];
+
+			ret = devm_request_irq(dev, rx_chn->irq, rx_irq_handler,
+					       IRQF_TRIGGER_HIGH, rx_chn->rx_chan_name, rx_chn);
+			if (ret) {
+				dev_err(dev, "failed to request rx irq: %u, err: %d\n",
+					rx_chn->irq, ret);
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int register_ipv4(struct virtual_port *vport)
+{
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	struct device *dev = proxy_priv->dev;
+	struct cpsw_proxy_req_params *req_p;
+	struct message resp_msg;
+	int ret;
+
+	mutex_lock(&proxy_priv->req_params_mutex);
+	req_p = &proxy_priv->req_params;
+	req_p->request_type = ETHFW_IPv4_REGISTER;
+	req_p->token = vport->port_token;
+	memcpy(req_p->ipv4_addr, vport->ipv4_addr, ETHFW_IPV4ADDRLEN);
+	ether_addr_copy(req_p->mac_addr, vport->mac_addr);
+	ret = send_request_get_response(proxy_priv, &resp_msg);
+	mutex_unlock(&proxy_priv->req_params_mutex);
+
+	if (ret) {
+		dev_err(dev, "failed to register IPv4 Address err: %d\n", ret);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int deregister_ipv4(struct virtual_port *vport)
+{
+	struct cpsw_proxy_priv *proxy_priv = vport->proxy_priv;
+	struct device *dev = proxy_priv->dev;
+	struct cpsw_proxy_req_params *req_p;
+	struct message resp_msg;
+	int ret;
+
+	mutex_lock(&proxy_priv->req_params_mutex);
+	req_p = &proxy_priv->req_params;
+	req_p->request_type = ETHFW_IPv4_DEREGISTER;
+	req_p->token = vport->port_token;
+	memcpy(req_p->ipv4_addr, vport->ipv4_addr, ETHFW_IPV4ADDRLEN);
+	ret = send_request_get_response(proxy_priv, &resp_msg);
+	mutex_unlock(&proxy_priv->req_params_mutex);
+
+	if (ret) {
+		dev_err(dev, "failed to deregister IPv4 Address err: %d\n", ret);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static bool cpsw_proxy_client_check(const struct net_device *ndev)
+{
+	struct virtual_port *vport = vport_ndev_to_vport(ndev);
+
+	return ndev->netdev_ops == &cpsw_proxy_client_netdev_ops &&
+				   vport->port_type == VIRT_SWITCH_PORT;
+}
+
+static int cpsw_proxy_client_inetaddr(struct notifier_block *unused,
+				      unsigned long event, void *ptr)
+{
+	struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
+	struct virtual_port *vport;
+	struct net_device *ndev;
+	int ret = 0;
+
+	ndev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
+	if (!ndev)
+		return NOTIFY_DONE;
+
+	if (!cpsw_proxy_client_check(ndev))
+		return NOTIFY_DONE;
+
+	vport = vport_ndev_to_vport(ndev);
+	memcpy(vport->ipv4_addr, &ifa->ifa_address, ETHFW_IPV4ADDRLEN);
+
+	switch (event) {
+	case NETDEV_UP:
+	case NETDEV_CHANGEADDR:
+		ret = register_ipv4(vport);
+		if (ret)
+			netdev_err(ndev, "IPv4 register failed: %d\n", ret);
+		break;
+
+	case NETDEV_DOWN:
+	case NETDEV_PRE_CHANGEADDR:
+		ret = deregister_ipv4(vport);
+		if (ret)
+			netdev_err(ndev, "IPv4 deregister failed: %d\n", ret);
+		break;
+	}
+
+	return notifier_from_errno(ret);
+}
+
+static void unregister_notifiers(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct virtual_port *vport;
+	u32 i;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+		if (vport->port_type == VIRT_SWITCH_PORT)
+			unregister_inetaddr_notifier(&vport->inetaddr_nb);
+	}
+}
+
+static void register_notifiers(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct virtual_port *vport;
+	u32 i;
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+		if (vport->port_type == VIRT_SWITCH_PORT) {
+			vport->inetaddr_nb.notifier_call = cpsw_proxy_client_inetaddr;
+			register_inetaddr_notifier(&vport->inetaddr_nb);
+		}
+	}
+}
+
+static void show_info(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct device *dev = proxy_priv->dev;
+	struct virtual_port *vport;
+	u32 i;
+
+	dev_info(dev, "%u Virtual Switch Port(s), %u Virtual MAC Only Port(s)\n",
+		 proxy_priv->num_switch_ports, proxy_priv->num_mac_ports);
+
+	for (i = 0; i < proxy_priv->num_virt_ports; i++) {
+		vport = &proxy_priv->virt_ports[i];
+
+		if (vport->port_type == VIRT_SWITCH_PORT)
+			dev_info(dev, "Virt Port: %u, Type: Switch Port, Iface: %s, Num TX: %u, Num RX: %u, Token: %u\n",
+				 vport->port_id, vport->ndev->name, vport->num_tx_chan,
+				 vport->num_rx_chan, vport->port_token);
+		else
+			dev_info(dev, "Virt Port: %u, Type: MAC Port, Iface: %s, Num TX: %u, Num RX: %u, Token: %u\n",
+				 vport->port_id, vport->ndev->name, vport->num_tx_chan,
+				 vport->num_rx_chan, vport->port_token);
+	}
+}
+
+struct client_soc_data {
+	const char	*dma_compatible;
+};
+
+static const struct client_soc_data j721e_soc_data = {
+	.dma_compatible = "ti,j721e-navss-main-udmap",
+};
+
+static const struct client_soc_data am62px_soc_data = {
+	.dma_compatible = "ti,am64-dmss-pktdma",
+};
+
+static const struct soc_device_attribute soc_dma_type[] = {
+	{ .family = "J7200", .data = &j721e_soc_data },
+	{ .family = "J721E", .data = &j721e_soc_data },
+	{ .family = "J784S4", .data = &j721e_soc_data },
+	{ .family = "AM62PX", .data = &am62px_soc_data },
+};
+
+static int cpsw_proxy_client_probe(struct rpmsg_device *rpdev)
+{
+	const struct soc_device_attribute *soc_match_data;
+	struct cpsw_proxy_priv *proxy_priv;
+	int ret;
+
+	proxy_priv = devm_kzalloc(&rpdev->dev, sizeof(struct cpsw_proxy_priv), GFP_KERNEL);
+	if (!proxy_priv)
+		return -ENOMEM;
+
+	proxy_priv->rpdev = rpdev;
+	proxy_priv->dev = &rpdev->dev;
+	soc_match_data = soc_device_match(soc_dma_type);
+	if (soc_match_data && soc_match_data->data) {
+		const struct client_soc_data *socdata = soc_match_data->data;
+
+		proxy_priv->dma_node =
+			of_find_compatible_node(NULL, NULL,
+						socdata->dma_compatible);
+	} else {
+		dev_err(proxy_priv->dev, "SoC not supported\n");
+		return -ENODEV;
+	}
+
+	dev_set_drvdata(proxy_priv->dev, proxy_priv);
+	dev_dbg(proxy_priv->dev, "driver probed\n");
+
+	proxy_priv->req_params.token = ETHFW_TOKEN_NONE;
+	proxy_priv->req_params.client_id = ETHFW_LINUX_CLIENT_TOKEN;
+	mutex_init(&proxy_priv->req_params_mutex);
+	init_completion(&proxy_priv->wait_for_response);
+
+	ret = get_virtual_port_info(proxy_priv);
+	if (ret)
+		return -EIO;
+
+	ret = attach_virtual_ports(proxy_priv);
+	if (ret)
+		return -EIO;
+
+	ret = allocate_port_resources(proxy_priv);
+	if (ret)
+		goto err_attach;
+
+	ret = init_tx_chans(proxy_priv);
+	if (ret)
+		goto err_attach;
+
+	ret = init_rx_chans(proxy_priv);
+	if (ret)
+		goto err_attach;
+
+	ret = init_netdevs(proxy_priv);
+	if (ret)
+		goto err_attach;
+
+	ret = register_dma_irq_handlers(proxy_priv);
+	if (ret)
+		goto err_netdevs;
+
+	register_notifiers(proxy_priv);
+	show_info(proxy_priv);
+
+	return 0;
+
+err_netdevs:
+	unreg_netdevs(proxy_priv);
+err_attach:
+	detach_virtual_ports(proxy_priv);
+	return ret;
+}
+
+static void cpsw_proxy_client_remove(struct rpmsg_device *rpdev)
+{
+	struct cpsw_proxy_priv *proxy_priv;
+	struct device *dev = &rpdev->dev;
+
+	dev_dbg(dev, "driver removed\n");
+	proxy_priv = dev_get_drvdata(&rpdev->dev);
+	unregister_notifiers(proxy_priv);
+	unreg_netdevs(proxy_priv);
+	destroy_vport_wqs(proxy_priv);
+	detach_virtual_ports(proxy_priv);
+}
+
+static struct rpmsg_device_id cpsw_proxy_client_id_table[] = {
+	{
+		.name = ETHFW_SERVICE_EP_NAME,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(rpmsg, cpsw_proxy_client_id_table);
+
+static struct rpmsg_driver cpsw_proxy_client_driver = {
+	.drv.name	= KBUILD_MODNAME,
+	.id_table	= cpsw_proxy_client_id_table,
+	.probe		= cpsw_proxy_client_probe,
+	.callback	= cpsw_proxy_client_cb,
+	.remove		= cpsw_proxy_client_remove,
+};
+module_rpmsg_driver(cpsw_proxy_client_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CPSW Proxy Client Driver");
+MODULE_AUTHOR("Siddharth Vadapalli <s-vadapalli@ti.com>");
diff -Naur --no-dereference a/drivers/net/ethernet/ti/ethfw_abi.h b/drivers/net/ethernet/ti/ethfw_abi.h
--- a/drivers/net/ethernet/ti/ethfw_abi.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/ethernet/ti/ethfw_abi.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,405 @@
+/* SPDX-License-Identifier: GPL-2.0-only or MIT */
+/* Texas Instruments Ethernet Switch Firmware (EthFw) ABIs
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+#ifndef __ETHFW_ABI_H_
+#define __ETHFW_ABI_H_
+
+/* Name of the RPMsg Endpoint announced by EthFw on the RPMsg-Bus */
+#define ETHFW_SERVICE_EP_NAME	"ti.ethfw.ethdevice"
+
+/* Response status set by EthFw on the Success of a Request */
+#define ETHFW_RES_OK			(0)
+
+/* Response status set by EthFw when an operation is in progress */
+#define ETHFW_RES_SINPROGRESS		(1)
+
+/* Response status set by EthFw on the Failure of a Request */
+#define ETHFW_RES_EFAIL			(-1)
+
+/* Response status set by EthFw when Client passes wrong arguments */
+#define ETHFW_RES_EBADARGS		(-2)
+
+/* Default VLAN ID for a Virtual Port */
+#define ETHFW_DFLT_VLAN			0xFFFF
+
+/* EthFw TX Checksum Offload Capability */
+#define ETHFW_TX_CSUM_OFFLOAD		BIT(0)
+
+/* EthFw Multicast Filtering Capability */
+#define ETHFW_MCAST_FILTERING		BIT(1)
+
+/* Token corresponding to the Linux CPSW Proxy Client assigned by EthFw */
+#define ETHFW_LINUX_CLIENT_TOKEN	3
+
+/* Default token used by Virtual Port to communicate with EthFw */
+#define ETHFW_TOKEN_NONE		0xFFFFFFFF
+
+/* MAC Address length in octets */
+#define ETHFW_MACADDRLEN		6
+
+/* IPV4 Address length in octets */
+#define ETHFW_IPV4ADDRLEN		4
+
+/* Types of request messages sent to EthFw from CPSW Proxy Client */
+enum request_msg_type {
+	/* Request details of Virtual Ports allocated to the Client.
+	 * Two types of Virtual Ports exist:
+	 * 1. MAC Only Port:
+	 *    The Physical MAC Port corresponding to this type of Virtual
+	 *    Port does not belong to the group of MAC Ports which Switch
+	 *    traffic among themselves. The Physical MAC Port is dedicated
+	 *    solely to the Client which has been allocated this type of
+	 *    Virtual Port.
+	 *
+	 * 2. Switch Port:
+	 *    The Physical MAC Port corresponding to this type of Virtual
+	 *    Port belongs to the group of MAC Ports which Switch traffic
+	 *    among themselves. The Physical MAC Port is shared with other
+	 *    Clients in terms of the traffic that is sent out of or received
+	 *    on this port.
+	 *
+	 * EthFw responds to this request by providing a bitmask of the
+	 * Virtual Port IDs for each type of Virtual Port allocated to
+	 * the Client.
+	 */
+	ETHFW_VIRT_PORT_INFO,
+
+	/* Request usage of a Virtual Port that has been allocated to the
+	 * Client.
+	 *
+	 * EthFw responds with details of the supported MTU size, the number
+	 * of TX DMA Channels and the number of RX DMA Flows for the specified
+	 * Virtual Port.
+	 */
+	ETHFW_VIRT_PORT_ATTACH,
+
+	ETHFW_UNUSED_REQUEST_1,
+
+	/* Request disuse of a Virtual Port that was in use prior to the
+	 * generation of this request.
+	 */
+	ETHFW_VIRT_PORT_DETACH,
+
+	/* Request to get link status */
+	ETHFW_VIRT_PORT_LINK_STATUS,
+
+	/* Request for allocation of a TX DMA Channel for a Virtual Port.
+	 * Client can request as many TX DMA Channels as have been allocated
+	 * by EthFw for the specified Virtual Port.
+	 *
+	 * EthFw responds with the TX PSI-L Thread ID corresponding to
+	 * the TX DMA Channel for the Virtual Port to transmit traffic
+	 * to CPSW.
+	 */
+	ETHFW_ALLOC_TX,
+
+	/* Request for allocation of an RX DMA Flow for a Virtual Port.
+	 * Client can request as many RX DMA Flows as have been allocated
+	 * by EthFw for the specified Virtual Port.
+	 *
+	 * EthFw responds with the RX PSI-L Thread ID, the base of the RX
+	 * Flow index and the offset from the base of the allocated RX Flow
+	 * index. The RX Flow/Channel is used to receive traffic from CPSW.
+	 */
+	ETHFW_ALLOC_RX,
+
+	/* Request for allocation of the MAC Address for a Virtual Port.
+	 *
+	 * EthFw responds with the MAC Address corresponding to the
+	 * specified Virtual Port.
+	 */
+	ETHFW_ALLOC_MAC,
+
+	/* Request for release of a TX DMA Channel that had been allocated
+	 * to the specified Virtual Port.
+	 */
+	ETHFW_FREE_TX,
+
+	/* Request for release of an RX DMA Flow that had been allocated to
+	 * the specified Virtual Port.
+	 */
+	ETHFW_FREE_RX,
+
+	/* Request for release of the MAC Address that had been allocated to
+	 * the specified Virtual Port.
+	 */
+	ETHFW_FREE_MAC,
+
+	/* Request for usage of the specified MAC Address for the traffic
+	 * sent or received on the Virtual Port for which the MAC Address
+	 * has been allocated.
+	 */
+	ETHFW_MAC_REGISTER,
+
+	/* Request for disuse of the specified MAC Address for the traffic
+	 * sent or received on the Virtual Port for which the MAC Address
+	 * had been allocated.
+	 */
+	ETHFW_MAC_DEREGISTER,
+
+	/* Request for setting the default RX DMA Flow for a Virtual Port. */
+	ETHFW_SET_DEFAULT_RX_FLOW,
+
+	/* Request for deleting the default RX DMA Flow for a Virtual Port. */
+	ETHFW_DEL_DEFAULT_RX_FLOW,
+
+	/* Request for registering the IPv4 Address of the Network Interface
+	 * in Linux corresponding to the specified Virtual Port.
+	 */
+	ETHFW_IPv4_REGISTER,
+
+	/* Request for deregistering the IPv4 Address of the Network Interface
+	 * in Linux corresponding to the specified Virtual Port that had been
+	 * registered prior to this request.
+	 */
+	ETHFW_IPv4_DEREGISTER,
+
+	/* Request for joining a VLAN */
+	ETHFW_JOIN_VLAN,
+
+	/* Request for leaving a VLAN */
+	ETHFW_LEAVE_VLAN,
+
+	/* Request for joining a Multicast Address group */
+	ETHFW_MCAST_FILTER_ADD,
+
+	/* Request for leaving a Multicast Address group */
+	ETHFW_MCAST_FILTER_DEL,
+
+	ETHFW_UNUSED_REQUEST_2,
+	ETHFW_UNUSED_REQUEST_3,
+	ETHFW_UNUSED_REQUEST_4,
+	ETHFW_UNUSED_REQUEST_5,
+	ETHFW_UNUSED_REQUEST_6,
+
+	/* Request for notifying teardown completion status */
+	ETHFW_TEARDOWN_COMPLETE,
+};
+
+enum notify_msg_type {
+	ETHFW_NOTIFYCLIENT_FWINFO,
+	ETHFW_NOTIFYCLIENT_HWPUSH,
+	ETHFW_NOTIFYCLIENT_HWERROR,
+	ETHFW_NOTIFYCLIENT_RECOVERED,
+	ETHFW_NOTIFYCLIENT_CUSTOM,
+	ETHFW_NOTIFYCLIENT_LAST,
+};
+
+enum ethfw_status {
+	ETHFW_UNINIT,
+	ETHFW_READY,
+	ETHFW_RECOVERY,
+	ETHFW_BAD,
+};
+
+enum message_type {
+	ETHFW_MSG_REQUEST,
+	ETHFW_MSG_NOTIFY,
+	ETHFW_MSG_RESPONSE,
+};
+
+struct message_header {
+	u32 token;
+	u32 client_id;
+	u32 msg_type;
+} __packed;
+
+struct message {
+	struct message_header msg_hdr;
+	u32 message_data[120];
+} __packed;
+
+struct request_message_header {
+	struct message_header msg_hdr;
+	u32 request_type;
+	u32 request_id;
+} __packed;
+
+struct response_message_header {
+	struct message_header msg_hdr;
+	u32 response_type; /* Same as request_type */
+	u32 response_id;
+	int response_status;
+} __packed;
+
+struct notify_message_header {
+	struct message_header msg_hdr;
+	u32 notify_type;
+} __packed;
+
+struct common_response_message {
+	struct response_message_header response_msg_hdr;
+} __packed;
+
+struct common_request_message {
+	struct request_message_header request_msg_hdr;
+} __packed;
+
+struct common_notify_message {
+	struct notify_message_header notify_msg_hdr;
+} __packed;
+
+struct virt_port_info_response {
+	struct response_message_header response_msg_hdr;
+	/* Port mask denoting absolute virtual switch ports allocated */
+	u32 switch_port_mask;
+	/* Port mask denoting absolute virtual MAC ports allocated */
+	u32 mac_port_mask;
+} __packed;
+
+struct attach_request {
+	struct request_message_header request_msg_hdr;
+	/* Virtual port which needs core attach */
+	u32 virt_port;
+} __packed;
+
+struct attach_response {
+	struct response_message_header response_msg_hdr;
+	/* MTU of RX packet */
+	u32 rx_mtu;
+	/* MTU of TX packet */
+	u32 tx_mtu;
+	/* Feature bitmask */
+	u32 features;
+	/* Number of TX DMA Channels available for the virtual port */
+	u32 num_tx_chan;
+	/* Number of RX DMA Flows available for the virtual port */
+	u32 num_rx_flow;
+} __packed;
+
+struct rx_flow_alloc_request {
+	struct request_message_header request_msg_hdr;
+	/* Relative index of RX flow among available num_rx_flow flows */
+	u32 rx_flow_idx;
+} __packed;
+
+struct rx_flow_alloc_response {
+	struct response_message_header response_msg_hdr;
+	/* Allocated RX flow index base */
+	u32 rx_flow_idx_base;
+	/* Allocated flow index offset */
+	u32 rx_flow_idx_offset;
+	/* RX PSIL Peer source thread id */
+	u32 rx_psil_src_id;
+} __packed;
+
+struct tx_thread_alloc_request {
+	struct request_message_header request_msg_hdr;
+	/* Relative index of TX channel among available num_tx_chan channels */
+	u32 tx_chan_idx;
+} __packed;
+
+struct tx_thread_alloc_response {
+	struct response_message_header response_msg_hdr;
+	/* TX PSIL peer destination thread id which should be paired with the TX UDMA channel */
+	u32 tx_psil_dest_id;
+} __packed;
+
+struct mac_alloc_response {
+	struct response_message_header response_msg_hdr;
+	/* Allocated MAC address */
+	u8 mac_addr[ETHFW_MACADDRLEN];
+} __packed;
+
+struct rx_flow_release_request {
+	struct request_message_header request_msg_hdr;
+	/* RX flow index base */
+	u32 rx_flow_idx_base;
+	/* RX flow index offset */
+	u32 rx_flow_idx_offset;
+} __packed;
+
+struct tx_thread_release_request {
+	struct request_message_header request_msg_hdr;
+	/* TX PSIL Peer destination thread id to be freed */
+	u32 tx_psil_dest_id;
+} __packed;
+
+struct mac_release_request {
+	struct request_message_header request_msg_hdr;
+	/* MAC address to be freed */
+	u8 mac_addr[ETHFW_MACADDRLEN];
+} __packed;
+
+struct mac_register_deregister_request {
+	struct request_message_header request_msg_hdr;
+	/* MAC address which needs to be registered/deregistered */
+	u8 mac_addr[ETHFW_MACADDRLEN];
+	/* RX flow index Base */
+	u32 rx_flow_idx_base;
+	/* RX flow index offset */
+	u32 rx_flow_idx_offset;
+} __packed;
+
+struct ipv4_register_request {
+	struct request_message_header request_msg_hdr;
+	/* IPv4 Address */
+	u8 ipv4_addr[ETHFW_IPV4ADDRLEN];
+	/* MAC address associated with the IP address which should be added to
+	 * the ARP table
+	 */
+	u8 mac_addr[ETHFW_MACADDRLEN];
+} __packed;
+
+struct ipv4_deregister_request {
+	struct request_message_header request_msg_hdr;
+	/* IPv4 Address */
+	u8 ipv4_addr[ETHFW_IPV4ADDRLEN];
+} __packed;
+
+struct vlan_join_leave_request {
+	struct request_message_header request_msg_hdr;
+	/* VLAN ID */
+	u16 vid;
+	/* MAC Address associated with the interface */
+	u8 mac_addr[ETHFW_MACADDRLEN];
+	/* RX Flow base and offset for receiving the VLAN packets */
+	u32 rx_flow_idx_base;
+	u32 rx_flow_idx_offset;
+} __packed;
+
+struct default_rx_flow_register_request {
+	struct request_message_header request_msg_hdr;
+	/* RX flow index Base */
+	u32 rx_flow_idx_base;
+	/* RX flow index offset */
+	u32 rx_flow_idx_offset;
+} __packed;
+
+struct port_link_status_response {
+	struct response_message_header response_msg_hdr;
+	/* Link status of the port */
+	bool link_up;
+	/* Link speed */
+	u32 speed;
+	/* Duplex mode */
+	u32 duplex;
+} __packed;
+
+struct add_multicast_request {
+	struct request_message_header request_msg_hdr;
+	/* Multicast MAC address to be added */
+	u8 mac_addr[ETHFW_MACADDRLEN];
+	/* VLAN id */
+	u16 vlan_id;
+	/* RX flow index from which the MAC_address association will be added.
+	 * It's applicable only for _exclusive multicast traffic_
+	 */
+	u32 rx_flow_idx_base;
+	/* RX flow index offset */
+	u32 rx_flow_idx_offset;
+} __packed;
+
+struct del_multicast_request {
+	struct request_message_header request_msg_hdr;
+	/* Multicast MAC address to be added */
+	u8 mac_addr[ETHFW_MACADDRLEN];
+	/* VLAN id */
+	u16 vlan_id;
+} __packed;
+
+#endif /* __ETHFW_ABI_H_ */
diff -Naur --no-dereference a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
--- a/drivers/net/ethernet/ti/icssg/icssg_common.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/icssg/icssg_common.c	2025-10-23 09:30:40.286462238 -0400
@@ -45,6 +45,11 @@
 			    struct prueth_rx_chn *rx_chn,
 			    int max_rflows)
 {
+	if (rx_chn->pg_pool) {
+		page_pool_destroy(rx_chn->pg_pool);
+		rx_chn->pg_pool = NULL;
+	}
+
 	if (rx_chn->desc_pool)
 		k3_cppi_desc_pool_destroy(rx_chn->desc_pool);
 
@@ -131,12 +136,13 @@
 	struct net_device *ndev = emac->ndev;
 	struct cppi5_host_desc_t *desc_tx;
 	struct netdev_queue *netif_txq;
+	struct prueth_swdata *swdata;
 	struct prueth_tx_chn *tx_chn;
 	unsigned int total_bytes = 0;
+	struct xdp_frame *xdpf;
 	struct sk_buff *skb;
 	dma_addr_t desc_dma;
 	int res, num_tx = 0;
-	void **swdata;
 
 	tx_chn = &emac->tx_chns[chn];
 
@@ -157,20 +163,26 @@
 						     desc_dma);
 		swdata = cppi5_hdesc_get_swdata(desc_tx);
 
-		/* was this command's TX complete? */
-		if (emac->is_sr1 && *(swdata) == emac->cmd_data) {
+		switch (swdata->type) {
+		case PRUETH_SWDATA_SKB:
+			skb = swdata->data.skb;
+			dev_sw_netstats_tx_add(skb->dev, 1, skb->len);
+			total_bytes += skb->len;
+			napi_consume_skb(skb, budget);
+			break;
+		case PRUETH_SWDATA_XDPF:
+			xdpf = swdata->data.xdpf;
+			dev_sw_netstats_tx_add(ndev, 1, xdpf->len);
+			total_bytes += xdpf->len;
+			xdp_return_frame(xdpf);
+			break;
+		default:
 			prueth_xmit_free(tx_chn, desc_tx);
+			ndev->stats.tx_dropped++;
 			continue;
 		}
 
-		skb = *(swdata);
 		prueth_xmit_free(tx_chn, desc_tx);
-
-		ndev = skb->dev;
-		ndev->stats.tx_packets++;
-		ndev->stats.tx_bytes += skb->len;
-		total_bytes += skb->len;
-		napi_consume_skb(skb, budget);
 		num_tx++;
 	}
 
@@ -461,17 +473,17 @@
 }
 EXPORT_SYMBOL_GPL(prueth_init_rx_chns);
 
-int prueth_dma_rx_push(struct prueth_emac *emac,
-		       struct sk_buff *skb,
-		       struct prueth_rx_chn *rx_chn)
+int prueth_dma_rx_push_mapped(struct prueth_emac *emac,
+			      struct prueth_rx_chn *rx_chn,
+			      struct page *page, u32 buf_len)
 {
 	struct net_device *ndev = emac->ndev;
 	struct cppi5_host_desc_t *desc_rx;
-	u32 pkt_len = skb_tailroom(skb);
+	struct prueth_swdata *swdata;
 	dma_addr_t desc_dma;
 	dma_addr_t buf_dma;
-	void **swdata;
 
+	buf_dma = page_pool_get_dma_addr(page) + PRUETH_HEADROOM;
 	desc_rx = k3_cppi_desc_pool_alloc(rx_chn->desc_pool);
 	if (!desc_rx) {
 		netdev_err(ndev, "rx push: failed to allocate descriptor\n");
@@ -479,25 +491,19 @@
 	}
 	desc_dma = k3_cppi_desc_pool_virt2dma(rx_chn->desc_pool, desc_rx);
 
-	buf_dma = dma_map_single(rx_chn->dma_dev, skb->data, pkt_len, DMA_FROM_DEVICE);
-	if (unlikely(dma_mapping_error(rx_chn->dma_dev, buf_dma))) {
-		k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
-		netdev_err(ndev, "rx push: failed to map rx pkt buffer\n");
-		return -EINVAL;
-	}
-
 	cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT,
 			 PRUETH_NAV_PS_DATA_SIZE);
 	k3_udma_glue_rx_dma_to_cppi5_addr(rx_chn->rx_chn, &buf_dma);
-	cppi5_hdesc_attach_buf(desc_rx, buf_dma, skb_tailroom(skb), buf_dma, skb_tailroom(skb));
+	cppi5_hdesc_attach_buf(desc_rx, buf_dma, buf_len, buf_dma, buf_len);
 
 	swdata = cppi5_hdesc_get_swdata(desc_rx);
-	*swdata = skb;
+	swdata->type = PRUETH_SWDATA_PAGE;
+	swdata->data.page = page;
 
-	return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, 0,
+	return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, PRUETH_RX_FLOW_DATA,
 					desc_rx, desc_dma);
 }
-EXPORT_SYMBOL_GPL(prueth_dma_rx_push);
+EXPORT_SYMBOL_GPL(prueth_dma_rx_push_mapped);
 
 u64 icssg_ts_to_ns(u32 hi_sw, u32 hi, u32 lo, u32 cycle_time_ns)
 {
@@ -535,18 +541,178 @@
 	ssh->hwtstamp = ns_to_ktime(ns);
 }
 
-static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id)
+/**
+ * emac_xmit_xdp_frame - transmits an XDP frame
+ * @emac: emac device
+ * @xdpf: data to transmit
+ * @page: page from page pool if already DMA mapped
+ * @q_idx: queue id
+ *
+ * Return: XDP state
+ */
+u32 emac_xmit_xdp_frame(struct prueth_emac *emac,
+			struct xdp_frame *xdpf,
+			struct page *page,
+			unsigned int q_idx)
+{
+	struct cppi5_host_desc_t *first_desc;
+	struct net_device *ndev = emac->ndev;
+	struct netdev_queue *netif_txq;
+	struct prueth_tx_chn *tx_chn;
+	dma_addr_t desc_dma, buf_dma;
+	struct prueth_swdata *swdata;
+	u32 *epib;
+	int ret;
+
+	if (q_idx >= PRUETH_MAX_TX_QUEUES) {
+		netdev_err(ndev, "xdp tx: invalid q_id %d\n", q_idx);
+		return ICSSG_XDP_CONSUMED;	/* drop */
+	}
+
+	tx_chn = &emac->tx_chns[q_idx];
+
+	first_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool);
+	if (!first_desc) {
+		netdev_dbg(ndev, "xdp tx: failed to allocate descriptor\n");
+		return ICSSG_XDP_CONSUMED;	/* drop */
+	}
+
+	if (page) { /* already DMA mapped by page_pool */
+		buf_dma = page_pool_get_dma_addr(page);
+		buf_dma += xdpf->headroom + sizeof(struct xdp_frame);
+	} else { /* Map the linear buffer */
+		buf_dma = dma_map_single(tx_chn->dma_dev, xdpf->data, xdpf->len, DMA_TO_DEVICE);
+		if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) {
+			netdev_err(ndev, "xdp tx: failed to map data buffer\n");
+			goto drop_free_descs;	/* drop */
+		}
+	}
+
+	cppi5_hdesc_init(first_desc, CPPI5_INFO0_HDESC_EPIB_PRESENT,
+			 PRUETH_NAV_PS_DATA_SIZE);
+	cppi5_hdesc_set_pkttype(first_desc, 0);
+	epib = first_desc->epib;
+	epib[0] = 0;
+	epib[1] = 0;
+
+	/* set dst tag to indicate internal qid at the firmware which is at
+	 * bit8..bit15. bit0..bit7 indicates port num for directed
+	 * packets in case of switch mode operation
+	 */
+	cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (emac->port_id | (q_idx << 8)));
+	k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma);
+	cppi5_hdesc_attach_buf(first_desc, buf_dma, xdpf->len, buf_dma, xdpf->len);
+	swdata = cppi5_hdesc_get_swdata(first_desc);
+	swdata->type = PRUETH_SWDATA_XDPF;
+	swdata->data.xdpf = xdpf;
+
+	/* Report BQL before sending the packet */
+	netif_txq = netdev_get_tx_queue(ndev, tx_chn->id);
+	netdev_tx_sent_queue(netif_txq, xdpf->len);
+
+	cppi5_hdesc_set_pktlen(first_desc, xdpf->len);
+	desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc);
+
+	ret = k3_udma_glue_push_tx_chn(tx_chn->tx_chn, first_desc, desc_dma);
+	if (ret) {
+		netdev_err(ndev, "xdp tx: push failed: %d\n", ret);
+		netdev_tx_completed_queue(netif_txq, 1, xdpf->len);
+		goto drop_free_descs;
+	}
+
+	return ICSSG_XDP_TX;
+
+drop_free_descs:
+	prueth_xmit_free(tx_chn, first_desc);
+	return ICSSG_XDP_CONSUMED;
+}
+EXPORT_SYMBOL_GPL(emac_xmit_xdp_frame);
+
+/**
+ * emac_run_xdp - run an XDP program
+ * @emac: emac device
+ * @xdp: XDP buffer containing the frame
+ * @page: page with RX data if already DMA mapped
+ * @len: Rx descriptor packet length
+ *
+ * Return: XDP state
+ */
+static u32 emac_run_xdp(struct prueth_emac *emac, struct xdp_buff *xdp,
+			struct page *page, u32 *len)
+{
+	struct net_device *ndev = emac->ndev;
+	struct netdev_queue *netif_txq;
+	int cpu = smp_processor_id();
+	struct bpf_prog *xdp_prog;
+	struct xdp_frame *xdpf;
+	u32 pkt_len = *len;
+	u32 act, result;
+	int q_idx, err;
+
+	xdp_prog = READ_ONCE(emac->xdp_prog);
+	act = bpf_prog_run_xdp(xdp_prog, xdp);
+	switch (act) {
+	case XDP_PASS:
+		return ICSSG_XDP_PASS;
+	case XDP_TX:
+		/* Send packet to TX ring for immediate transmission */
+		xdpf = xdp_convert_buff_to_frame(xdp);
+		if (unlikely(!xdpf)) {
+			ndev->stats.tx_dropped++;
+			goto drop;
+		}
+
+		q_idx = cpu % emac->tx_ch_num;
+		netif_txq = netdev_get_tx_queue(ndev, q_idx);
+		__netif_tx_lock(netif_txq, cpu);
+		result = emac_xmit_xdp_frame(emac, xdpf, page, q_idx);
+		__netif_tx_unlock(netif_txq);
+		if (result == ICSSG_XDP_CONSUMED) {
+			ndev->stats.tx_dropped++;
+			goto drop;
+		}
+
+		dev_sw_netstats_rx_add(ndev, xdpf->len);
+		return result;
+	case XDP_REDIRECT:
+		err = xdp_do_redirect(emac->ndev, xdp, xdp_prog);
+		if (err)
+			goto drop;
+
+		dev_sw_netstats_rx_add(ndev, pkt_len);
+		return ICSSG_XDP_REDIR;
+	default:
+		bpf_warn_invalid_xdp_action(emac->ndev, xdp_prog, act);
+		fallthrough;
+	case XDP_ABORTED:
+drop:
+		trace_xdp_exception(emac->ndev, xdp_prog, act);
+		fallthrough; /* handle aborts by dropping packet */
+	case XDP_DROP:
+		ndev->stats.rx_dropped++;
+		page_pool_recycle_direct(emac->rx_chns.pg_pool, page);
+		return ICSSG_XDP_CONSUMED;
+	}
+}
+
+static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id, u32 *xdp_state)
 {
 	struct prueth_rx_chn *rx_chn = &emac->rx_chns;
 	u32 buf_dma_len, pkt_len, port_id = 0;
 	struct net_device *ndev = emac->ndev;
 	struct cppi5_host_desc_t *desc_rx;
-	struct sk_buff *skb, *new_skb;
+	struct prueth_swdata *swdata;
 	dma_addr_t desc_dma, buf_dma;
-	void **swdata;
+	struct page *page, *new_page;
+	struct page_pool *pool;
+	struct sk_buff *skb;
+	struct xdp_buff xdp;
 	u32 *psdata;
+	void *pa;
 	int ret;
 
+	*xdp_state = 0;
+	pool = rx_chn->pg_pool;
 	ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma);
 	if (ret) {
 		if (ret != -ENODATA)
@@ -558,15 +724,15 @@
 		return 0;
 
 	desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma);
-
 	swdata = cppi5_hdesc_get_swdata(desc_rx);
-	skb = *swdata;
-
-	psdata = cppi5_hdesc_get_psdata(desc_rx);
-	/* RX HW timestamp */
-	if (emac->rx_ts_enabled)
-		emac_rx_timestamp(emac, skb, psdata);
+	if (swdata->type != PRUETH_SWDATA_PAGE) {
+		netdev_err(ndev, "rx_pkt: invalid swdata->type %d\n", swdata->type);
+		k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
+		return 0;
+	}
 
+	page = swdata->data.page;
+	page_pool_dma_sync_for_cpu(pool, page, 0, PAGE_SIZE);
 	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
 	k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma);
 	pkt_len = cppi5_hdesc_get_pktlen(desc_rx);
@@ -574,32 +740,60 @@
 	pkt_len -= 4;
 	cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL);
 
-	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE);
 	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
 
-	skb->dev = ndev;
-	new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE);
 	/* if allocation fails we drop the packet but push the
-	 * descriptor back to the ring with old skb to prevent a stall
+	 * descriptor back to the ring with old page to prevent a stall
 	 */
-	if (!new_skb) {
+	new_page = page_pool_dev_alloc_pages(pool);
+	if (unlikely(!new_page)) {
+		new_page = page;
 		ndev->stats.rx_dropped++;
-		new_skb = skb;
-	} else {
-		/* send the filled skb up the n/w stack */
-		skb_put(skb, pkt_len);
-		if (emac->prueth->is_switch_mode)
-			skb->offload_fwd_mark = emac->offload_fwd_mark;
-		skb->protocol = eth_type_trans(skb, ndev);
-		napi_gro_receive(&emac->napi_rx, skb);
-		ndev->stats.rx_bytes += pkt_len;
-		ndev->stats.rx_packets++;
+		goto requeue;
 	}
 
+	pa = page_address(page);
+	if (emac->xdp_prog) {
+		xdp_init_buff(&xdp, PAGE_SIZE, &rx_chn->xdp_rxq);
+		xdp_prepare_buff(&xdp, pa, PRUETH_HEADROOM, pkt_len, false);
+
+		*xdp_state = emac_run_xdp(emac, &xdp, page, &pkt_len);
+		if (*xdp_state != ICSSG_XDP_PASS)
+			goto requeue;
+	}
+
+	/* prepare skb and send to n/w stack */
+	skb = napi_build_skb(pa, PAGE_SIZE);
+	if (!skb) {
+		ndev->stats.rx_dropped++;
+		page_pool_recycle_direct(pool, page);
+		goto requeue;
+	}
+
+	skb_reserve(skb, PRUETH_HEADROOM);
+	skb_put(skb, pkt_len);
+	skb->dev = ndev;
+
+	psdata = cppi5_hdesc_get_psdata(desc_rx);
+	/* RX HW timestamp */
+	if (emac->rx_ts_enabled)
+		emac_rx_timestamp(emac, skb, psdata);
+
+	if (emac->prueth->is_switch_mode)
+		skb->offload_fwd_mark = emac->offload_fwd_mark;
+	skb->protocol = eth_type_trans(skb, ndev);
+
+	skb_mark_for_recycle(skb);
+	napi_gro_receive(&emac->napi_rx, skb);
+	ndev->stats.rx_bytes += pkt_len;
+	ndev->stats.rx_packets++;
+
+requeue:
 	/* queue another RX DMA */
-	ret = prueth_dma_rx_push(emac, new_skb, &emac->rx_chns);
+	ret = prueth_dma_rx_push_mapped(emac, &emac->rx_chns, new_page,
+					PRUETH_MAX_PKT_SIZE);
 	if (WARN_ON(ret < 0)) {
-		dev_kfree_skb_any(new_skb);
+		page_pool_recycle_direct(pool, new_page);
 		ndev->stats.rx_errors++;
 		ndev->stats.rx_dropped++;
 	}
@@ -611,22 +805,19 @@
 {
 	struct prueth_rx_chn *rx_chn = data;
 	struct cppi5_host_desc_t *desc_rx;
-	struct sk_buff *skb;
-	dma_addr_t buf_dma;
-	u32 buf_dma_len;
-	void **swdata;
+	struct prueth_swdata *swdata;
+	struct page_pool *pool;
+	struct page *page;
 
+	pool = rx_chn->pg_pool;
 	desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma);
 	swdata = cppi5_hdesc_get_swdata(desc_rx);
-	skb = *swdata;
-	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
-	k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma);
+	if (swdata->type == PRUETH_SWDATA_PAGE) {
+		page = swdata->data.page;
+		page_pool_recycle_direct(pool, page);
+	}
 
-	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len,
-			 DMA_FROM_DEVICE);
 	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
-
-	dev_kfree_skb_any(skb);
 }
 
 static int prueth_tx_ts_cookie_get(struct prueth_emac *emac)
@@ -662,13 +853,13 @@
 	struct prueth_emac *emac = netdev_priv(ndev);
 	struct prueth *prueth = emac->prueth;
 	struct netdev_queue *netif_txq;
+	struct prueth_swdata *swdata;
 	struct prueth_tx_chn *tx_chn;
 	dma_addr_t desc_dma, buf_dma;
 	u32 pkt_len, dst_tag_id;
 	int i, ret = 0, q_idx;
 	bool in_tx_ts = 0;
 	int tx_ts_cookie;
-	void **swdata;
 	u32 *epib;
 
 	pkt_len = skb_headlen(skb);
@@ -730,7 +921,8 @@
 	k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma);
 	cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len);
 	swdata = cppi5_hdesc_get_swdata(first_desc);
-	*swdata = skb;
+	swdata->type = PRUETH_SWDATA_SKB;
+	swdata->data.skb = skb;
 
 	/* Handle the case where skb is fragmented in pages */
 	cur_desc = first_desc;
@@ -780,6 +972,7 @@
 	ret = k3_udma_glue_push_tx_chn(tx_chn->tx_chn, first_desc, desc_dma);
 	if (ret) {
 		netdev_err(ndev, "tx: push failed: %d\n", ret);
+		netdev_tx_completed_queue(netif_txq, 1, pkt_len);
 		goto drop_free_descs;
 	}
 
@@ -833,15 +1026,27 @@
 {
 	struct prueth_tx_chn *tx_chn = data;
 	struct cppi5_host_desc_t *desc_tx;
+	struct prueth_swdata *swdata;
+	struct xdp_frame *xdpf;
 	struct sk_buff *skb;
-	void **swdata;
 
 	desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma);
 	swdata = cppi5_hdesc_get_swdata(desc_tx);
-	skb = *(swdata);
-	prueth_xmit_free(tx_chn, desc_tx);
 
-	dev_kfree_skb_any(skb);
+	switch (swdata->type) {
+	case PRUETH_SWDATA_SKB:
+		skb = swdata->data.skb;
+		dev_kfree_skb_any(skb);
+		break;
+	case PRUETH_SWDATA_XDPF:
+		xdpf = swdata->data.xdpf;
+		xdp_return_frame(xdpf);
+		break;
+	default:
+		break;
+	}
+
+	prueth_xmit_free(tx_chn, desc_tx);
 }
 
 irqreturn_t prueth_rx_irq(int irq, void *dev_id)
@@ -875,15 +1080,18 @@
 		PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA;
 	int flow = emac->is_sr1 ?
 		PRUETH_MAX_RX_FLOWS_SR1 : PRUETH_MAX_RX_FLOWS;
+	int xdp_state_or = 0;
 	int num_rx = 0;
 	int cur_budget;
+	u32 xdp_state;
 	int ret;
 
 	while (flow--) {
 		cur_budget = budget - num_rx;
 
 		while (cur_budget--) {
-			ret = emac_rx_packet(emac, flow);
+			ret = emac_rx_packet(emac, flow, &xdp_state);
+			xdp_state_or |= xdp_state;
 			if (ret)
 				break;
 			num_rx++;
@@ -893,6 +1101,9 @@
 			break;
 	}
 
+	if (xdp_state_or & ICSSG_XDP_REDIR)
+		xdp_do_flush();
+
 	if (num_rx < budget && napi_complete_done(napi_rx, num_rx)) {
 		if (unlikely(emac->rx_pace_timeout_ns)) {
 			hrtimer_start(&emac->rx_hrtimer,
@@ -907,29 +1118,71 @@
 }
 EXPORT_SYMBOL_GPL(icssg_napi_rx_poll);
 
+static struct page_pool *prueth_create_page_pool(struct prueth_emac *emac,
+						 struct device *dma_dev,
+						 int size)
+{
+	struct page_pool_params pp_params = { 0 };
+	struct page_pool *pool;
+
+	pp_params.order = 0;
+	pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
+	pp_params.pool_size = size;
+	pp_params.nid = dev_to_node(emac->prueth->dev);
+	pp_params.dma_dir = DMA_BIDIRECTIONAL;
+	pp_params.dev = dma_dev;
+	pp_params.napi = &emac->napi_rx;
+	pp_params.max_len = PAGE_SIZE;
+
+	pool = page_pool_create(&pp_params);
+	if (IS_ERR(pool))
+		netdev_err(emac->ndev, "cannot create rx page pool\n");
+
+	return pool;
+}
+
 int prueth_prepare_rx_chan(struct prueth_emac *emac,
 			   struct prueth_rx_chn *chn,
 			   int buf_size)
 {
-	struct sk_buff *skb;
+	struct page_pool *pool;
+	struct page *page;
 	int i, ret;
 
+	pool = prueth_create_page_pool(emac, chn->dma_dev, chn->descs_num);
+	if (IS_ERR(pool))
+		return PTR_ERR(pool);
+
+	chn->pg_pool = pool;
+
 	for (i = 0; i < chn->descs_num; i++) {
-		skb = __netdev_alloc_skb_ip_align(NULL, buf_size, GFP_KERNEL);
-		if (!skb)
-			return -ENOMEM;
+		/* NOTE: we're not using memory efficiently here.
+		 * 1 full page (4KB?) used here instead of
+		 * PRUETH_MAX_PKT_SIZE (~1.5KB?)
+		 */
+		page = page_pool_dev_alloc_pages(pool);
+		if (!page) {
+			netdev_err(emac->ndev, "couldn't allocate rx page\n");
+			ret = -ENOMEM;
+			goto recycle_alloc_pg;
+		}
 
-		ret = prueth_dma_rx_push(emac, skb, chn);
+		ret = prueth_dma_rx_push_mapped(emac, chn, page, buf_size);
 		if (ret < 0) {
 			netdev_err(emac->ndev,
-				   "cannot submit skb for rx chan %s ret %d\n",
+				   "cannot submit page for rx chan %s ret %d\n",
 				   chn->name, ret);
-			kfree_skb(skb);
-			return ret;
+			page_pool_recycle_direct(pool, page);
+			goto recycle_alloc_pg;
 		}
 	}
 
 	return 0;
+
+recycle_alloc_pg:
+	prueth_reset_rx_chan(&emac->rx_chns, PRUETH_MAX_RX_FLOWS, false);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(prueth_prepare_rx_chan);
 
diff -Naur --no-dereference a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
--- a/drivers/net/ethernet/ti/icssg/icssg_config.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/icssg/icssg_config.c	2025-10-23 09:30:40.286462238 -0400
@@ -220,6 +220,27 @@
 	}
 }
 
+static void icssg_config_cut_thru(struct prueth_emac *emac)
+{
+	void __iomem *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
+	u8 mask = ICSSG_CUT_THRU_BIT;
+	u8 val;
+	int i;
+
+	for (i = 0; i < PRUETH_MAX_TX_QUEUES * PRUETH_NUM_MACS; i++) {
+		val = readb(config + EXPRESS_PRE_EMPTIVE_Q_MAP + i);
+		if (emac->cut_thru_queue_map & BIT(i)) {
+			val |= mask;
+			netdev_info(emac->ndev, "cut-thru enabled for q%d\n", i);
+		} else if (val & mask){
+			val &= ~mask;
+			netdev_info(emac->ndev, "cut-thru disabled for q%d\n", i);
+		}
+
+		writeb(val, config + EXPRESS_PRE_EMPTIVE_Q_MAP + i);
+	}
+}
+
 void icssg_config_ipg(struct prueth_emac *emac)
 {
 	struct prueth *prueth = emac->prueth;
@@ -326,14 +347,23 @@
 	if (!slice)
 		addr += PRUETH_SW_NUM_BUF_POOLS_HOST * PRUETH_SW_BUF_POOL_SIZE_HOST;
 	else
-		addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
+		addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2;
 
+	/* Pre-emptible RX buffer queue */
 	rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET;
 	for (i = 0; i < 3; i++)
 		writel(addr, &rxq_ctx->start[i]);
 
 	addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
-	writel(addr - SZ_2K, &rxq_ctx->end);
+	writel(addr, &rxq_ctx->end);
+
+	/* Express RX buffer queue */
+	rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET;
+	for (i = 0; i < 3; i++)
+		writel(addr, &rxq_ctx->start[i]);
+
+	addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
+	writel(addr, &rxq_ctx->end);
 
 	return 0;
 }
@@ -498,6 +528,9 @@
 
 	emac_r30_cmd_init(emac);
 
+	if (prueth->is_switch_mode || prueth->is_hsr_offload_mode)
+		icssg_config_cut_thru(emac);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(icssg_config);
diff -Naur --no-dereference a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c
--- a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c	2025-10-23 09:30:40.286462238 -0400
@@ -294,6 +294,61 @@
 	return 0;
 }
 
+static int emac_get_mm(struct net_device *ndev, struct ethtool_mm_state *state)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct prueth_qos_iet *iet = &emac->qos.iet;
+	void __iomem *config;
+
+	config = emac->dram.va + ICSSG_CONFIG_OFFSET;
+
+	state->tx_enabled = iet->fpe_enabled;
+	state->pmac_enabled = true;
+	state->verify_status = readb(config + PRE_EMPTION_VERIFY_STATUS);
+	state->tx_min_frag_size = iet->tx_min_frag_size;
+	state->rx_min_frag_size = 124;
+	state->tx_active = readb(config + PRE_EMPTION_ACTIVE_TX) ? true : false;
+	state->verify_enabled = readb(config + PRE_EMPTION_ENABLE_VERIFY) ? true : false;
+	state->verify_time = iet->verify_time_ms;
+
+	/* 802.3-2018 clause 30.14.1.6, says that the aMACMergeVerifyTime
+	 * variable has a range between 1 and 128 ms inclusive. Limit to that.
+	 */
+	state->max_verify_time = 128;
+
+	return 0;
+}
+
+static int emac_set_mm(struct net_device *ndev, struct ethtool_mm_cfg *cfg,
+		       struct netlink_ext_ack *extack)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct prueth_qos_iet *iet = &emac->qos.iet;
+
+	if (!cfg->pmac_enabled)
+		netdev_err(ndev, "preemptible MAC is always enabled");
+
+	iet->verify_time_ms = cfg->verify_time;
+	iet->tx_min_frag_size = cfg->tx_min_frag_size;
+
+	iet->fpe_configured = cfg->tx_enabled;
+	iet->mac_verify_configured = cfg->verify_enabled;
+
+	return 0;
+}
+
+static void emac_get_mm_stats(struct net_device *ndev,
+			      struct ethtool_mm_stats *s)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+
+	s->MACMergeFrameAssOkCount = emac_get_stat_by_name(emac, "FW_PREEMPT_ASSEMBLY_OK");
+	s->MACMergeFrameAssErrorCount = emac_get_stat_by_name(emac, "FW_PREEMPT_ASSEMBLY_ERR");
+	s->MACMergeFragCountRx = emac_get_stat_by_name(emac, "FW_PREEMPT_FRAG_CNT_RX");
+	s->MACMergeFragCountTx = emac_get_stat_by_name(emac, "FW_PREEMPT_FRAG_CNT_TX");
+	s->MACMergeFrameSmdErrorCount = emac_get_stat_by_name(emac, "FW_PREEMPT_BAD_FRAG");
+}
+
 const struct ethtool_ops icssg_ethtool_ops = {
 	.get_drvinfo = emac_get_drvinfo,
 	.get_msglevel = emac_get_msglevel,
@@ -317,5 +372,8 @@
 	.set_eee = emac_set_eee,
 	.nway_reset = emac_nway_reset,
 	.get_rmon_stats = emac_get_rmon_stats,
+	.get_mm = emac_get_mm,
+	.set_mm = emac_set_mm,
+	.get_mm_stats = emac_get_mm_stats,
 };
 EXPORT_SYMBOL_GPL(icssg_ethtool_ops);
diff -Naur --no-dereference a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c	2025-10-23 09:30:40.286462238 -0400
@@ -125,45 +125,6 @@
 	return IRQ_HANDLED;
 }
 
-static struct icssg_firmwares icssg_hsr_firmwares[] = {
-	{
-		.pru = "ti-pruss/am65x-sr2-pru0-pruhsr-fw.elf",
-		.rtu = "ti-pruss/am65x-sr2-rtu0-pruhsr-fw.elf",
-		.txpru = "ti-pruss/am65x-sr2-txpru0-pruhsr-fw.elf",
-	},
-	{
-		.pru = "ti-pruss/am65x-sr2-pru1-pruhsr-fw.elf",
-		.rtu = "ti-pruss/am65x-sr2-rtu1-pruhsr-fw.elf",
-		.txpru = "ti-pruss/am65x-sr2-txpru1-pruhsr-fw.elf",
-	}
-};
-
-static struct icssg_firmwares icssg_switch_firmwares[] = {
-	{
-		.pru = "ti-pruss/am65x-sr2-pru0-prusw-fw.elf",
-		.rtu = "ti-pruss/am65x-sr2-rtu0-prusw-fw.elf",
-		.txpru = "ti-pruss/am65x-sr2-txpru0-prusw-fw.elf",
-	},
-	{
-		.pru = "ti-pruss/am65x-sr2-pru1-prusw-fw.elf",
-		.rtu = "ti-pruss/am65x-sr2-rtu1-prusw-fw.elf",
-		.txpru = "ti-pruss/am65x-sr2-txpru1-prusw-fw.elf",
-	}
-};
-
-static struct icssg_firmwares icssg_emac_firmwares[] = {
-	{
-		.pru = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
-		.rtu = "ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
-		.txpru = "ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
-	},
-	{
-		.pru = "ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
-		.rtu = "ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
-		.txpru = "ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
-	}
-};
-
 static int prueth_start(struct rproc *rproc, const char *fw_name)
 {
 	int ret;
@@ -186,11 +147,13 @@
 	int ret, slice;
 
 	if (prueth->is_switch_mode)
-		firmwares = icssg_switch_firmwares;
-	else if (prueth->is_hsr_offload_mode)
-		firmwares = icssg_hsr_firmwares;
+		firmwares = prueth->icssg_switch_firmwares;
+	else if (prueth->is_hsr_offload_mode && HSR_V1 == prueth->hsr_prp_version)
+		firmwares = prueth->icssg_hsr_firmwares;
+	else if (prueth->is_hsr_offload_mode && PRP_V1 == prueth->hsr_prp_version)
+		firmwares = prueth->icssg_prp_firmwares;
 	else
-		firmwares = icssg_emac_firmwares;
+		firmwares = prueth->icssg_emac_firmwares;
 
 	for (slice = 0; slice < PRUETH_NUM_MACS; slice++) {
 		ret = prueth_start(prueth->pru[slice], firmwares[slice].pru);
@@ -368,6 +331,12 @@
 		} else {
 			icssg_set_port_state(emac, ICSSG_EMAC_PORT_DISABLE);
 		}
+
+		if (emac->link) {
+			icssg_qos_link_up(ndev);
+		} else {
+			icssg_qos_link_down(ndev);
+		}
 	}
 
 	if (emac->link) {
@@ -453,6 +422,7 @@
 
 	ts = ((u64)hi_rollover_count) << 23 | iepcount_hi;
 	ts = ts * (u64)IEP_DEFAULT_CYCLE_TIME_NS + iepcount_lo;
+	ts += readl(prueth->shram.va + TIMESYNC_CYCLE_EXTN_TIME);
 
 	return ts;
 }
@@ -491,6 +461,9 @@
 		usleep_range(500, 1000);
 	}
 
+	/* Clear the Cycle extension adjustments */
+	writel(0, emac->dram.va + TIMESYNC_CYCLE_EXTN_TIME);
+
 	dev_err(emac->prueth->dev, "settime timeout\n");
 }
 
@@ -559,63 +532,163 @@
 	.perout_enable = prueth_perout_enable,
 };
 
+static int prueth_create_xdp_rxqs(struct prueth_emac *emac)
+{
+	struct xdp_rxq_info *rxq = &emac->rx_chns.xdp_rxq;
+	struct page_pool *pool = emac->rx_chns.pg_pool;
+	int ret;
+
+	ret = xdp_rxq_info_reg(rxq, emac->ndev, 0, emac->napi_rx.napi_id);
+	if (ret)
+		return ret;
+
+	ret = xdp_rxq_info_reg_mem_model(rxq, MEM_TYPE_PAGE_POOL, pool);
+	if (ret)
+		xdp_rxq_info_unreg(rxq);
+
+	return ret;
+}
+
+static void prueth_destroy_xdp_rxqs(struct prueth_emac *emac)
+{
+	struct xdp_rxq_info *rxq = &emac->rx_chns.xdp_rxq;
+
+	if (!xdp_rxq_info_is_reg(rxq))
+		return;
+
+	xdp_rxq_info_unreg(rxq);
+}
+
 static int icssg_prueth_add_mcast(struct net_device *ndev, const u8 *addr)
 {
-	struct prueth_emac *emac = netdev_priv(ndev);
-	int port_mask = BIT(emac->port_id);
+	struct net_device *real_dev;
+	struct prueth_emac *emac;
+	int port_mask;
+	u8 vlan_id;
 
-	port_mask |= icssg_fdb_lookup(emac, addr, 0);
-	icssg_fdb_add_del(emac, addr, 0, port_mask, true);
-	icssg_vtbl_modify(emac, 0, port_mask, port_mask, true);
+	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_MAC;
+	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
+	emac = netdev_priv(real_dev);
+
+	port_mask = BIT(emac->port_id) | icssg_fdb_lookup(emac, addr, vlan_id);
+	icssg_fdb_add_del(emac, addr, vlan_id, port_mask, true);
+	icssg_vtbl_modify(emac, vlan_id, port_mask, port_mask, true);
 
 	return 0;
 }
 
 static int icssg_prueth_del_mcast(struct net_device *ndev, const u8 *addr)
 {
-	struct prueth_emac *emac = netdev_priv(ndev);
-	int port_mask = BIT(emac->port_id);
+	struct net_device *real_dev;
+	struct prueth_emac *emac;
 	int other_port_mask;
+	int port_mask;
+	u8 vlan_id;
+
+	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_MAC;
+	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
+	emac = netdev_priv(real_dev);
 
-	other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, 0);
+	port_mask = BIT(emac->port_id);
+	other_port_mask = port_mask ^ icssg_fdb_lookup(emac, addr, vlan_id);
 
-	icssg_fdb_add_del(emac, addr, 0, port_mask, false);
-	icssg_vtbl_modify(emac, 0, port_mask, port_mask, false);
+	icssg_fdb_add_del(emac, addr, vlan_id, port_mask, false);
+	icssg_vtbl_modify(emac, vlan_id, port_mask, port_mask, false);
 
 	if (other_port_mask) {
-		icssg_fdb_add_del(emac, addr, 0, other_port_mask, true);
-		icssg_vtbl_modify(emac, 0, other_port_mask, other_port_mask, true);
+		icssg_fdb_add_del(emac, addr, vlan_id, other_port_mask, true);
+		icssg_vtbl_modify(emac, vlan_id, other_port_mask,
+				  other_port_mask, true);
 	}
 
 	return 0;
 }
 
-static int icssg_prueth_hsr_add_mcast(struct net_device *ndev, const u8 *addr)
+static void icssg_prueth_hsr_fdb_add_del(struct prueth_emac *emac,
+					 const u8 *addr, u8 vid, bool add)
 {
-	struct prueth_emac *emac = netdev_priv(ndev);
-	struct prueth *prueth = emac->prueth;
-
-	icssg_fdb_add_del(emac, addr, prueth->default_vlan,
+	icssg_fdb_add_del(emac, addr, vid,
 			  ICSSG_FDB_ENTRY_P0_MEMBERSHIP |
 			  ICSSG_FDB_ENTRY_P1_MEMBERSHIP |
 			  ICSSG_FDB_ENTRY_P2_MEMBERSHIP |
-			  ICSSG_FDB_ENTRY_BLOCK, true);
+			  ICSSG_FDB_ENTRY_BLOCK, add);
+
+	if (add)
+		icssg_vtbl_modify(emac, vid, BIT(emac->port_id),
+				  BIT(emac->port_id), add);
+}
+
+static int icssg_prueth_hsr_add_mcast(struct net_device *ndev, const u8 *addr)
+{
+	struct net_device *real_dev;
+	struct prueth_emac *emac;
+	u8 vlan_id, i;
+
+	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_HSR;
+	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
+
+	if (is_hsr_master(real_dev)) {
+		for (i = HSR_PT_SLAVE_A; i < HSR_PT_INTERLINK; i++) {
+			emac = netdev_priv(hsr_get_port_ndev(real_dev, i));
+			if (!emac)
+				return -EINVAL;
+			icssg_prueth_hsr_fdb_add_del(emac, addr, vlan_id,
+						     true);
+		}
+	} else {
+		emac = netdev_priv(real_dev);
+		icssg_prueth_hsr_fdb_add_del(emac, addr, vlan_id, true);
+	}
 
-	icssg_vtbl_modify(emac, emac->port_vlan, BIT(emac->port_id),
-			  BIT(emac->port_id), true);
 	return 0;
 }
 
 static int icssg_prueth_hsr_del_mcast(struct net_device *ndev, const u8 *addr)
 {
-	struct prueth_emac *emac = netdev_priv(ndev);
-	struct prueth *prueth = emac->prueth;
+	struct net_device *real_dev;
+	struct prueth_emac *emac;
+	u8 vlan_id, i;
 
-	icssg_fdb_add_del(emac, addr, prueth->default_vlan,
-			  ICSSG_FDB_ENTRY_P0_MEMBERSHIP |
-			  ICSSG_FDB_ENTRY_P1_MEMBERSHIP |
-			  ICSSG_FDB_ENTRY_P2_MEMBERSHIP |
-			  ICSSG_FDB_ENTRY_BLOCK, false);
+	vlan_id = is_vlan_dev(ndev) ? vlan_dev_vlan_id(ndev) : PRUETH_DFLT_VLAN_HSR;
+	real_dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev;
+
+	if (is_hsr_master(real_dev)) {
+		for (i = HSR_PT_SLAVE_A; i < HSR_PT_INTERLINK; i++) {
+			emac = netdev_priv(hsr_get_port_ndev(real_dev, i));
+			if (!emac)
+				return -EINVAL;
+			icssg_prueth_hsr_fdb_add_del(emac, addr, vlan_id,
+						     false);
+		}
+	} else {
+		emac = netdev_priv(real_dev);
+		icssg_prueth_hsr_fdb_add_del(emac, addr, vlan_id, false);
+	}
+
+	return 0;
+}
+
+static int icssg_update_vlan_mcast(struct net_device *vdev, int vid,
+				   void *args)
+{
+	struct prueth_emac *emac = args;
+
+	if (!vdev || !vid)
+		return 0;
+
+	netif_addr_lock_bh(vdev);
+	__hw_addr_sync_multiple(&emac->vlan_mcast_list[vid], &vdev->mc,
+				vdev->addr_len);
+	netif_addr_unlock_bh(vdev);
+
+	if (emac->prueth->is_hsr_offload_mode)
+		__hw_addr_sync_dev(&emac->vlan_mcast_list[vid], vdev,
+				   icssg_prueth_hsr_add_mcast,
+				   icssg_prueth_hsr_del_mcast);
+	else
+		__hw_addr_sync_dev(&emac->vlan_mcast_list[vid], vdev,
+				   icssg_prueth_add_mcast,
+				   icssg_prueth_del_mcast);
 
 	return 0;
 }
@@ -707,10 +780,14 @@
 	if (ret)
 		goto free_tx_ts_irq;
 
-	ret = k3_udma_glue_enable_rx_chn(emac->rx_chns.rx_chn);
+	ret = prueth_create_xdp_rxqs(emac);
 	if (ret)
 		goto reset_rx_chn;
 
+	ret = k3_udma_glue_enable_rx_chn(emac->rx_chns.rx_chn);
+	if (ret)
+		goto destroy_xdp_rxqs;
+
 	for (i = 0; i < emac->tx_ch_num; i++) {
 		ret = k3_udma_glue_enable_tx_chn(emac->tx_chns[i].tx_chn);
 		if (ret)
@@ -722,6 +799,8 @@
 		napi_enable(&emac->tx_chns[i].napi_tx);
 	napi_enable(&emac->napi_rx);
 
+	icssg_qos_init(ndev);
+
 	/* start PHY */
 	phy_start(ndev->phydev);
 
@@ -736,6 +815,8 @@
 	 * any SKB for completion. So set false to free_skb
 	 */
 	prueth_reset_tx_chan(emac, i, false);
+destroy_xdp_rxqs:
+	prueth_destroy_xdp_rxqs(emac);
 reset_rx_chn:
 	prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, false);
 free_tx_ts_irq:
@@ -806,7 +887,7 @@
 	k3_udma_glue_tdown_rx_chn(emac->rx_chns.rx_chn, true);
 
 	prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, true);
-
+	prueth_destroy_xdp_rxqs(emac);
 	napi_disable(&emac->napi_rx);
 	hrtimer_cancel(&emac->rx_hrtimer);
 
@@ -857,12 +938,22 @@
 		return;
 	}
 
-	if (emac->prueth->is_hsr_offload_mode)
+	if (emac->prueth->is_hsr_offload_mode) {
 		__dev_mc_sync(ndev, icssg_prueth_hsr_add_mcast,
 			      icssg_prueth_hsr_del_mcast);
-	else
+		if (rtnl_trylock()) {
+			vlan_for_each(emac->prueth->hsr_dev,
+				      icssg_update_vlan_mcast, emac);
+			rtnl_unlock();
+		}
+	} else {
 		__dev_mc_sync(ndev, icssg_prueth_add_mcast,
 			      icssg_prueth_del_mcast);
+		if (rtnl_trylock()) {
+			vlan_for_each(ndev, icssg_update_vlan_mcast, emac);
+			rtnl_unlock();
+		}
+	}
 }
 
 /**
@@ -902,6 +993,132 @@
 	return features;
 }
 
+static int emac_ndo_vlan_rx_add_vid(struct net_device *ndev,
+				    __be16 proto, u16 vid)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct prueth *prueth = emac->prueth;
+	int port_mask = BIT(emac->port_id);
+	int untag_mask = 0;
+
+	if (prueth->is_hsr_offload_mode)
+		port_mask |= BIT(PRUETH_PORT_HOST);
+
+	__hw_addr_init(&emac->vlan_mcast_list[vid]);
+	netdev_dbg(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n",
+		   vid, port_mask, untag_mask);
+
+	icssg_vtbl_modify(emac, vid, port_mask, untag_mask, true);
+	icssg_set_pvid(emac->prueth, vid, emac->port_id);
+
+	return 0;
+}
+
+static int emac_ndo_vlan_rx_del_vid(struct net_device *ndev,
+				    __be16 proto, u16 vid)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct prueth *prueth = emac->prueth;
+	int port_mask = BIT(emac->port_id);
+	int untag_mask = 0;
+
+	if (prueth->is_hsr_offload_mode)
+		port_mask = BIT(PRUETH_PORT_HOST);
+
+	netdev_dbg(emac->ndev, "VID del vid:%u port_mask:%X untag_mask  %X\n",
+		   vid, port_mask, untag_mask);
+	icssg_vtbl_modify(emac, vid, port_mask, untag_mask, false);
+
+	return 0;
+}
+
+/**
+ * emac_xdp_xmit - Implements ndo_xdp_xmit
+ * @dev: netdev
+ * @n: number of frames
+ * @frames: array of XDP buffer pointers
+ * @flags: XDP extra info
+ *
+ * Return: number of frames successfully sent. Failed frames
+ * will be free'ed by XDP core.
+ *
+ * For error cases, a negative errno code is returned and no-frames
+ * are transmitted (caller must handle freeing frames).
+ **/
+static int emac_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
+			 u32 flags)
+{
+	struct prueth_emac *emac = netdev_priv(dev);
+	struct net_device *ndev = emac->ndev;
+	struct netdev_queue *netif_txq;
+	int cpu = smp_processor_id();
+	struct xdp_frame *xdpf;
+	unsigned int q_idx;
+	int nxmit = 0;
+	u32 err;
+	int i;
+
+	q_idx = cpu % emac->tx_ch_num;
+	netif_txq = netdev_get_tx_queue(ndev, q_idx);
+
+	if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
+		return -EINVAL;
+
+	__netif_tx_lock(netif_txq, cpu);
+	for (i = 0; i < n; i++) {
+		xdpf = frames[i];
+		err = emac_xmit_xdp_frame(emac, xdpf, NULL, q_idx);
+		if (err != ICSSG_XDP_TX) {
+			ndev->stats.tx_dropped++;
+			break;
+		}
+		nxmit++;
+	}
+	__netif_tx_unlock(netif_txq);
+
+	return nxmit;
+}
+
+/**
+ * emac_xdp_setup - add/remove an XDP program
+ * @emac: emac device
+ * @bpf: XDP program
+ *
+ * Return: Always 0 (Success)
+ **/
+static int emac_xdp_setup(struct prueth_emac *emac, struct netdev_bpf *bpf)
+{
+	struct bpf_prog *prog = bpf->prog;
+
+	if (!emac->xdpi.prog && !prog)
+		return 0;
+
+	WRITE_ONCE(emac->xdp_prog, prog);
+
+	xdp_attachment_setup(&emac->xdpi, bpf);
+
+	return 0;
+}
+
+/**
+ * emac_ndo_bpf - implements ndo_bpf for icssg_prueth
+ * @ndev: network adapter device
+ * @bpf: XDP program
+ *
+ * Return: 0 on success, error code on failure.
+ **/
+static int emac_ndo_bpf(struct net_device *ndev, struct netdev_bpf *bpf)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+
+	switch (bpf->command) {
+	case XDP_SETUP_PROG:
+		return emac_xdp_setup(emac, bpf);
+	default:
+		return -EINVAL;
+	}
+}
+
 static const struct net_device_ops emac_netdev_ops = {
 	.ndo_open = emac_ndo_open,
 	.ndo_stop = emac_ndo_stop,
@@ -912,8 +1129,12 @@
 	.ndo_set_rx_mode = emac_ndo_set_rx_mode,
 	.ndo_eth_ioctl = icssg_ndo_ioctl,
 	.ndo_get_stats64 = icssg_ndo_get_stats64,
-	.ndo_get_phys_port_name = icssg_ndo_get_phys_port_name,
 	.ndo_fix_features = emac_ndo_fix_features,
+	.ndo_vlan_rx_add_vid = emac_ndo_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid = emac_ndo_vlan_rx_del_vid,
+	.ndo_bpf = emac_ndo_bpf,
+	.ndo_xdp_xmit = emac_xdp_xmit,
+	.ndo_setup_tc = icssg_qos_ndo_setup_tc,
 };
 
 static int prueth_netdev_init(struct prueth *prueth,
@@ -942,6 +1163,8 @@
 	emac->prueth = prueth;
 	emac->ndev = ndev;
 	emac->port_id = port;
+	emac->xdp_prog = NULL;
+	emac->ndev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
 	emac->cmd_wq = create_singlethread_workqueue("icssg_cmd_wq");
 	if (!emac->cmd_wq) {
 		ret = -ENOMEM;
@@ -1041,8 +1264,12 @@
 	ndev->netdev_ops = &emac_netdev_ops;
 	ndev->ethtool_ops = &icssg_ethtool_ops;
 	ndev->hw_features = NETIF_F_SG;
-	ndev->features = ndev->hw_features;
+	ndev->features = ndev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER;
 	ndev->hw_features |= NETIF_PRUETH_HSR_OFFLOAD_FEATURES;
+	xdp_set_features_flag(ndev,
+			      NETDEV_XDP_ACT_BASIC |
+			      NETDEV_XDP_ACT_REDIRECT |
+			      NETDEV_XDP_ACT_NDO_XMIT);
 
 	netif_napi_add(ndev, &emac->napi_rx, icssg_napi_rx_poll);
 	hrtimer_init(&emac->rx_hrtimer, CLOCK_MONOTONIC,
@@ -1211,7 +1438,7 @@
 		if (prueth->br_members & BIT(PRUETH_PORT_MII0) &&
 		    prueth->br_members & BIT(PRUETH_PORT_MII1)) {
 			prueth->is_switch_mode = true;
-			prueth->default_vlan = 1;
+			prueth->default_vlan = PRUETH_DFLT_VLAN_SW;
 			emac->port_vlan = prueth->default_vlan;
 			icssg_change_mode(prueth);
 		}
@@ -1269,7 +1496,7 @@
 			      NETIF_PRUETH_HSR_OFFLOAD_FEATURES))
 				return -EOPNOTSUPP;
 			prueth->is_hsr_offload_mode = true;
-			prueth->default_vlan = 1;
+			prueth->default_vlan = PRUETH_DFLT_VLAN_HSR;
 			emac0->port_vlan = prueth->default_vlan;
 			emac1->port_vlan = prueth->default_vlan;
 			icssg_change_mode(prueth);
@@ -1315,6 +1542,7 @@
 	struct netdev_notifier_changeupper_info *info;
 	struct prueth_emac *emac = netdev_priv(ndev);
 	struct prueth *prueth = emac->prueth;
+	enum hsr_version hsr_ndev_version;
 	int ret = NOTIFY_DONE;
 
 	if (ndev->netdev_ops != &emac_netdev_ops)
@@ -1326,6 +1554,11 @@
 
 		if ((ndev->features & NETIF_PRUETH_HSR_OFFLOAD_FEATURES) &&
 		    is_hsr_master(info->upper_dev)) {
+			hsr_get_version(info->upper_dev, &hsr_ndev_version);
+			if (hsr_ndev_version != HSR_V1 && hsr_ndev_version != PRP_V1)
+				return -EOPNOTSUPP;
+			prueth->hsr_prp_version = hsr_ndev_version;
+
 			if (info->linking) {
 				if (!prueth->hsr_dev) {
 					prueth->hsr_dev = info->upper_dev;
@@ -1381,6 +1614,256 @@
 	unregister_netdevice_notifier(&prueth->prueth_netdevice_nb);
 }
 
+static const struct devlink_ops prueth_devlink_ops = {};
+
+static u8 prueth_dl_cut_thru_check(struct prueth_emac *emac)
+{
+	void __iomem *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
+	u8 queue_map = 0U;
+	u8 cut_thru_val;
+	int i;
+
+	for (i = 0; i < PRUETH_MAX_TX_QUEUES * PRUETH_NUM_MACS; i++) {
+		cut_thru_val = readb(config + EXPRESS_PRE_EMPTIVE_Q_MAP + i);
+		if (cut_thru_val & ICSSG_CUT_THRU_BIT)
+			queue_map |= BIT(i);
+	}
+
+	return queue_map;
+}
+
+static int prueth_dl_cut_thru_en_get(struct devlink *dl, u32 id,
+				     struct devlink_param_gset_ctx *ctx)
+{
+	struct prueth_devlink *dl_priv = devlink_priv(dl);
+	struct prueth *prueth = dl_priv->prueth;
+	u16 tx_queues = 0U;
+	int slice;
+
+	dev_dbg(prueth->dev, "%s id:%u\n", __func__, id);
+
+	if (id != PRUETH_DL_PARAM_CUT_THRU_EN)
+		return -EOPNOTSUPP;
+
+	for (slice = PRUETH_MAC0; slice < PRUETH_NUM_MACS; slice++) {
+		if (!(prueth->emac[slice]))
+			return -EINVAL;
+		tx_queues |= prueth_dl_cut_thru_check(prueth->emac[slice]) << (8 * slice);
+	}
+
+	ctx->val.vu16 = tx_queues;
+
+	return 0;
+}
+
+static int prueth_dl_cut_thru_en_set(struct devlink *dl, u32 id,
+				     struct devlink_param_gset_ctx *ctx,
+				     struct netlink_ext_ack *extack)
+{
+	struct prueth_devlink *dl_priv = devlink_priv(dl);
+	struct prueth *prueth = dl_priv->prueth;
+	u16 tx_queues = ctx->val.vu16;
+	struct prueth_emac *emac;
+	int slice;
+
+	if (id != PRUETH_DL_PARAM_CUT_THRU_EN)
+		return -EOPNOTSUPP;
+
+	for (slice = PRUETH_MAC0; slice < PRUETH_NUM_MACS; slice++) {
+		if (!(prueth->emac[slice]))
+			return -EINVAL;
+		emac = prueth->emac[slice];
+		emac->cut_thru_queue_map = tx_queues >> (8 * slice);
+	}
+	return 0;
+}
+
+static const struct devlink_param prueth_devlink_params[] = {
+	DEVLINK_PARAM_DRIVER(PRUETH_DL_PARAM_CUT_THRU_EN, "cut_thru",
+			     DEVLINK_PARAM_TYPE_U16,
+			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+			     prueth_dl_cut_thru_en_get,
+			     prueth_dl_cut_thru_en_set, NULL),
+};
+
+static void prueth_unregister_devlink_ports(struct prueth *prueth)
+{
+	struct devlink_port *dl_port;
+	struct prueth_emac *emac;
+	int i;
+
+	for (i = PRUETH_MAC0; i < PRUETH_NUM_MACS; i++) {
+		emac = prueth->emac[i];
+		if (!emac)
+			continue;
+
+		dl_port = &emac->devlink_port;
+
+		if (dl_port->registered)
+			devlink_port_unregister(dl_port);
+	}
+}
+
+static int prueth_register_devlink(struct prueth *prueth)
+{
+	struct devlink_port_attrs attrs = {};
+	struct device *dev = prueth->dev;
+	struct prueth_devlink *dl_priv;
+	struct devlink_port *dl_port;
+	struct prueth_emac *emac;
+	int slice, ret;
+
+	prueth->devlink =
+		devlink_alloc(&prueth_devlink_ops, sizeof(*dl_priv), dev);
+	if (!prueth->devlink)
+		return -ENOMEM;
+
+	dl_priv = devlink_priv(prueth->devlink);
+	dl_priv->prueth = prueth;
+
+	/* Provide devlink hook to switch mode when multiple external ports
+	 * are present and ICSSG switch mode is enabled.
+	 */
+	if (prueth->is_switchmode_supported) {
+		ret = devlink_params_register(prueth->devlink,
+					      prueth_devlink_params,
+					      ARRAY_SIZE(prueth_devlink_params));
+		if (ret) {
+			dev_err(dev, "devlink params reg fail ret:%d\n", ret);
+			goto dl_unreg;
+		}
+	}
+
+	for (slice = PRUETH_MAC0; slice < PRUETH_NUM_MACS; slice++) {
+		emac = prueth->emac[slice];
+		if (!emac)
+			continue;
+
+		dl_port = &emac->devlink_port;
+
+		if (emac->ndev)
+			attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+		else
+			attrs.flavour = DEVLINK_PORT_FLAVOUR_UNUSED;
+		attrs.phys.port_number = emac->port_id;
+		attrs.switch_id.id_len = sizeof(resource_size_t);
+		memcpy(attrs.switch_id.id, prueth->switch_id, attrs.switch_id.id_len);
+		devlink_port_attrs_set(dl_port, &attrs);
+
+		ret = devlink_port_register(prueth->devlink, dl_port, emac->port_id);
+		if (ret) {
+			dev_err(dev, "devlink_port reg fail for port %d, ret:%d\n",
+				emac->port_id, ret);
+			goto dl_port_unreg;
+		}
+	}
+
+	devlink_register(prueth->devlink);
+	return 0;
+
+dl_port_unreg:
+	prueth_unregister_devlink_ports(prueth);
+dl_unreg:
+	devlink_free(prueth->devlink);
+
+	return ret;
+}
+
+static void prueth_unregister_devlink(struct prueth *prueth)
+{
+	devlink_unregister(prueth->devlink);
+
+	if (prueth->is_switchmode_supported) {
+		devlink_params_unregister(prueth->devlink, prueth_devlink_params,
+					  ARRAY_SIZE(prueth_devlink_params));
+	}
+
+	prueth_unregister_devlink_ports(prueth);
+	devlink_unregister(prueth->devlink);
+	devlink_free(prueth->devlink);
+}
+
+static void icssg_read_firmware_names(struct device_node *np,
+				      struct icssg_firmwares *fw)
+{
+	int i;
+
+	for (i = 0; i < PRUETH_NUM_MACS; i++) {
+		of_property_read_string_index(np, "firmware-name", i * 3 + 0,
+					      &fw[i].pru);
+		of_property_read_string_index(np, "firmware-name", i * 3 + 1,
+					      &fw[i].rtu);
+		of_property_read_string_index(np, "firmware-name", i * 3 + 2,
+					      &fw[i].txpru);
+	}
+}
+
+/* icssg_firmware_name_replace - Replace a substring in firmware name
+ * @dev: device pointer for memory allocation
+ * @src: source firmware name string
+ * @from: substring to replace
+ * @to: replacement substring
+ *
+ * Return: a newly allocated string with the replacement, or the original
+ * string if replacement is not possible.
+ */
+static const char *icssg_firmware_name_replace(struct device *dev,
+					       const char *src,
+					       const char *from,
+					       const char *to)
+{
+	size_t prefix, from_len, to_len, total;
+	const char *p = strstr(src, from);
+	char *buf;
+
+	if (!p)
+		return src; /* fallback: no replacement, use original */
+
+	prefix = p - src;
+	from_len = strlen(from);
+	to_len = strlen(to);
+	total = strlen(src) - from_len + to_len + 1;
+
+	buf = devm_kzalloc(dev, total, GFP_KERNEL);
+	if (!buf)
+		return src; /* fallback: allocation failed, use original */
+
+	strscpy(buf, src, prefix + 1);
+	strscpy(buf + prefix, to, to_len + 1);
+	strscpy(buf + prefix + to_len, p + from_len, total - prefix - to_len);
+
+	return buf;
+}
+
+/**
+ * icssg_mode_firmware_names - Generate firmware names for a specific mode
+ * @dev: device pointer for logging and context
+ * @src: source array of firmware name structures
+ * @dst: destination array to store updated firmware name structures
+ * @from: substring in firmware names to be replaced
+ * @to: substring to replace @from in firmware names
+ *
+ * Iterates over all MACs and replaces occurrences of the @from substring
+ * with @to in the firmware names (pru, rtu, txpru) for each MAC. The
+ * updated firmware names are stored in the @dst array.
+ */
+static void icssg_mode_firmware_names(struct device *dev,
+				      struct icssg_firmwares *src,
+				      struct icssg_firmwares *dst,
+				      const char *from, const char *to)
+{
+	int i;
+
+	for (i = 0; i < PRUETH_NUM_MACS; i++) {
+		dst[i].pru = icssg_firmware_name_replace(dev, src[i].pru,
+							 from, to);
+		dst[i].rtu = icssg_firmware_name_replace(dev, src[i].rtu,
+							 from, to);
+		dst[i].txpru = icssg_firmware_name_replace(dev, src[i].txpru,
+							   from, to);
+	}
+}
+
 static int prueth_probe(struct platform_device *pdev)
 {
 	struct device_node *eth_node, *eth_ports_node;
@@ -1398,6 +1881,9 @@
 
 	np = dev->of_node;
 
+	BUILD_BUG_ON_MSG((sizeof(struct prueth_swdata) > PRUETH_NAV_SW_DATA_SIZE),
+			 "insufficient SW_DATA size");
+
 	prueth = devm_kzalloc(dev, sizeof(*prueth), GFP_KERNEL);
 	if (!prueth)
 		return -ENOMEM;
@@ -1554,6 +2040,17 @@
 		icss_iep_init_fw(prueth->iep1);
 	}
 
+	/* Read EMAC firmware names from device tree */
+	icssg_read_firmware_names(np, prueth->icssg_emac_firmwares);
+
+	/* Generate other mode firmware names based on EMAC firmware names */
+	icssg_mode_firmware_names(dev, prueth->icssg_emac_firmwares,
+				  prueth->icssg_switch_firmwares, "eth", "sw");
+	icssg_mode_firmware_names(dev, prueth->icssg_emac_firmwares,
+				  prueth->icssg_hsr_firmwares, "eth", "hsr");
+	icssg_mode_firmware_names(dev, prueth->icssg_emac_firmwares,
+				  prueth->icssg_prp_firmwares, "eth", "prp");
+
 	spin_lock_init(&prueth->vtbl_lock);
 	spin_lock_init(&prueth->stats_lock);
 	/* setup netdev interfaces */
@@ -1585,12 +2082,18 @@
 		prueth->emac[PRUETH_MAC1]->iep = prueth->iep0;
 	}
 
+	ret = prueth_register_devlink(prueth);
+	if (ret)
+		goto netdev_exit;
+
 	/* register the network devices */
 	if (eth0_node) {
+		SET_NETDEV_DEVLINK_PORT(prueth->emac[PRUETH_MAC0]->ndev,
+					&prueth->emac[PRUETH_MAC0]->devlink_port);
 		ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev);
 		if (ret) {
 			dev_err(dev, "can't register netdev for port MII0");
-			goto netdev_exit;
+			goto unregister_devlink;
 		}
 
 		prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev;
@@ -1605,6 +2108,8 @@
 	}
 
 	if (eth1_node) {
+		SET_NETDEV_DEVLINK_PORT(prueth->emac[PRUETH_MAC1]->ndev,
+					&prueth->emac[PRUETH_MAC1]->devlink_port);
 		ret = register_netdev(prueth->emac[PRUETH_MAC1]->ndev);
 		if (ret) {
 			dev_err(dev, "can't register netdev for port MII1");
@@ -1649,6 +2154,9 @@
 		unregister_netdev(prueth->registered_netdevs[i]);
 	}
 
+unregister_devlink:
+	prueth_unregister_devlink(prueth);
+
 netdev_exit:
 	for (i = 0; i < PRUETH_NUM_MACS; i++) {
 		eth_node = prueth->eth_node[i];
@@ -1706,6 +2214,7 @@
 		prueth->emac[i]->ndev->phydev = NULL;
 		unregister_netdev(prueth->registered_netdevs[i]);
 	}
+	prueth_unregister_devlink(prueth);
 
 	for (i = 0; i < PRUETH_NUM_MACS; i++) {
 		eth_node = prueth->eth_node[i];
diff -Naur --no-dereference a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h	2025-10-23 09:30:40.286462238 -0400
@@ -8,9 +8,12 @@
 #ifndef __NET_TI_ICSSG_PRUETH_H
 #define __NET_TI_ICSSG_PRUETH_H
 
+#include <linux/bpf.h>
+#include <linux/bpf_trace.h>
 #include <linux/etherdevice.h>
 #include <linux/genalloc.h>
 #include <linux/if_vlan.h>
+#include <linux/if_hsr.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/mfd/syscon.h>
@@ -33,10 +36,13 @@
 #include <linux/dma/k3-udma-glue.h>
 
 #include <net/devlink.h>
+#include <net/xdp.h>
+#include <net/page_pool/helpers.h>
 
 #include "icssg_config.h"
 #include "icss_iep.h"
 #include "icssg_switch_map.h"
+#include "icssg_qos.h"
 
 #define PRUETH_MAX_MTU          (2000 - ETH_HLEN - ETH_FCS_LEN)
 #define PRUETH_MIN_PKT_SIZE     (VLAN_ETH_ZLEN)
@@ -50,7 +56,8 @@
 
 #define ICSSG_MAX_RFLOWS	8	/* per slice */
 
-#define ICSSG_NUM_PA_STATS	4
+#define ICSSG_CUT_THRU_BIT	BIT(7)
+#define ICSSG_NUM_PA_STATS	37
 #define ICSSG_NUM_MIIG_STATS	60
 /* Number of ICSSG related stats */
 #define ICSSG_NUM_STATS (ICSSG_NUM_MIIG_STATS + ICSSG_NUM_PA_STATS)
@@ -83,6 +90,12 @@
 #define ICSS_CMD_ADD_FILTER 0x7
 #define ICSS_CMD_ADD_MAC 0x8
 
+/* VLAN Filtering Related MACROs */
+#define PRUETH_DFLT_VLAN_HSR	1
+#define PRUETH_DFLT_VLAN_SW	1
+#define PRUETH_DFLT_VLAN_MAC	0
+#define MAX_VLAN_ID		256
+
 /* In switch mode there are 3 real ports i.e. 3 mac addrs.
  * however Linux sees only the host side port. The other 2 ports
  * are the switch ports.
@@ -103,6 +116,15 @@
 	PRUETH_MAC_INVALID,
 };
 
+enum prueth_devlink_param_id {
+	PRUETH_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
+	PRUETH_DL_PARAM_CUT_THRU_EN,
+};
+
+struct prueth_devlink {
+	struct prueth *prueth;
+};
+
 struct prueth_tx_chn {
 	struct device *dma_dev;
 	struct napi_struct napi_tx;
@@ -125,6 +147,26 @@
 	u32 descs_num;
 	unsigned int irq[ICSSG_MAX_RFLOWS];	/* separate irq per flow */
 	char name[32];
+	struct page_pool *pg_pool;
+	struct xdp_rxq_info xdp_rxq;
+};
+
+enum prueth_swdata_type {
+	PRUETH_SWDATA_INVALID = 0,
+	PRUETH_SWDATA_SKB,
+	PRUETH_SWDATA_PAGE,
+	PRUETH_SWDATA_CMD,
+	PRUETH_SWDATA_XDPF,
+};
+
+struct prueth_swdata {
+	enum prueth_swdata_type type;
+	union prueth_data {
+		struct sk_buff *skb;
+		struct page *page;
+		u32 cmd;
+		struct xdp_frame *xdpf;
+	} data;
 };
 
 /* There are 4 Tx DMA channels, but the highest priority is CH3 (thread 3)
@@ -134,6 +176,12 @@
 
 #define PRUETH_MAX_TX_TS_REQUESTS	50 /* Max simultaneous TX_TS requests */
 
+/* XDP BPF state */
+#define ICSSG_XDP_PASS           0
+#define ICSSG_XDP_CONSUMED       BIT(0)
+#define ICSSG_XDP_TX             BIT(1)
+#define ICSSG_XDP_REDIR          BIT(2)
+
 /* Minimum coalesce time in usecs for both Tx and Rx */
 #define ICSSG_MIN_COALESCE_USECS 20
 
@@ -190,6 +238,8 @@
 
 	struct pruss_mem_region dram;
 
+	struct devlink_port devlink_port;
+	u8 cut_thru_queue_map;
 	bool offload_fwd_mark;
 	int port_vlan;
 
@@ -200,8 +250,17 @@
 	/* RX IRQ Coalescing Related */
 	struct hrtimer rx_hrtimer;
 	unsigned long rx_pace_timeout_ns;
+
+	struct netdev_hw_addr_list vlan_mcast_list[MAX_VLAN_ID];
+	struct bpf_prog *xdp_prog;
+	struct xdp_attachment_info xdpi;
+	struct prueth_qos qos;
 };
 
+/* The buf includes headroom compatible with both skb and xdpf */
+#define PRUETH_HEADROOM_NA (max(XDP_PACKET_HEADROOM, NET_SKB_PAD) + NET_IP_ALIGN)
+#define PRUETH_HEADROOM  ALIGN(PRUETH_HEADROOM_NA, sizeof(long))
+
 /**
  * struct prueth_pdata - PRUeth platform data
  * @fdqring_mode: Free desc queue mode
@@ -215,9 +274,9 @@
 };
 
 struct icssg_firmwares {
-	char *pru;
-	char *rtu;
-	char *txpru;
+	const char *pru;
+	const char *rtu;
+	const char *txpru;
 };
 
 /**
@@ -246,6 +305,7 @@
  * @vlan_tbl: VLAN-FID table pointer
  * @hw_bridge_dev: pointer to HW bridge net device
  * @hsr_dev: pointer to the HSR net device
+ * @hsr_prp_version: enum to store the protocol version of hsr master
  * @br_members: bitmask of bridge member ports
  * @hsr_members: bitmask of hsr member ports
  * @prueth_netdevice_nb: netdevice notifier block
@@ -256,6 +316,11 @@
  * @is_switchmode_supported: indicates platform support for switch mode
  * @switch_id: ID for mapping switch ports to bridge
  * @default_vlan: Default VLAN for host
+ * @devlink: pointer to devlink
+ * @icssg_emac_firmwares: Firmware names for EMAC mode, indexed per MAC
+ * @icssg_switch_firmwares: Firmware names for SWITCH mode, indexed per MAC
+ * @icssg_hsr_firmwares: Firmware names for HSR mode, indexed per MAC
+ * @icssg_prp_firmwares: Firmware names for PRP mode, indexed per MAC
  */
 struct prueth {
 	struct device *dev;
@@ -285,6 +350,7 @@
 
 	struct net_device *hw_bridge_dev;
 	struct net_device *hsr_dev;
+	enum hsr_version hsr_prp_version;
 	u8 br_members;
 	u8 hsr_members;
 	struct notifier_block prueth_netdevice_nb;
@@ -297,8 +363,13 @@
 	int default_vlan;
 	/** @vtbl_lock: Lock for vtbl in shared memory */
 	spinlock_t vtbl_lock;
+	struct devlink *devlink;
 	/** @stats_lock: Lock for reading icssg stats */
 	spinlock_t stats_lock;
+	struct icssg_firmwares icssg_emac_firmwares[PRUETH_NUM_MACS];
+	struct icssg_firmwares icssg_switch_firmwares[PRUETH_NUM_MACS];
+	struct icssg_firmwares icssg_hsr_firmwares[PRUETH_NUM_MACS];
+	struct icssg_firmwares icssg_prp_firmwares[PRUETH_NUM_MACS];
 };
 
 struct emac_tx_ts_response {
@@ -404,9 +475,10 @@
 			struct prueth_rx_chn *rx_chn,
 			char *name, u32 max_rflows,
 			u32 max_desc_num);
-int prueth_dma_rx_push(struct prueth_emac *emac,
-		       struct sk_buff *skb,
-		       struct prueth_rx_chn *rx_chn);
+int prueth_dma_rx_push_mapped(struct prueth_emac *emac,
+			      struct prueth_rx_chn *rx_chn,
+			      struct page *page, u32 buf_len);
+unsigned int prueth_rxbuf_total_len(unsigned int len);
 void emac_rx_timestamp(struct prueth_emac *emac,
 		       struct sk_buff *skb, u32 *psdata);
 enum netdev_tx icssg_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev);
@@ -435,5 +507,9 @@
 
 /* Revision specific helper */
 u64 icssg_ts_to_ns(u32 hi_sw, u32 hi, u32 lo, u32 cycle_time_ns);
+u32 emac_xmit_xdp_frame(struct prueth_emac *emac,
+			struct xdp_frame *xdpf,
+			struct page *page,
+			unsigned int q_idx);
 
 #endif /* __NET_TI_ICSSG_PRUETH_H */
diff -Naur --no-dereference a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c	2025-10-23 09:30:40.286462238 -0400
@@ -84,7 +84,7 @@
 	__le32 *data = emac->cmd_data;
 	dma_addr_t desc_dma, buf_dma;
 	struct prueth_tx_chn *tx_chn;
-	void **swdata;
+	struct prueth_swdata *swdata;
 	int ret = 0;
 	u32 *epib;
 
@@ -122,7 +122,8 @@
 
 	cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len);
 	swdata = cppi5_hdesc_get_swdata(first_desc);
-	*swdata = data;
+	swdata->type = PRUETH_SWDATA_CMD;
+	swdata->data.cmd = le32_to_cpu(data[0]);
 
 	cppi5_hdesc_set_pktlen(first_desc, pkt_len);
 	desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc);
@@ -268,16 +269,16 @@
  * Returns skb pointer if packet found else NULL
  * Caller must free the returned skb.
  */
-static struct sk_buff *prueth_process_rx_mgm(struct prueth_emac *emac,
-					     u32 flow_id)
+static struct page *prueth_process_rx_mgm(struct prueth_emac *emac,
+					  u32 flow_id)
 {
 	struct prueth_rx_chn *rx_chn = &emac->rx_mgm_chn;
 	struct net_device *ndev = emac->ndev;
 	struct cppi5_host_desc_t *desc_rx;
-	struct sk_buff *skb, *new_skb;
+	struct page *page, *new_page;
+	struct prueth_swdata *swdata;
 	dma_addr_t desc_dma, buf_dma;
-	u32 buf_dma_len, pkt_len;
-	void **swdata;
+	u32 buf_dma_len;
 	int ret;
 
 	ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma);
@@ -299,34 +300,31 @@
 	}
 
 	swdata = cppi5_hdesc_get_swdata(desc_rx);
-	skb = *swdata;
+	page = swdata->data.page;
 	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
-	pkt_len = cppi5_hdesc_get_pktlen(desc_rx);
 
 	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE);
 	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
 
-	new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE);
+	new_page = page_pool_dev_alloc_pages(rx_chn->pg_pool);
 	/* if allocation fails we drop the packet but push the
 	 * descriptor back to the ring with old skb to prevent a stall
 	 */
-	if (!new_skb) {
+	if (!new_page) {
 		netdev_err(ndev,
-			   "skb alloc failed, dropped mgm pkt from flow %d\n",
+			   "page alloc failed, dropped mgm pkt from flow %d\n",
 			   flow_id);
-		new_skb = skb;
-		skb = NULL;	/* return NULL */
-	} else {
-		/* return the filled skb */
-		skb_put(skb, pkt_len);
+		new_page = page;
+		page = NULL;	/* return NULL */
 	}
 
 	/* queue another DMA */
-	ret = prueth_dma_rx_push(emac, new_skb, &emac->rx_mgm_chn);
+	ret = prueth_dma_rx_push_mapped(emac, &emac->rx_chns, new_page,
+					PRUETH_MAX_PKT_SIZE);
 	if (WARN_ON(ret < 0))
-		dev_kfree_skb_any(new_skb);
+		page_pool_recycle_direct(rx_chn->pg_pool, new_page);
 
-	return skb;
+	return page;
 }
 
 static void prueth_tx_ts_sr1(struct prueth_emac *emac,
@@ -362,14 +360,14 @@
 static irqreturn_t prueth_rx_mgm_ts_thread_sr1(int irq, void *dev_id)
 {
 	struct prueth_emac *emac = dev_id;
-	struct sk_buff *skb;
+	struct page *page;
 
-	skb = prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_TIMESTAMP_SR1);
-	if (!skb)
+	page = prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_TIMESTAMP_SR1);
+	if (!page)
 		return IRQ_NONE;
 
-	prueth_tx_ts_sr1(emac, (void *)skb->data);
-	dev_kfree_skb_any(skb);
+	prueth_tx_ts_sr1(emac, (void *)page_address(page));
+	page_pool_recycle_direct(page->pp, page);
 
 	return IRQ_HANDLED;
 }
@@ -377,15 +375,15 @@
 static irqreturn_t prueth_rx_mgm_rsp_thread(int irq, void *dev_id)
 {
 	struct prueth_emac *emac = dev_id;
-	struct sk_buff *skb;
+	struct page *page;
 	u32 rsp;
 
-	skb = prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_RESPONSE_SR1);
-	if (!skb)
+	page = prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_RESPONSE_SR1);
+	if (!page)
 		return IRQ_NONE;
 
 	/* Process command response */
-	rsp = le32_to_cpu(*(__le32 *)skb->data) & 0xffff0000;
+	rsp = le32_to_cpu(*(__le32 *)page_address(page)) & 0xffff0000;
 	if (rsp == ICSSG_SHUTDOWN_CMD_SR1) {
 		netdev_dbg(emac->ndev, "f/w Shutdown cmd resp %x\n", rsp);
 		complete(&emac->cmd_complete);
@@ -394,7 +392,7 @@
 		complete(&emac->cmd_complete);
 	}
 
-	dev_kfree_skb_any(skb);
+	page_pool_recycle_direct(page->pp, page);
 
 	return IRQ_HANDLED;
 }
diff -Naur --no-dereference a/drivers/net/ethernet/ti/icssg/icssg_qos.c b/drivers/net/ethernet/ti/icssg/icssg_qos.c
--- a/drivers/net/ethernet/ti/icssg/icssg_qos.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/ethernet/ti/icssg/icssg_qos.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Texas Instruments ICSSG PRUETH QoS submodule
+ * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include <linux/printk.h>
+#include "icssg_prueth.h"
+#include "icssg_switch_map.h"
+
+static void icssg_qos_tas_init(struct net_device *ndev);
+static void icssg_prueth_iet_fpe_disable(struct prueth_qos_iet *iet);
+static int icssg_prueth_iet_fpe_enable(struct prueth_emac *emac);
+static void icssg_prueth_iet_fpe_disable(struct prueth_qos_iet *iet);
+static void icssg_qos_enable_ietfpe(struct work_struct *work);
+
+void icssg_qos_init(struct net_device *ndev)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct prueth_qos_iet *iet = &emac->qos.iet;
+
+	icssg_qos_tas_init(ndev);
+
+	if (!iet->fpe_configured)
+		return;
+
+	/* Init work queue for IET MAC verify process */
+	iet->emac = emac;
+	INIT_WORK(&iet->fpe_config_task, icssg_qos_enable_ietfpe);
+	init_completion(&iet->fpe_config_compl);
+
+	/* As worker may be sleeping, check this flag to abort
+	 * as soon as it comes of out of sleep and cancel the
+	 * fpe config task.
+	 */
+	atomic_set(&iet->cancel_fpe_config, 0);
+}
+
+static void tas_update_fw_list_pointers(struct prueth_emac *emac)
+{
+	struct tas_config *tas = &emac->qos.tas.config;
+
+	if ((readb(tas->active_list)) == TAS_LIST0) {
+		tas->fw_active_list = emac->dram.va + TAS_GATE_MASK_LIST0;
+		tas->fw_shadow_list = emac->dram.va + TAS_GATE_MASK_LIST1;
+	} else {
+		tas->fw_active_list = emac->dram.va + TAS_GATE_MASK_LIST1;
+		tas->fw_shadow_list = emac->dram.va + TAS_GATE_MASK_LIST0;
+	}
+}
+
+void icssg_qos_link_up(struct net_device *ndev)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct prueth_qos_iet *iet = &emac->qos.iet;
+
+	if (!iet->fpe_configured)
+		return;
+
+	icssg_prueth_iet_fpe_enable(emac);
+}
+
+void icssg_qos_link_down(struct net_device *ndev)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct prueth_qos_iet *iet = &emac->qos.iet;
+
+	if (iet->fpe_configured)
+		icssg_prueth_iet_fpe_disable(iet);
+}
+
+static void tas_update_maxsdu_table(struct prueth_emac *emac)
+{
+	struct tas_config *tas = &emac->qos.tas.config;
+	u16 __iomem *max_sdu_tbl_ptr;
+	u8 gate_idx;
+
+	/* update the maxsdu table */
+	max_sdu_tbl_ptr = emac->dram.va + TAS_QUEUE_MAX_SDU_LIST;
+
+	for (gate_idx = 0; gate_idx < TAS_MAX_NUM_QUEUES; gate_idx++) {
+		if (!tas->max_sdu_table.max_sdu[gate_idx])
+			tas->max_sdu_table.max_sdu[gate_idx] = PRUETH_MAX_MTU;
+		writew(tas->max_sdu_table.max_sdu[gate_idx], &max_sdu_tbl_ptr[gate_idx]);
+	}
+}
+
+static void tas_reset(struct prueth_emac *emac)
+{
+	struct tas_config *tas = &emac->qos.tas.config;
+	int i;
+
+	for (i = 0; i < TAS_MAX_NUM_QUEUES; i++)
+		tas->max_sdu_table.max_sdu[i] = PRUETH_MAX_MTU;
+
+	tas_update_maxsdu_table(emac);
+
+	memset_io(tas->fw_active_list, 0, sizeof(*tas->fw_active_list));
+	memset_io(tas->fw_shadow_list, 0, sizeof(*tas->fw_shadow_list));
+}
+
+static int tas_set_state(struct prueth_emac *emac, enum tas_state state)
+{
+	struct tas_config *tas = &emac->qos.tas.config;
+	int ret;
+
+	if (tas->state == state)
+		return 0;
+
+	switch (state) {
+	case TAS_STATE_RESET:
+		tas_reset(emac);
+		ret = icssg_set_port_state(emac, ICSSG_EMAC_PORT_TAS_RESET);
+		break;
+	case TAS_STATE_ENABLE:
+		ret = icssg_set_port_state(emac, ICSSG_EMAC_PORT_TAS_ENABLE);
+		break;
+	case TAS_STATE_DISABLE:
+		ret = icssg_set_port_state(emac, ICSSG_EMAC_PORT_TAS_DISABLE);
+		break;
+	}
+
+	if (!ret)
+		tas->state = state;
+
+	return ret;
+}
+
+static int tas_set_trigger_list_change(struct prueth_emac *emac)
+{
+	struct tc_taprio_qopt_offload *admin_list = emac->qos.tas.taprio_admin;
+	struct tas_config *tas = &emac->qos.tas.config;
+	u32 change_cycle_count;
+	u32 extension_time;
+	u32 cycle_time;
+	u64 base_time;
+
+	/* IEP clock has a hardware errata due to which it wraps around exactly
+	 * once every taprio cycle. To compensate for that, adjust cycle time
+	 * by the wrap around time which is stored in emac->iep->def_inc
+	 */
+	cycle_time = admin_list->cycle_time - emac->iep->def_inc;
+	base_time = admin_list->base_time;
+
+	change_cycle_count = base_time / cycle_time;
+	extension_time = base_time % cycle_time;
+
+	writel(cycle_time, emac->dram.va + TAS_ADMIN_CYCLE_TIME);
+	writel(change_cycle_count, emac->dram.va + TAS_CONFIG_CHANGE_CYCLE_COUNT);
+	writeb(admin_list->num_entries, emac->dram.va + TAS_ADMIN_LIST_LENGTH);
+	writel(extension_time, emac->dram.va + TAS_CONFIG_EXTN_TIME);
+
+	/* config_change cleared by f/w to ack reception of new shadow list */
+	writeb(1, &tas->config_list->config_change);
+	/* config_pending cleared by f/w when new shadow list is copied to active list */
+	writeb(1, &tas->config_list->config_pending);
+
+	return icssg_set_port_state(emac, ICSSG_EMAC_PORT_TAS_TRIGGER);
+}
+
+static int tas_update_oper_list(struct prueth_emac *emac)
+{
+	struct tc_taprio_qopt_offload *admin_list = emac->qos.tas.taprio_admin;
+	struct tas_config *tas = &emac->qos.tas.config;
+	u32 tas_acc_gate_close_time = 0;
+	u8 idx, gate_idx, val;
+	int ret;
+
+	tas_update_fw_list_pointers(emac);
+
+	for (idx = 0; idx < admin_list->num_entries; idx++) {
+		writeb(admin_list->entries[idx].gate_mask,
+		       &tas->fw_shadow_list->gate_mask_list[idx]);
+		tas_acc_gate_close_time += admin_list->entries[idx].interval;
+
+		/* extend last entry till end of cycle time */
+		if (idx == admin_list->num_entries - 1)
+			writel(admin_list->cycle_time,
+			       &tas->fw_shadow_list->win_end_time_list[idx]);
+		else
+			writel(tas_acc_gate_close_time,
+			       &tas->fw_shadow_list->win_end_time_list[idx]);
+	}
+
+	/* clear remaining entries */
+	for (idx = admin_list->num_entries; idx < TAS_MAX_CMD_LISTS; idx++) {
+		writeb(0, &tas->fw_shadow_list->gate_mask_list[idx]);
+		writel(0, &tas->fw_shadow_list->win_end_time_list[idx]);
+	}
+
+	/* update the Array of gate close time for each queue in each window */
+	for (idx = 0 ; idx < admin_list->num_entries; idx++) {
+		/* On Linux, only PRUETH_MAX_TX_QUEUES are supported per port */
+		for (gate_idx = 0; gate_idx < PRUETH_MAX_TX_QUEUES; gate_idx++) {
+			u8 gate_mask_list_idx = readb(&tas->fw_shadow_list->gate_mask_list[idx]);
+			u32 gate_close_time = 0;
+
+			if (gate_mask_list_idx & BIT(gate_idx))
+				gate_close_time = readl(&tas->fw_shadow_list->win_end_time_list[idx]);
+
+			writel(gate_close_time,
+			       &tas->fw_shadow_list->gate_close_time_list[idx][gate_idx]);
+		}
+	}
+
+	/* Update the maxsdu table for firmware */
+	tas_update_maxsdu_table(emac);
+
+	/* tell f/w to swap active & shadow list */
+	ret = tas_set_trigger_list_change(emac);
+	if (ret) {
+		netdev_err(emac->ndev, "failed to swap f/w config list: %d\n", ret);
+		return ret;
+	}
+
+	/* Wait for completion */
+	ret = readb_poll_timeout(&tas->config_list->config_change, val, !val,
+				 USEC_PER_MSEC, 10 * USEC_PER_MSEC);
+	if (ret) {
+		netdev_err(emac->ndev, "TAS list change completion time out\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int emac_taprio_replace(struct net_device *ndev,
+			       struct tc_taprio_qopt_offload *taprio)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	int ret;
+
+	if (taprio->cycle_time_extension) {
+		NL_SET_ERR_MSG_MOD(taprio->extack, "Cycle time extension not supported");
+		return -EOPNOTSUPP;
+	}
+
+	if (taprio->cycle_time > TAS_MAX_CYCLE_TIME) {
+		NL_SET_ERR_MSG_FMT_MOD(taprio->extack, "cycle_time %llu is more than max supported cycle_time",
+				       taprio->cycle_time);
+		return -EINVAL;
+	}
+
+	if (taprio->cycle_time < TAS_MIN_CYCLE_TIME) {
+		NL_SET_ERR_MSG_FMT_MOD(taprio->extack, "cycle_time %llu is less than min supported cycle_time %d",
+				       taprio->cycle_time, TAS_MIN_CYCLE_TIME);
+		return -EINVAL;
+	}
+
+	if (taprio->num_entries > TAS_MAX_CMD_LISTS) {
+		NL_SET_ERR_MSG_FMT_MOD(taprio->extack, "num_entries %lu is more than max supported entries %d",
+				       taprio->num_entries, TAS_MAX_CMD_LISTS);
+		return -EINVAL;
+	}
+
+	if (emac->qos.tas.taprio_admin)
+		taprio_offload_free(emac->qos.tas.taprio_admin);
+
+	emac->qos.tas.taprio_admin = taprio_offload_get(taprio);
+	ret = tas_update_oper_list(emac);
+	if (ret)
+		goto clear_taprio;
+
+	ret = tas_set_state(emac, TAS_STATE_ENABLE);
+	if (ret)
+		goto clear_taprio;
+
+	return 0;
+
+clear_taprio:
+	emac->qos.tas.taprio_admin = NULL;
+	taprio_offload_free(taprio);
+
+	return ret;
+}
+
+static int emac_taprio_destroy(struct net_device *ndev,
+			       struct tc_taprio_qopt_offload *taprio)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	int ret;
+
+	ret = tas_set_state(emac, TAS_STATE_DISABLE);
+	if (ret)
+		return ret;
+
+	return tas_set_state(emac, TAS_STATE_RESET);
+}
+
+static int emac_setup_taprio(struct net_device *ndev, void *type_data)
+{
+	struct tc_taprio_qopt_offload *taprio = type_data;
+	int ret;
+
+	switch (taprio->cmd) {
+	case TAPRIO_CMD_REPLACE:
+		ret = emac_taprio_replace(ndev, taprio);
+		break;
+	case TAPRIO_CMD_DESTROY:
+		ret = emac_taprio_destroy(ndev, taprio);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+}
+
+static int emac_tc_query_caps(struct net_device *ndev, void *type_data)
+{
+	struct tc_query_caps_base *base = type_data;
+
+	switch (base->type) {
+	case TC_SETUP_QDISC_TAPRIO: {
+		struct tc_taprio_caps *caps = base->caps;
+
+		caps->gate_mask_per_txq = true;
+
+		return 0;
+	}
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type,
+			   void *type_data)
+{
+	switch (type) {
+	case TC_SETUP_QDISC_TAPRIO:
+		return emac_setup_taprio(ndev, type_data);
+	case TC_QUERY_CAPS:
+		return emac_tc_query_caps(ndev, type_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL_GPL(icssg_qos_ndo_setup_tc);
+
+static void icssg_qos_tas_init(struct net_device *ndev)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct tas_config *tas;
+
+	tas = &emac->qos.tas.config;
+
+	tas->config_list = emac->dram.va + TAS_CONFIG_CHANGE_TIME;
+	tas->active_list = emac->dram.va + TAS_ACTIVE_LIST_INDEX;
+
+	tas_update_fw_list_pointers(emac);
+
+	tas_set_state(emac, TAS_STATE_RESET);
+}
+
+static int icssg_config_ietfpe(struct prueth_qos_iet *iet, bool enable)
+{
+	void __iomem *config = iet->emac->dram.va + ICSSG_CONFIG_OFFSET;
+	int ret, i;
+	u8 val;
+
+	/* If FPE is to be enabled, first configure MAC Verify state
+	 * machine in firmware as firmware kicks the Verify process
+	 * as soon as ICSSG_EMAC_PORT_PREMPT_TX_ENABLE command is
+	 * received.
+	 */
+	if (enable && iet->mac_verify_configured) {
+		writeb(1, config + PRE_EMPTION_ENABLE_VERIFY);
+		writew(iet->tx_min_frag_size, config + PRE_EMPTION_ADD_FRAG_SIZE_LOCAL);
+		writel(iet->verify_time_ms, config + PRE_EMPTION_VERIFY_TIME);
+	}
+
+	/* Send command to enable FPE Tx side. Rx is always enabled */
+	ret = icssg_set_port_state(iet->emac,
+				   enable ? ICSSG_EMAC_PORT_PREMPT_TX_ENABLE :
+					    ICSSG_EMAC_PORT_PREMPT_TX_DISABLE);
+	if (ret) {
+		netdev_err(iet->emac->ndev, "TX preempt %s command failed\n",
+			   str_enable_disable(enable));
+		writeb(0, config + PRE_EMPTION_ENABLE_VERIFY);
+		return ret;
+	}
+
+	/* Update FPE Tx enable bit. Assume firmware use this bit
+	 * and enable PRE_EMPTION_ACTIVE_TX if everything looks
+	 * good at firmware
+	 */
+	writeb(enable ? 1 : 0, config + PRE_EMPTION_ENABLE_TX);
+
+	if (enable && iet->mac_verify_configured) {
+		ret = readb_poll_timeout(config + PRE_EMPTION_VERIFY_STATUS, val,
+					 (val == ICSSG_IETFPE_STATE_SUCCEEDED),
+					 USEC_PER_MSEC, 5 * USEC_PER_SEC);
+		if (ret) {
+			netdev_err(iet->emac->ndev,
+				   "timeout for MAC Verify: status %x\n",
+				   val);
+			return ret;
+		}
+	} else {
+		/* Give f/w some time to update PRE_EMPTION_ACTIVE_TX state */
+		usleep_range(100, 200);
+	}
+
+	if (enable) {
+		val = readb(config + PRE_EMPTION_ACTIVE_TX);
+		if (val != 1) {
+			netdev_err(iet->emac->ndev,
+				   "F/w fails to activate IET/FPE\n");
+			writeb(0, config + PRE_EMPTION_ENABLE_TX);
+			return -ENODEV;
+		}
+	} else {
+		return 0;
+	}
+
+	/* Configure highest queue as express. Set Bit 4 for FPE,
+	 * Reset for express
+	 */
+
+	/* first set all 8 queues as Pre-emptive */
+	for (i = 0; i < PRUETH_MAX_TX_QUEUES * PRUETH_NUM_MACS; i++)
+		writeb(BIT(4), config + EXPRESS_PRE_EMPTIVE_Q_MAP + i);
+
+	/* set highest priority channel queue as express */
+	writeb(0, config + EXPRESS_PRE_EMPTIVE_Q_MAP + iet->emac->tx_ch_num - 1);
+
+	/* set up queue mask for FPE. 1 means express */
+	writeb(BIT(iet->emac->tx_ch_num - 1), config + EXPRESS_PRE_EMPTIVE_Q_MASK);
+
+	iet->fpe_enabled = true;
+
+	return ret;
+}
+
+static void icssg_qos_enable_ietfpe(struct work_struct *work)
+{
+	struct prueth_qos_iet *iet =
+		container_of(work, struct prueth_qos_iet, fpe_config_task);
+	int ret;
+
+	/* Set the required flag and send a command to ICSSG firmware to
+	 * enable FPE and start MAC verify
+	 */
+	ret = icssg_config_ietfpe(iet, true);
+
+	/* if verify configured, poll for the status and complete.
+	 * Or just do completion
+	 */
+	if (!ret)
+		netdev_err(iet->emac->ndev, "IET FPE configured successfully\n");
+	else
+		netdev_err(iet->emac->ndev, "IET FPE config error\n");
+	complete(&iet->fpe_config_compl);
+}
+
+static void icssg_prueth_iet_fpe_disable(struct prueth_qos_iet *iet)
+{
+	int ret;
+
+	atomic_set(&iet->cancel_fpe_config, 1);
+	cancel_work_sync(&iet->fpe_config_task);
+	ret = icssg_config_ietfpe(iet, false);
+	if (!ret)
+		netdev_err(iet->emac->ndev, "IET FPE disabled successfully\n");
+	else
+		netdev_err(iet->emac->ndev, "IET FPE disable failed\n");
+}
+
+static int icssg_prueth_iet_fpe_enable(struct prueth_emac *emac)
+{
+	struct prueth_qos_iet *iet = &emac->qos.iet;
+	int ret;
+
+	/* Schedule MAC Verify and enable IET FPE if configured */
+	atomic_set(&iet->cancel_fpe_config, 0);
+	reinit_completion(&iet->fpe_config_compl);
+	schedule_work(&iet->fpe_config_task);
+	/* By trial, found it takes about 1.5s. So
+	 * wait for 10s
+	 */
+	ret = wait_for_completion_timeout(&iet->fpe_config_compl,
+					  msecs_to_jiffies(10000));
+	if (!ret) {
+		netdev_err(emac->ndev,
+			   "IET verify completion timeout\n");
+		/* cancel verify in progress */
+		atomic_set(&iet->cancel_fpe_config, 1);
+		cancel_work_sync(&iet->fpe_config_task);
+	}
+
+	return ret;
+}
diff -Naur --no-dereference a/drivers/net/ethernet/ti/icssg/icssg_qos.h b/drivers/net/ethernet/ti/icssg/icssg_qos.h
--- a/drivers/net/ethernet/ti/icssg/icssg_qos.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/ethernet/ti/icssg/icssg_qos.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#ifndef __NET_TI_ICSSG_QOS_H
+#define __NET_TI_ICSSG_QOS_H
+
+#include <linux/atomic.h>
+#include <linux/netdevice.h>
+#include <net/pkt_sched.h>
+
+/* Maximum number of gate command entries in each list. */
+#define TAS_MAX_CMD_LISTS   (16)
+
+/* Maximum number of transmit queues supported by implementation */
+#define TAS_MAX_NUM_QUEUES  (8)
+
+/* Minimum cycle time supported by implementation (in ns) */
+#define TAS_MIN_CYCLE_TIME  (1000000)
+
+/* Minimum cycle time supported by implementation (in ns) */
+#define TAS_MAX_CYCLE_TIME  (4000000000)
+
+/* Minimum TAS window duration supported by implementation (in ns) */
+#define TAS_MIN_WINDOW_DURATION  (10000)
+
+/**
+ * enum tas_list_num - TAS list number
+ * @TAS_LIST0: TAS list number is 0
+ * @TAS_LIST1: TAS list number is 1
+ */
+enum tas_list_num {
+	TAS_LIST0 = 0,
+	TAS_LIST1 = 1
+};
+
+/**
+ * enum tas_state - State of TAS in firmware
+ * @TAS_STATE_DISABLE: TAS state machine is disabled.
+ * @TAS_STATE_ENABLE: TAS state machine is enabled.
+ * @TAS_STATE_RESET: TAS state machine is reset.
+ */
+enum tas_state {
+	TAS_STATE_DISABLE = 0,
+	TAS_STATE_ENABLE = 1,
+	TAS_STATE_RESET = 2,
+};
+
+/**
+ * struct tas_config_list - Config state machine variables
+ * @config_change_time: New list is copied at this time
+ * @config_change_error_counter: Incremented if admin->BaseTime < current time
+ *				 and TAS_enabled is true
+ * @config_pending: True if list update is pending
+ * @config_change: Set to true when application trigger updating of admin list
+ *		   to active list, cleared when configChangeTime is updated
+ */
+struct __packed tas_config_list {
+	u64 config_change_time;
+	u32 config_change_error_counter;
+	u8 config_pending;
+	u8 config_change;
+};
+
+/* Max SDU table. See IEEE Std 802.1Q-2018 12.29.1.1 */
+struct tas_max_sdu_table {
+	u16 max_sdu[TAS_MAX_NUM_QUEUES];
+};
+
+/**
+ * struct tas_firmware_list - TAS List Structure based on firmware memory map
+ * @gate_mask_list: Window gate mask list
+ * @win_end_time_list: Window end time list
+ * @gate_close_time_list: Array of gate close time for each queue in each window
+ */
+struct __packed tas_firmware_list {
+	u8 gate_mask_list[TAS_MAX_CMD_LISTS];
+	u32 win_end_time_list[TAS_MAX_CMD_LISTS];
+	u32 gate_close_time_list[TAS_MAX_CMD_LISTS][TAS_MAX_NUM_QUEUES];
+};
+
+/**
+ * struct tas_config - Main Time Aware Shaper Handle
+ * @state: TAS state
+ * @max_sdu_table: Max SDU table
+ * @config_list: Config change variables
+ * @active_list: Current operating list operating list
+ * @fw_active_list: Active List pointer, used by firmware
+ * @fw_shadow_list: Shadow List pointer, used by driver
+ */
+struct tas_config {
+	enum tas_state state;
+	struct tas_max_sdu_table max_sdu_table;
+	struct tas_config_list __iomem *config_list;
+	u8 __iomem *active_list;
+	struct tas_firmware_list __iomem *fw_active_list;
+	struct tas_firmware_list __iomem *fw_shadow_list;
+};
+
+struct prueth_qos_tas {
+	struct tc_taprio_qopt_offload *taprio_admin;
+	struct tas_config config;
+};
+
+struct prueth_qos_iet {
+	struct work_struct fpe_config_task;
+	struct completion fpe_config_compl;
+	struct prueth_emac *emac;
+	atomic_t cancel_fpe_config;
+	/* Set through priv flags to enable IET frame preemption */
+	bool fpe_configured;
+	/* Set through priv flags to enable IET MAC Verify state machine
+	 * in firmware
+	 */
+	bool mac_verify_configured;
+	/* Min TX fragment size, set via ethtool */
+	u32 tx_min_frag_size;
+	/* wait time between verification attempts in ms (according to clause
+	 * 30.14.1.6 aMACMergeVerifyTime), set via ethtool
+	 */
+	u32 verify_time_ms;
+	/* Set if IET FPE is active */
+	bool fpe_enabled;
+};
+
+struct prueth_qos {
+	struct prueth_qos_tas tas;
+	struct prueth_qos_iet iet;
+};
+
+void icssg_qos_init(struct net_device *ndev);
+int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type,
+			   void *type_data);
+void icssg_qos_link_up(struct net_device *ndev);
+void icssg_qos_link_down(struct net_device *ndev);
+#endif /* __NET_TI_ICSSG_QOS_H */
diff -Naur --no-dereference a/drivers/net/ethernet/ti/icssg/icssg_stats.c b/drivers/net/ethernet/ti/icssg/icssg_stats.c
--- a/drivers/net/ethernet/ti/icssg/icssg_stats.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/icssg/icssg_stats.c	2025-10-23 09:30:40.286462238 -0400
@@ -11,7 +11,6 @@
 
 #define ICSSG_TX_PACKET_OFFSET	0xA0
 #define ICSSG_TX_BYTE_OFFSET	0xEC
-#define ICSSG_FW_STATS_BASE	0x0248
 
 static u32 stats_base[] = {	0x54c,	/* Slice 0 stats start */
 				0xb18,	/* Slice 1 stats start */
@@ -54,9 +53,8 @@
 
 	if (prueth->pa_stats) {
 		for (i = 0; i < ARRAY_SIZE(icssg_all_pa_stats); i++) {
-			reg = ICSSG_FW_STATS_BASE +
-			      icssg_all_pa_stats[i].offset *
-			      PRUETH_NUM_MACS + slice * sizeof(u32);
+			reg = icssg_all_pa_stats[i].offset +
+			      slice * sizeof(u32);
 			regmap_read(prueth->pa_stats, reg, &val);
 			emac->pa_stats[i] += val;
 		}
@@ -88,7 +86,7 @@
 	if (emac->prueth->pa_stats) {
 		for (i = 0; i < ARRAY_SIZE(icssg_all_pa_stats); i++) {
 			if (!strcmp(icssg_all_pa_stats[i].name, stat_name))
-				return emac->pa_stats[icssg_all_pa_stats[i].offset / sizeof(u32)];
+				return emac->pa_stats[i];
 		}
 	}
 
diff -Naur --no-dereference a/drivers/net/ethernet/ti/icssg/icssg_stats.h b/drivers/net/ethernet/ti/icssg/icssg_stats.h
--- a/drivers/net/ethernet/ti/icssg/icssg_stats.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/icssg/icssg_stats.h	2025-10-23 09:30:40.286462238 -0400
@@ -155,24 +155,10 @@
 	ICSSG_MIIG_STATS(tx_bytes, true),
 };
 
-/**
- * struct pa_stats_regs - ICSSG Firmware maintained PA Stats register
- * @fw_rx_cnt: Number of valid packets sent by Rx PRU to Host on PSI
- * @fw_tx_cnt: Number of valid packets copied by RTU0 to Tx queues
- * @fw_tx_pre_overflow: Host Egress Q (Pre-emptible) Overflow Counter
- * @fw_tx_exp_overflow: Host Egress Q (Express) Overflow Counter
- */
-struct pa_stats_regs {
-	u32 fw_rx_cnt;
-	u32 fw_tx_cnt;
-	u32 fw_tx_pre_overflow;
-	u32 fw_tx_exp_overflow;
-};
-
-#define ICSSG_PA_STATS(field)			\
-{						\
-	#field,					\
-	offsetof(struct pa_stats_regs, field),	\
+#define ICSSG_PA_STATS(field)	\
+{				\
+	#field,			\
+	field,			\
 }
 
 struct icssg_pa_stats {
@@ -181,10 +167,43 @@
 };
 
 static const struct icssg_pa_stats icssg_all_pa_stats[] = {
-	ICSSG_PA_STATS(fw_rx_cnt),
-	ICSSG_PA_STATS(fw_tx_cnt),
-	ICSSG_PA_STATS(fw_tx_pre_overflow),
-	ICSSG_PA_STATS(fw_tx_exp_overflow),
+	ICSSG_PA_STATS(FW_RTU_PKT_DROP),
+	ICSSG_PA_STATS(FW_Q0_OVERFLOW),
+	ICSSG_PA_STATS(FW_Q1_OVERFLOW),
+	ICSSG_PA_STATS(FW_Q2_OVERFLOW),
+	ICSSG_PA_STATS(FW_Q3_OVERFLOW),
+	ICSSG_PA_STATS(FW_Q4_OVERFLOW),
+	ICSSG_PA_STATS(FW_Q5_OVERFLOW),
+	ICSSG_PA_STATS(FW_Q6_OVERFLOW),
+	ICSSG_PA_STATS(FW_Q7_OVERFLOW),
+	ICSSG_PA_STATS(FW_DROPPED_PKT),
+	ICSSG_PA_STATS(FW_RX_ERROR),
+	ICSSG_PA_STATS(FW_RX_DS_INVALID),
+	ICSSG_PA_STATS(FW_TX_DROPPED_PACKET),
+	ICSSG_PA_STATS(FW_TX_TS_DROPPED_PACKET),
+	ICSSG_PA_STATS(FW_INF_PORT_DISABLED),
+	ICSSG_PA_STATS(FW_INF_SAV),
+	ICSSG_PA_STATS(FW_INF_SA_BL),
+	ICSSG_PA_STATS(FW_INF_PORT_BLOCKED),
+	ICSSG_PA_STATS(FW_INF_DROP_TAGGED),
+	ICSSG_PA_STATS(FW_INF_DROP_PRIOTAGGED),
+	ICSSG_PA_STATS(FW_INF_DROP_NOTAG),
+	ICSSG_PA_STATS(FW_INF_DROP_NOTMEMBER),
+	ICSSG_PA_STATS(FW_PREEMPT_BAD_FRAG),
+	ICSSG_PA_STATS(FW_PREEMPT_ASSEMBLY_ERR),
+	ICSSG_PA_STATS(FW_PREEMPT_FRAG_CNT_TX),
+	ICSSG_PA_STATS(FW_PREEMPT_ASSEMBLY_OK),
+	ICSSG_PA_STATS(FW_PREEMPT_FRAG_CNT_RX),
+	ICSSG_PA_STATS(FW_RX_EOF_SHORT_FRMERR),
+	ICSSG_PA_STATS(FW_RX_B0_DROP_EARLY_EOF),
+	ICSSG_PA_STATS(FW_TX_JUMBO_FRM_CUTOFF),
+	ICSSG_PA_STATS(FW_RX_EXP_FRAG_Q_DROP),
+	ICSSG_PA_STATS(FW_RX_FIFO_OVERRUN),
+	ICSSG_PA_STATS(FW_CUT_THR_PKT),
+	ICSSG_PA_STATS(FW_HOST_RX_PKT_CNT),
+	ICSSG_PA_STATS(FW_HOST_TX_PKT_CNT),
+	ICSSG_PA_STATS(FW_HOST_EGRESS_Q_PRE_OVERFLOW),
+	ICSSG_PA_STATS(FW_HOST_EGRESS_Q_EXP_OVERFLOW),
 };
 
 #endif /* __NET_TI_ICSSG_STATS_H */
diff -Naur --no-dereference a/drivers/net/ethernet/ti/icssg/icssg_switch_map.h b/drivers/net/ethernet/ti/icssg/icssg_switch_map.h
--- a/drivers/net/ethernet/ti/icssg/icssg_switch_map.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/icssg/icssg_switch_map.h	2025-10-23 09:30:40.286462238 -0400
@@ -46,6 +46,9 @@
 /* Same as P2_PORT_DF_VLAN_OFFSET */
 #define EMAC_ICSSG_SWITCH_PORT2_DEFAULT_VLAN_OFFSET        P2_PORT_DF_VLAN_OFFSET
 
+/* Time adjustment to be done due to Cycle extension */
+#define TIMESYNC_CYCLE_EXTN_TIME                           0x0028
+
 /* VLAN-FID Table offset. 4096 VIDs. 2B per VID = 8KB = 0x2000 */
 #define VLAN_STATIC_REG_TABLE_OFFSET                       0x0100
 
@@ -177,6 +180,9 @@
 /* Stores the table used for priority mapping. 1B per PCP/Queue */
 #define PORT_Q_PRIORITY_MAPPING_OFFSET                     0x003C
 
+/* Memory to store time value to be used for Cycle extension */
+#define TAS_CONFIG_EXTN_TIME                               0x00A4
+
 /* Used to notify the FW of the current link speed */
 #define PORT_LINK_SPEED_OFFSET                             0x00A8
 
@@ -231,4 +237,109 @@
 /* Start of 32 bits PA_STAT counters */
 #define PA_STAT_32b_START_OFFSET                           0x0080
 
+/* Diagnostic error counter which increments when RTU drops a locally injected
+ * packet due to port disabled or rule violation.
+ */
+#define FW_RTU_PKT_DROP		0x0088
+
+/* Tx Queue Overflow Counters */
+#define FW_Q0_OVERFLOW		0x0090
+#define FW_Q1_OVERFLOW		0x0098
+#define FW_Q2_OVERFLOW		0x00A0
+#define FW_Q3_OVERFLOW		0x00A8
+#define FW_Q4_OVERFLOW		0x00B0
+#define FW_Q5_OVERFLOW		0x00B8
+#define FW_Q6_OVERFLOW		0x00C0
+#define FW_Q7_OVERFLOW		0x00C8
+
+/* Incremented if a packet is dropped at PRU because of a rule violation */
+#define FW_DROPPED_PKT		0x00F8
+
+/* Incremented if there was a CRC error or Min/Max frame error at PRU0 */
+#define FW_RX_ERROR		0x0100
+
+/* Incremented when RTU detects Data Status invalid condition */
+#define FW_RX_DS_INVALID	0x0108
+
+/* Counter for packets dropped via TX Port */
+#define FW_TX_DROPPED_PACKET	0x0110
+
+/* Counter for packets with TS flag dropped via TX Port */
+#define FW_TX_TS_DROPPED_PACKET	0x0118
+
+/* Incremented when RX frame is dropped due to port being disabled */
+#define FW_INF_PORT_DISABLED	0x0120
+
+/* Incremented when RX frame is dropped due to Source Address violation */
+#define FW_INF_SAV		0x0128
+
+/* Incremented when RX frame is dropped due to Source Address being black
+ * listed
+ */
+#define FW_INF_SA_BL		0x0130
+
+/* Incremented when RX frame is dropped due to port being blocked and frame
+ * is being a special frame
+ */
+#define FW_INF_PORT_BLOCKED	0x0138
+
+/* Incremented when RX frame is dropped for being tagged */
+#define FW_INF_DROP_TAGGED	0x0140
+
+/* Incremented when RX frame is dropped for being priority tagged */
+#define FW_INF_DROP_PRIOTAGGED	0x0148
+
+/* Incremented when RX frame is dropped for being untagged */
+#define FW_INF_DROP_NOTAG	0x0150
+
+/* Incremented when RX frame is dropped for port not being member of VLAN */
+#define FW_INF_DROP_NOTMEMBER	0x0158
+
+/* Bad fragment Error Counter */
+#define FW_PREEMPT_BAD_FRAG	0x0160
+
+/* Fragment assembly Error Counter */
+#define FW_PREEMPT_ASSEMBLY_ERR	0x0168
+
+/* Fragment count in TX */
+#define FW_PREEMPT_FRAG_CNT_TX	0x0170
+
+/* Assembly Completed */
+#define FW_PREEMPT_ASSEMBLY_OK	0x0178
+
+/* Fragments received */
+#define FW_PREEMPT_FRAG_CNT_RX	0x0180
+
+/* Incremented if EOF task is scheduled without seeing RX_B1 */
+#define FW_RX_EOF_SHORT_FRMERR	0x0188
+
+/* Incremented when frame is dropped due to Early EOF received in B0 */
+#define FW_RX_B0_DROP_EARLY_EOF	0x0190
+
+/* Incremented when frame is cut off to prevent packet size > 2000B */
+#define FW_TX_JUMBO_FRM_CUTOFF	0x0198
+
+/* Incremented when express frame is received in the same queue as the previous
+ * fragment
+ */
+#define FW_RX_EXP_FRAG_Q_DROP	0x01A0
+
+/* RX fifo overrun counter */
+#define FW_RX_FIFO_OVERRUN	0x01A8
+
+/* Cut-through packet Counter */
+#define FW_CUT_THR_PKT		0x01B0
+
+/* Number of valid packets sent by Rx PRU to Host on PSI */
+#define FW_HOST_RX_PKT_CNT	0x0248
+
+/* Number of valid packets copied by RTU0 to Tx queues */
+#define FW_HOST_TX_PKT_CNT	0x0250
+
+/* Host Egress Q (Pre-emptible) Overflow Counter */
+#define FW_HOST_EGRESS_Q_PRE_OVERFLOW 0x0258
+
+/* Host Egress Q (Pre-emptible) Overflow Counter */
+#define FW_HOST_EGRESS_Q_EXP_OVERFLOW 0x0260
+
 #endif /* __NET_TI_ICSSG_SWITCH_MAP_H  */
diff -Naur --no-dereference a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
--- a/drivers/net/ethernet/ti/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/Kconfig	2025-10-23 09:30:40.286462238 -0400
@@ -79,6 +79,20 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called cpsw_new.
 
+config TI_CPSW_PROXY_CLIENT
+	tristate "TI CPSW Proxy Client"
+	depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
+	help
+		This driver supports Ethernet functionality for CPSWnG
+		Ethernet Subsystem which is configured by Ethernet Switch
+		Firmware (EthFw).
+
+		The Ethernet Switch Firmware acts as a proxy to the Linux
+		Client driver by performing all the necessary configuration
+		of the CPSW Peripheral while enabling network data transfer
+		to/from the Linux Client to CPSW over the allocated TX DMA
+		Channels and RX DMA Flows.
+
 config TI_CPTS
 	tristate "TI Common Platform Time Sync (CPTS) Support"
 	depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST
@@ -188,10 +202,12 @@
 	select PHYLIB
 	select TI_ICSS_IEP
 	select TI_K3_CPPI_DESC_POOL
+	select PAGE_POOL
 	depends on PRU_REMOTEPROC
 	depends on NET_SWITCHDEV
 	depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
 	depends on PTP_1588_CLOCK_OPTIONAL
+	depends on NET_SCH_TAPRIO || NET_SCH_TAPRIO=n
 	help
 	  Support dual Gigabit Ethernet ports over the ICSSG PRU Subsystem.
 	  This subsystem is available starting with the AM65 platform.
diff -Naur --no-dereference a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile
--- a/drivers/net/ethernet/ti/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/ethernet/ti/Makefile	2025-10-23 09:30:40.286462238 -0400
@@ -7,6 +7,9 @@
 obj-$(CONFIG_TI_DAVINCI_EMAC) += cpsw-common.o
 obj-$(CONFIG_TI_CPSW_SWITCHDEV) += cpsw-common.o
 
+obj-$(CONFIG_TI_CPSW_PROXY_CLIENT) += ti-cpsw-proxy-client.o
+ti-cpsw-proxy-client-y := cpsw-proxy-client.o
+
 obj-$(CONFIG_TLAN) += tlan.o
 obj-$(CONFIG_TI_DAVINCI_EMAC) += ti_davinci_emac.o
 ti_davinci_emac-y := davinci_emac.o davinci_cpdma.o
@@ -26,13 +29,13 @@
 obj-$(CONFIG_TI_K3_CPPI_DESC_POOL) += k3-cppi-desc-pool.o
 
 obj-$(CONFIG_TI_K3_AM65_CPSW_NUSS) += ti-am65-cpsw-nuss.o
-ti-am65-cpsw-nuss-y := am65-cpsw-nuss.o cpsw_sl.o am65-cpsw-ethtool.o cpsw_ale.o
+ti-am65-cpsw-nuss-y := am65-cpsw-nuss.o cpsw_sl.o am65-cpsw-ethtool.o cpsw_ale.o am65-debugfs.o
 ti-am65-cpsw-nuss-$(CONFIG_TI_AM65_CPSW_QOS) += am65-cpsw-qos.o
 ti-am65-cpsw-nuss-$(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV) += am65-cpsw-switchdev.o
 obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o
 
 obj-$(CONFIG_TI_ICSSG_PRUETH) += icssg-prueth.o icssg.o
-icssg-prueth-y := icssg/icssg_prueth.o icssg/icssg_switchdev.o
+icssg-prueth-y := icssg/icssg_prueth.o icssg/icssg_switchdev.o icssg/icssg_qos.o
 
 obj-$(CONFIG_TI_ICSSG_PRUETH_SR1) += icssg-prueth-sr1.o icssg.o
 icssg-prueth-sr1-y := icssg/icssg_prueth_sr1.o
diff -Naur --no-dereference a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
--- a/drivers/net/phy/mscc/mscc.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/phy/mscc/mscc.h	2025-10-23 09:30:40.286462238 -0400
@@ -196,6 +196,8 @@
 #define MSCC_PHY_EXTENDED_INT_MS_EGR	  BIT(9)
 
 /* Extended Page 3 Registers */
+#define MSCC_PHY_SERDES_PCS_CTRL          16
+#define MSCC_PHY_SERDES_ANEG              BIT(7)
 #define MSCC_PHY_SERDES_TX_VALID_CNT	  21
 #define MSCC_PHY_SERDES_TX_CRC_ERR_CNT	  22
 #define MSCC_PHY_SERDES_RX_VALID_CNT	  28
diff -Naur --no-dereference a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
--- a/drivers/net/phy/mscc/mscc_main.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/phy/mscc/mscc_main.c	2025-10-23 09:30:40.286462238 -0400
@@ -1700,6 +1700,21 @@
 			   PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
 }
 
+static int vsc85xx_config_inband_aneg(struct phy_device *phydev, bool enabled)
+{
+	u16 reg_val = 0;
+	int rc;
+
+	if (enabled)
+		reg_val = MSCC_PHY_SERDES_ANEG;
+
+	rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_3,
+			      MSCC_PHY_SERDES_PCS_CTRL, MSCC_PHY_SERDES_ANEG,
+			      reg_val);
+
+	return rc;
+}
+
 static int vsc8584_config_init(struct phy_device *phydev)
 {
 	struct vsc8531_private *vsc8531 = phydev->priv;
@@ -2110,6 +2125,11 @@
 
 	if (ret)
 		return ret;
+
+	ret = vsc85xx_config_inband_aneg(phydev, true);
+
+	if (ret)
+		return ret;
 
 	for (i = 0; i < vsc8531->nleds; i++) {
 		ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/acx.c b/drivers/net/wireless/ti/cc33xx/acx.c
--- a/drivers/net/wireless/ti/cc33xx/acx.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/acx.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,931 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include "acx.h"
+
+int cc33xx_acx_clear_statistics(struct cc33xx *cc)
+{
+	struct acx_header *acx;
+	int ret = 0;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = cc33xx_cmd_configure(cc, ACX_CLEAR_STATISTICS, acx, sizeof(*acx));
+	if (ret < 0) {
+		cc33xx_warning("failed to clear firmware statistics: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int cc33xx_acx_wake_up_conditions(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				  u8 wake_up_event, u8 listen_interval)
+{
+	struct acx_wake_up_condition *wake_up;
+	int ret;
+
+	wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
+	if (!wake_up) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	wake_up->wake_up_event = wake_up_event;
+	wake_up->listen_interval = listen_interval;
+
+	ret = cc33xx_cmd_configure(cc, WAKE_UP_CONDITIONS_CFG,
+				   wake_up, sizeof(*wake_up));
+	if (ret < 0) {
+		cc33xx_warning("could not set wake up conditions: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(wake_up);
+	return ret;
+}
+
+int cc33xx_acx_sleep_auth(struct cc33xx *cc, u8 sleep_auth)
+{
+	struct acx_sleep_auth *auth;
+	int ret;
+
+	auth = kzalloc(sizeof(*auth), GFP_KERNEL);
+	if (!auth) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	auth->sleep_auth = sleep_auth;
+
+	ret = cc33xx_cmd_configure(cc, ACX_SLEEP_AUTH, auth, sizeof(*auth));
+	if (ret < 0) {
+		cc33xx_error("could not configure sleep_auth to %d: %d",
+			     sleep_auth, ret);
+		goto out;
+	}
+
+	cc->sleep_auth = sleep_auth;
+out:
+	kfree(auth);
+	return ret;
+}
+
+int cc33xx_ble_enable(struct cc33xx *cc, u8 ble_enable)
+{
+	struct debug_header *buf;
+	int ret;
+
+	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+	if (!buf) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = cc33xx_cmd_debug(cc, BLE_ENABLE, buf, sizeof(*buf));
+	if (ret < 0) {
+		cc33xx_error("could not enable ble");
+		goto out;
+	}
+
+	cc->ble_enable = 1;
+out:
+	kfree(buf);
+	return ret;
+}
+
+int cc33xx_acx_tx_power(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			int power)
+{
+	struct acx_tx_power_cfg *acx;
+	int ret;
+
+	if (power < CC33XX_MIN_TXPWR) {
+		cc33xx_warning("Configured Tx power %d dBm. Increasing to minimum %d dBm",
+			       power, CC33XX_MIN_TXPWR);
+		power = CC33XX_MIN_TXPWR;
+	} else if (power > CC33XX_MAX_TXPWR) {
+		cc33xx_warning("Configured Tx power %d dBm is bigger than upper limit: %d dBm. Attenuating to max limit",
+			       power, CC33XX_MAX_TXPWR);
+		power = CC33XX_MAX_TXPWR;
+	}
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->role_id = wlvif->role_id;
+	acx->tx_power = power;
+
+	ret = cc33xx_cmd_configure(cc, TX_POWER_CFG, acx, sizeof(*acx));
+	if (ret < 0) {
+		cc33xx_warning("Configure of tx power failed: %d", ret);
+		goto out;
+	}
+
+	wlvif->power_level = power;
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+static int cc33xx_acx_mem_map(struct cc33xx *cc,
+			      struct acx_header *memeroy_map, size_t len)
+{
+	int ret;
+
+	ret = cc33xx_cmd_interrogate(cc, MEM_MAP_INTR, memeroy_map,
+				     sizeof(struct acx_header), len);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int cc33xx_acx_get_fw_versions(struct cc33xx *cc,
+				      struct cc33xx_acx_fw_versions *get_fw_versions,
+				      size_t len)
+{
+	int ret;
+
+	ret = cc33xx_cmd_interrogate(cc, GET_FW_VERSIONS_INTR, get_fw_versions,
+				     sizeof(struct cc33xx_acx_fw_versions), len);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+int cc33xx_acx_slot(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+		    enum acx_slot_type slot_time)
+{
+	struct acx_slot *slot;
+	int ret;
+
+	slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+	if (!slot) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	slot->role_id = wlvif->role_id;
+	slot->slot_time = slot_time;
+	ret = cc33xx_cmd_configure(cc, SLOT_CFG, slot, sizeof(*slot));
+
+	if (ret < 0) {
+		cc33xx_warning("failed to set slot time: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(slot);
+	return ret;
+}
+
+int cc33xx_acx_group_address_tbl(struct cc33xx *cc, bool enable, void *mc_list, u32 mc_list_len)
+{
+	struct acx_dot11_grp_addr_tbl *acx;
+	int ret;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->enabled = enable;
+	acx->num_groups = mc_list_len;
+	memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
+
+	ret = cc33xx_cmd_configure(cc, DOT11_GROUP_ADDRESS_TBL,
+				   acx, sizeof(*acx));
+	if (ret < 0) {
+		cc33xx_warning("failed to set group addr table: %d", ret);
+		goto out;
+	}
+out:
+	kfree(acx);
+	return ret;
+}
+
+int cc33xx_acx_beacon_filter_opt(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				 bool enable_filter)
+{
+	struct acx_beacon_filter_option *beacon_filter = NULL;
+	int ret = 0;
+
+	if (enable_filter &&
+	    cc->conf.host_conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED)
+		goto out;
+
+	beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
+	if (!beacon_filter) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	beacon_filter->role_id = wlvif->role_id;
+	beacon_filter->enable = enable_filter;
+
+	/* When set to zero, and the filter is enabled, beacons
+	 * without the unicast TIM bit set are dropped.
+	 */
+	beacon_filter->max_num_beacons = 0;
+
+	ret = cc33xx_cmd_configure(cc, BEACON_FILTER_OPT,
+				   beacon_filter, sizeof(*beacon_filter));
+	if (ret < 0) {
+		cc33xx_warning("failed to set beacon filter opt: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(beacon_filter);
+	return ret;
+}
+
+int cc33xx_acx_beacon_filter_table(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	struct acx_beacon_filter_ie_table *ie_table;
+	struct conf_bcn_filt_rule *r = &cc->conf.host_conf.conn.bcn_filt_ie0;
+	struct conf_bcn_filt_rule *itr_end;
+	int idx = 0;
+	int ret;
+	bool vendor_spec = false;
+
+	if (WARN_ON(cc->conf.host_conf.conn.bcn_filt_ie_count > CONF_MAX_BCN_FILT_IE_COUNT))
+		return -EINVAL;
+
+	itr_end = r + cc->conf.host_conf.conn.bcn_filt_ie_count;
+
+	ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
+	if (!ie_table) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* configure default beacon pass-through rules */
+	ie_table->role_id = wlvif->role_id;
+	ie_table->num_ie = 0;
+
+	while (r < itr_end) {
+		ie_table->table[idx++] = r->ie;
+		ie_table->table[idx++] = r->rule;
+
+		if (r->ie == WLAN_EID_VENDOR_SPECIFIC) {
+			/* only one vendor specific ie allowed */
+			if (vendor_spec)
+				continue;
+
+			/* for vendor specific rules configure the
+			 * additional fields
+			 */
+			memcpy(&ie_table->table[idx], r->oui,
+			       CONF_BCN_IE_OUI_LEN);
+			idx += CONF_BCN_IE_OUI_LEN;
+			ie_table->table[idx++] = r->type;
+			memcpy(&ie_table->table[idx], r->version,
+			       CONF_BCN_IE_VER_LEN);
+			idx += CONF_BCN_IE_VER_LEN;
+			vendor_spec = true;
+		}
+
+		ie_table->num_ie++;
+		r++;
+	}
+
+	ret = cc33xx_cmd_configure(cc, BEACON_FILTER_TABLE,
+				   ie_table, sizeof(*ie_table));
+	if (ret < 0) {
+		cc33xx_warning("failed to set beacon filter table: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(ie_table);
+	return ret;
+}
+
+int cc33xx_assoc_info_cfg(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			  struct ieee80211_sta *sta, u16 aid)
+{
+	struct assoc_info_cfg *cfg;
+	int ret;
+
+	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+	if (!cfg) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cfg->role_id = wlvif->role_id;
+	cfg->aid = cpu_to_le16(aid);
+	cfg->wmm_enabled = wlvif->wmm_enabled;
+
+	cfg->nontransmitted = wlvif->nontransmitted;
+	cfg->bssid_index = wlvif->bssid_index;
+	cfg->bssid_indicator = wlvif->bssid_indicator;
+	cfg->ht_supported = sta->deflink.ht_cap.ht_supported;
+	cfg->vht_supported = sta->deflink.vht_cap.vht_supported;
+	cfg->has_he = sta->deflink.he_cap.has_he;
+	memcpy(cfg->transmitter_bssid, wlvif->transmitter_bssid, ETH_ALEN);
+	ret = cc33xx_cmd_configure(cc, ASSOC_INFO_CFG, cfg, sizeof(*cfg));
+	if (ret < 0) {
+		cc33xx_warning("failed to set aid: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(cfg);
+	return ret;
+}
+
+int cc33xx_acx_set_preamble(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			    enum acx_preamble_type preamble)
+{
+	struct acx_preamble *acx;
+	int ret;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->role_id = wlvif->role_id;
+	acx->preamble = preamble;
+
+	ret = cc33xx_cmd_configure(cc, PREAMBLE_TYPE_CFG, acx, sizeof(*acx));
+	if (ret < 0) {
+		cc33xx_warning("Setting of preamble failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int cc33xx_acx_cts_protect(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			   enum acx_ctsprotect_type ctsprotect)
+{
+	struct acx_ctsprotect *acx;
+	int ret;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->role_id = wlvif->role_id;
+	acx->ctsprotect = ctsprotect;
+
+	ret = cc33xx_cmd_configure(cc, CTS_PROTECTION_CFG, acx, sizeof(*acx));
+	if (ret < 0) {
+		cc33xx_warning("Setting of ctsprotect failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int cc33xx_acx_statistics(struct cc33xx *cc, void *stats)
+{
+	int ret;
+
+	ret = cc33xx_cmd_interrogate(cc, ACX_STATISTICS, stats,
+				     sizeof(struct acx_header),
+				     sizeof(struct cc33xx_acx_statistics));
+	if (ret < 0) {
+		cc33xx_warning("acx statistics failed: %d", ret);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+int cc33xx_update_ap_rates(struct cc33xx *cc, u8 role_id,
+			   u32 basic_rates_set, u32 supported_rates)
+{
+	struct ap_rates_class_cfg *cfg;
+	int ret;
+
+	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+
+	if (!cfg) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cfg->basic_rates_set = cpu_to_le32(basic_rates_set);
+	cfg->supported_rates = cpu_to_le32(supported_rates);
+	cfg->role_id = role_id;
+	ret = cc33xx_cmd_configure(cc, AP_RATES_CFG, cfg, sizeof(*cfg));
+	if (ret < 0) {
+		cc33xx_warning("Updating AP Rates  failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(cfg);
+	return ret;
+}
+
+int cc33xx_tx_param_cfg(struct cc33xx *cc, struct cc33xx_vif *wlvif, u8 ac,
+			u8 cw_min, u16 cw_max, u8 aifsn, u16 txop, bool acm,
+			u8 ps_scheme, u8 is_mu_edca, u8 mu_edca_aifs,
+			u8 mu_edca_ecw_min_max, u8 mu_edca_timer)
+{
+	struct tx_param_cfg *cfg;
+	int ret = 0;
+
+	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+
+	if (!cfg) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cfg->role_id = wlvif->role_id;
+	cfg->ac = ac;
+	cfg->cw_min = cw_min;
+	cfg->cw_max = cpu_to_le16(cw_max);
+	cfg->aifsn = aifsn;
+	cfg->tx_op_limit = cpu_to_le16(txop);
+	cfg->acm = cpu_to_le16(acm);
+	cfg->ps_scheme = ps_scheme;
+	cfg->is_mu_edca = is_mu_edca;
+	cfg->mu_edca_aifs = mu_edca_aifs;
+	cfg->mu_edca_ecw_min_max = mu_edca_ecw_min_max;
+	cfg->mu_edca_timer = mu_edca_timer;
+
+	ret = cc33xx_cmd_configure(cc, TX_PARAMS_CFG, cfg, sizeof(*cfg));
+	if (ret < 0) {
+		cc33xx_warning("tx param cfg failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(cfg);
+	return ret;
+}
+
+int cc33xx_acx_init_mem_config(struct cc33xx *cc)
+{
+	int ret;
+
+	cc->target_mem_map = kzalloc(sizeof(*cc->target_mem_map),
+				     GFP_KERNEL);
+	if (!cc->target_mem_map) {
+		cc33xx_error("couldn't allocate target memory map");
+		return -ENOMEM;
+	}
+
+	/* we now ask for the firmware built memory map */
+	ret = cc33xx_acx_mem_map(cc, (void *)cc->target_mem_map,
+				 sizeof(struct cc33xx_acx_mem_map));
+	if (ret < 0) {
+		cc33xx_error("couldn't retrieve firmware memory map");
+		kfree(cc->target_mem_map);
+		cc->target_mem_map = NULL;
+		return ret;
+	}
+
+	/* initialize TX block book keeping */
+	cc->tx_blocks_available =
+		le32_to_cpu(cc->target_mem_map->num_tx_mem_blocks);
+
+	return 0;
+}
+
+int cc33xx_acx_init_get_fw_versions(struct cc33xx *cc)
+{
+	int ret;
+
+	cc->fw_ver = kzalloc(sizeof(*cc->fw_ver),
+			     GFP_KERNEL);
+	if (!cc->fw_ver) {
+		cc33xx_error("couldn't allocate cc33xx_acx_fw_versions");
+		return -ENOMEM;
+	}
+
+	ret = cc33xx_acx_get_fw_versions(cc, (void *)cc->fw_ver,
+					 sizeof(struct cc33xx_acx_fw_versions));
+	if (ret < 0) {
+		cc33xx_error("couldn't retrieve firmware versions");
+		kfree(cc->fw_ver);
+		cc->fw_ver = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+
+int cc33xx_acx_set_ht_information(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				  u16 ht_operation_mode, u32 he_oper_params,
+				  u16 he_oper_nss_set)
+{
+	struct cc33xx_acx_ht_information *acx;
+	int ret = 0;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->role_id = wlvif->role_id;
+	acx->ht_protection =
+		(u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION);
+	acx->rifs_mode = 0;
+	acx->gf_protection =
+		!!(ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+
+	acx->dual_cts_protection = 0;
+
+	acx->he_operation = cpu_to_le32(he_oper_params);
+	acx->bss_basic_mcs_set = cpu_to_le16(he_oper_nss_set);
+	acx->qos_info_more_data_ack_bit = 0;
+	ret = cc33xx_cmd_configure(cc, BSS_OPERATION_CFG, acx, sizeof(*acx));
+
+	if (ret < 0) {
+		cc33xx_warning("acx ht information setting failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+/* setup BA session receiver setting in the FW. */
+int cc33xx_acx_set_ba_receiver_session(struct cc33xx *cc, u8 tid_index, u16 ssn,
+				       bool enable, u8 peer_hlid, u8 win_size)
+{
+	struct cc33xx_acx_ba_receiver_setup *acx;
+	int ret;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->hlid = peer_hlid;
+	acx->tid = tid_index;
+	acx->enable = enable;
+	acx->win_size =	win_size;
+	acx->ssn = cpu_to_le16(ssn);
+
+	ret = cc33xx_cmd_configure_failsafe(cc, BA_SESSION_RX_SETUP_CFG,
+					    acx, sizeof(*acx),
+					    BIT(CMD_STATUS_NO_RX_BA_SESSION));
+	if (ret < 0) {
+		cc33xx_warning("acx ba receiver session failed: %d", ret);
+		goto out;
+	}
+
+	/* sometimes we can't start the session */
+	if (ret == CMD_STATUS_NO_RX_BA_SESSION) {
+		cc33xx_warning("no fw rx ba on tid %d", tid_index);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = 0;
+out:
+	kfree(acx);
+	return ret;
+}
+
+int cc33xx_acx_tsf_info(struct cc33xx *cc,
+			struct cc33xx_vif *wlvif, u64 *mactime)
+{
+	struct cc33xx_acx_fw_tsf_information *tsf_info;
+	int ret = 0;
+
+	tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
+	if (!tsf_info) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	tsf_info->role_id = wlvif->role_id;
+
+	*mactime = le32_to_cpu(tsf_info->current_tsf_low) |
+		((u64)le32_to_cpu(tsf_info->current_tsf_high) << 32);
+
+out:
+	kfree(tsf_info);
+	return ret;
+}
+
+int cc33xx_acx_config_ps(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	struct cc33xx_acx_config_ps *config_ps;
+	int ret;
+
+	config_ps = kzalloc(sizeof(*config_ps), GFP_KERNEL);
+	if (!config_ps) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	config_ps->exit_retries = cc->conf.host_conf.conn.psm_exit_retries;
+	config_ps->enter_retries = cc->conf.host_conf.conn.psm_entry_retries;
+	config_ps->null_data_rate = cpu_to_le32(wlvif->basic_rate);
+
+	ret = cc33xx_cmd_configure(cc, ACX_CONFIG_PS, config_ps,
+				   sizeof(*config_ps));
+
+	if (ret < 0) {
+		cc33xx_warning("acx config ps failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(config_ps);
+	return ret;
+}
+
+int cc33xx_acx_average_rssi(struct cc33xx *cc,
+			    struct cc33xx_vif *wlvif, s8 *avg_rssi)
+{
+	struct acx_roaming_stats *acx;
+	int ret = 0;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->role_id = wlvif->role_id;
+
+	ret = cc33xx_cmd_interrogate(cc, RSSI_INTR,
+				     acx, sizeof(*acx), sizeof(*acx));
+	if (ret	< 0) {
+		cc33xx_warning("acx roaming statistics failed: %d", ret);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	*avg_rssi = acx->rssi_beacon;
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+static const u16 cc33xx_idx_to_rate_100kbps[] = {
+	10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540
+};
+
+int cc33xx_acx_get_tx_rate(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			   struct station_info *sinfo)
+{
+	struct acx_preamble_and_tx_rate *acx;
+	int ret;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->role_id = wlvif->role_id;
+
+	ret = cc33xx_cmd_interrogate(cc, GET_PREAMBLE_AND_TX_RATE_INTR,
+				     acx, sizeof(*acx), sizeof(*acx));
+	if (ret	< 0) {
+		cc33xx_warning("acx get preamble and tx rate failed: %d", ret);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	sinfo->txrate.flags = 0;
+	if (acx->preamble == CONF_PREAMBLE_TYPE_AC_VHT)
+		sinfo->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
+	else if ((acx->preamble >= CONF_PREAMBLE_TYPE_AX_SU) &&
+		 (acx->preamble <= CONF_PREAMBLE_TYPE_AX_TB_NDP_FB))
+		sinfo->txrate.flags = RATE_INFO_FLAGS_HE_MCS;
+	else if ((acx->preamble == CONF_PREAMBLE_TYPE_N_MIXED_MODE) ||
+		 (acx->preamble == CONF_PREAMBLE_TYPE_GREENFIELD))
+		sinfo->txrate.flags = RATE_INFO_FLAGS_MCS;
+
+	if (acx->tx_rate >= CONF_HW_RATE_INDEX_MCS0)
+		sinfo->txrate.mcs = acx->tx_rate - CONF_HW_RATE_INDEX_MCS0;
+	else
+		sinfo->txrate.legacy = cc33xx_idx_to_rate_100kbps[acx->tx_rate - 1];
+
+	sinfo->txrate.nss = 1;
+	sinfo->txrate.bw = RATE_INFO_BW_20;
+	sinfo->txrate.he_gi = NL80211_RATE_INFO_HE_GI_3_2;
+	sinfo->txrate.he_dcm = 0;
+	sinfo->txrate.he_ru_alloc = 0;
+	sinfo->txrate.n_bonded_ch = 0;
+	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+#ifdef CONFIG_PM
+/* Set the global behaviour of RX filters - On/Off + default action */
+int cc33xx_acx_default_rx_filter_enable(struct cc33xx *cc, bool enable,
+					enum rx_filter_action action)
+{
+	struct acx_default_rx_filter *acx;
+	int ret;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx)
+		return -ENOMEM;
+
+	acx->enable = enable;
+	acx->default_action = action;
+	acx->special_packet_bitmask = 0;
+
+	ret = cc33xx_cmd_configure(cc, ACX_ENABLE_RX_DATA_FILTER, acx,
+				   sizeof(*acx));
+	if (ret < 0) {
+		cc33xx_warning("acx default rx filter enable failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+static int cc33xx_rx_filter_get_fields_size(struct cc33xx_rx_filter *filter)
+{
+	int i, fields_size = 0;
+
+	for (i = 0; i < filter->num_fields; i++) {
+		fields_size += filter->fields[i].len - sizeof(u8 *)
+					+ sizeof(struct cc33xx_rx_filter_field);
+	}
+
+	return fields_size;
+}
+
+static void cc33xx_rx_filter_flatten_fields(struct cc33xx_rx_filter *filter,
+					    u8 *buf)
+{
+	int i;
+	struct cc33xx_rx_filter_field *field;
+
+	for (i = 0; i < filter->num_fields; i++) {
+		field = (struct cc33xx_rx_filter_field *)buf;
+
+		field->offset = filter->fields[i].offset;
+		field->flags = filter->fields[i].flags;
+		field->len = filter->fields[i].len;
+
+		memcpy(&field->pattern, filter->fields[i].pattern, field->len);
+		buf += sizeof(struct cc33xx_rx_filter_field) - sizeof(u8 *);
+		buf += field->len;
+	}
+}
+
+/* Configure or disable a specific RX filter pattern */
+int cc33xx_acx_set_rx_filter(struct cc33xx *cc, u8 index, bool enable,
+			     struct cc33xx_rx_filter *filter)
+{
+	struct acx_rx_filter_cfg *acx;
+	int fields_size = 0;
+	int acx_size;
+	int ret;
+
+	WARN_ON(enable && !filter);
+	WARN_ON(index >= CC33XX_MAX_RX_FILTERS);
+
+	if (enable)
+		fields_size = cc33xx_rx_filter_get_fields_size(filter);
+
+	acx_size = ALIGN(sizeof(*acx) + fields_size, 4);
+	acx = kzalloc(acx_size, GFP_KERNEL);
+
+	if (!acx)
+		return -ENOMEM;
+
+	acx->enable = enable;
+	acx->index = index;
+
+	if (enable) {
+		acx->num_fields = filter->num_fields;
+		acx->action = filter->action;
+		cc33xx_rx_filter_flatten_fields(filter, acx->fields);
+	}
+
+	cc33xx_dump(DEBUG_ACX, "RX_FILTER: ", acx, acx_size);
+
+	ret = cc33xx_cmd_configure(cc, ACX_SET_RX_DATA_FILTER, acx, acx_size);
+	if (ret < 0) {
+		cc33xx_warning("setting rx filter failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+#endif /* CONFIG_PM */
+
+/* this command is basically the same as cc33xx_acx_ht_capabilities,
+ * with the addition of supported rates. they should be unified in
+ * the next fw api change
+ */
+int cc33xx_acx_set_peer_cap(struct cc33xx *cc,
+			    struct ieee80211_sta_ht_cap *ht_cap,
+			    struct ieee80211_sta_he_cap *he_cap,
+			    struct cc33xx_vif *wlvif, bool allow_ht_operation,
+			    u32 rate_set, u8 hlid)
+{
+	struct cc33xx_acx_peer_cap *acx;
+	int ret = 0;
+	u32 ht_capabilites = 0;
+	u8 *cap_info = NULL;
+	u8 dcm_max_const_rx_mask = IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK;
+	u8 partial_bw_ext_range = IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (allow_ht_operation && ht_cap->ht_supported) {
+		/* no need to translate capabilities - use the spec values */
+		ht_capabilites = ht_cap->cap;
+
+		/* this bit is not employed by the spec but only by FW to
+		 * indicate peer HT support
+		 */
+		ht_capabilites |= CC33XX_HT_CAP_HT_OPERATION;
+
+		/* get data from A-MPDU parameters field */
+		acx->ampdu_max_length = ht_cap->ampdu_factor;
+		acx->ampdu_min_spacing = ht_cap->ampdu_density;
+	}
+
+	acx->ht_capabilites = cpu_to_le32(ht_capabilites);
+	acx->supported_rates = cpu_to_le32(rate_set);
+
+	acx->role_id = wlvif->role_id;
+	acx->has_he = he_cap->has_he;
+	memcpy(acx->mac_cap_info, he_cap->he_cap_elem.mac_cap_info, 6);
+	cap_info = he_cap->he_cap_elem.phy_cap_info;
+	acx->nominal_packet_padding = (cap_info[8] & NOMINAL_PACKET_PADDING);
+	/* Max DCM constelation for RX - bits [4:3] in PHY capabilities byte 3 */
+	acx->dcm_max_constelation = (cap_info[3] & dcm_max_const_rx_mask) >> 3;
+	acx->er_upper_supported = ((cap_info[6] & partial_bw_ext_range) != 0);
+	ret = cc33xx_cmd_configure(cc, PEER_CAP_CFG, acx, sizeof(*acx));
+
+	if (ret < 0) {
+		cc33xx_warning("acx ht capabilities setting failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int cc33xx_acx_trigger_fw_assert(struct cc33xx *cc)
+{
+	struct debug_header *buf;
+	int ret;
+
+	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+	if (!buf) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = cc33xx_cmd_debug(cc, TRIGGER_FW_ASSERT, buf, sizeof(*buf));
+	if (ret < 0) {
+		cc33xx_error("failed to trigger firmware assert");
+		goto out;
+	}
+
+out:
+	kfree(buf);
+	return ret;
+}
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/acx.h b/drivers/net/wireless/ti/cc33xx/acx.h
--- a/drivers/net/wireless/ti/cc33xx/acx.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/acx.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,835 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __ACX_H__
+#define __ACX_H__
+
+#include "cmd.h"
+#include "debug.h"
+
+enum {
+	/* Regular PS: simple sending of packets */
+	PS_SCHEME_LEGACY         = 0,
+	/* UPSD: sending a packet triggers a UPSD downstream*/
+	PS_SCHEME_UPSD_TRIGGER   = 1,
+	/* Mixed mode is partially supported: we are not going to sleep, and
+	 * triggers (on APSD AC's) are not sent when service period ends with
+	 * more_data = 1.
+	 */
+	PS_SCHEME_MIXED_MODE     = 2,
+	/* Legacy PSPOLL: a PSPOLL packet will be sent before every data packet
+	 * transmission in this queue.
+	 */
+	PS_SCHEME_LEGACY_PSPOLL  = 3,
+	/* Scheduled APSD mode. */
+	PS_SCHEME_SAPSD          = 4,
+	/* No PSPOLL: move to active after first packet. no need to sent pspoll */
+	PS_SCHEME_NOPSPOLL       = 5,
+
+	MAX_PS_SCHEME = PS_SCHEME_NOPSPOLL
+};
+
+/* Target's information element */
+struct acx_header {
+	struct cc33xx_cmd_header cmd;
+
+	/* acx (or information element) header */
+	__le16 id;
+
+	/* payload length (not including headers */
+	__le16 len;
+} __packed;
+
+struct debug_header {
+	struct cc33xx_cmd_header cmd;
+
+	/* debug (or information element) header */
+	__le16 id;
+
+	/* payload length (not including headers */
+	__le16 len;
+} __packed;
+
+enum cc33xx_role {
+	CC33XX_ROLE_STA = 0,
+	CC33XX_ROLE_IBSS,
+	CC33XX_ROLE_AP,
+	CC33XX_ROLE_DEVICE,
+	CC33XX_ROLE_P2P_CL,
+	CC33XX_ROLE_P2P_GO,
+	CC33XX_ROLE_MESH_POINT,
+
+	ROLE_TRANSCEIVER     = 16,
+
+	CC33XX_INVALID_ROLE_TYPE = 0xff
+};
+
+enum cc33xx_psm_mode {
+	/* Active mode */
+	CC33XX_PSM_CAM = 0,
+
+	/* Power save mode */
+	CC33XX_PSM_PS = 1,
+
+	/* Extreme low power */
+	CC33XX_PSM_ELP = 2,
+
+	CC33XX_PSM_MAX = CC33XX_PSM_ELP,
+
+	/* illegal out of band value of PSM mode */
+	CC33XX_PSM_ILLEGAL = 0xff
+};
+
+struct acx_sleep_auth {
+	struct acx_header header;
+
+	/* The sleep level authorization of the device. */
+	/* 0 - Always active*/
+	/* 1 - Power down mode: light / fast sleep*/
+	/* 2 - ELP mode: Deep / Max sleep*/
+	u8  sleep_auth;
+	u8  padding[3];
+} __packed;
+
+enum acx_slot_type {
+	SLOT_TIME_LONG = 0,
+	SLOT_TIME_SHORT = 1,
+	DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
+	MAX_SLOT_TIMES = 0xFF
+};
+
+struct acx_slot {
+	struct acx_header header;
+
+	u8 role_id;
+	u8 slot_time;
+	u8 reserved[2];
+} __packed;
+
+#define ACX_MC_ADDRESS_GROUP_MAX	(20)
+#define ADDRESS_GROUP_MAX_LEN		(ETH_ALEN * ACX_MC_ADDRESS_GROUP_MAX)
+
+struct acx_dot11_grp_addr_tbl {
+	struct acx_header header;
+
+	u8 enabled;
+	u8 num_groups;
+	u8 pad[2];
+	u8 mac_table[ADDRESS_GROUP_MAX_LEN];
+} __packed;
+
+struct acx_beacon_filter_option {
+	struct acx_header header;
+
+	u8 role_id;
+	u8 enable;
+	/* The number of beacons without the unicast TIM
+	 * bit set that the firmware buffers before
+	 * signaling the host about ready frames.
+	 * When set to 0 and the filter is enabled, beacons
+	 * without the unicast TIM bit set are dropped.
+	 */
+	u8 max_num_beacons;
+	u8 pad;
+} __packed;
+
+/* ACXBeaconFilterEntry (not 221)
+ * Byte Offset     Size (Bytes)    Definition
+ * ===========     ============    ==========
+ * 0               1               IE identifier
+ * 1               1               Treatment bit mask
+ *
+ * ACXBeaconFilterEntry (221)
+ * Byte Offset     Size (Bytes)    Definition
+ * ===========     ============    ==========
+ * 0               1               IE identifier
+ * 1               1               Treatment bit mask
+ * 2               3               OUI
+ * 5               1               Type
+ * 6               2               Version
+ *
+ *
+ * Treatment bit mask - The information element handling:
+ * bit 0 - The information element is compared and transferred
+ * in case of change.
+ * bit 1 - The information element is transferred to the host
+ * with each appearance or disappearance.
+ * Note that both bits can be set at the same time.
+ */
+
+enum {
+	BEACON_FILTER_TABLE_MAX_IE_NUM				= 32,
+	BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM		= 6,
+	BEACON_FILTER_TABLE_IE_ENTRY_SIZE			= 2,
+	BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE	= 6
+};
+
+#define BEACON_FILTER_TABLE_MAX_SIZE					\
+		((BEACON_FILTER_TABLE_MAX_IE_NUM *			\
+		BEACON_FILTER_TABLE_IE_ENTRY_SIZE) +			\
+		(BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM *	\
+		BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
+
+struct acx_beacon_filter_ie_table {
+	struct acx_header header;
+
+	u8 role_id;
+	u8 num_ie;
+	u8 pad[2];
+	u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
+} __packed;
+
+struct acx_energy_detection {
+	struct acx_header header;
+
+	/* The RX Clear Channel Assessment threshold in the PHY */
+	__le16 rx_cca_threshold;
+	u8 tx_energy_detection;
+	u8 pad;
+} __packed;
+
+struct acx_event_mask {
+	struct acx_header header;
+
+	__le32 event_mask;
+	__le32 high_event_mask; /* Unused */
+} __packed;
+
+struct acx_tx_power_cfg {
+	struct acx_header header;
+
+	u8 role_id;
+	s8 tx_power;
+	u8 padding[2];
+} __packed;
+
+struct acx_wake_up_condition {
+	struct acx_header header;
+
+	u8 wake_up_event;
+	u8 listen_interval;
+	u8 padding[2];
+} __packed;
+
+struct assoc_info_cfg {
+	struct acx_header header;
+
+	u8 role_id;
+	__le16 aid;
+	u8 wmm_enabled;
+	u8 nontransmitted;
+	u8 bssid_index;
+	u8 bssid_indicator;
+	u8 transmitter_bssid[ETH_ALEN];
+	u8 ht_supported;
+	u8 vht_supported;
+	u8 has_he;
+} __packed;
+
+enum acx_preamble_type {
+	ACX_PREAMBLE_LONG = 0,
+	ACX_PREAMBLE_SHORT = 1
+};
+
+struct acx_preamble {
+	struct acx_header header;
+
+	/* When set, the WiLink transmits the frames with a short preamble and
+	 * when cleared, the WiLink transmits the frames with a long preamble.
+	 */
+	u8 role_id;
+	u8 preamble;
+	u8 padding[2];
+} __packed;
+
+enum acx_ctsprotect_type {
+	CTSPROTECT_DISABLE = 0,
+	CTSPROTECT_ENABLE = 1
+};
+
+struct acx_ctsprotect {
+	struct acx_header header;
+	u8 role_id;
+	u8 ctsprotect;
+	u8 padding[2];
+} __packed;
+
+struct ap_rates_class_cfg {
+	struct acx_header header;
+	u8 role_id;
+	__le32 basic_rates_set;
+	__le32 supported_rates;
+	u8 padding[3];
+} __packed;
+
+struct tx_param_cfg {
+	struct acx_header header;
+
+	u8 role_id;
+	u8 ac;
+	u8 aifsn;
+	u8 cw_min;
+
+	__le16 cw_max;
+	__le16 tx_op_limit;
+
+	__le16 acm;
+
+	u8 ps_scheme;
+
+	u8 is_mu_edca;
+	u8 mu_edca_aifs;
+	u8 mu_edca_ecw_min_max;
+	u8 mu_edca_timer;
+
+	u8 reserved;
+} __packed;
+
+struct cc33xx_acx_config_memory {
+	struct acx_header header;
+
+	u8 rx_mem_block_num;
+	u8 tx_min_mem_block_num;
+	u8 num_stations;
+	u8 num_ssid_profiles;
+	__le32 total_tx_descriptors;
+	u8 dyn_mem_enable;
+	u8 tx_free_req;
+	u8 rx_free_req;
+	u8 tx_min;
+	u8 fwlog_blocks;
+	u8 padding[3];
+} __packed;
+
+struct cc33xx_acx_mem_map {
+	struct acx_header header;
+
+	/* Number of blocks FW allocated for TX packets */
+	__le32 num_tx_mem_blocks;
+
+	/* Number of blocks FW allocated for RX packets */
+	__le32 num_rx_mem_blocks;
+
+	/* Number of TX descriptor that allocated. */
+	__le32 num_tx_descriptor;
+
+	__le32 tx_result;
+
+} __packed;
+
+struct cc33xx_acx_fw_versions {
+	struct acx_header header;
+
+	__le16 major_version;
+	__le16 minor_version;
+	__le16 api_version;
+	__le16 build_version;
+
+	u8 phy_version[6];
+	u8 padding[2];
+} __packed;
+
+/* special capability bit (not employed by the 802.11n spec) */
+#define CC33XX_HT_CAP_HT_OPERATION BIT(16)
+
+/* ACX_HT_BSS_OPERATION
+ * Configure HT capabilities - AP rules for behavior in the BSS.
+ */
+struct cc33xx_acx_ht_information {
+	struct acx_header header;
+
+	u8 role_id;
+
+	/* Values: 0 - RIFS not allowed, 1 - RIFS allowed */
+	u8 rifs_mode;
+
+	/* Values: 0 - 3 like in spec */
+	u8 ht_protection;
+
+	/* Values: 0 - GF protection not required, 1 - GF protection required */
+	u8 gf_protection;
+
+	/* Values: 0 - Dual CTS protection not required,
+	 *         1 - Dual CTS Protection required
+	 * Note: When this value is set to 1 FW will protect all TXOP with RTS
+	 * frame and will not use CTS-to-self regardless of the value of the
+	 * ACX_CTS_PROTECTION information element
+	 */
+	u8 dual_cts_protection;
+
+	__le32 he_operation;
+
+	__le16 bss_basic_mcs_set;
+	u8 qos_info_more_data_ack_bit;
+
+} __packed;
+
+struct cc33xx_acx_ba_receiver_setup {
+	struct acx_header header;
+
+	/* Specifies link id, range 0-31 */
+	u8 hlid;
+
+	u8 tid;
+
+	u8 enable;
+
+	/* Windows size in number of packets */
+	u8 win_size;
+
+	/* BA session starting sequence number.  RANGE 0-FFF */
+	__le16 ssn;
+
+	u8 padding[2];
+} __packed;
+
+struct cc33xx_acx_fw_tsf_information {
+	struct acx_header header;
+
+	u8 role_id;
+	u8 padding1[3];
+	__le32 current_tsf_high;
+	__le32 current_tsf_low;
+	__le32 last_bttt_high;
+	__le32 last_tbtt_low;
+	u8 last_dtim_count;
+	u8 padding2[3];
+} __packed;
+
+struct cc33xx_acx_config_ps {
+	struct acx_header header;
+
+	u8 exit_retries;
+	u8 enter_retries;
+	u8 padding[2];
+	__le32 null_data_rate;
+} __packed;
+
+#define ACX_RATE_MGMT_ALL_PARAMS 0xff
+
+struct acx_default_rx_filter {
+	struct acx_header header;
+	u8 enable;
+
+	/* action of type FILTER_XXX */
+	u8 default_action;
+
+	/* special packet bitmask - packet that use for trigger the host */
+	u8 special_packet_bitmask;
+
+	u8 padding;
+} __packed;
+
+struct acx_rx_filter_cfg {
+	struct acx_header header;
+
+	u8 enable;
+
+	/* 0 - WL1271_MAX_RX_FILTERS-1 */
+	u8 index;
+
+	u8 action;
+
+	u8 num_fields;
+	u8 fields[];
+} __packed;
+
+struct acx_roaming_stats {
+	struct acx_header header;
+
+	u8	role_id;
+	u8	pad[3];
+	__le32	missed_beacons;
+	u8	snr_data;
+	u8	snr_bacon;
+	s8	rssi_data;
+	s8	rssi_beacon;
+} __packed;
+
+enum cfg {
+	CTS_PROTECTION_CFG			= 0,
+	TX_PARAMS_CFG				= 1,
+	ASSOC_INFO_CFG				= 2,
+	PEER_CAP_CFG				= 3,
+	BSS_OPERATION_CFG			= 4,
+	SLOT_CFG				= 5,
+	PREAMBLE_TYPE_CFG			= 6,
+	DOT11_GROUP_ADDRESS_TBL			= 7,
+	BA_SESSION_RX_SETUP_CFG			= 8,
+	ACX_SLEEP_AUTH				= 9,
+	STATIC_CALIBRATION_CFG			= 10,
+	AP_RATES_CFG				= 11,
+	WAKE_UP_CONDITIONS_CFG			= 12,
+	SET_ANTENNA_SELECT_CFG			= 13,
+	TX_POWER_CFG				= 14,
+	VENDOR_IE_CFG				= 15,
+	START_COEX_STATISTICS_CFG		= 16,
+	BEACON_FILTER_OPT			= 17,
+	BEACON_FILTER_TABLE			= 18,
+	ACX_ENABLE_RX_DATA_FILTER		= 19,
+	ACX_SET_RX_DATA_FILTER			= 20,
+	ACX_GET_DATA_FILTER_STATISTICS		= 21,
+	TWT_SETUP				= 22,
+	TWT_TERMINATE				= 23,
+	TWT_SUSPEND				= 24,
+	TWT_RESUME				= 25,
+	ANT_DIV_ENABLE				= 26,
+	ANT_DIV_SET_RSSI_THRESHOLD		= 27,
+	ANT_DIV_SELECT_DEFAULT_ANTENNA		= 28,
+
+	LAST_CFG_VALUE,
+	MAX_DOT11_CFG = LAST_CFG_VALUE,
+
+	MAX_CFG = 0xFFFF	/*force enumeration to 16bits*/
+};
+
+enum cmd_debug {
+	UPLINK_MULTI_USER_CFG,
+	UPLINK_MULTI_USER_DATA_CFG,
+	OPERATION_MODE_CTRL_CFG,
+	UPLINK_POWER_HEADER_CFG,
+	MCS_FIXED_RATE_CFG,
+	GI_LTF_CFG,
+	TRANSMIT_OMI_CFG,
+	TB_ONLY_CFG,
+	BA_SESSION_CFG,
+	FORCE_PS_CFG,
+	RATE_OVERRRIDE_CFG,
+	BLS_CFG,
+	BLE_ENABLE,
+	SET_TSF,
+	RTS_TH_CFG,
+	LINK_ADAPT_CFG,
+	CALIB_BITMAP_CFG,
+	PWR_PARTIAL_MODES_CFG,
+	TRIGGER_FW_ASSERT,
+	BURST_MODE_CFG,
+
+	LAST_DEBUG_VALUE,
+
+	MAX_DEBUG = 0xFFFF /*force enumeration to 16bits*/
+
+};
+
+enum interrogate_opt {
+	MEM_MAP_INTR = 0,
+	GET_FW_VERSIONS_INTR = 1,
+	RSSI_INTR = 2,
+	GET_ANTENNA_SELECT_INTR = 3,
+	GET_PREAMBLE_AND_TX_RATE_INTR = 4,
+	GET_MAC_ADDRESS = 5,
+	READ_COEX_STATISTICS = 6,
+	LAST_IE_VALUE,
+	MAX_DOT11_IE = LAST_IE_VALUE,
+
+	MAX_IE = 0xFFFF /*force enumeration to 16bits*/
+};
+
+enum {
+	ACX_STATISTICS = LAST_CFG_VALUE,
+	ACX_CONFIG_PS,
+	ACX_CLEAR_STATISTICS		 = 0x0054,
+};
+
+struct cc33xx_acx_error_stats {
+	__le32 error_frame_non_ctrl;
+	__le32 error_frame_ctrl;
+	__le32 error_frame_during_protection;
+	__le32 null_frame_tx_start;
+	__le32 null_frame_cts_start;
+	__le32 bar_retry;
+	__le32 num_frame_cts_nul_flid;
+	__le32 tx_abort_failure;
+	__le32 tx_resume_failure;
+	__le32 rx_cmplt_db_overflow_cnt;
+	__le32 elp_while_rx_exch;
+	__le32 elp_while_tx_exch;
+	__le32 elp_while_tx;
+	__le32 elp_while_nvic_pending;
+	__le32 rx_excessive_frame_len;
+	__le32 burst_mismatch;
+	__le32 tbc_exch_mismatch;
+} __packed;
+
+#define NUM_OF_RATES_INDEXES 30
+struct cc33xx_acx_tx_stats {
+	__le32 tx_prepared_descs;
+	__le32 tx_cmplt;
+	__le32 tx_template_prepared;
+	__le32 tx_data_prepared;
+	__le32 tx_template_programmed;
+	__le32 tx_data_programmed;
+	__le32 tx_burst_programmed;
+	__le32 tx_starts;
+	__le32 tx_stop;
+	__le32 tx_start_templates;
+	__le32 tx_start_int_templates;
+	__le32 tx_start_fw_gen;
+	__le32 tx_start_data;
+	__le32 tx_start_null_frame;
+	__le32 tx_exch;
+	__le32 tx_retry_template;
+	__le32 tx_retry_data;
+	__le32 tx_retry_per_rate[NUM_OF_RATES_INDEXES];
+	__le32 tx_exch_pending;
+	__le32 tx_exch_expiry;
+	__le32 tx_done_template;
+	__le32 tx_done_data;
+	__le32 tx_done_int_template;
+	__le32 tx_cfe1;
+	__le32 tx_cfe2;
+	__le32 frag_called;
+	__le32 frag_mpdu_alloc_failed;
+	__le32 frag_init_called;
+	__le32 frag_in_process_called;
+	__le32 frag_tkip_called;
+	__le32 frag_key_not_found;
+	__le32 frag_need_fragmentation;
+	__le32 frag_bad_mblk_num;
+	__le32 frag_failed;
+	__le32 frag_cache_hit;
+	__le32 frag_cache_miss;
+} __packed;
+
+struct cc33xx_acx_rx_stats {
+	__le32 rx_beacon_early_term;
+	__le32 rx_out_of_mpdu_nodes;
+	__le32 rx_hdr_overflow;
+	__le32 rx_dropped_frame;
+	__le32 rx_done_stage;
+	__le32 rx_done;
+	__le32 rx_defrag;
+	__le32 rx_defrag_end;
+	__le32 rx_cmplt;
+	__le32 rx_pre_complt;
+	__le32 rx_cmplt_task;
+	__le32 rx_phy_hdr;
+	__le32 rx_timeout;
+	__le32 rx_rts_timeout;
+	__le32 rx_timeout_wa;
+	__le32 defrag_called;
+	__le32 defrag_init_called;
+	__le32 defrag_in_process_called;
+	__le32 defrag_tkip_called;
+	__le32 defrag_need_defrag;
+	__le32 defrag_decrypt_failed;
+	__le32 decrypt_key_not_found;
+	__le32 defrag_need_decrypt;
+	__le32 rx_tkip_replays;
+	__le32 rx_xfr;
+} __packed;
+
+struct cc33xx_acx_isr_stats {
+	__le32 irqs;
+} __packed;
+
+#define PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD 10
+
+struct cc33xx_acx_pwr_stats {
+	__le32 missing_bcns_cnt;
+	__le32 rcvd_bcns_cnt;
+	__le32 connection_out_of_sync;
+	__le32 cont_miss_bcns_spread[PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD];
+	__le32 rcvd_awake_bcns_cnt;
+	__le32 sleep_time_count;
+	__le32 sleep_time_avg;
+	__le32 sleep_cycle_avg;
+	__le32 sleep_percent;
+	__le32 ap_sleep_active_conf;
+	__le32 ap_sleep_user_conf;
+	__le32 ap_sleep_counter;
+} __packed;
+
+struct cc33xx_acx_rx_filter_stats {
+	__le32 beacon_filter;
+	__le32 arp_filter;
+	__le32 mc_filter;
+	__le32 dup_filter;
+	__le32 data_filter;
+	__le32 ibss_filter;
+	__le32 protection_filter;
+	__le32 accum_arp_pend_requests;
+	__le32 max_arp_queue_dep;
+} __packed;
+
+struct cc33xx_acx_rx_rate_stats {
+	__le32 rx_frames_per_rates[50];
+} __packed;
+
+#define AGGR_STATS_TX_AGG	16
+#define AGGR_STATS_RX_SIZE_LEN	16
+
+struct cc33xx_acx_aggr_stats {
+	__le32 tx_agg_rate[AGGR_STATS_TX_AGG];
+	__le32 tx_agg_len[AGGR_STATS_TX_AGG];
+	__le32 rx_size[AGGR_STATS_RX_SIZE_LEN];
+} __packed;
+
+#define PIPE_STATS_HW_FIFO	11
+
+struct cc33xx_acx_pipeline_stats {
+	__le32 hs_tx_stat_fifo_int;
+	__le32 hs_rx_stat_fifo_int;
+	__le32 enc_tx_stat_fifo_int;
+	__le32 enc_rx_stat_fifo_int;
+	__le32 rx_complete_stat_fifo_int;
+	__le32 pre_proc_swi;
+	__le32 post_proc_swi;
+	__le32 sec_frag_swi;
+	__le32 pre_to_defrag_swi;
+	__le32 defrag_to_rx_xfer_swi;
+	__le32 dec_packet_in;
+	__le32 dec_packet_in_fifo_full;
+	__le32 dec_packet_out;
+	__le16 pipeline_fifo_full[PIPE_STATS_HW_FIFO];
+	__le16 padding;
+} __packed;
+
+#define DIVERSITY_STATS_NUM_OF_ANT	2
+
+struct cc33xx_acx_diversity_stats {
+	__le32 num_of_packets_per_ant[DIVERSITY_STATS_NUM_OF_ANT];
+	__le32 total_num_of_toggles;
+} __packed;
+
+struct cc33xx_acx_thermal_stats {
+	__le16 irq_thr_low;
+	__le16 irq_thr_high;
+	__le16 tx_stop;
+	__le16 tx_resume;
+	__le16 false_irq;
+	__le16 adc_source_unexpected;
+} __packed;
+
+#define CC33XX_NUM_OF_CALIBRATIONS_ERRORS 18
+struct cc33xx_acx_calib_failure_stats {
+	__le16 fail_count[CC33XX_NUM_OF_CALIBRATIONS_ERRORS];
+	__le32 calib_count;
+} __packed;
+
+struct cc33xx_roaming_stats {
+	s32 rssi_level;
+} __packed;
+
+struct cc33xx_dfs_stats {
+	__le32 num_of_radar_detections;
+} __packed;
+
+struct cc33xx_acx_statistics {
+	struct acx_header header;
+
+	struct cc33xx_acx_error_stats		error;
+	struct cc33xx_acx_tx_stats		tx;
+	struct cc33xx_acx_rx_stats		rx;
+	struct cc33xx_acx_isr_stats		isr;
+	struct cc33xx_acx_pwr_stats		pwr;
+	struct cc33xx_acx_rx_filter_stats	rx_filter;
+	struct cc33xx_acx_rx_rate_stats		rx_rate;
+	struct cc33xx_acx_aggr_stats		aggr_size;
+	struct cc33xx_acx_pipeline_stats	pipeline;
+	struct cc33xx_acx_diversity_stats	diversity;
+	struct cc33xx_acx_thermal_stats		thermal;
+	struct cc33xx_acx_calib_failure_stats	calib;
+	struct cc33xx_roaming_stats		roaming;
+	struct cc33xx_dfs_stats			dfs;
+} __packed;
+
+/* ACX_PEER_CAP
+ * this struct is very similar to cc33xx_acx_ht_capabilities, with the
+ * addition of supported rates
+ */
+#define NOMINAL_PACKET_PADDING (0xC0)
+struct cc33xx_acx_peer_cap {
+	struct acx_header header;
+
+	u8 role_id;
+
+	/* rates supported by the remote peer */
+	__le32 supported_rates;
+
+	/* bitmask of capability bits supported by the peer */
+	__le32 ht_capabilites;
+	/* This the maximum A-MPDU length supported by the AP. The FW may not
+	 * exceed this length when sending A-MPDUs
+	 */
+	u8 ampdu_max_length;
+
+	/* This is the minimal spacing required when sending A-MPDUs to the AP*/
+	u8 ampdu_min_spacing;
+
+	/* HE capabilities */
+	u8 mac_cap_info[8];
+
+	/* Nominal packet padding value, used for determining the packet extension duration */
+	u8 nominal_packet_padding;
+
+	/* HE peer support */
+	bool has_he;
+
+	u8 dcm_max_constelation;
+
+	u8 er_upper_supported;
+
+	u8 padding;
+} __packed;
+
+struct acx_preamble_and_tx_rate {
+	struct acx_header header;
+	u16 tx_rate;
+	u8 preamble;
+	u8 role_id;
+} __packed;
+
+int cc33xx_acx_wake_up_conditions(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				  u8 wake_up_event, u8 listen_interval);
+int cc33xx_acx_sleep_auth(struct cc33xx *cc, u8 sleep_auth);
+int cc33xx_ble_enable(struct cc33xx *cc, u8 ble_enable);
+int cc33xx_acx_tx_power(struct cc33xx *cc, struct cc33xx_vif *wlvif, int power);
+int cc33xx_acx_slot(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+		    enum acx_slot_type slot_time);
+int cc33xx_acx_group_address_tbl(struct cc33xx *cc, bool enable, void *mc_list, u32 mc_list_len);
+int cc33xx_acx_beacon_filter_opt(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				 bool enable_filter);
+int cc33xx_acx_beacon_filter_table(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+int cc33xx_assoc_info_cfg(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			  struct ieee80211_sta *sta, u16 aid);
+int cc33xx_acx_set_preamble(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			    enum acx_preamble_type preamble);
+int cc33xx_acx_cts_protect(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			   enum acx_ctsprotect_type ctsprotect);
+int cc33xx_acx_statistics(struct cc33xx *cc, void *stats);
+int cc33xx_tx_param_cfg(struct cc33xx *cc, struct cc33xx_vif *wlvif, u8 ac,
+			u8 cw_min, u16 cw_max, u8 aifsn, u16 txop, bool acm,
+			u8 ps_scheme, u8 is_mu_edca, u8 mu_edca_aifs,
+			u8 mu_edca_ecw_min_max, u8 mu_edca_timer);
+int cc33xx_update_ap_rates(struct cc33xx *cc, u8 role_id,
+			   u32 basic_rates_set, u32 supported_rates);
+int cc33xx_acx_init_mem_config(struct cc33xx *cc);
+int cc33xx_acx_init_get_fw_versions(struct cc33xx *cc);
+int cc33xx_acx_set_ht_information(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				  u16 ht_operation_mode, u32 he_oper_params,
+				  u16 he_oper_nss_set);
+int cc33xx_acx_set_ba_receiver_session(struct cc33xx *cc, u8 tid_index, u16 ssn,
+				       bool enable, u8 peer_hlid, u8 win_size);
+int cc33xx_acx_tsf_info(struct cc33xx *cc,
+			struct cc33xx_vif *wlvif, u64 *mactime);
+int cc33xx_acx_config_ps(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+int cc33xx_acx_get_tx_rate(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			   struct station_info *sinfo);
+int cc33xx_acx_average_rssi(struct cc33xx *cc,
+			    struct cc33xx_vif *wlvif, s8 *avg_rssi);
+int cc33xx_acx_default_rx_filter_enable(struct cc33xx *cc, bool enable,
+					enum rx_filter_action action);
+int cc33xx_acx_set_rx_filter(struct cc33xx *cc, u8 index, bool enable,
+			     struct cc33xx_rx_filter *filter);
+int cc33xx_acx_clear_statistics(struct cc33xx *cc);
+int cc33xx_acx_set_peer_cap(struct cc33xx *cc,
+			    struct ieee80211_sta_ht_cap *ht_cap,
+			    struct ieee80211_sta_he_cap *he_cap,
+			    struct cc33xx_vif *wlvif, bool allow_ht_operation,
+			    u32 rate_set, u8 hlid);
+int cc33xx_acx_trigger_fw_assert(struct cc33xx *cc);
+
+#endif /* __CC33XX_ACX_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/boot.c b/drivers/net/wireless/ti/cc33xx/boot.c
--- a/drivers/net/wireless/ti/cc33xx/boot.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/boot.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,345 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <linux/firmware.h>
+#include <linux/vmalloc.h>
+
+#include "boot.h"
+#include "cmd.h"
+#include "debug.h"
+#include "init.h"
+#include "io.h"
+
+#define CC33XX_BOOT_TIMEOUT 2000
+
+struct hwinfo_bitmap {
+	u32 disable_5g			: 1u;
+	u32 disable_6g			: 1u;
+	u32 disable_ble			: 1u;
+	u32 disable_ble_m0plus		: 1u;
+	u32 disable_m33			: 1u;
+	u64 udi				: 64u;
+	u32 pg_version			: 4u;
+	u32 metal_version		: 4u;
+	u32 boot_rom_version		: 4u;
+	u32 m3_rom_version		: 4u;
+	u32 fuse_rom_structure_version	: 4u;
+	u64 mac_address			: 48u;
+	u32 device_part_number		: 6u;
+	u32 package_type		: 4u;
+	u32 fw_rollback_protection_1	: 32u;
+	u32 fw_rollback_protection_2	: 32u;
+	u32 fw_rollback_protection_3	: 32u;
+	u32 reserved			: 13u;
+} /* Aligned with boot code, must not be __packed */;
+
+union hw_info {
+	struct hwinfo_bitmap	bitmap;
+	u8			bytes[sizeof(struct hwinfo_bitmap)];
+};
+
+/* Called from threaded irq context */
+void cc33xx_handle_boot_irqs(struct cc33xx *cc, u32 pending_interrupts)
+{
+	if (WARN_ON(!cc->fw_download))
+		return;
+
+	atomic_or(pending_interrupts, &cc->fw_download->pending_irqs);
+	complete(&cc->fw_download->wait_on_irq);
+}
+
+static u8 *fetch_container(struct cc33xx *cc, const char *container_name,
+			   size_t *container_len)
+{
+	u8 *container_data = NULL;
+	const struct firmware *container;
+	int ret;
+
+	ret = request_firmware(&container, container_name, cc->dev);
+
+	if (ret < 0) {
+		cc33xx_error("could not get container %s: (%d)",
+			     container_name, ret);
+		return NULL;
+	}
+
+	if (container->size % 4) {
+		cc33xx_error("container size is not word-aligned: %zu",
+			     container->size);
+		goto out;
+	}
+
+	*container_len = container->size;
+	container_data = vmalloc(container->size);
+
+	if (!container_data) {
+		cc33xx_error("could not allocate memory for the container");
+		goto out;
+	}
+
+	memcpy(container_data, container->data, container->size);
+
+out:
+	release_firmware(container);
+	return container_data;
+}
+
+static int cc33xx_set_power_on(struct cc33xx *cc)
+{
+	int ret;
+
+	msleep(CC33XX_PRE_POWER_ON_SLEEP);
+	ret = cc33xx_power_on(cc);
+	if (ret < 0)
+		goto out;
+	msleep(CC33XX_POWER_ON_SLEEP);
+	cc33xx_io_reset(cc);
+	cc33xx_io_init(cc);
+
+out:
+	return ret;
+}
+
+static int cc33xx_chip_wakeup(struct cc33xx *cc)
+{
+	int ret = 0;
+
+	ret = cc33xx_set_power_on(cc);
+	if (ret < 0)
+		goto out;
+
+	if (!cc33xx_set_block_size(cc))
+		cc->quirks &= ~CC33XX_QUIRK_TX_BLOCKSIZE_ALIGN;
+
+out:
+	return ret;
+}
+
+static int wait_for_boot_irq(struct cc33xx *cc, u32 boot_irq_mask,
+			     unsigned long timeout)
+{
+	int ret;
+	u32 pending_irqs;
+	struct cc33xx_fw_download *fw_download;
+
+	fw_download = cc->fw_download;
+
+	ret = wait_for_completion_interruptible_timeout(&fw_download->wait_on_irq,
+							msecs_to_jiffies(timeout));
+
+	/* Fetch pending IRQs while clearing them in fw_download */
+	pending_irqs = atomic_fetch_and(0, &fw_download->pending_irqs);
+	pending_irqs &= ~HINT_COMMAND_COMPLETE;
+
+	reinit_completion(&fw_download->wait_on_irq);
+
+	if (ret == 0) {
+		cc33xx_error("boot IRQ timeout");
+		return -1;
+	} else if (ret < 0) {
+		cc33xx_error("boot IRQ completion error %d", ret);
+		return -2;
+	}
+
+	if (boot_irq_mask != pending_irqs) {
+		cc33xx_error("Unexpected IRQ received @ boot: 0x%x",
+			     pending_irqs);
+		return -3;
+	}
+
+	return 0;
+}
+
+static int download_container(struct cc33xx *cc, u8 *container, size_t len)
+{
+	int ret = 0;
+	u8 *current_transfer;
+	size_t current_transfer_size;
+	u8 *const container_end = container + len;
+	size_t max_transfer_size = cc->fw_download->max_transfer_size;
+	bool is_last_transfer;
+
+	current_transfer = container;
+
+	while (current_transfer < container_end) {
+		current_transfer_size = container_end - current_transfer;
+		current_transfer_size =
+			min(current_transfer_size, max_transfer_size);
+
+		is_last_transfer = (current_transfer + current_transfer_size >= container_end);
+
+		ret = cmd_download_container_chunk(cc,
+						   current_transfer,
+						   current_transfer_size,
+						   is_last_transfer);
+
+		current_transfer += current_transfer_size;
+
+		if (ret < 0) {
+			cc33xx_error("Chunk transfer failed");
+			goto out;
+		}
+	}
+
+out:
+	return ret;
+}
+
+static int container_download_and_wait(struct cc33xx *cc,
+				       const char *container_name,
+				       const u32 irq_wait_mask)
+{
+	int ret =  -1;
+	u8 *container_data;
+	size_t container_len;
+
+	container_data = fetch_container(cc, container_name, &container_len);
+	if (!container_data)
+		return ret;
+
+	ret = download_container(cc, container_data, container_len);
+	if (ret < 0) {
+		cc33xx_error("Transfer error while downloading %s",
+			     container_name);
+		goto out;
+	}
+
+	ret = wait_for_boot_irq(cc, irq_wait_mask, CC33XX_BOOT_TIMEOUT);
+
+	if (ret < 0) {
+		cc33xx_error("%s boot signal timeout", container_name);
+		goto out;
+	}
+
+	ret = 0;
+
+out:
+	vfree(container_data);
+	return ret;
+}
+
+static int fw_download_alloc(struct cc33xx *cc)
+{
+	if (WARN_ON(cc->fw_download))
+		return -EFAULT;
+
+	cc->fw_download = kzalloc(sizeof(*cc->fw_download), GFP_KERNEL);
+	if (!cc->fw_download)
+		return -ENOMEM;
+
+	init_completion(&cc->fw_download->wait_on_irq);
+
+	return 0;
+}
+
+static void fw_download_free(struct cc33xx *cc)
+{
+	if (WARN_ON(!cc->fw_download))
+		return;
+
+	kfree(cc->fw_download);
+	cc->fw_download = NULL;
+}
+
+static int get_device_info(struct cc33xx *cc)
+{
+	int ret;
+	union hw_info hw_info;
+	u64 mac_address;
+
+	ret = cmd_get_device_info(cc, hw_info.bytes, sizeof(hw_info.bytes));
+	if (ret < 0)
+		return ret;
+
+	cc->fw_download->max_transfer_size = 640;
+
+	mac_address = hw_info.bitmap.mac_address;
+
+	cc->fuse_rom_structure_version = hw_info.bitmap.fuse_rom_structure_version;
+	cc->pg_version = hw_info.bitmap.pg_version;
+	cc->device_part_number = hw_info.bitmap.device_part_number;
+	cc->disable_5g = hw_info.bitmap.disable_5g;
+	cc->disable_6g = hw_info.bitmap.disable_6g;
+
+	cc->efuse_mac_address[5] = (u8)(mac_address);
+	cc->efuse_mac_address[4] = (u8)(mac_address >> 8);
+	cc->efuse_mac_address[3] = (u8)(mac_address >> 16);
+	cc->efuse_mac_address[2] = (u8)(mac_address >> 24);
+	cc->efuse_mac_address[1] = (u8)(mac_address >> 32);
+	cc->efuse_mac_address[0] = (u8)(mac_address >> 40);
+
+	return 0;
+}
+
+int cc33xx_init_fw(struct cc33xx *cc)
+{
+	int ret;
+
+	cc->max_cmd_size = CC33XX_CMD_MAX_SIZE;
+
+	ret = fw_download_alloc(cc);
+	if (ret < 0)
+		return ret;
+
+	reinit_completion(&cc->fw_download->wait_on_irq);
+
+	ret = cc33xx_chip_wakeup(cc);
+	if (ret < 0)
+		goto power_off;
+
+	cc33xx_enable_interrupts(cc);
+
+	ret = wait_for_boot_irq(cc, HINT_ROM_LOADER_INIT_COMPLETE,
+				CC33XX_BOOT_TIMEOUT);
+	if (ret < 0)
+		goto disable_irq;
+
+	ret = get_device_info(cc);
+	if (ret < 0)
+		goto disable_irq;
+
+	ret = container_download_and_wait(cc, SECOND_LOADER_NAME,
+					  HINT_SECOND_LOADER_INIT_COMPLETE);
+	if (ret < 0)
+		goto disable_irq;
+
+	ret = container_download_and_wait(cc,  FW_NAME,
+					  HINT_FW_WAKEUP_COMPLETE);
+	if (ret < 0)
+		goto disable_irq;
+
+	ret = cc33xx_download_ini_params_and_wait(cc);
+
+	if (ret < 0)
+		goto disable_irq;
+
+	ret = wait_for_boot_irq(cc, HINT_FW_INIT_COMPLETE, CC33XX_BOOT_TIMEOUT);
+
+	if (ret < 0)
+		goto disable_irq;
+
+	ret = cc33xx_hw_init(cc);
+	if (ret < 0)
+		goto disable_irq;
+
+	/* Now we know if 11a is supported (info from the INI File), so disable
+	 * 11a channels if not supported
+	 */
+	cc->enable_11a = cc->conf.core.enable_5ghz;
+
+	cc->state = CC33XX_STATE_ON;
+	ret = 0;
+	goto out;
+
+disable_irq:
+	cc33xx_disable_interrupts_nosync(cc);
+
+power_off:
+	cc33xx_power_off(cc);
+
+out:
+	fw_download_free(cc);
+	return ret;
+}
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/boot.h b/drivers/net/wireless/ti/cc33xx/boot.h
--- a/drivers/net/wireless/ti/cc33xx/boot.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/boot.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __BOOT_H__
+#define __BOOT_H__
+
+#include "cc33xx.h"
+
+int cc33xx_init_fw(struct cc33xx *cc);
+
+void cc33xx_handle_boot_irqs(struct cc33xx *cc, u32 pending_interrupts);
+
+#define SECOND_LOADER_NAME "ti-connectivity/cc33xx_2nd_loader.bin"
+#define FW_NAME "ti-connectivity/cc33xx_fw.bin"
+
+struct cc33xx_fw_download {
+	atomic_t pending_irqs;
+	struct completion wait_on_irq;
+	size_t max_transfer_size;
+};
+
+#endif /* __BOOT_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/cc33xx.h b/drivers/net/wireless/ti/cc33xx/cc33xx.h
--- a/drivers/net/wireless/ti/cc33xx/cc33xx.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/cc33xx.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,483 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __CC33XX_H__
+#define __CC33XX_H__
+
+#include "cc33xx_i.h"
+#include "rx.h"
+
+/* The maximum number of Tx descriptors in all chip families */
+#define CC33XX_MAX_TX_DESCRIPTORS 32
+
+#define CC33XX_CMD_MAX_SIZE          (896)
+#define CC33XX_INI_PARAM_COMMAND_SIZE (16UL)
+#define CC33XX_INI_CMD_MAX_SIZE      (CC33X_CONF_SIZE + CC33XX_INI_PARAM_COMMAND_SIZE + sizeof(int))
+
+#define CC33XX_CMD_BUFFER_SIZE ((CC33XX_INI_CMD_MAX_SIZE > CC33XX_CMD_MAX_SIZE)\
+				? CC33XX_INI_CMD_MAX_SIZE : CC33XX_CMD_MAX_SIZE)
+
+#define CC33XX_NUM_MAC_ADDRESSES 3
+
+#define CC33XX_AGGR_BUFFER_SIZE		(8 * PAGE_SIZE)
+
+#define CC33XX_NUM_TX_DESCRIPTORS 32
+#define CC33XX_NUM_RX_DESCRIPTORS 32
+
+#define CC33XX_RX_BA_MAX_SESSIONS 13
+
+#define CC33XX_MAX_AP_STATIONS 16
+
+struct cc33xx_tx_hw_descr;
+struct cc33xx_rx_descriptor;
+struct partial_rx_frame;
+struct core_fw_status;
+struct core_status;
+
+enum wl_rx_buf_align;
+
+struct cc33xx_stats {
+	void *fw_stats;
+	unsigned long fw_stats_update;
+	unsigned int retry_count;
+	unsigned int excessive_retries;
+};
+
+struct cc33xx_ant_diversity {
+	u8 diversity_enable;
+	s8 rssi_threshold;
+	u8 default_antenna;
+	u8 padding;
+};
+
+struct cc33xx {
+	bool initialized;
+	struct ieee80211_hw *hw;
+	bool mac80211_registered;
+
+	struct device *dev;
+	struct platform_device *pdev;
+
+	const struct cc33xx_if_operations *if_ops;
+
+	int wakeirq;
+
+	/* Protects all mac80211 operations and parts of Rx, Tx and IRQ handling.
+	 * All functions postfixed with "_locked" (i.e, cc33xx_irq_locked)
+	 * assume this lock is held by caller.
+	 */
+	struct mutex mutex;
+
+	/* Used independently from above mutex to protect short critical sections.
+	 * Though many of these sections may theoretically execute in parallel, a
+	 * single lock will be used for simplicity.
+	 */
+	spinlock_t cc_lock;
+
+	enum cc33xx_state state;
+	bool plt;
+	enum plt_mode plt_mode;
+	u8 plt_role_id;
+	u8 fem_manuf;
+	u8 last_vif_count;
+
+	struct core_status *core_status;
+	u8 last_fw_rls_idx;
+	u8 command_result[CC33XX_CMD_MAX_SIZE];
+	u16 result_length;
+	struct partial_rx_frame partial_rx;
+
+	unsigned long flags;
+
+	void *nvs_mac_addr;
+	size_t nvs_mac_addr_len;
+	struct cc33xx_fw_download *fw_download;
+
+	struct mac_address addresses[CC33XX_NUM_MAC_ADDRESSES];
+
+	unsigned long links_map[BITS_TO_LONGS(CC33XX_MAX_LINKS)];
+	unsigned long roles_map[BITS_TO_LONGS(CC33XX_MAX_ROLES)];
+	unsigned long roc_map[BITS_TO_LONGS(CC33XX_MAX_ROLES)];
+	unsigned long rate_policies_map[BITS_TO_LONGS(CC33XX_MAX_RATE_POLICIES)];
+
+	u8 session_ids[CC33XX_MAX_LINKS];
+
+	struct list_head wlvif_list;
+
+	u8 sta_count;
+	u8 ap_count;
+
+	struct cc33xx_acx_mem_map *target_mem_map;
+
+	/* Accounting for allocated / available TX blocks on HW */
+
+	u32 tx_blocks_available;
+	u32 tx_allocated_blocks;
+
+	/* Accounting for allocated / available Tx packets in HW */
+
+	u32 tx_allocated_pkts[NUM_TX_QUEUES];
+
+	/* Time-offset between host and chipset clocks */
+
+	/* Frames scheduled for transmission, not handled yet */
+	int tx_queue_count[NUM_TX_QUEUES];
+	unsigned long queue_stop_reasons[NUM_TX_QUEUES * CC33XX_NUM_MAC_ADDRESSES];
+
+	/* Frames received, not handled yet by mac80211 */
+	struct sk_buff_head deferred_rx_queue;
+
+	/* Frames sent, not returned yet to mac80211 */
+	struct sk_buff_head deferred_tx_queue;
+
+	struct work_struct tx_work;
+	struct workqueue_struct *freezable_wq;
+
+	/*freezable wq for netstack_work*/
+	struct workqueue_struct *freezable_netstack_wq;
+
+	/* Pending TX frames */
+	unsigned long tx_frames_map[BITS_TO_LONGS(CC33XX_MAX_TX_DESCRIPTORS)];
+	struct sk_buff *tx_frames[CC33XX_MAX_TX_DESCRIPTORS];
+	int tx_frames_cnt;
+
+	/* FW Rx counter */
+	u32 rx_counter;
+
+	/* Intermediate buffer, used for packet aggregation */
+	u8 *aggr_buf;
+	u32 aggr_buf_size;
+	size_t max_transaction_len;
+
+	/* Reusable dummy packet template */
+	struct sk_buff *dummy_packet;
+
+	/* Network stack work  */
+	struct work_struct netstack_work;
+	/* FW log buffer */
+	u8 *fwlog;
+
+	/* Number of valid bytes in the FW log buffer */
+	ssize_t fwlog_size;
+
+	/* Hardware recovery work */
+	struct work_struct recovery_work;
+
+	struct work_struct irq_deferred_work;
+
+	/* Reg domain last configuration */
+	DECLARE_BITMAP(reg_ch_conf_last, 64);
+	/* Reg domain pending configuration */
+	DECLARE_BITMAP(reg_ch_conf_pending, 64);
+
+	/* Lock-less list for deferred event handling */
+	struct llist_head event_list;
+	/* The mbox event mask */
+	u32 event_mask;
+	/* events to unmask only when ap interface is up */
+	u32 ap_event_mask;
+
+	/* Are we currently scanning */
+	struct cc33xx_vif *scan_wlvif;
+	struct cc33xx_scan scan;
+	struct delayed_work scan_complete_work;
+
+	struct ieee80211_vif *roc_vif;
+	struct delayed_work roc_complete_work;
+
+	struct cc33xx_vif *sched_vif;
+
+	u8 mac80211_scan_stopped;
+
+	/* The current band */
+	enum nl80211_band band;
+
+	/* in dBm */
+	int power_level;
+
+	struct cc33xx_stats stats;
+
+	__le32 *buffer_32;
+
+	/* Current chipset configuration */
+	struct cc33xx_conf_file conf;
+
+	bool enable_11a;
+
+	/* bands supported by this instance of cc33xx */
+	struct ieee80211_supported_band bands[CC33XX_NUM_BANDS];
+
+	/* wowlan trigger was configured during suspend.
+	 * (currently, only "ANY" and "PATTERN" trigger is supported)
+	 */
+
+	bool keep_device_power;
+
+	/* AP-mode - links indexed by HLID. The global and broadcast links
+	 * are always active.
+	 */
+	struct cc33xx_link links[CC33XX_MAX_LINKS];
+
+	/* number of currently active links */
+	int active_link_count;
+
+	/* AP-mode - a bitmap of links currently in PS mode according to FW */
+	unsigned long ap_fw_ps_map;
+
+	/* AP-mode - a bitmap of links currently in PS mode in mac80211 */
+	unsigned long ap_ps_map;
+
+	/* Quirks of specific hardware revisions */
+	unsigned int quirks;
+
+	/* number of currently active RX BA sessions */
+	int ba_rx_session_count;
+
+	/* AP-mode - number of currently connected stations */
+	int active_sta_count;
+
+	/* last wlvif we transmitted from */
+	struct cc33xx_vif *last_wlvif;
+
+	/* work to fire when Tx is stuck */
+	struct delayed_work tx_watchdog_work;
+
+	/* HW HT (11n) capabilities */
+	struct ieee80211_sta_ht_cap ht_cap[CC33XX_NUM_BANDS];
+
+	/* the current dfs region */
+	enum nl80211_dfs_regions dfs_region;
+	bool radar_debug_mode;
+
+	/* RX Data filter rule state - enabled/disabled */
+	/* used in CONFIG PM AND W8 Code */
+	unsigned long rx_filter_enabled[BITS_TO_LONGS(CC33XX_MAX_RX_FILTERS)];
+
+	/* mutex for protecting the tx_flush function */
+	struct mutex flush_mutex;
+
+	/* sleep auth value currently configured to FW */
+	int sleep_auth;
+
+	/*ble_enable value - 1=enabled, 0=disabled. */
+	int ble_enable;
+
+	/* parameters for joining a TWT agreement */
+	int min_wake_duration_usec;
+	int min_wake_interval_mantissa;
+	int min_wake_interval_exponent;
+	int max_wake_interval_mantissa;
+	int max_wake_interval_exponent;
+
+	/* the number of allocated MAC addresses in this chip */
+	int num_mac_addr;
+
+	/* sta role index - if 0 - wlan0 primary station interface,
+	 * if 1 - wlan2 - secondary station interface
+	 */
+	u8 sta_role_idx;
+
+	u16 max_cmd_size;
+
+	struct completion nvs_loading_complete;
+	struct completion command_complete;
+
+	/* dynamic fw traces */
+	u32 dynamic_fw_traces;
+
+	/* buffer for sending commands to FW */
+	u8 cmd_buf[CC33XX_CMD_BUFFER_SIZE];
+
+	/* number of keys requiring extra spare mem-blocks */
+	int extra_spare_key_count;
+
+	u8 efuse_mac_address[ETH_ALEN];
+
+	u32 fuse_rom_structure_version;
+	u32 device_part_number;
+	u32 pg_version;
+	u8 disable_5g;
+	u8 disable_6g;
+
+	struct cc33xx_acx_fw_versions *fw_ver;
+
+	u8 antenna_selection;
+
+	/* burst mode cfg */
+	u8 burst_disable;
+
+	struct cc33xx_ant_diversity diversity;
+};
+
+void cc33xx_update_inconn_sta(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			      struct cc33xx_station *wl_sta, bool in_conn);
+
+void cc33xx_irq(void *cookie);
+
+/* Quirks */
+
+/* the first start_role(sta) sometimes doesn't work on wl12xx */
+#define CC33XX_QUIRK_START_STA_FAILS		BIT(1)
+
+/* wl127x and SPI don't support SDIO block size alignment */
+#define CC33XX_QUIRK_TX_BLOCKSIZE_ALIGN		BIT(2)
+
+/* means aggregated Rx packets are aligned to a SDIO block */
+#define CC33XX_QUIRK_RX_BLOCKSIZE_ALIGN		BIT(3)
+
+/* pad only the last frame in the aggregate buffer */
+#define CC33XX_QUIRK_TX_PAD_LAST_FRAME		BIT(7)
+
+/* extra header space is required for TKIP */
+#define CC33XX_QUIRK_TKIP_HEADER_SPACE		BIT(8)
+
+/* Some firmwares not support sched scans while connected */
+#define CC33XX_QUIRK_NO_SCHED_SCAN_WHILE_CONN	BIT(9)
+
+/* separate probe response templates for one-shot and sched scans */
+#define CC33XX_QUIRK_DUAL_PROBE_TMPL		BIT(10)
+
+/* Firmware requires reg domain configuration for active calibration */
+#define CC33XX_QUIRK_REGDOMAIN_CONF		BIT(11)
+
+/* The FW only support a zero session id for AP */
+#define CC33XX_QUIRK_AP_ZERO_SESSION_ID		BIT(12)
+
+/* TODO: move all these common registers and values elsewhere */
+#define HW_ACCESS_ELP_CTRL_REG		0x1FFFC
+
+enum CC33xx_FRAME_FORMAT {
+	CC33xx_B_SHORT = 0,
+	CC33xx_B_LONG,
+	CC33xx_LEGACY_OFDM,
+	CC33xx_HT_MF,
+	CC33xx_HT_GF,
+	CC33xx_HE_SU,
+	CC33xx_HE_MU,
+	CC33xx_HE_SU_ER,
+	CC33xx_HE_TB,
+	CC33xx_HE_TB_NDP_FB,
+	CC33xx_VHT
+};
+
+/* CC33xx HW Common Definitions */
+
+#define HOST_SYNC_PATTERN	0x5C5C5C5C
+#define DEVICE_SYNC_PATTERN	0xABCDDCBA
+#define NAB_DATA_ADDR		0x0000BFF0
+#define NAB_CONTROL_ADDR	0x0000BFF8
+#define NAB_STATUS_ADDR		0x0000BFFC
+
+#define NAB_SEND_CMD			0x940d
+#define NAB_SEND_FLAGS			0x08
+#define CC33xx_INTERNAL_DESC_SIZE	200
+#define NAB_EXTRA_BYTES			4
+
+#define TX_RESULT_QUEUE_SIZE  108
+
+struct control_info_descriptor {
+	__le16 type_and_length;
+};
+
+enum control_message_type {
+	CTRL_MSG_NONE = 0,
+	CTRL_MSG_EVENT = 1,
+	CTRL_MSG_COMMND_COMPLETE = 2
+};
+
+struct core_fw_status {
+	u8	tx_result_queue_index;
+	u8	reserved1[3];
+	u8	tx_result_queue[TX_RESULT_QUEUE_SIZE];
+
+	/* A bitmap (where each bit represents a single HLID)
+	 * to indicate PS/Active mode of the link
+	 */
+	__le32	link_ps_bitmap;
+
+	/* A bitmap (where each bit represents a single HLID)
+	 * to indicate if the station is in Fast mode
+	 */
+	__le32	link_fast_bitmap;
+
+	/* A bitmap (where each bit represents a single HLID)
+	 * to indicate if a links is suspended/about to be suspended
+	 */
+	__le32	link_suspend_bitmap;
+
+	/* Host TX Flow Control descriptor per AC threshold */
+	u8      tx_flow_control_ac_threshold;
+
+	/* Host TX Flow Control descriptor PS link threshold */
+	u8      tx_ps_threshold;
+
+	/* Host TX Flow Control descriptor Suspended link threshold */
+	u8      tx_suspend_threshold;
+
+	/* Host TX Flow Control descriptor Slow link threshold */
+	u8      tx_slow_link_prio_threshold;
+
+	/* Host TX Flow Control descriptor Fast link threshold */
+	u8      tx_fast_link_prio_threshold;
+
+	/* Host TX Flow Control descriptor Stop Slow link threshold */
+	u8      tx_slow_stop_threshold;
+
+	/* Host TX Flow Control descriptor Stop Fast link threshold */
+	u8      tx_fast_stop_threshold;
+
+	u8      reserved2;
+	/* Additional information can be added here */
+} __packed;
+
+struct core_status {
+	__le32 block_pad[28];
+	__le32 host_interrupt_status;
+	__le32 rx_status;
+	struct core_fw_status fw_info;
+	__le32 tsf;
+} __packed;
+
+struct NAB_header {
+	__le32 sync_pattern;
+	__le16 opcode;
+	__le16 len;
+};
+
+/* rx_status lower bytes hold the rx byte count */
+#define RX_BYTE_COUNT_MASK 0xFFFF
+
+#define HINT_NEW_TX_RESULT			0x1
+#define HINT_COMMAND_COMPLETE			0x2
+#define HINT_ROM_LOADER_INIT_COMPLETE		0x8
+#define HINT_SECOND_LOADER_INIT_COMPLETE	0x10
+#define HINT_FW_WAKEUP_COMPLETE			0x20
+#define HINT_FW_INIT_COMPLETE			0x40
+#define HINT_GENERAL_ERROR			0x80000000
+
+#define BOOT_TIME_INTERRUPTS (\
+	HINT_ROM_LOADER_INIT_COMPLETE    | \
+	HINT_SECOND_LOADER_INIT_COMPLETE | \
+	HINT_FW_WAKEUP_COMPLETE | \
+	HINT_FW_INIT_COMPLETE)
+
+struct NAB_tx_header {
+	__le32 sync;
+	__le16 opcode;
+	__le16 len;
+	__le16 desc_length;
+	u8     sd;
+	u8     flags;
+} __packed;
+
+struct NAB_rx_header {
+	__le32 cnys;
+	__le16 opcode;
+	__le16 len;
+	__le32 rx_desc;
+	__le32 reserved;
+} __packed;
+
+#endif /* __CC33XX_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/cc33xx_i.h b/drivers/net/wireless/ti/cc33xx/cc33xx_i.h
--- a/drivers/net/wireless/ti/cc33xx/cc33xx_i.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/cc33xx_i.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,459 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __CC33XX_I_H__
+#define __CC33XX_I_H__
+
+#include <net/mac80211.h>
+#include <linux/platform_device.h>
+
+#include "conf.h"
+
+struct cc33xx_family_data {
+	const char *name;
+	const char *nvs_name;	/* nvs file */
+	const char *cfg_name;	/* cfg file */
+};
+
+#define CC33XX_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
+#define CC33XX_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
+#define CC33XX_TX_SQN_POST_RECOVERY_PADDING 0xff
+/* Use smaller padding for GEM, as some  APs have issues when it's too big */
+#define CC33XX_TX_SQN_POST_RECOVERY_PADDING_GEM 0x20
+
+#define CC33XX_CIPHER_SUITE_GEM 0x00147201
+
+#define CC33XX_BUSY_WORD_LEN (sizeof(u32))
+
+#define CC33XX_DEFAULT_BEACON_INT  100
+
+#define CC33XX_MAX_ROLES           4
+#define CC33XX_INVALID_ROLE_ID     0xff
+#define CC33XX_INVALID_LINK_ID     0xff
+
+#define CC33XX_MAX_LINKS 21
+
+/* the driver supports the 2.4Ghz and 5Ghz bands */
+#define CC33XX_NUM_BANDS           2
+
+#define CC33XX_MAX_RATE_POLICIES 16
+
+/* Defined by FW as 0. Will not be freed or allocated. */
+#define CC33XX_SYSTEM_HLID         0
+
+/* When in AP-mode, we allow (at least) this number of packets
+ * to be transmitted to FW for a STA in PS-mode. Only when packets are
+ * present in the FW buffers it will wake the sleeping STA. We want to put
+ * enough packets for the driver to transmit all of its buffered data before
+ * the STA goes to sleep again. But we don't want to take too much memory
+ * as it might hurt the throughput of active STAs.
+ */
+#define CC33XX_PS_STA_MAX_PACKETS  2
+
+#define CC33XX_AP_BSS_INDEX        0
+
+enum cc33xx_state {
+	CC33XX_STATE_OFF,
+	CC33XX_STATE_RESTARTING,
+	CC33XX_STATE_ON,
+};
+
+struct cc33xx;
+
+#define NUM_TX_QUEUES              4
+
+#define CC33XX_MAX_CHANNELS 64
+struct cc33xx_scan {
+	struct cfg80211_scan_request *req;
+	unsigned long scanned_ch[BITS_TO_LONGS(CC33XX_MAX_CHANNELS)];
+	bool failed;
+	u8 state;
+	u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
+	size_t ssid_len;
+};
+
+struct cc33xx_if_operations {
+	void (*interface_claim)(struct device *child);
+	void (*interface_release)(struct device *child);
+	int __must_check (*read)(struct device *child, int addr, void *buf,
+				 size_t len, bool fixed);
+	int __must_check (*write)(struct device *child, int addr, void *buf,
+				  size_t len, bool fixed);
+	void (*reset)(struct device *child);
+	void (*init)(struct device *child);
+	int (*power)(struct device *child, bool enable);
+	void (*set_block_size)(struct device *child, unsigned int blksz);
+	size_t (*get_max_transaction_len)(struct device *child);
+	void (*set_irq_handler)(struct device *child, void *irq_handler);
+	void (*enable_irq)(struct device *child);
+	void (*disable_irq)(struct device *child);
+};
+
+struct cc33xx_platdev_data {
+	const struct cc33xx_if_operations *if_ops;
+	const struct cc33xx_family_data *family;
+	void (*irq_handler)(struct platform_device *pdev);
+	int  gpio_irq_num;
+
+	bool ref_clock_xtal;	/* specify whether the clock is XTAL or not */
+	bool pwr_in_suspend;
+};
+
+#define MAX_NUM_KEYS 14
+#define MAX_KEY_SIZE 32
+
+struct cc33xx_ap_key {
+	u8 id;
+	u8 key_type;
+	u8 key_size;
+	u8 key[MAX_KEY_SIZE];
+	u8 hlid;
+	u32 tx_seq_32;
+	u16 tx_seq_16;
+};
+
+enum cc33xx_flags {
+	CC33XX_FLAG_GPIO_POWER,
+	CC33XX_FLAG_TX_PENDING,
+	CC33XX_FLAG_IN_ELP,
+	CC33XX_FLAG_FW_TX_BUSY,
+	CC33XX_FLAG_DUMMY_PACKET_PENDING,
+	CC33XX_FLAG_SUSPENDED,
+	CC33XX_FLAG_PENDING_WORK,
+	CC33XX_FLAG_SOFT_GEMINI,
+	CC33XX_FLAG_DRIVER_REMOVED,
+	CC33XX_FLAG_RECOVERY_IN_PROGRESS,
+	CC33XX_FLAG_VIF_CHANGE_IN_PROGRESS,
+	CC33XX_FLAG_IO_FAILED,
+	CC33XX_FLAG_REINIT_TX_WDOG,
+};
+
+enum cc33xx_vif_flags {
+	WLVIF_FLAG_INITIALIZED,
+	WLVIF_FLAG_STA_ASSOCIATED,
+	WLVIF_FLAG_STA_AUTHORIZED,
+	WLVIF_FLAG_IBSS_JOINED,
+	WLVIF_FLAG_AP_STARTED,
+	WLVIF_FLAG_IN_PS,
+	WLVIF_FLAG_STA_STATE_SENT,
+	WLVIF_FLAG_PSPOLL_FAILURE,
+	WLVIF_FLAG_CS_PROGRESS,
+	WLVIF_FLAG_AP_PROBE_RESP_SET,
+	WLVIF_FLAG_IN_USE,
+	WLVIF_FLAG_ACTIVE,
+	WLVIF_FLAG_BEACON_DISABLED,
+};
+
+struct cc33xx_vif;
+
+struct cc33xx_link {
+	/* AP-mode - TX queue per AC in link */
+	struct sk_buff_head tx_queue[NUM_TX_QUEUES];
+
+	/* accounting for allocated / freed packets in FW */
+	u8 allocated_pkts;
+	u8 prev_freed_pkts;
+
+	u8 addr[ETH_ALEN];
+
+	/* bitmap of TIDs where RX BA sessions are active for this link */
+	u8 ba_bitmap;
+
+	/* the last fw rate index we used for this link */
+	u8 fw_rate_idx;
+
+	/* the last fw rate [Mbps] we used for this link */
+	u8 fw_rate_mbps;
+
+	/* The wlvif this link belongs to. Might be null for global links */
+	struct cc33xx_vif *wlvif;
+
+	/* total freed FW packets on the link - used for tracking the
+	 * AES/TKIP PN across recoveries. Re-initialized each time
+	 * from the cc33xx_station structure.
+	 */
+	u64 total_freed_pkts;
+};
+
+#define CC33XX_MAX_RX_FILTERS 5
+#define CC33XX_RX_FILTER_MAX_FIELDS 8
+
+#define CC33XX_RX_FILTER_ETH_HEADER_SIZE 14
+#define CC33XX_RX_FILTER_MAX_FIELDS_SIZE 95
+#define RX_FILTER_FIELD_OVERHEAD				\
+	(sizeof(struct cc33xx_rx_filter_field) - sizeof(u8 *))
+#define CC33XX_RX_FILTER_MAX_PATTERN_SIZE			\
+	(CC33XX_RX_FILTER_MAX_FIELDS_SIZE - RX_FILTER_FIELD_OVERHEAD)
+
+#define CC33XX_RX_FILTER_FLAG_IP_HEADER           0
+#define CC33XX_RX_FILTER_FLAG_ETHERNET_HEADER     BIT(1)
+
+struct ieee80211_header {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 da[ETH_ALEN];
+	u8 sa[ETH_ALEN];
+	u8 bssid[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 payload[];
+} __packed;
+
+enum rx_filter_action {
+	FILTER_DROP = 0,
+	FILTER_SIGNAL = 1,
+	FILTER_FW_HANDLE = 2
+};
+
+enum plt_mode {
+	PLT_OFF = 0,
+	PLT_ON = 1,
+	PLT_FEM_DETECT = 2,
+	PLT_CHIP_AWAKE = 3
+};
+
+struct cc33xx_rx_filter_field {
+	__le16 offset;
+	u8 len;
+	u8 flags;
+	u8 *pattern;
+} __packed;
+
+struct cc33xx_rx_filter {
+	u8 action;
+	int num_fields;
+	struct cc33xx_rx_filter_field fields[CC33XX_RX_FILTER_MAX_FIELDS];
+};
+
+struct cc33xx_station {
+	u8 hlid;
+	bool in_connection;
+
+	/* total freed FW packets on the link to the STA - used for tracking the
+	 * AES/TKIP PN across recoveries. Re-initialized each time from the
+	 * cc33xx_station structure.
+	 * Used in both AP and STA mode.
+	 */
+	u64 total_freed_pkts;
+};
+
+struct cc33xx_vif {
+	struct cc33xx *cc;
+	struct list_head list;
+	unsigned long flags;
+	u8 bss_type;
+	u8 p2p; /* we are using p2p role */
+	u8 role_id;
+
+	/* sta/ibss specific */
+	u8 dev_role_id;
+	u8 dev_hlid;
+
+	union {
+		struct {
+			u8 hlid;
+
+			u8 basic_rate_idx;
+			u8 ap_rate_idx;
+			u8 p2p_rate_idx;
+
+			bool qos;
+			/* channel type we started the STA role with */
+			enum nl80211_channel_type role_chan_type;
+		} sta;
+		struct {
+			u8 global_hlid;
+			u8 bcast_hlid;
+
+			/* HLIDs bitmap of associated stations */
+			unsigned long sta_hlid_map[BITS_TO_LONGS(CC33XX_MAX_LINKS)];
+
+			/* recoreded keys - set here before AP startup */
+			struct cc33xx_ap_key *recorded_keys[MAX_NUM_KEYS];
+
+			u8 mgmt_rate_idx;
+			u8 bcast_rate_idx;
+			u8 ucast_rate_idx[CONF_TX_MAX_AC_COUNT];
+		} ap;
+	};
+
+	/* the hlid of the last transmitted skb */
+	int last_tx_hlid;
+
+	/* counters of packets per AC, across all links in the vif */
+	int tx_queue_count[NUM_TX_QUEUES];
+
+	unsigned long links_map[BITS_TO_LONGS(CC33XX_MAX_LINKS)];
+
+	u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
+	u8 ssid_len;
+
+	/* The current band */
+	enum nl80211_band band;
+	int channel;
+	enum nl80211_channel_type channel_type;
+
+	u32 bitrate_masks[CC33XX_NUM_BANDS];
+	u32 basic_rate_set;
+
+	/* currently configured rate set:
+	 *	bits  0-15 - 802.11abg rates
+	 *	bits 16-23 - 802.11n   MCS index mask
+	 * support only 1 stream, thus only 8 bits for the MCS rates (0-7).
+	 */
+	u32 basic_rate;
+	u32 rate_set;
+
+	/* probe-req template for the current AP */
+	struct sk_buff *probereq;
+
+	/* Beaconing interval (needed for ad-hoc) */
+	u32 beacon_int;
+
+	/* Default key (for WEP) */
+	u32 default_key;
+
+	/* Our association ID */
+	u16 aid;
+
+	/* retry counter for PSM entries */
+	u8 psm_entry_retry;
+
+	/* in dBm */
+	int power_level;
+
+	int rssi_thold;
+	int last_rssi_event;
+
+	/* save the current encryption type for auto-arp config */
+	u8 encryption_type;
+	__be32 ip_addr;
+
+	/* RX BA constraint value */
+	bool ba_support;
+	bool ba_allowed;
+
+	bool wmm_enabled;
+
+	bool radar_enabled;
+
+	struct delayed_work channel_switch_work;
+	struct delayed_work connection_loss_work;
+
+	/* number of in connection stations */
+	int inconn_count;
+
+	/* This vif's queues are mapped to mac80211 HW queues as:
+	 * VO - hw_queue_base
+	 * VI - hw_queue_base + 1
+	 * BE - hw_queue_base + 2
+	 * BK - hw_queue_base + 3
+	 */
+	int hw_queue_base;
+
+	/* do we have a pending auth reply? (and ROC) */
+	bool ap_pending_auth_reply;
+
+	/* time when we sent the pending auth reply */
+	unsigned long pending_auth_reply_time;
+
+	/* work for canceling ROC after pending auth reply */
+	struct delayed_work pending_auth_complete_work;
+
+	struct delayed_work roc_timeout_work;
+
+	/* update rate control */
+	enum ieee80211_sta_rx_bandwidth rc_update_bw;
+	struct ieee80211_sta_ht_cap rc_ht_cap;
+	struct work_struct rc_update_work;
+
+	/* total freed FW packets on the link.
+	 * For STA this holds the PN of the link to the AP.
+	 * For AP this holds the PN of the broadcast link.
+	 */
+	u64 total_freed_pkts;
+
+	/* for MBSSID: this BSS is a nontransmitted BSS profile
+	 * Relevant for STA role
+	 */
+	bool nontransmitted;
+
+	/* for MBSSID: update transmitter BSSID */
+	u8 transmitter_bssid[ETH_ALEN];
+
+	/* for MBSSID: BSSID index */
+	u8 bssid_index;
+
+	/* for MBSSID: BSSID indicator */
+	u8 bssid_indicator;
+
+	/* for STA: if connection established and has HE support*/
+	u8 sta_has_he;
+
+	/* This struct must be last!
+	 * data that has to be saved acrossed reconfigs (e.g. recovery)
+	 * should be declared in this struct.
+	 */
+	u8 persistent[];
+};
+
+static inline struct cc33xx_vif *cc33xx_vif_to_data(struct ieee80211_vif *vif)
+{
+	WARN_ON(!vif);
+	return (struct cc33xx_vif *)vif->drv_priv;
+}
+
+static inline
+struct ieee80211_vif *cc33xx_wlvif_to_vif(struct cc33xx_vif *wlvif)
+{
+	return container_of((void *)wlvif, struct ieee80211_vif, drv_priv);
+}
+
+static inline bool cc33xx_is_p2p_mgmt(struct cc33xx_vif *wlvif)
+{
+	return cc33xx_wlvif_to_vif(wlvif)->type == NL80211_IFTYPE_P2P_DEVICE;
+}
+
+#define cc33xx_for_each_wlvif(cc, wlvif) \
+		list_for_each_entry(wlvif, &(cc)->wlvif_list, list)
+
+#define cc33xx_for_each_wlvif_continue(cc, wlvif) \
+		list_for_each_entry_continue(wlvif, &(cc)->wlvif_list, list)
+
+#define cc33xx_for_each_wlvif_bss_type(cc, wlvif, _bss_type)	\
+		cc33xx_for_each_wlvif((cc), (wlvif))		\
+			if ((wlvif)->bss_type == (_bss_type))
+
+#define cc33xx_for_each_wlvif_sta(cc, wlvif)	\
+		cc33xx_for_each_wlvif_bss_type(cc, wlvif, BSS_TYPE_STA_BSS)
+
+#define cc33xx_for_each_wlvif_ap(cc, wlvif)	\
+		cc33xx_for_each_wlvif_bss_type(cc, wlvif, BSS_TYPE_AP_BSS)
+
+int cc33xx_plt_start(struct cc33xx *cc, const enum plt_mode plt_mode);
+int cc33xx_plt_stop(struct cc33xx *cc);
+void cc33xx_queue_recovery_work(struct cc33xx *cc);
+void cc33xx_flush_deferred_work(struct cc33xx *cc);
+
+#define SESSION_COUNTER_INVALID 7 /* used with dummy_packet */
+
+#define CC33XX_MAX_TXPWR 21 /* maximum power limit is 21dBm */
+#define CC33XX_MIN_TXPWR -10 /* minimum power limit is -10dBm */
+
+#define CC33XX_TX_QUEUE_LOW_WATERMARK  32
+#define CC33XX_TX_QUEUE_HIGH_WATERMARK 256
+
+#define CC33XX_RX_QUEUE_MAX_LEN 256
+
+/* cc33xx needs a 200ms sleep after power on, and a 20ms sleep before power
+ * on in case is has been shut down shortly before
+ */
+#define CC33XX_PRE_POWER_ON_SLEEP 20 /* in milliseconds */
+#define CC33XX_POWER_ON_SLEEP 200 /* in milliseconds */
+
+/* Macros to handle cc33xx.sta_rate_set */
+#define HW_HT_RATES_OFFSET	16
+#define HW_MIMO_RATES_OFFSET	24
+
+#endif /* __CC33XX_I_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/cmd.c b/drivers/net/wireless/ti/cc33xx/cmd.c
--- a/drivers/net/wireless/ti/cc33xx/cmd.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/cmd.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,1920 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include "acx.h"
+#include "event.h"
+#include "io.h"
+#include "tx.h"
+
+#define CC33XX_REBOOT_TIMEOUT_MSEC		100
+
+static void init_cmd_header(struct cc33xx_cmd_header *header,
+			    size_t cmd_len, u16 id)
+{
+	header->NAB_header.len = cpu_to_le16(cmd_len);
+	WARN_ON(le16_to_cpu(header->NAB_header.len) != cmd_len);
+
+	header->NAB_header.sync_pattern = cpu_to_le32(HOST_SYNC_PATTERN);
+	header->NAB_header.opcode = cpu_to_le16(id);
+}
+
+int cc33xx_set_max_buffer_size(struct cc33xx *cc, enum buffer_size max_buffer_size)
+{
+	switch (max_buffer_size) {
+	case INI_MAX_BUFFER_SIZE:
+		/* INI FILE PAYLOAD SIZE + INI CMD PARAM + INT */
+		cc->max_cmd_size = CC33XX_INI_CMD_MAX_SIZE;
+		cc->max_cmd_size += sizeof(struct cc33xx_cmd_ini_params_download);
+		cc->max_cmd_size += sizeof(u32);
+		break;
+
+	case CMD_MAX_BUFFER_SIZE:
+		cc->max_cmd_size = CC33XX_CMD_MAX_SIZE;
+		break;
+
+	default:
+		cc33xx_warning("max_buffer_size invalid, not changing buffer size");
+		break;
+	}
+
+	return 0;
+}
+
+static int send_buffer(struct cc33xx *cc, int cmd_box_addr,
+		       void *buf, size_t len)
+{
+	size_t max_cmd_size_align;
+
+	memcpy(cc->cmd_buf, buf, len);
+
+	memset(cc->cmd_buf + len, 0, (CC33XX_CMD_BUFFER_SIZE) - len);
+
+	max_cmd_size_align = __ALIGN_MASK(cc->max_cmd_size,
+					  CC33XX_BUS_BLOCK_SIZE * 2 - 1);
+
+	return cc33xx_write(cc, cmd_box_addr, cc->cmd_buf,
+			    max_cmd_size_align, true);
+}
+
+/* send command to firmware
+ *
+ * @cc: cc struct
+ * @id: command id
+ * @buf: buffer containing the command, must work with dma
+ * @len: length of the buffer
+ * return the cmd status code on success.
+ */
+static int __cc33xx_cmd_send(struct cc33xx *cc, u16 id, void *buf,
+			     size_t len, size_t res_len, bool sync)
+{
+	struct cc33xx_cmd_header *cmd;
+	unsigned long timeout;
+	int ret;
+
+	if (id >= CMD_LAST_SUPPORTED_COMMAND) {
+		cc33xx_debug(DEBUG_CMD, "command ID: %d, blocked", id);
+		return CMD_STATUS_SUCCESS;
+	}
+
+	if (WARN_ON(len < sizeof(*cmd))		||
+	    WARN_ON(len > cc->max_cmd_size)	||
+	    WARN_ON(len % 4 != 0))
+		return -EIO;
+
+	cmd = buf;
+	cmd->id = cpu_to_le16(id);
+	cmd->status = 0;
+
+	init_cmd_header(cmd, len, id);
+	init_completion(&cc->command_complete);
+	ret = send_buffer(cc, NAB_DATA_ADDR, buf, len);
+
+	if (ret < 0)
+		return ret;
+
+	if (unlikely(!sync))
+		return CMD_STATUS_SUCCESS;
+
+	timeout = msecs_to_jiffies(CC33XX_COMMAND_TIMEOUT);
+	ret = wait_for_completion_timeout(&cc->command_complete, timeout);
+
+	if (ret < 1) {
+		cc33xx_debug(DEBUG_CMD, "Command T.O");
+		return -EIO;
+	}
+
+	switch (id) {
+	case CMD_INTERROGATE:
+	case CMD_DEBUG_READ:
+	case CMD_TEST_MODE:
+	case CMD_BM_READ_DEVICE_INFO:
+		if (!res_len)
+			break; /* Response should be discarded */
+
+		if (WARN_ON(cc->result_length > res_len)) {
+			cc33xx_error("Error, insufficient response buffer");
+			break;
+		}
+
+		memcpy(buf + sizeof(struct NAB_header),
+		       cc->command_result,
+			cc->result_length);
+
+		break;
+
+	default:
+		break;
+	}
+
+	return CMD_STATUS_SUCCESS;
+}
+
+/* send command to fw and return cmd status on success
+ * valid_rets contains a bitmap of allowed error codes
+ */
+static int cc33xx_cmd_send_failsafe(struct cc33xx *cc, u16 id, void *buf,
+				    size_t len, size_t res_len,
+				    unsigned long valid_rets)
+{
+	int ret = __cc33xx_cmd_send(cc, id, buf, len, res_len, true);
+
+	if (ret < 0)
+		goto fail;
+
+	/* success is always a valid status */
+	valid_rets |= BIT(CMD_STATUS_SUCCESS);
+
+	if (ret >= MAX_COMMAND_STATUS || !test_bit(ret, &valid_rets)) {
+		cc33xx_error("command execute failure %d", ret);
+		ret = -EIO;
+	}
+
+	return ret;
+fail:
+	cc33xx_queue_recovery_work(cc);
+	return ret;
+}
+
+/* wrapper for cc33xx_cmd_send that accept only CMD_STATUS_SUCCESS
+ * return 0 on success.
+ */
+int cc33xx_cmd_send(struct cc33xx *cc, u16 id, void *buf,
+		    size_t len, size_t res_len)
+{
+	int ret;
+	/* Support id */
+	switch ((enum cc33xx_cmd)id) {
+	case CMD_EMPTY:
+	case CMD_START_DHCP_MGMT_SEQ:
+	case CMD_STOP_DHCP_MGMT_SEQ:
+	case CMD_START_SECURITY_MGMT_SEQ:
+	case CMD_STOP_SECURITY_MGMT_SEQ:
+	case CMD_START_ARP_MGMT_SEQ:
+	case CMD_STOP_ARP_MGMT_SEQ:
+	case CMD_START_DNS_MGMT_SEQ:
+	case CMD_STOP_DNS_MGMT_SEQ:
+	case CMD_SEND_DEAUTH_DISASSOC:
+	case CMD_SCHED_STATE_EVENT:
+	{
+		return 0;
+	} break;
+	default:
+	{
+		if ((enum cc33xx_cmd)id >= CMD_LAST_SUPPORTED_COMMAND)
+			return 0;
+		goto send;
+	}
+	}
+send:
+	ret = cc33xx_cmd_send_failsafe(cc, id, buf, len, res_len, 0);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int cc33xx_count_role_set_bits(unsigned long role_map)
+{
+	int count = 0;
+	/* if device bit is set ( BIT_2 = ROLE_DEVICE)
+	 * since role device is not counted
+	 * remove it from map
+	 */
+	role_map &= ~BIT(2);
+
+	while (role_map != 0) {
+		count += role_map & 1;
+		role_map >>= 1;
+	}
+
+	return count;
+}
+
+int cc33xx_cmd_role_enable(struct cc33xx *cc, u8 *addr,
+			   u8 role_type, u8 *role_id)
+{
+	struct cc33xx_cmd_role_enable *cmd;
+
+	int ret;
+	unsigned long role_count;
+
+	struct cc33xx_cmd_complete_role_enable *command_complete =
+		  (struct cc33xx_cmd_complete_role_enable *)&cc->command_result;
+
+	role_count = *cc->roles_map;
+	ret = cc33xx_count_role_set_bits(role_count);
+
+	/* do not enable more than 2 roles at once, exception is device role */
+	if (ret >= 2 && role_type != CC33XX_ROLE_DEVICE) {
+		cc33xx_error("failed to initiate cmd role enable");
+		ret = -EBUSY;
+		goto out;
+	}
+
+	if (WARN_ON(*role_id != CC33XX_INVALID_ROLE_ID))
+		return -EBUSY;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(cmd->mac_address, addr, ETH_ALEN);
+	cmd->role_type = role_type;
+
+	ret = cc33xx_cmd_send(cc, CMD_ROLE_ENABLE, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to initiate cmd role enable");
+		goto out_free;
+	}
+	__set_bit(command_complete->role_id, cc->roles_map);
+	*role_id = command_complete->role_id;
+
+out_free:
+	kfree(cmd);
+out:
+	return ret;
+}
+
+int cc33xx_cmd_role_disable(struct cc33xx *cc, u8 *role_id)
+{
+	struct cc33xx_cmd_role_disable *cmd;
+	int ret;
+
+	if (WARN_ON(*role_id == CC33XX_INVALID_ROLE_ID))
+		return -ENOENT;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	cmd->role_id = *role_id;
+
+	ret = cc33xx_cmd_send(cc, CMD_ROLE_DISABLE, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to initiate cmd role disable");
+		goto out_free;
+	}
+
+	__clear_bit(*role_id, cc->roles_map);
+	*role_id = CC33XX_INVALID_ROLE_ID;
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+int cc33xx_set_link(struct cc33xx *cc, struct cc33xx_vif *wlvif, u8 link)
+{
+	unsigned long flags;
+
+	/* these bits are used by op_tx */
+	spin_lock_irqsave(&cc->cc_lock, flags);
+	__set_bit(link, cc->links_map);
+	__set_bit(link, wlvif->links_map);
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+	cc->links[link].wlvif = wlvif;
+
+	/* Take saved value for total freed packets from wlvif, in case this is
+	 * recovery/resume
+	 */
+	if (wlvif->bss_type != BSS_TYPE_AP_BSS)
+		cc->links[link].total_freed_pkts = wlvif->total_freed_pkts;
+
+	cc->active_link_count++;
+	return 0;
+}
+
+void cc33xx_clear_link(struct cc33xx *cc, struct cc33xx_vif *wlvif, u8 *hlid)
+{
+	unsigned long flags;
+
+	if (*hlid == CC33XX_INVALID_LINK_ID)
+		return;
+
+	/* these bits are used by op_tx */
+	spin_lock_irqsave(&cc->cc_lock, flags);
+	__clear_bit(*hlid, cc->links_map);
+	__clear_bit(*hlid, wlvif->links_map);
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+
+	cc->links[*hlid].prev_freed_pkts = 0;
+	cc->links[*hlid].ba_bitmap = 0;
+	eth_zero_addr(cc->links[*hlid].addr);
+
+	/* At this point op_tx() will not add more packets to the queues. We
+	 * can purge them.
+	 */
+	cc33xx_tx_reset_link_queues(cc, *hlid);
+	cc->links[*hlid].wlvif = NULL;
+
+	if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
+	    *hlid == wlvif->ap.bcast_hlid) {
+		u32 sqn_padding = CC33XX_TX_SQN_POST_RECOVERY_PADDING;
+		/* save the total freed packets in the wlvif, in case this is
+		 * recovery or suspend
+		 */
+		wlvif->total_freed_pkts = cc->links[*hlid].total_freed_pkts;
+
+		/* increment the initial seq number on recovery to account for
+		 * transmitted packets that we haven't yet got in the FW status
+		 */
+		if (wlvif->encryption_type == KEY_GEM)
+			sqn_padding = CC33XX_TX_SQN_POST_RECOVERY_PADDING_GEM;
+
+		if (test_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS, &cc->flags))
+			wlvif->total_freed_pkts += sqn_padding;
+	}
+
+	cc->links[*hlid].total_freed_pkts = 0;
+
+	*hlid = CC33XX_INVALID_LINK_ID;
+	cc->active_link_count--;
+	WARN_ON_ONCE(cc->active_link_count < 0);
+}
+
+static u8 cc33xx_get_native_channel_type(u8 nl_channel_type)
+{
+	switch (nl_channel_type) {
+	case NL80211_CHAN_NO_HT:
+		return CC33XX_CHAN_NO_HT;
+	case NL80211_CHAN_HT20:
+		return CC33XX_CHAN_HT20;
+	case NL80211_CHAN_HT40MINUS:
+		return CC33XX_CHAN_HT40MINUS;
+	case NL80211_CHAN_HT40PLUS:
+		return CC33XX_CHAN_HT40PLUS;
+	default:
+		WARN_ON(1);
+		return CC33XX_CHAN_NO_HT;
+	}
+}
+
+static int cc33xx_cmd_role_start_dev(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				     enum nl80211_band band, int channel)
+{
+	struct cc33xx_cmd_role_start *cmd;
+	int ret;
+
+	struct cc33xx_cmd_complete_role_start *command_complete =
+		(struct cc33xx_cmd_complete_role_start *)&cc->command_result;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->role_id = wlvif->dev_role_id;
+	cmd->role_type = CC33XX_ROLE_DEVICE;
+	if (band == NL80211_BAND_5GHZ)
+		cmd->band = CC33XX_BAND_5GHZ;
+	cmd->channel = channel;
+	cmd->channel_type = cc33xx_get_native_channel_type(wlvif->channel_type);
+
+	ret = cc33xx_cmd_send(cc, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to initiate cmd role device start");
+		goto err_hlid;
+	}
+
+	wlvif->dev_hlid = command_complete->sta.hlid;
+	cc->links[wlvif->dev_hlid].allocated_pkts = 0;
+	cc->session_ids[wlvif->dev_hlid] = command_complete->sta.session;
+	cc33xx_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d ",
+		     wlvif->dev_role_id, command_complete->sta.hlid,
+		     command_complete->sta.session);
+	ret = cc33xx_set_link(cc, wlvif, wlvif->dev_hlid);
+	goto out_free;
+
+err_hlid:
+	/* clear links on error */
+	cc33xx_clear_link(cc, wlvif, &wlvif->dev_hlid);
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+int cc33xx_cmd_role_stop_transceiver(struct cc33xx *cc)
+{
+	struct cc33xx_cmd_role_stop *cmd;
+	int ret;
+
+	if (unlikely(cc->state != CC33XX_STATE_ON || !cc->plt)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->role_id = cc->plt_role_id;
+
+	ret = cc33xx_cmd_send(cc, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("transceiver - failed to initiate cmd role stop");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+int cc33xx_cmd_plt_disable(struct cc33xx *cc)
+{
+	struct cc33xx_cmd_PLT_disable *cmd;
+	int ret;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = cc33xx_cmd_send(cc, CMD_PLT_DISABLE, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("transceiver: failed to disable Transceiver mode");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+static int cc333xx_cmd_role_stop_dev(struct cc33xx *cc,
+				     struct cc33xx_vif *wlvif)
+{
+	struct cc33xx_cmd_role_stop *cmd;
+	int ret;
+
+	if (WARN_ON(wlvif->dev_hlid == CC33XX_INVALID_LINK_ID))
+		return -EINVAL;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->role_id = wlvif->dev_role_id;
+
+	ret = cc33xx_cmd_send(cc, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to initiate cmd role stop");
+		goto out_free;
+	}
+
+	cc33xx_clear_link(cc, wlvif, &wlvif->dev_hlid);
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+int cc33xx_cmd_plt_enable(struct cc33xx *cc, u8 role_id)
+{
+	struct cc33xx_cmd_PLT_enable *cmd;
+	s32 ret;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = cc33xx_cmd_send(cc, CMD_PLT_ENABLE, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("Failed to send CMD_PLT_ENABLE");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+out:
+	return ret;
+}
+
+int cc33xx_cmd_role_start_transceiver(struct cc33xx *cc, u8 role_id)
+{
+	struct cc33xx_cmd_role_start *cmd;
+	s32 ret;
+	u8 role_type = ROLE_TRANSCEIVER;
+
+	/* Default values */
+	u8 band = NL80211_BAND_2GHZ;
+	u8 channel = 6;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->role_type = role_type;
+	cmd->role_id = role_id;
+	cmd->channel = channel;
+	cmd->band = band;
+
+	ret = cc33xx_cmd_send(cc, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to initiate cmd role start PLT");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+out:
+	return ret;
+}
+
+int cc33xx_cmd_role_start_sta(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
+	struct cc33xx_cmd_role_start *cmd;
+
+	u32 supported_rates;
+	int ret;
+
+	struct cc33xx_cmd_complete_role_start *command_complete =
+		(struct cc33xx_cmd_complete_role_start *)&cc->command_result;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->role_id = wlvif->role_id;
+	cmd->role_type = CC33XX_ROLE_STA;
+	cmd->channel = wlvif->channel;
+	if (wlvif->band == NL80211_BAND_5GHZ) {
+		cmd->band = CC33XX_BAND_5GHZ;
+		cmd->sta.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set
+							& ~CONF_TX_CCK_RATES);
+	} else {
+		cmd->sta.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
+	}
+	cmd->sta.beacon_interval = cpu_to_le16(wlvif->beacon_int);
+	cmd->sta.ssid_type = CC33XX_SSID_TYPE_ANY;
+	cmd->sta.ssid_len = wlvif->ssid_len;
+	memcpy(cmd->sta.ssid, wlvif->ssid, wlvif->ssid_len);
+	memcpy(cmd->sta.bssid, vif->bss_conf.bssid, ETH_ALEN);
+
+	supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES | wlvif->rate_set;
+	if (wlvif->band == NL80211_BAND_5GHZ)
+		supported_rates &= ~CONF_TX_CCK_RATES;
+
+	if (wlvif->p2p)
+		supported_rates &= ~CONF_TX_CCK_RATES;
+
+	cmd->sta.local_rates = cpu_to_le32(supported_rates);
+
+	cmd->channel_type = cc33xx_get_native_channel_type(wlvif->channel_type);
+
+	/* We don't have the correct remote rates in this stage.  The
+	 * rates will be reconfigured later, after association, if the
+	 * firmware supports ACX_PEER_CAP.  Otherwise, there's nothing
+	 * we can do, so use all supported_rates here.
+	 */
+	cmd->sta.remote_rates = cpu_to_le32(supported_rates);
+
+	ret = cc33xx_cmd_send(cc, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to initiate cmd role start sta");
+		goto err_hlid;
+	}
+
+	wlvif->sta.role_chan_type = wlvif->channel_type;
+
+	wlvif->sta.hlid = command_complete->sta.hlid;
+	cc->links[wlvif->sta.hlid].allocated_pkts = 0;
+	cc->session_ids[wlvif->sta.hlid] = command_complete->sta.session;
+	cc33xx_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d basic_rate_set: 0x%x, remote_rates: 0x%x",
+		     wlvif->role_id,
+		     command_complete->sta.hlid, command_complete->sta.session,
+		     wlvif->basic_rate_set, wlvif->rate_set);
+	ret = cc33xx_set_link(cc, wlvif, wlvif->sta.hlid);
+
+	goto out_free;
+
+err_hlid:
+	cc33xx_clear_link(cc, wlvif, &wlvif->sta.hlid);
+
+out_free:
+	kfree(cmd);
+out:
+	return ret;
+}
+
+/* use this function to stop ibss as well */
+int cc33xx_cmd_role_stop_sta(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	struct cc33xx_cmd_role_stop *cmd;
+	int ret;
+
+	if (WARN_ON(wlvif->sta.hlid == CC33XX_INVALID_LINK_ID))
+		return -EINVAL;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->role_id = wlvif->role_id;
+
+	ret = cc33xx_cmd_send(cc, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to initiate cmd role stop sta");
+		goto out_free;
+	}
+
+	cc33xx_clear_link(cc, wlvif, &wlvif->sta.hlid);
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+int cc33xx_cmd_role_start_ap(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	struct cc33xx_cmd_role_start *cmd;
+	struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
+	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+	u32 supported_rates;
+	int ret;
+
+	struct cc33xx_cmd_complete_role_start *command_complete =
+		(struct cc33xx_cmd_complete_role_start *)&cc->command_result;
+
+	/* If MESH --> ssid_len is always 0 */
+	if (!ieee80211_vif_is_mesh(vif)) {
+		/* trying to use hidden SSID with an old hostapd version */
+		if (wlvif->ssid_len == 0 && !bss_conf->hidden_ssid) {
+			cc33xx_error("got a null SSID from beacon/bss");
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->role_id = wlvif->role_id;
+	cmd->role_type = CC33XX_ROLE_AP;
+	cmd->ap.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
+	cmd->ap.beacon_interval = cpu_to_le16(wlvif->beacon_int);
+	cmd->ap.dtim_interval = bss_conf->dtim_period;
+	cmd->ap.wmm = wlvif->wmm_enabled;
+	cmd->channel = wlvif->channel;
+	cmd->channel_type = cc33xx_get_native_channel_type(wlvif->channel_type);
+
+	supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES;
+	if (wlvif->p2p)
+		supported_rates &= ~CONF_TX_CCK_RATES;
+
+	cmd->ap.local_rates = cpu_to_le32(supported_rates);
+
+	switch (wlvif->band) {
+	case NL80211_BAND_2GHZ:
+		cmd->band = CC33XX_BAND_2_4GHZ;
+		break;
+	case NL80211_BAND_5GHZ:
+		cmd->band = CC33XX_BAND_5GHZ;
+		break;
+	default:
+		cc33xx_warning("ap start - unknown band: %d", (int)wlvif->band);
+		cmd->band = CC33XX_BAND_2_4GHZ;
+		break;
+	}
+
+	ret = cc33xx_cmd_send(cc, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to initiate cmd role start ap");
+		goto out_free_bcast;
+	}
+
+	wlvif->ap.global_hlid = command_complete->ap.global_hlid;
+	wlvif->ap.bcast_hlid  = command_complete->ap.broadcast_hlid;
+	cc->session_ids[wlvif->ap.global_hlid] = command_complete->ap.global_session_id;
+	cc->session_ids[wlvif->ap.bcast_hlid] = command_complete->ap.bcast_session_id;
+
+	cc33xx_debug(DEBUG_CMD, "role start: roleid=%d, global_hlid=%d, broadcast_hlid=%d, global_session_id=%d, bcast_session_id=%d, basic_rate_set: 0x%x, remote_rates: 0x%x",
+		     wlvif->role_id,
+		     command_complete->ap.global_hlid,
+		     command_complete->ap.broadcast_hlid,
+		     command_complete->ap.global_session_id,
+		     command_complete->ap.bcast_session_id,
+		     wlvif->basic_rate_set, wlvif->rate_set);
+
+	ret = cc33xx_set_link(cc, wlvif, wlvif->ap.global_hlid);
+	ret = cc33xx_set_link(cc, wlvif, wlvif->ap.bcast_hlid);
+
+	goto out_free;
+
+out_free_bcast:
+	cc33xx_clear_link(cc, wlvif, &wlvif->ap.bcast_hlid);
+	cc33xx_clear_link(cc, wlvif, &wlvif->ap.global_hlid);
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+int cc33xx_cmd_role_stop_ap(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	struct cc33xx_cmd_role_stop *cmd;
+	int ret;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->role_id = wlvif->role_id;
+
+	ret = cc33xx_cmd_send(cc, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to initiate cmd role stop ap");
+		goto out_free;
+	}
+
+	cc33xx_clear_link(cc, wlvif, &wlvif->ap.bcast_hlid);
+	cc33xx_clear_link(cc, wlvif, &wlvif->ap.global_hlid);
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+int cc33xx_cmd_role_start_ibss(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
+	struct cc33xx_cmd_role_start *cmd;
+	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+	int ret;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->role_id = wlvif->role_id;
+	cmd->role_type = CC33XX_ROLE_IBSS;
+	if (wlvif->band == NL80211_BAND_5GHZ)
+		cmd->band = CC33XX_BAND_5GHZ;
+	cmd->channel = wlvif->channel;
+	cmd->ibss.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
+	cmd->ibss.beacon_interval = cpu_to_le16(wlvif->beacon_int);
+	cmd->ibss.dtim_interval = bss_conf->dtim_period;
+	cmd->ibss.ssid_type = CC33XX_SSID_TYPE_ANY;
+	cmd->ibss.ssid_len = wlvif->ssid_len;
+	memcpy(cmd->ibss.ssid, wlvif->ssid, wlvif->ssid_len);
+	memcpy(cmd->ibss.bssid, vif->bss_conf.bssid, ETH_ALEN);
+	cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set);
+
+	if (wlvif->sta.hlid == CC33XX_INVALID_LINK_ID) {
+		ret = cc33xx_set_link(cc, wlvif, wlvif->sta.hlid);
+		if (ret)
+			goto out_free;
+	}
+	cmd->ibss.hlid = wlvif->sta.hlid;
+	cmd->ibss.remote_rates = cpu_to_le32(wlvif->rate_set);
+
+	ret = cc33xx_cmd_send(cc, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to initiate cmd role enable");
+		goto err_hlid;
+	}
+
+	goto out_free;
+
+err_hlid:
+	/* clear links on error. */
+	cc33xx_clear_link(cc, wlvif, &wlvif->sta.hlid);
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+/* send test command to firmware
+ *
+ * @cc: cc struct
+ * @buf: buffer containing the command, with all headers, must work with dma
+ * @len: length of the buffer
+ * @answer: is answer needed
+ */
+int cc33xx_cmd_test(struct cc33xx *cc, void *buf, size_t buf_len, u8 answer)
+{
+	int ret;
+	size_t res_len = 0;
+
+	if (answer)
+		res_len = buf_len;
+
+	ret = cc33xx_cmd_send(cc, CMD_TEST_MODE, buf, buf_len, res_len);
+
+	if (ret < 0) {
+		cc33xx_warning("TEST command failed");
+		return ret;
+	}
+
+	return ret;
+}
+
+/* read acx from firmware
+ *
+ * @cc: cc struct
+ * @id: acx id
+ * @buf: buffer for the response, including all headers, must work with dma
+ * @len: length of buf
+ */
+int cc33xx_cmd_interrogate(struct cc33xx *cc, u16 id, void *buf,
+			   size_t cmd_len, size_t res_len)
+{
+	struct acx_header *acx = buf;
+	int ret;
+
+	acx->id = cpu_to_le16(id);
+
+	/* response payload length, does not include any headers */
+	acx->len = cpu_to_le16(res_len - sizeof(*acx));
+
+	ret = cc33xx_cmd_send(cc, CMD_INTERROGATE, acx, cmd_len, res_len);
+	if (ret < 0)
+		cc33xx_error("INTERROGATE command failed");
+
+	return ret;
+}
+
+/* read debug acx from firmware
+ *
+ * @cc: cc struct
+ * @id: acx id
+ * @buf: buffer for the response, including all headers, must work with dma
+ * @len: length of buf
+ */
+int cc33xx_cmd_debug_inter(struct cc33xx *cc, u16 id, void *buf,
+			   size_t cmd_len, size_t res_len)
+{
+	struct acx_header *acx = buf;
+	int ret;
+
+	acx->id = cpu_to_le16(id);
+
+	/* response payload length, does not include any headers */
+	acx->len = cpu_to_le16(res_len - sizeof(*acx));
+
+	ret = cc33xx_cmd_send(cc, CMD_DEBUG_READ, acx, cmd_len, res_len);
+	if (ret < 0)
+		cc33xx_error("CMD_DEBUG_READ command failed");
+
+	return ret;
+}
+
+/* write acx value to firmware
+ *
+ * @cc: cc struct
+ * @id: acx id
+ * @buf: buffer containing acx, including all headers, must work with dma
+ * @len: length of buf
+ * @valid_rets: bitmap of valid cmd status codes (i.e. return values).
+ * return the cmd status on success.
+ */
+int cc33xx_cmd_configure_failsafe(struct cc33xx *cc, u16 id, void *buf,
+				  size_t len, unsigned long valid_rets)
+{
+	struct acx_header *acx = buf;
+	int ret;
+
+	if (WARN_ON_ONCE(len < sizeof(*acx)))
+		return -EIO;
+
+	acx->id = cpu_to_le16(id);
+
+	/* payload length, does not include any headers */
+	acx->len = cpu_to_le16(len - sizeof(*acx));
+
+	ret = cc33xx_cmd_send_failsafe(cc, CMD_CONFIGURE, acx, len, 0,
+				       valid_rets);
+	if (ret < 0) {
+		cc33xx_warning("CONFIGURE command NOK");
+		return ret;
+	}
+
+	return ret;
+}
+
+/* wrapper for cc33xx_cmd_configure that accepts only success status.
+ * return 0 on success
+ */
+int cc33xx_cmd_configure(struct cc33xx *cc, u16 id, void *buf, size_t len)
+{
+	int ret = cc33xx_cmd_configure_failsafe(cc, id, buf, len, 0);
+
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+/* write acx value to firmware
+ *
+ * @cc: cc struct
+ * @id: acx id
+ * @buf: buffer containing debug, including all headers, must work with dma
+ * @len: length of buf
+ * @valid_rets: bitmap of valid cmd status codes (i.e. return values).
+ * return the cmd status on success.
+ */
+static int cc33xx_cmd_debug_failsafe(struct cc33xx *cc, u16 id, void *buf,
+				     size_t len, unsigned long valid_rets)
+{
+	struct debug_header *acx = buf;
+	int ret;
+
+	if (WARN_ON_ONCE(len < sizeof(*acx)))
+		return -EIO;
+
+	acx->id = cpu_to_le16(id);
+
+	/* payload length, does not include any headers */
+	acx->len = cpu_to_le16(len - sizeof(*acx));
+
+	ret = cc33xx_cmd_send_failsafe(cc, CMD_DEBUG, acx, len, 0,
+				       valid_rets);
+	if (ret < 0) {
+		cc33xx_warning("CONFIGURE command NOK");
+		return ret;
+	}
+
+	return ret;
+}
+
+/* wrapper for cc33xx_cmd_debug that accepts only success status.
+ * return 0 on success
+ */
+int cc33xx_cmd_debug(struct cc33xx *cc, u16 id, void *buf, size_t len)
+{
+	int ret = cc33xx_cmd_debug_failsafe(cc, id, buf, len, 0);
+
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+int cc33xx_cmd_ps_mode(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+		       u8 ps_mode, u16 auto_ps_timeout)
+{
+	struct cc33xx_cmd_ps_params *ps_params = NULL;
+	int ret = 0;
+
+	ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
+	if (!ps_params) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ps_params->role_id = wlvif->role_id;
+	ps_params->ps_mode = ps_mode;
+	ps_params->auto_ps_timeout = cpu_to_le16(auto_ps_timeout);
+
+	ret = cc33xx_cmd_send(cc, CMD_SET_PS_MODE, ps_params,
+			      sizeof(*ps_params), 0);
+	if (ret < 0) {
+		cc33xx_error("cmd set_ps_mode failed");
+		goto out;
+	}
+
+out:
+	kfree(ps_params);
+	return ret;
+}
+
+int cc33xx_cmd_set_default_wep_key(struct cc33xx *cc, u8 id, u8 hlid)
+{
+	struct cc33xx_cmd_set_keys *cmd;
+	int ret = 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->hlid = hlid;
+	cmd->key_id = id;
+	cmd->lid_key_type = WEP_DEFAULT_LID_TYPE;
+	cmd->key_action = cpu_to_le16(KEY_SET_ID);
+	cmd->key_type = KEY_WEP;
+
+	ret = cc33xx_cmd_send(cc, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_warning("cmd set_default_wep_key failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(cmd);
+
+	return ret;
+}
+
+int cc33xx_cmd_set_sta_key(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			   u16 action, u8 id, u8 key_type, u8 key_size,
+			   const u8 *key, const u8 *addr, u32 tx_seq_32,
+			   u16 tx_seq_16)
+{
+	struct cc33xx_cmd_set_keys *cmd;
+	int ret = 0;
+
+	/* hlid might have already been deleted */
+	if (wlvif->sta.hlid == CC33XX_INVALID_LINK_ID)
+		return 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->hlid = wlvif->sta.hlid;
+
+	if (key_type == KEY_WEP)
+		cmd->lid_key_type = WEP_DEFAULT_LID_TYPE;
+	else if (is_broadcast_ether_addr(addr))
+		cmd->lid_key_type = BROADCAST_LID_TYPE;
+	else
+		cmd->lid_key_type = UNICAST_LID_TYPE;
+
+	cmd->key_action = cpu_to_le16(action);
+	cmd->key_size = key_size;
+	cmd->key_type = key_type;
+
+	cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16);
+	cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32);
+
+	cmd->key_id = id;
+
+	if (key_type == KEY_TKIP) {
+		/* We get the key in the following form:
+		 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
+		 * but the target is expecting:
+		 * TKIP - RX MIC - TX MIC
+		 */
+		memcpy(cmd->key, key, 16);
+		memcpy(cmd->key + 16, key + 24, 8);
+		memcpy(cmd->key + 24, key + 16, 8);
+
+	} else {
+		memcpy(cmd->key, key, key_size);
+	}
+
+	ret = cc33xx_cmd_send(cc, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_warning("could not set keys");
+		goto out;
+	}
+
+out:
+	kfree(cmd);
+
+	return ret;
+}
+
+int cc33xx_cmd_set_ap_key(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			  u16 action, u8 id, u8 key_type, u8 key_size,
+			  const u8 *key, u8 hlid, u32 tx_seq_32, u16 tx_seq_16)
+{
+	struct cc33xx_cmd_set_keys *cmd;
+	int ret = 0;
+	u8 lid_type;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	if (hlid == wlvif->ap.bcast_hlid) {
+		if (key_type == KEY_WEP)
+			lid_type = WEP_DEFAULT_LID_TYPE;
+		else
+			lid_type = BROADCAST_LID_TYPE;
+	} else {
+		lid_type = UNICAST_LID_TYPE;
+	}
+
+	cmd->lid_key_type = lid_type;
+	cmd->hlid = hlid;
+	cmd->key_action = cpu_to_le16(action);
+	cmd->key_size = key_size;
+	cmd->key_type = key_type;
+	cmd->key_id = id;
+	cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16);
+	cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32);
+
+	if (key_type == KEY_TKIP) {
+		/* We get the key in the following form:
+		 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
+		 * but the target is expecting:
+		 * TKIP - RX MIC - TX MIC
+		 */
+		memcpy(cmd->key, key, 16);
+		memcpy(cmd->key + 16, key + 24, 8);
+		memcpy(cmd->key + 24, key + 16, 8);
+	} else {
+		memcpy(cmd->key, key, key_size);
+	}
+
+	cc33xx_dump(DEBUG_CRYPT, "TARGET AP KEY: ", cmd, sizeof(*cmd));
+
+	ret = cc33xx_cmd_send(cc, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_warning("could not set ap keys");
+		goto out;
+	}
+
+out:
+	kfree(cmd);
+	return ret;
+}
+
+int cc33xx_cmd_set_peer_state(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			      u8 hlid)
+{
+	struct cc33xx_cmd_set_peer_state *cmd;
+	int ret = 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->hlid = hlid;
+	cmd->state = CC33XX_CMD_STA_STATE_CONNECTED;
+
+	ret = cc33xx_cmd_send(cc, CMD_SET_LINK_CONNECTION_STATE,
+			      cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to send set peer state command");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+int cc33xx_cmd_add_peer(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			struct ieee80211_sta *sta, u8 *hlid, u8 is_connected)
+{
+	struct cc33xx_cmd_add_peer *cmd;
+
+	struct cc33xx_cmd_complete_add_peer *command_complete =
+		(struct cc33xx_cmd_complete_add_peer *)&cc->command_result;
+
+	int i, ret;
+	u32 sta_rates;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->is_connected = is_connected;
+	cmd->role_id = wlvif->role_id;
+	cmd->role_type = CC33XX_ROLE_AP;
+	cmd->link_type = 1;
+
+	memcpy(cmd->addr, sta->addr, ETH_ALEN);
+	cmd->bss_index = CC33XX_AP_BSS_INDEX;
+	cmd->aid = cpu_to_le16(sta->aid);
+	cmd->sp_len = sta->max_sp;
+	cmd->wmm = sta->wme ? 1 : 0;
+
+	for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++) {
+		if (sta->wme && (sta->uapsd_queues & BIT(i))) {
+			cmd->psd_type[NUM_ACCESS_CATEGORIES_COPY - 1 - i] =
+					CC33XX_PSD_UPSD_TRIGGER;
+		} else {
+			cmd->psd_type[NUM_ACCESS_CATEGORIES_COPY - 1 - i] =
+					CC33XX_PSD_LEGACY;
+		}
+	}
+
+	sta_rates = sta->deflink.supp_rates[wlvif->band];
+	if (sta->deflink.ht_cap.ht_supported) {
+		sta_rates |=
+			(sta->deflink.ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) |
+			(sta->deflink.ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET);
+	}
+
+	cmd->supported_rates =
+		cpu_to_le32(cc33xx_tx_enabled_rates_get(cc, sta_rates,
+							wlvif->band));
+
+	if (!cmd->supported_rates)
+		cmd->supported_rates = cpu_to_le32(wlvif->basic_rate_set);
+
+	if (sta->deflink.ht_cap.ht_supported) {
+		cmd->ht_capabilities = cpu_to_le32(sta->deflink.ht_cap.cap);
+		cmd->ht_capabilities |= cpu_to_le32(CC33XX_HT_CAP_HT_OPERATION);
+		cmd->ampdu_params = sta->deflink.ht_cap.ampdu_factor |
+				    sta->deflink.ht_cap.ampdu_density;
+	}
+
+	cmd->has_he = sta->deflink.he_cap.has_he;
+	cmd->mfp = sta->mfp;
+	ret = cc33xx_cmd_send(cc, CMD_ADD_PEER, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to initiate cmd add peer");
+		goto out_free;
+	}
+
+	if (hlid) {
+		if (le16_to_cpu(command_complete->header.status) == CMD_STATUS_SUCCESS) {
+			*hlid = command_complete->hlid;
+			cc->links[*hlid].allocated_pkts = 0;
+			cc->session_ids[*hlid] = command_complete->session_id;
+		} else {
+			ret = -EMLINK;
+		}
+	}
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+int cc33xx_cmd_remove_peer(struct cc33xx *cc,
+			   struct cc33xx_vif *wlvif, u8 hlid)
+{
+	struct cc33xx_cmd_remove_peer *cmd;
+	int ret;
+	bool timeout = false;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->hlid = hlid;
+
+	cmd->role_id = wlvif->role_id;
+
+	ret = cc33xx_cmd_send(cc, CMD_REMOVE_PEER, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to initiate cmd remove peer");
+		goto out_free;
+	}
+
+	ret = cc33xx_wait_for_event(cc, CC33XX_EVENT_PEER_REMOVE_COMPLETE,
+				    &timeout);
+
+	/* We are ok with a timeout here. The event is sometimes not sent
+	 * due to a firmware bug. In case of another error (like SDIO timeout)
+	 * queue a recovery.
+	 */
+	if (ret < 0)
+		cc33xx_queue_recovery_work(cc);
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+static int cc33xx_get_reg_conf_ch_idx(enum nl80211_band band, u16 ch)
+{
+	/* map the given band/channel to the respective predefined
+	 * bit expected by the fw
+	 */
+	switch (band) {
+	case NL80211_BAND_2GHZ:
+		/* channels 1..14 are mapped to 0..13 */
+		if (ch >= 1 && ch <= 14)
+			return ch - 1;
+		break;
+	case NL80211_BAND_5GHZ:
+		switch (ch) {
+		case 8 ... 16:
+			/* channels 8,12,16 are mapped to 18,19,20 */
+			return 18 + (ch - 8) / 4;
+		case 34 ... 48:
+			/* channels 34,36..48 are mapped to 21..28 */
+			return 21 + (ch - 34) / 2;
+		case 52 ... 64:
+			/* channels 52,56..64 are mapped to 29..32 */
+			return 29 + (ch - 52) / 4;
+		case 100 ... 140:
+			/* channels 100,104..140 are mapped to 33..43 */
+			return 33 + (ch - 100) / 4;
+		case 149 ... 165:
+			/* channels 149,153..165 are mapped to 44..48 */
+			return 44 + (ch - 149) / 4;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	cc33xx_error("%s: unknown band/channel: %d/%d", __func__, band, ch);
+	return -1;
+}
+
+void cc33xx_set_pending_regdomain_ch(struct cc33xx *cc, u16 channel,
+				     enum nl80211_band band)
+{
+	int ch_bit_idx = 0;
+
+	if (!(cc->quirks & CC33XX_QUIRK_REGDOMAIN_CONF))
+		return;
+
+	ch_bit_idx = cc33xx_get_reg_conf_ch_idx(band, channel);
+
+	if (ch_bit_idx >= 0 && ch_bit_idx <= CC33XX_MAX_CHANNELS)
+		__set_bit_le(ch_bit_idx, (long *)cc->reg_ch_conf_pending);
+}
+
+int cc33xx_cmd_regdomain_config_locked(struct cc33xx *cc)
+{
+	struct cc33xx_cmd_regdomain_dfs_config *cmd = NULL;
+	int ret = 0, i, b, ch_bit_idx;
+	__le32 tmp_ch_bitmap[2] __aligned(sizeof(unsigned long));
+	struct wiphy *wiphy = cc->hw->wiphy;
+	struct ieee80211_supported_band *band;
+	bool timeout = false;
+
+	if (!(cc->quirks & CC33XX_QUIRK_REGDOMAIN_CONF))
+		return 0;
+
+	memcpy(tmp_ch_bitmap, cc->reg_ch_conf_pending, sizeof(tmp_ch_bitmap));
+
+	for (b = NL80211_BAND_2GHZ; b <= NL80211_BAND_5GHZ; b++) {
+		band = wiphy->bands[b];
+		for (i = 0; i < band->n_channels; i++) {
+			struct ieee80211_channel *channel = &band->channels[i];
+			u16 ch = channel->hw_value;
+			u32 flags = channel->flags;
+
+			if (flags & (IEEE80211_CHAN_DISABLED |
+				     IEEE80211_CHAN_NO_IR))
+				continue;
+
+			if ((flags & IEEE80211_CHAN_RADAR) &&
+			    channel->dfs_state != NL80211_DFS_AVAILABLE)
+				continue;
+
+			ch_bit_idx = cc33xx_get_reg_conf_ch_idx(b, ch);
+			if (ch_bit_idx < 0)
+				continue;
+
+			__set_bit_le(ch_bit_idx, (long *)tmp_ch_bitmap);
+		}
+	}
+
+	if (!memcmp(tmp_ch_bitmap, cc->reg_ch_conf_last, sizeof(tmp_ch_bitmap)))
+		goto out;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->ch_bit_map1 = tmp_ch_bitmap[0];
+	cmd->ch_bit_map2 = tmp_ch_bitmap[1];
+	cmd->dfs_region = cc->dfs_region;
+
+	ret = cc33xx_cmd_send(cc, CMD_DFS_CHANNEL_CONFIG, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to send reg domain dfs config");
+		goto out;
+	}
+
+	ret = cc33xx_wait_for_event(cc, CC33XX_EVENT_DFS_CONFIG_COMPLETE,
+				    &timeout);
+
+	if (ret < 0 || timeout) {
+		cc33xx_error("reg domain conf %serror",
+			     timeout ? "completion " : "");
+		ret = timeout ? -ETIMEDOUT : ret;
+		goto out;
+	}
+
+	memcpy(cc->reg_ch_conf_last, tmp_ch_bitmap, sizeof(tmp_ch_bitmap));
+	memset(cc->reg_ch_conf_pending, 0, sizeof(cc->reg_ch_conf_pending));
+
+out:
+	kfree(cmd);
+	return ret;
+}
+
+int cc33xx_cmd_config_fwlog(struct cc33xx *cc)
+{
+	struct cc33xx_cmd_config_fwlog *cmd;
+	int ret = 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->logger_mode = cc->conf.host_conf.fwlog.mode;
+	cmd->log_severity = cc->conf.host_conf.fwlog.severity;
+	cmd->timestamp = cc->conf.host_conf.fwlog.timestamp;
+	cmd->output = cc->conf.host_conf.fwlog.output;
+	cmd->threshold = cc->conf.host_conf.fwlog.threshold;
+
+	ret = cc33xx_cmd_send(cc, CMD_CONFIG_FWLOGGER, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to send config firmware logger command");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+static int cc33xx_cmd_roc(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			  u8 role_id, enum nl80211_band band, u8 channel)
+{
+	struct cc33xx_cmd_roc *cmd;
+	int ret = 0;
+
+	if (WARN_ON(role_id == CC33XX_INVALID_ROLE_ID))
+		return -EINVAL;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->role_id = role_id;
+	cmd->channel = channel;
+	switch (band) {
+	case NL80211_BAND_2GHZ:
+		cmd->band = CC33XX_BAND_2_4GHZ;
+		break;
+	case NL80211_BAND_5GHZ:
+		cmd->band = CC33XX_BAND_5GHZ;
+		break;
+	default:
+		cc33xx_error("roc - unknown band: %d", (int)wlvif->band);
+		ret = -EINVAL;
+		goto out_free;
+	}
+
+	ret = cc33xx_cmd_send(cc, CMD_REMAIN_ON_CHANNEL, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to send ROC command");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+static int cc33xx_cmd_croc(struct cc33xx *cc, u8 role_id)
+{
+	struct cc33xx_cmd_croc *cmd;
+	int ret = 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	cmd->role_id = role_id;
+
+	ret = cc33xx_cmd_send(cc, CMD_CANCEL_REMAIN_ON_CHANNEL, cmd,
+			      sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to send ROC command");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+int cc33xx_roc(struct cc33xx *cc, struct cc33xx_vif *wlvif, u8 role_id,
+	       enum nl80211_band band, u8 channel)
+{
+	int ret = 0;
+
+	if (WARN_ON(test_bit(role_id, cc->roc_map)))
+		return 0;
+
+	ret = cc33xx_cmd_roc(cc, wlvif, role_id, band, channel);
+	if (ret < 0)
+		goto out;
+
+	__set_bit(role_id, cc->roc_map);
+out:
+	return ret;
+}
+
+int cc33xx_croc(struct cc33xx *cc, u8 role_id)
+{
+	int ret = 0;
+
+	if (WARN_ON(!test_bit(role_id, cc->roc_map)))
+		return 0;
+
+	ret = cc33xx_cmd_croc(cc, role_id);
+	if (ret < 0)
+		goto out;
+
+	__clear_bit(role_id, cc->roc_map);
+
+	/* Rearm the tx watchdog when removing the last ROC. This prevents
+	 * recoveries due to just finished ROCs - when Tx hasn't yet had
+	 * a chance to get out.
+	 */
+	if (find_first_bit(cc->roc_map, CC33XX_MAX_ROLES) >= CC33XX_MAX_ROLES)
+		cc33xx_rearm_tx_watchdog_locked(cc);
+out:
+	return ret;
+}
+
+int cc33xx_cmd_stop_channel_switch(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	struct cc33xx_cmd_stop_channel_switch *cmd;
+	int ret;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->role_id = wlvif->role_id;
+
+	ret = cc33xx_cmd_send(cc, CMD_STOP_CHANNEL_SWITCH,
+			      cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to stop channel switch command");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+/* start dev role and roc on its channel */
+int cc33xx_start_dev(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+		     enum nl80211_band band, int channel)
+{
+	int ret;
+
+	if (WARN_ON(!(wlvif->bss_type == BSS_TYPE_STA_BSS ||
+		      wlvif->bss_type == BSS_TYPE_IBSS)))
+		return -EINVAL;
+
+	/* the dev role is already started for p2p mgmt interfaces */
+
+	if (!cc33xx_is_p2p_mgmt(wlvif)) {
+		ret = cc33xx_cmd_role_enable(cc,
+					     cc33xx_wlvif_to_vif(wlvif)->addr,
+					     CC33XX_ROLE_DEVICE,
+					     &wlvif->dev_role_id);
+		if (ret < 0)
+			goto out;
+	}
+
+	ret = cc33xx_cmd_role_start_dev(cc, wlvif, band, channel);
+	if (ret < 0)
+		goto out_disable;
+
+	ret = cc33xx_roc(cc, wlvif, wlvif->dev_role_id, band, channel);
+	if (ret < 0)
+		goto out_stop;
+
+	return 0;
+
+out_stop:
+	cc333xx_cmd_role_stop_dev(cc, wlvif);
+out_disable:
+	if (!cc33xx_is_p2p_mgmt(wlvif))
+		cc33xx_cmd_role_disable(cc, &wlvif->dev_role_id);
+out:
+	return ret;
+}
+
+/* croc dev hlid, and stop the role */
+int cc33xx_stop_dev(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	int ret;
+
+	if (WARN_ON(!(wlvif->bss_type == BSS_TYPE_STA_BSS ||
+		      wlvif->bss_type == BSS_TYPE_IBSS)))
+		return -EINVAL;
+
+	/* flush all pending packets */
+	ret = cc33xx_tx_work_locked(cc);
+	if (ret < 0)
+		goto out;
+
+	if (test_bit(wlvif->dev_role_id, cc->roc_map)) {
+		ret = cc33xx_croc(cc, wlvif->dev_role_id);
+		if (ret < 0)
+			goto out;
+	}
+
+	ret = cc333xx_cmd_role_stop_dev(cc, wlvif);
+	if (ret < 0)
+		goto out;
+
+	if (!cc33xx_is_p2p_mgmt(wlvif)) {
+		ret = cc33xx_cmd_role_disable(cc, &wlvif->dev_role_id);
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	return ret;
+}
+
+int cc33xx_cmd_generic_cfg(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			   u8 feature, u8 enable, u8 value)
+{
+	struct cc33xx_cmd_generic_cfg *cmd;
+	int ret;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->role_id = wlvif->role_id;
+	cmd->feature = feature;
+	cmd->enable = enable;
+	cmd->value = value;
+
+	ret = cc33xx_cmd_send(cc, CMD_GENERIC_CFG, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to send generic cfg command");
+		goto out_free;
+	}
+out_free:
+	kfree(cmd);
+	return ret;
+}
+
+int cmd_channel_switch(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+		       struct ieee80211_channel_switch *ch_switch)
+{
+	struct cmd_channel_switch *cmd;
+	u32 supported_rates;
+	int ret;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->role_id = wlvif->role_id;
+	cmd->channel = ch_switch->chandef.chan->hw_value;
+	cmd->switch_time = ch_switch->count;
+	cmd->stop_tx = ch_switch->block_tx;
+
+	switch (ch_switch->chandef.chan->band) {
+	case NL80211_BAND_2GHZ:
+		cmd->band = CC33XX_BAND_2_4GHZ;
+		break;
+	case NL80211_BAND_5GHZ:
+		cmd->band = CC33XX_BAND_5GHZ;
+		break;
+	default:
+		cc33xx_error("invalid channel switch band: %d",
+			     ch_switch->chandef.chan->band);
+		ret = -EINVAL;
+		goto out_free;
+	}
+
+	supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES;
+	supported_rates |= wlvif->rate_set;
+	if (wlvif->p2p)
+		supported_rates &= ~CONF_TX_CCK_RATES;
+	cmd->local_supported_rates = cpu_to_le32(supported_rates);
+	cmd->channel_type = wlvif->channel_type;
+
+	ret = cc33xx_cmd_send(cc, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to send channel switch command");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+out:
+	return ret;
+}
+
+int cmd_dfs_master_restart(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	struct cmd_dfs_master_restart *cmd;
+	int ret = 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->role_id = wlvif->role_id;
+
+	ret = cc33xx_cmd_send(cc, CMD_DFS_MASTER_RESTART,
+			      cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to send dfs master restart command");
+		goto out_free;
+	}
+out_free:
+	kfree(cmd);
+	return ret;
+}
+
+int cmd_set_cac(struct cc33xx *cc, struct cc33xx_vif *wlvif, bool start)
+{
+	struct cmd_cac_start *cmd;
+	int ret = 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->role_id = wlvif->role_id;
+	cmd->channel = wlvif->channel;
+	if (wlvif->band == NL80211_BAND_5GHZ)
+		cmd->band = CC33XX_BAND_5GHZ;
+	cmd->bandwidth = cc33xx_get_native_channel_type(wlvif->channel_type);
+
+	ret = cc33xx_cmd_send(cc, start ? CMD_CAC_START : CMD_CAC_STOP,
+			      cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to send cac command");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+	return ret;
+}
+
+int cmd_set_bd_addr(struct cc33xx *cc, u8 *bd_addr)
+{
+	struct cmd_set_bd_addr *cmd;
+	int ret = 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(cmd->bd_addr, bd_addr, sizeof(cmd->bd_addr));
+
+	ret = cc33xx_cmd_send(cc, CMD_SET_BD_ADDR, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to set BD address");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+out:
+	return ret;
+}
+
+int cmd_get_device_info(struct cc33xx *cc, u8 *info_buffer, size_t buffer_len)
+{
+	struct cc33xx_cmd_get_device_info *cmd;
+	int ret = 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	ret = cc33xx_cmd_send(cc, CMD_BM_READ_DEVICE_INFO, cmd,
+			      sizeof(*cmd), sizeof(*cmd));
+	if (ret < 0) {
+		cc33xx_error("Device info command failure ");
+	} else {
+		WARN_ON(buffer_len > sizeof(cmd->device_info));
+		memcpy(info_buffer, cmd->device_info, buffer_len);
+	}
+
+	kfree(cmd);
+
+	return ret;
+}
+
+int cmd_download_container_chunk(struct cc33xx *cc, u8 *chunk,
+				 size_t chunk_len, bool is_last_chunk)
+{
+	struct cc33xx_cmd_container_download *cmd;
+	const size_t command_size = sizeof(*cmd) + chunk_len;
+	int ret;
+	bool  is_sync_transfer = !is_last_chunk;
+
+	cmd = kzalloc(command_size, GFP_KERNEL);
+
+	if (!cmd) {
+		cc33xx_error("Chunk buffer allocation failure");
+		return -ENOMEM;
+	}
+
+	memcpy(cmd->payload, chunk, chunk_len);
+	cmd->length = cpu_to_le32(chunk_len);
+
+	if (is_last_chunk) {
+		cc33xx_debug(DEBUG_BOOT, "Suspending IRQ while device reboots");
+		cc33xx_disable_interrupts_nosync(cc);
+	}
+
+	ret = __cc33xx_cmd_send(cc, CMD_CONTAINER_DOWNLOAD, cmd,
+				command_size, sizeof(u32), is_sync_transfer);
+
+	kfree(cmd);
+
+	if (is_last_chunk) {
+		msleep(CC33XX_REBOOT_TIMEOUT_MSEC);
+		cc33xx_enable_interrupts(cc);
+	}
+
+	return ret;
+}
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/cmd.h b/drivers/net/wireless/ti/cc33xx/cmd.h
--- a/drivers/net/wireless/ti/cc33xx/cmd.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/cmd.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,700 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __CMD_H__
+#define __CMD_H__
+
+#include "cc33xx.h"
+
+struct acx_header;
+
+enum buffer_size {
+	INI_MAX_BUFFER_SIZE,
+	CMD_MAX_BUFFER_SIZE
+};
+
+int cc33xx_set_max_buffer_size(struct cc33xx *cc, enum buffer_size max_buffer_size);
+int cc33xx_cmd_send(struct cc33xx *cc, u16 id, void *buf,
+		    size_t len, size_t res_len);
+int cc33xx_cmd_role_enable(struct cc33xx *cc, u8 *addr,
+			   u8 role_type, u8 *role_id);
+int cc33xx_cmd_role_disable(struct cc33xx *cc, u8 *role_id);
+int cc33xx_cmd_role_start_sta(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+int cc33xx_cmd_role_stop_sta(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+int cc33xx_cmd_role_start_ap(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+int cc33xx_cmd_role_stop_ap(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+int cc33xx_cmd_role_start_ibss(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+int cc33xx_start_dev(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+		     enum nl80211_band band, int channel);
+int cc33xx_stop_dev(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+int cc33xx_cmd_test(struct cc33xx *cc, void *buf, size_t buf_len, u8 answer);
+int cc33xx_cmd_interrogate(struct cc33xx *cc, u16 id, void *buf,
+			   size_t cmd_len, size_t res_len);
+int cc33xx_cmd_debug_inter(struct cc33xx *cc, u16 id, void *buf,
+			   size_t cmd_len, size_t res_len);
+int cc33xx_cmd_configure(struct cc33xx *cc, u16 id, void *buf, size_t len);
+int cc33xx_cmd_debug(struct cc33xx *cc, u16 id, void *buf, size_t len);
+int cc33xx_cmd_configure_failsafe(struct cc33xx *cc, u16 id, void *buf,
+				  size_t len, unsigned long valid_rets);
+int cc33xx_cmd_ps_mode(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+		       u8 ps_mode, u16 auto_ps_timeout);
+int cc33xx_cmd_set_default_wep_key(struct cc33xx *cc, u8 id, u8 hlid);
+int cc33xx_cmd_set_sta_key(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			   u16 action, u8 id, u8 key_type,
+			   u8 key_size, const u8 *key, const u8 *addr,
+			   u32 tx_seq_32, u16 tx_seq_16);
+int cc33xx_cmd_set_ap_key(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			  u16 action, u8 id, u8 key_type, u8 key_size,
+			  const u8 *key, u8 hlid, u32 tx_seq_32, u16 tx_seq_16);
+int cc33xx_cmd_set_peer_state(struct cc33xx *cc,
+			      struct cc33xx_vif *wlvif, u8 hlid);
+int cc33xx_roc(struct cc33xx *cc, struct cc33xx_vif *wlvif, u8 role_id,
+	       enum nl80211_band band, u8 channel);
+int cc33xx_croc(struct cc33xx *cc, u8 role_id);
+int cc33xx_cmd_add_peer(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			struct ieee80211_sta *sta, u8 *hlid, u8 is_connected);
+int cc33xx_cmd_remove_peer(struct cc33xx *cc,
+			   struct cc33xx_vif *wlvif, u8 hlid);
+void cc33xx_set_pending_regdomain_ch(struct cc33xx *cc, u16 channel,
+				     enum nl80211_band band);
+int cc33xx_cmd_regdomain_config_locked(struct cc33xx *cc);
+int cc33xx_cmd_generic_cfg(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			   u8 feature, u8 enable, u8 value);
+int cc33xx_cmd_config_fwlog(struct cc33xx *cc);
+int cc33xx_cmd_stop_channel_switch(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+int cc33xx_set_link(struct cc33xx *cc, struct cc33xx_vif *wlvif, u8 link);
+void cc33xx_clear_link(struct cc33xx *cc, struct cc33xx_vif *wlvif, u8 *hlid);
+int cc33xx_cmd_role_start_transceiver(struct cc33xx *cc, u8 role_id);
+int cc33xx_cmd_role_stop_transceiver(struct cc33xx *cc);
+int cc33xx_cmd_plt_enable(struct cc33xx *cc, u8 role_id);
+int cc33xx_cmd_plt_disable(struct cc33xx *cc);
+int cmd_channel_switch(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+		       struct ieee80211_channel_switch *ch_switch);
+int cmd_dfs_master_restart(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+int cmd_set_cac(struct cc33xx *cc, struct cc33xx_vif *wlvif, bool start);
+int cmd_set_bd_addr(struct cc33xx *cc, u8 *bd_addr);
+int cmd_get_device_info(struct cc33xx *cc, u8 *info_buffer, size_t buffer_len);
+int cmd_download_container_chunk(struct cc33xx *cc, u8 *chunk,
+				 size_t chunk_len, bool is_last_chunk);
+
+enum cc33xx_cmd {
+	CMD_EMPTY,
+	CMD_SET_KEYS = 1,
+	CMD_SET_LINK_CONNECTION_STATE = 2,
+
+	CMD_CHANNEL_SWITCH = 3,
+	CMD_STOP_CHANNEL_SWITCH = 4,
+
+	CMD_REMAIN_ON_CHANNEL = 5,
+	CMD_CANCEL_REMAIN_ON_CHANNEL = 6,
+
+	CMD_START_DHCP_MGMT_SEQ = 7,
+	CMD_STOP_DHCP_MGMT_SEQ = 8,
+
+	CMD_START_SECURITY_MGMT_SEQ = 9,
+	CMD_STOP_SECURITY_MGMT_SEQ = 10,
+
+	CMD_START_ARP_MGMT_SEQ = 11,
+	CMD_STOP_ARP_MGMT_SEQ = 12,
+
+	CMD_START_DNS_MGMT_SEQ = 13,
+	CMD_STOP_DNS_MGMT_SEQ = 14,
+
+	/* Access point commands */
+	CMD_ADD_PEER = 15,
+	CMD_REMOVE_PEER = 16,
+
+	/* Role API */
+	CMD_ROLE_ENABLE = 17,
+	CMD_ROLE_DISABLE = 18,
+	CMD_ROLE_START = 19,
+	CMD_ROLE_STOP = 20,
+
+	CMD_AP_SET_BEACON_INFO = 21, /* Set AP beacon template */
+
+	/* Managed sequence of sending deauth / disassoc frame */
+	CMD_SEND_DEAUTH_DISASSOC = 22,
+
+	CMD_SCHED_STATE_EVENT = 23,
+	CMD_SCAN = 24,
+	CMD_STOP_SCAN = 25,
+	CMD_SET_PROBE_IE = 26,
+
+	CMD_CONFIGURE = 27,
+	CMD_INTERROGATE = 28,
+
+	CMD_DEBUG = 29,
+	CMD_DEBUG_READ = 30,
+
+	CMD_TEST_MODE = 31,
+	CMD_PLT_ENABLE = 32,
+	CMD_PLT_DISABLE = 33,
+	CMD_CONNECTION_SCAN_SSID_CFG = 34,
+	CMD_BM_READ_DEVICE_INFO = 35,
+	CMD_CONTAINER_DOWNLOAD = 36,
+	CMD_DOWNLOAD_INI_PARAMS = 37,
+	CMD_SET_BD_ADDR = 38,
+	CMD_BLE_COMMANDS = 39,
+
+	CMD_LAST_SUPPORTED_COMMAND,
+
+	/* The following commands are legacy and are not yet supported */
+
+	CMD_SET_PS_MODE,
+	CMD_DFS_CHANNEL_CONFIG,
+	CMD_CONFIG_FWLOGGER,
+	CMD_START_FWLOGGER,
+	CMD_STOP_FWLOGGER,
+	CMD_GENERIC_CFG,
+	CMD_DFS_MASTER_RESTART,
+	CMD_CAC_START,
+	CMD_CAC_STOP,
+	CMD_DFS_RADAR_DETECTION_DEBUG,
+
+	MAX_COMMAND_ID_CC33xx = 0x7FFF,
+};
+
+#define MAX_CMD_PARAMS 572
+
+/* unit ms */
+#define CC33XX_COMMAND_TIMEOUT     2000
+#define CC33XX_CMD_TEMPL_MAX_SIZE  512
+#define CC33XX_EVENT_TIMEOUT       5000
+
+struct cc33xx_cmd_header {
+	struct NAB_header NAB_header;
+	__le16 id;
+	__le16 status;
+
+	/* payload */
+	u8 data[];
+} __packed;
+
+#define CC33XX_CMD_MAX_PARAMS 572
+
+struct cc33xx_command {
+	struct cc33xx_cmd_header header;
+	u8  parameters[CC33XX_CMD_MAX_PARAMS];
+} __packed;
+
+enum {
+	CMD_MAILBOX_IDLE		=  0,
+	CMD_STATUS_SUCCESS		=  1,
+	CMD_STATUS_UNKNOWN_CMD		=  2,
+	CMD_STATUS_UNKNOWN_IE		=  3,
+	CMD_STATUS_REJECT_MEAS_SG_ACTIVE	= 11,
+	CMD_STATUS_RX_BUSY		= 13,
+	CMD_STATUS_INVALID_PARAM		= 14,
+	CMD_STATUS_TEMPLATE_TOO_LARGE		= 15,
+	CMD_STATUS_OUT_OF_MEMORY		= 16,
+	CMD_STATUS_STA_TABLE_FULL		= 17,
+	CMD_STATUS_RADIO_ERROR		= 18,
+	CMD_STATUS_WRONG_NESTING		= 19,
+	CMD_STATUS_TIMEOUT		= 21, /* Driver internal use.*/
+	CMD_STATUS_FW_RESET		= 22, /* Driver internal use.*/
+	CMD_STATUS_TEMPLATE_OOM		= 23,
+	CMD_STATUS_NO_RX_BA_SESSION	= 24,
+
+	MAX_COMMAND_STATUS
+};
+
+enum {
+	BSS_TYPE_IBSS = 0,
+	BSS_TYPE_STA_BSS = 2,
+	BSS_TYPE_AP_BSS = 3,
+	MAX_BSS_TYPE = 0xFF
+};
+
+struct cc33xx_cmd_role_enable {
+	struct cc33xx_cmd_header header;
+
+	u8 role_type;
+	u8 mac_address[ETH_ALEN];
+	u8 padding;
+} __packed;
+
+struct command_complete_header {
+	__le16 id;
+	__le16 status;
+
+	/* payload */
+	u8 data[];
+} __packed;
+
+struct cc33xx_cmd_complete_role_enable {
+	struct command_complete_header header;
+	u8 role_id;
+	u8 padding[3];
+} __packed;
+
+struct cc33xx_cmd_role_disable {
+	struct cc33xx_cmd_header header;
+
+	u8 role_id;
+	u8 padding[3];
+} __packed;
+
+enum cc33xx_band {
+	CC33XX_BAND_2_4GHZ		= 0,
+	CC33XX_BAND_5GHZ		= 1,
+	CC33XX_BAND_JAPAN_4_9_GHZ	= 2,
+	CC33XX_BAND_DEFAULT		= CC33XX_BAND_2_4GHZ,
+	CC33XX_BAND_INVALID		= 0x7E,
+	CC33XX_BAND_MAX_RADIO		= 0x7F,
+};
+
+enum cc33xx_channel_type {
+	CC33XX_CHAN_NO_HT,
+	CC33XX_CHAN_HT20,
+	CC33XX_CHAN_HT40MINUS,
+	CC33XX_CHAN_HT40PLUS
+};
+
+struct cc33xx_cmd_role_start {
+	struct cc33xx_cmd_header header;
+	u8 role_id;
+	u8 role_type;
+	u8 band;
+	u8 channel;
+
+	u8 channel_type;
+
+	union {
+		struct {
+			u8 padding_1[54];
+		} __packed device;
+		/* sta & p2p_cli use the same struct */
+		struct {
+			u8 bssid[ETH_ALEN];
+
+			__le32 remote_rates; /* remote supported rates */
+
+			/* The target uses this field to determine the rate at
+			 * which to transmit control frame responses (such as
+			 * ACK or CTS frames).
+			 */
+			__le32 basic_rate_set;
+			__le32 local_rates; /* local supported rates */
+
+			u8 ssid_type;
+			u8 ssid_len;
+			u8 ssid[IEEE80211_MAX_SSID_LEN];
+
+			__le16 beacon_interval; /* in TBTTs */
+		} __packed sta;
+		struct {
+			u8 bssid[ETH_ALEN];
+			u8 hlid; /* data hlid */
+			u8 dtim_interval;
+			__le32 remote_rates; /* remote supported rates */
+
+			__le32 basic_rate_set;
+			__le32 local_rates; /* local supported rates */
+
+			u8 ssid_type;
+			u8 ssid_len;
+			u8 ssid[IEEE80211_MAX_SSID_LEN];
+
+			__le16 beacon_interval; /* in TBTTs */
+
+			u8 padding_1[2];
+		} __packed ibss;
+		/* ap & p2p_go use the same struct */
+		struct {
+			__le16 beacon_interval; /* in TBTTs */
+
+			__le32 basic_rate_set;
+			__le32 local_rates; /* local supported rates */
+
+			u8 dtim_interval;
+			/* ap supports wmm (note that there is additional
+			 * per-sta wmm configuration)
+			 */
+			u8 wmm;
+			u8 padding_1[42];
+		} __packed ap;
+	};
+	u8 padding;
+} __packed;
+
+struct cc33xx_cmd_complete_role_start {
+	struct command_complete_header header;
+	union {
+		struct {
+			u8 hlid;
+			u8 session;
+			u8 padding[2];
+		} __packed sta;
+		struct {
+			/* The host link id for the AP's global queue */
+			u8 global_hlid;
+			/* The host link id for the AP's broadcast queue */
+			u8 broadcast_hlid;
+			u8 bcast_session_id;
+			u8 global_session_id;
+		} __packed ap;
+	};
+} __packed;
+
+struct cc33xx_cmd_role_stop {
+	struct cc33xx_cmd_header header;
+
+	u8 role_id;
+	u8 padding[3];
+} __packed;
+
+struct cmd_enabledisable_path {
+	struct cc33xx_cmd_header header;
+
+	u8 channel;
+	u8 padding[3];
+} __packed;
+
+enum cc33xx_cmd_ps_mode_e {
+	STATION_AUTO_PS_MODE,   /* Dynamic Power Save */
+	STATION_ACTIVE_MODE,
+	STATION_POWER_SAVE_MODE
+};
+
+struct cc33xx_cmd_ps_params {
+	struct cc33xx_cmd_header header;
+
+	u8 role_id;
+	u8 ps_mode; /* STATION_* */
+	__le16 auto_ps_timeout;
+} __packed;
+
+/* HW encryption keys */
+#define NUM_ACCESS_CATEGORIES_COPY 4
+
+enum cc33xx_cmd_key_action {
+	KEY_ADD_OR_REPLACE = 1,
+	KEY_REMOVE         = 2,
+	KEY_SET_ID         = 3,
+	MAX_KEY_ACTION     = 0xffff,
+};
+
+enum cc33xx_cmd_lid_key_type {
+	UNICAST_LID_TYPE     = 0,
+	BROADCAST_LID_TYPE   = 1,
+	WEP_DEFAULT_LID_TYPE = 2
+};
+
+enum cc33xx_cmd_key_type {
+	KEY_NONE = 0,
+	KEY_WEP  = 1,
+	KEY_TKIP = 2,
+	KEY_AES  = 3, /* aes_ccmp_128 */
+	KEY_GEM  = 4,
+	KEY_IGTK = 5, /* bip_cmac_128 */
+	KEY_CMAC_256 = 6,
+	KEY_GMAC_128 = 7,
+	KEY_GMAC_256 = 8,
+	KEY_GCMP_256 = 9,
+	KEY_CCMP256 = 10,
+	KEY_GCMP128 = 11,
+};
+
+struct cc33xx_cmd_set_keys {
+	struct cc33xx_cmd_header header;
+
+	/* Indicates whether the HLID is a unicast key set
+	 * or broadcast key set. A special value 0xFF is
+	 * used to indicate that the HLID is on WEP-default
+	 * (multi-hlids). of type cc33xx_cmd_lid_key_type.
+	 */
+	u8 hlid;
+
+	/* In WEP-default network (hlid == 0xFF) used to
+	 * indicate which network STA/IBSS/AP role should be
+	 * changed
+	 */
+	u8 lid_key_type;
+
+	/* Key ID - For TKIP and AES key types, this field
+	 * indicates the value that should be inserted into
+	 * the KeyID field of frames transmitted using this
+	 * key entry. For broadcast keys the index use as a
+	 * marker for TX/RX key.
+	 * For WEP default network (HLID=0xFF), this field
+	 * indicates the ID of the key to add or remove.
+	 */
+	u8 key_id;
+	u8 reserved_1;
+
+	/* key_action_e */
+	__le16 key_action;
+
+	/* key size in bytes */
+	u8 key_size;
+
+	/* key_type_e */
+	u8 key_type;
+
+	/* This field holds the security key data to add to the STA table */
+	u8 key[MAX_KEY_SIZE];
+	__le16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
+	__le32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
+} __packed;
+
+struct cc33xx_cmd_test_header {
+	u8 id;
+	u8 padding[3];
+} __packed;
+
+#define CC33XX_CMD_STA_STATE_CONNECTED  1
+
+struct cc33xx_cmd_set_peer_state {
+	struct cc33xx_cmd_header header;
+
+	u8 hlid;
+	u8 state;
+	u8 padding[2];
+} __packed;
+
+struct cc33xx_cmd_roc {
+	struct cc33xx_cmd_header header;
+
+	u8 role_id;
+	u8 channel;
+	u8 band;
+	u8 padding;
+};
+
+struct cc33xx_cmd_croc {
+	struct cc33xx_cmd_header header;
+
+	u8 role_id;
+	u8 padding[3];
+};
+
+enum cc33xx_ssid_type {
+	CC33XX_SSID_TYPE_PUBLIC = 0,
+	CC33XX_SSID_TYPE_HIDDEN = 1,
+	CC33XX_SSID_TYPE_ANY = 2,
+};
+
+enum CC33XX_psd_type {
+	CC33XX_PSD_LEGACY = 0,
+	CC33XX_PSD_UPSD_TRIGGER = 1,
+	CC33XX_PSD_LEGACY_PSPOLL = 2,
+	CC33XX_PSD_SAPSD = 3
+};
+
+#define MAX_SIZE_BEACON_TEMP    (450)
+struct cc33xx_cmd_set_beacon_info {
+	struct cc33xx_cmd_header header;
+
+	u8 role_id;
+	__le16 beacon_len;
+	u8 beacon[MAX_SIZE_BEACON_TEMP];
+	u8 padding[3];
+} __packed;
+
+struct cc33xx_cmd_add_peer {
+	struct cc33xx_cmd_header header;
+
+	u8 is_connected;
+	u8 role_id;
+	u8 role_type;
+	u8 link_type;
+	u8 addr[ETH_ALEN];
+	__le16 aid;
+	u8 psd_type[NUM_ACCESS_CATEGORIES_COPY];
+	__le32 supported_rates;
+	u8 bss_index;
+	u8 sp_len;
+	u8 wmm;
+	__le32 ht_capabilities;
+	u8  ampdu_params;
+
+	/* HE peer support */
+	bool has_he;
+	bool mfp;
+	u8 padding[2];
+} __packed;
+
+struct cc33xx_cmd_complete_add_peer {
+	struct command_complete_header header;
+	u8 hlid;
+	u8 session_id;
+} __packed;
+
+struct cc33xx_cmd_remove_peer {
+	struct cc33xx_cmd_header header;
+	u8 hlid;
+	u8 role_id;
+	u8 padding[2];
+} __packed;
+
+/* Continuous mode - packets are transferred to the host periodically
+ * via the data path.
+ * On demand - Log messages are stored in a cyclic buffer in the
+ * firmware, and only transferred to the host when explicitly requested
+ */
+enum cc33xx_fwlogger_log_mode {
+	CC33XX_FWLOG_CONTINUOUS,
+};
+
+/* Include/exclude timestamps from the log messages */
+enum cc33xx_fwlogger_timestamp {
+	CC33XX_FWLOG_TIMESTAMP_DISABLED,
+	CC33XX_FWLOG_TIMESTAMP_ENABLED
+};
+
+/* Logs can be routed to the debug pinouts (where available), to the host bus
+ * (SDIO/SPI), or dropped
+ */
+enum cc33xx_fwlogger_output {
+	CC33XX_FWLOG_OUTPUT_NONE,
+	CC33XX_FWLOG_OUTPUT_DBG_PINS,
+	CC33XX_FWLOG_OUTPUT_HOST,
+};
+
+struct cc33xx_cmd_regdomain_dfs_config {
+	struct cc33xx_cmd_header header;
+
+	__le32 ch_bit_map1;
+	__le32 ch_bit_map2;
+	u8 dfs_region;
+	u8 padding[3];
+} __packed;
+
+enum cc33xx_generic_cfg_feature {
+	CC33XX_CFG_FEATURE_RADAR_DEBUG = 2,
+};
+
+struct cc33xx_cmd_generic_cfg {
+	struct cc33xx_cmd_header header;
+
+	u8 role_id;
+	u8 feature;
+	u8 enable;
+	u8 value;
+} __packed;
+
+struct cc33xx_cmd_config_fwlog {
+	struct cc33xx_cmd_header header;
+
+	/* See enum cc33xx_fwlogger_log_mode */
+	u8 logger_mode;
+
+	/* Minimum log level threshold */
+	u8 log_severity;
+
+	/* Include/exclude timestamps from the log messages */
+	u8 timestamp;
+
+	/* See enum cc33xx_fwlogger_output */
+	u8 output;
+
+	/* Regulates the frequency of log messages */
+	u8 threshold;
+
+	u8 padding[3];
+} __packed;
+
+struct cc33xx_cmd_stop_channel_switch {
+	struct cc33xx_cmd_header header;
+
+	u8 role_id;
+	u8 padding[3];
+} __packed;
+
+/* Used to check radio status after calibration */
+#define MAX_TLV_LENGTH		500
+#define TEST_CMD_P2G_CAL	2	/* TX BiP */
+
+struct cc33xx_cmd_cal_p2g {
+	struct cc33xx_cmd_header header;
+
+	struct cc33xx_cmd_test_header test;
+
+	__le32 ver;
+	__le16 len;
+	u8 buf[MAX_TLV_LENGTH];
+	u8 type;
+	u8 padding;
+
+	__le16 radio_status;
+
+	u8 sub_band_mask;
+	u8 padding2;
+} __packed;
+
+struct cmd_channel_switch {
+	struct cc33xx_cmd_header header;
+
+	u8 role_id;
+
+	/* The new serving channel */
+	u8 channel;
+	/* Relative time of the serving channel switch in TBTT units */
+	u8 switch_time;
+	/* Stop the role TX, should expect it after radar detection */
+	u8 stop_tx;
+
+	__le32 local_supported_rates;
+
+	u8 channel_type;
+	u8 band;
+
+	u8 padding[2];
+} __packed;
+
+struct cmd_set_bd_addr {
+	struct cc33xx_cmd_header header;
+
+	u8 bd_addr[ETH_ALEN];
+	u8 padding[2];
+} __packed;
+
+struct cmd_dfs_master_restart {
+	struct cc33xx_cmd_header header;
+
+	u8 role_id;
+	u8 padding[3];
+} __packed;
+
+/* cac_start and cac_stop share the same params */
+struct cmd_cac_start {
+	struct cc33xx_cmd_header header;
+
+	u8 role_id;
+	u8 channel;
+	u8 band;
+	u8 bandwidth;
+} __packed;
+
+/* PLT structs */
+
+struct cc33xx_cmd_PLT_enable {
+	struct cc33xx_cmd_header header;
+	__le32 dummy;
+};
+
+struct cc33xx_cmd_PLT_disable {
+	struct cc33xx_cmd_header header;
+	__le32 dummy;
+};
+
+struct cc33xx_cmd_ini_params_download {
+	struct cc33xx_cmd_header header;
+	__le32 length;
+	u8 payload[];
+} __packed;
+
+struct cc33xx_cmd_container_download {
+	struct cc33xx_cmd_header header;
+	__le32 length;
+	u8 payload[];
+} __packed;
+
+struct cc33xx_cmd_get_device_info {
+	struct cc33xx_cmd_header header;
+	u8 device_info[700];
+} __packed;
+
+#endif /* __CC33XX_CMD_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/conf.h b/drivers/net/wireless/ti/cc33xx/conf.h
--- a/drivers/net/wireless/ti/cc33xx/conf.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/conf.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,1246 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __CONF_H__
+#define __CONF_H__
+
+struct cc33xx_conf_header {
+	__le32 magic;
+	__le32 version;
+	__le32 checksum;
+} __packed;
+
+#define CC33XX_CONF_MAGIC	0x10e100ca
+#define CC33XX_CONF_VERSION	0x01070069
+#define CC33XX_CONF_MASK	0x0000ffff
+#define CC33X_CONF_SIZE	(sizeof(struct cc33xx_conf_file))
+
+enum {
+	CONF_HW_BIT_RATE_1MBPS   = BIT(1),
+	CONF_HW_BIT_RATE_2MBPS   = BIT(2),
+	CONF_HW_BIT_RATE_5_5MBPS = BIT(3),
+	CONF_HW_BIT_RATE_11MBPS  = BIT(4),
+	CONF_HW_BIT_RATE_6MBPS   = BIT(5),
+	CONF_HW_BIT_RATE_9MBPS   = BIT(6),
+	CONF_HW_BIT_RATE_12MBPS  = BIT(7),
+	CONF_HW_BIT_RATE_18MBPS  = BIT(8),
+	CONF_HW_BIT_RATE_24MBPS  = BIT(9),
+	CONF_HW_BIT_RATE_36MBPS  = BIT(10),
+	CONF_HW_BIT_RATE_48MBPS  = BIT(11),
+	CONF_HW_BIT_RATE_54MBPS  = BIT(12),
+	CONF_HW_BIT_RATE_MCS_0   = BIT(13),
+	CONF_HW_BIT_RATE_MCS_1   = BIT(14),
+	CONF_HW_BIT_RATE_MCS_2   = BIT(15),
+	CONF_HW_BIT_RATE_MCS_3   = BIT(16),
+	CONF_HW_BIT_RATE_MCS_4   = BIT(17),
+	CONF_HW_BIT_RATE_MCS_5   = BIT(18),
+	CONF_HW_BIT_RATE_MCS_6   = BIT(19),
+	CONF_HW_BIT_RATE_MCS_7   = BIT(20)
+};
+
+enum {
+	CONF_HW_RATE_INDEX_1MBPS      = 1,
+	CONF_HW_RATE_INDEX_2MBPS      = 2,
+	CONF_HW_RATE_INDEX_5_5MBPS    = 3,
+	CONF_HW_RATE_INDEX_11MBPS     = 4,
+	CONF_HW_RATE_INDEX_6MBPS      = 5,
+	CONF_HW_RATE_INDEX_9MBPS      = 6,
+	CONF_HW_RATE_INDEX_12MBPS     = 7,
+	CONF_HW_RATE_INDEX_18MBPS     = 8,
+	CONF_HW_RATE_INDEX_24MBPS     = 9,
+	CONF_HW_RATE_INDEX_36MBPS     = 10,
+	CONF_HW_RATE_INDEX_48MBPS     = 11,
+	CONF_HW_RATE_INDEX_54MBPS     = 12,
+	CONF_HW_RATE_INDEX_MCS0       = 13,
+	CONF_HW_RATE_INDEX_MCS1       = 14,
+	CONF_HW_RATE_INDEX_MCS2       = 15,
+	CONF_HW_RATE_INDEX_MCS3       = 16,
+	CONF_HW_RATE_INDEX_MCS4       = 17,
+	CONF_HW_RATE_INDEX_MCS5       = 18,
+	CONF_HW_RATE_INDEX_MCS6       = 19,
+	CONF_HW_RATE_INDEX_MCS7       = 20,
+
+	CONF_HW_RATE_INDEX_MAX        = CONF_HW_RATE_INDEX_MCS7,
+};
+
+enum {
+	CONF_PREAMBLE_TYPE_SHORT	= 0,
+	CONF_PREAMBLE_TYPE_LONG		= 1,
+	CONF_PREAMBLE_TYPE_OFDM		= 2,
+	CONF_PREAMBLE_TYPE_N_MIXED_MODE	= 3,
+	CONF_PREAMBLE_TYPE_GREENFIELD	= 4,
+	CONF_PREAMBLE_TYPE_AX_SU	= 5,
+	CONF_PREAMBLE_TYPE_AX_MU	= 6,
+	CONF_PREAMBLE_TYPE_AX_SU_ER	= 7,
+	CONF_PREAMBLE_TYPE_AX_TB	= 8,
+	CONF_PREAMBLE_TYPE_AX_TB_NDP_FB	= 9,
+	CONF_PREAMBLE_TYPE_AC_VHT	= 10,
+	CONF_PREAMBLE_TYPE_BE_EHT_MU	= 13,
+	CONF_PREAMBLE_TYPE_BE_EHT_TB	= 14,
+	CONF_PREAMBLE_TYPE_INVALID	= 0xFF
+};
+
+#define CONF_HW_RXTX_RATE_UNSUPPORTED 0xff
+
+enum conf_rx_queue_type {
+	CONF_RX_QUEUE_TYPE_LOW_PRIORITY,  /* All except the high priority */
+	CONF_RX_QUEUE_TYPE_HIGH_PRIORITY, /* Management and voice packets */
+};
+
+struct cc33xx_clk_cfg {
+	u32 n;
+	u32 m;
+	u32 p;
+	u32 q;
+	u8 swallow;
+};
+
+struct conf_rx_settings {
+	/* The maximum amount of time, in TU, before the
+	 * firmware discards the MSDU.
+	 *
+	 * Range: 0 - 0xFFFFFFFF
+	 */
+	u32 rx_msdu_life_time;
+
+	/* Packet detection threshold in the PHY.
+	 *
+	 * FIXME: details unknown.
+	 */
+	u32 packet_detection_threshold;
+
+	/* The longest time the STA will wait to receive traffic from the AP
+	 * after a PS-poll has been transmitted.
+	 *
+	 * Range: 0 - 200000
+	 */
+	u16 ps_poll_timeout;
+	/* The longest time the STA will wait to receive traffic from the AP
+	 * after a frame has been sent from an UPSD enabled queue.
+	 *
+	 * Range: 0 - 200000
+	 */
+	u16 upsd_timeout;
+
+	/* The number of octets in an MPDU, below which an RTS/CTS
+	 * handshake is not performed.
+	 *
+	 * Range: 0 - 4096
+	 */
+	u16 rts_threshold;
+
+	/* The RX Clear Channel Assessment threshold in the PHY
+	 * (the energy threshold).
+	 *
+	 * Range: ENABLE_ENERGY_D  == 0x140A
+	 *        DISABLE_ENERGY_D == 0xFFEF
+	 */
+	u16 rx_cca_threshold;
+
+	/* Occupied Rx mem-blocks number which requires interrupting the host
+	 * (0 = no buffering, 0xffff = disabled).
+	 *
+	 * Range: uint16_t
+	 */
+	u16 irq_blk_threshold;
+
+	/* Rx packets number which requires interrupting the host
+	 * (0 = no buffering).
+	 *
+	 * Range: uint16_t
+	 */
+	u16 irq_pkt_threshold;
+
+	/* Max time in msec the FW may delay RX-Complete interrupt.
+	 *
+	 * Range: 1 - 100
+	 */
+	u16 irq_timeout;
+
+	/* The RX queue type.
+	 *
+	 * Range: RX_QUEUE_TYPE_RX_LOW_PRIORITY, RX_QUEUE_TYPE_RX_HIGH_PRIORITY,
+	 */
+	u8 queue_type;
+} __packed;
+
+#define CONF_TX_MAX_RATE_CLASSES       10
+
+#define CONF_TX_RATE_MASK_UNSPECIFIED  0
+#define CONF_TX_RATE_MASK_BASIC        (CONF_HW_BIT_RATE_1MBPS | \
+					CONF_HW_BIT_RATE_2MBPS)
+#define CONF_TX_RATE_RETRY_LIMIT       10
+
+/* basic rates for p2p operations (probe req/resp, etc.) */
+#define CONF_TX_RATE_MASK_BASIC_P2P    CONF_HW_BIT_RATE_6MBPS
+
+/* Rates supported for data packets when operating as STA/AP. Note the absence
+ * of the 22Mbps rate. There is a FW limitation on 12 rates so we must drop
+ * one. The rate dropped is not mandatory under any operating mode.
+ */
+#define CONF_TX_ENABLED_RATES       (CONF_HW_BIT_RATE_1MBPS |    \
+	CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS |      \
+	CONF_HW_BIT_RATE_6MBPS | CONF_HW_BIT_RATE_9MBPS |        \
+	CONF_HW_BIT_RATE_11MBPS | CONF_HW_BIT_RATE_12MBPS |      \
+	CONF_HW_BIT_RATE_18MBPS | CONF_HW_BIT_RATE_24MBPS |      \
+	CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS |      \
+	CONF_HW_BIT_RATE_54MBPS)
+
+#define CONF_TX_CCK_RATES  (CONF_HW_BIT_RATE_1MBPS |		\
+	CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS |	\
+	CONF_HW_BIT_RATE_11MBPS)
+
+#define CONF_TX_OFDM_RATES (CONF_HW_BIT_RATE_6MBPS |             \
+	CONF_HW_BIT_RATE_12MBPS | CONF_HW_BIT_RATE_24MBPS |      \
+	CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS |      \
+	CONF_HW_BIT_RATE_54MBPS)
+
+#define CONF_TX_MCS_RATES (CONF_HW_BIT_RATE_MCS_0 |              \
+	CONF_HW_BIT_RATE_MCS_1 | CONF_HW_BIT_RATE_MCS_2 |        \
+	CONF_HW_BIT_RATE_MCS_3 | CONF_HW_BIT_RATE_MCS_4 |        \
+	CONF_HW_BIT_RATE_MCS_5 | CONF_HW_BIT_RATE_MCS_6 |        \
+	CONF_HW_BIT_RATE_MCS_7)
+
+/* Default rates for management traffic when operating in AP mode. This
+ * should be configured according to the basic rate set of the AP
+ */
+#define CONF_TX_AP_DEFAULT_MGMT_RATES  (CONF_HW_BIT_RATE_1MBPS | \
+	CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS)
+
+/* default rates for working as IBSS (11b and OFDM) */
+#define CONF_TX_IBSS_DEFAULT_RATES  (CONF_HW_BIT_RATE_1MBPS |       \
+		CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
+		CONF_HW_BIT_RATE_11MBPS | CONF_TX_OFDM_RATES)
+
+struct conf_tx_rate_class {
+	/* The rates enabled for this rate class.
+	 *
+	 * Range: CONF_HW_BIT_RATE_* bit mask
+	 */
+	u32 enabled_rates;
+
+	/* The dot11 short retry limit used for TX retries.
+	 *
+	 * Range: uint8_t
+	 */
+	u8 short_retry_limit;
+
+	/* The dot11 long retry limit used for TX retries.
+	 *
+	 * Range: uint8_t
+	 */
+	u8 long_retry_limit;
+
+	/* Flags controlling the attributes of TX transmission.
+	 *
+	 * Range: bit 0: Truncate - when set, FW attempts to send a frame stop
+	 *               when the total valid per-rate attempts have
+	 *               been exhausted; otherwise transmissions
+	 *               will continue at the lowest available rate
+	 *               until the appropriate one of the
+	 *               short_retry_limit, long_retry_limit,
+	 *               dot11_max_transmit_msdu_life_time, or
+	 *               max_tx_life_time, is exhausted.
+	 *            1: Preamble Override - indicates if the preamble type
+	 *               should be used in TX.
+	 *            2: Preamble Type - the type of the preamble to be used by
+	 *               the policy (0 - long preamble, 1 - short preamble.
+	 */
+	u8 aflags;
+} __packed;
+
+#define CONF_TX_MAX_AC_COUNT 4
+
+/* Slot number setting to start transmission at PIFS interval */
+#define CONF_TX_AIFS_PIFS 1
+/* Slot number setting to start transmission at DIFS interval normal
+ * DCF access
+ */
+#define CONF_TX_AIFS_DIFS 2
+
+enum conf_tx_ac {
+	CONF_TX_AC_BE = 0,         /* best effort / legacy */
+	CONF_TX_AC_BK = 1,         /* background */
+	CONF_TX_AC_VI = 2,         /* video */
+	CONF_TX_AC_VO = 3,         /* voice */
+	CONF_TX_AC_CTS2SELF = 4,   /* fictitious AC, follows AC_VO */
+	CONF_TX_AC_ANY_TID = 0xff
+};
+
+struct conf_sig_weights {
+	/* RSSI from beacons average weight.
+	 *
+	 * Range: uint8_t
+	 */
+	u8 rssi_bcn_avg_weight;
+
+	/* RSSI from data average weight.
+	 *
+	 * Range: uint8_t
+	 */
+	u8 rssi_pkt_avg_weight;
+
+	/* SNR from beacons average weight.
+	 *
+	 * Range: uint8_t
+	 */
+	u8 snr_bcn_avg_weight;
+
+	/* SNR from data average weight.
+	 *
+	 * Range: uint8_t
+	 */
+	u8 snr_pkt_avg_weight;
+} __packed;
+
+struct conf_tx_ac_category {
+	/* The AC class identifier.
+	 *
+	 * Range: enum conf_tx_ac
+	 */
+	u8 ac;
+
+	/* The contention window minimum size (in slots) for the access
+	 * class.
+	 *
+	 * Range: uint8_t
+	 */
+	u8 cw_min;
+
+	/* The contention window maximum size (in slots) for the access
+	 * class.
+	 *
+	 * Range: uint8_t
+	 */
+	u16 cw_max;
+
+	/* The AIF value (in slots) for the access class.
+	 *
+	 * Range: uint8_t
+	 */
+	u8 aifsn;
+
+	/* The TX Op Limit (in microseconds) for the access class.
+	 *
+	 * Range: uint16_t
+	 */
+	u16 tx_op_limit;
+
+	/* Is the MU EDCA configured
+	 *
+	 * Range: uint8_t
+	 */
+	u8 is_mu_edca;
+
+	/*  The AIFSN value for the corresponding access class
+	 *
+	 * Range: uint8_t
+	 */
+	u8 mu_edca_aifs;
+
+	/* The ECWmin and ECWmax value is indicating contention window maximum
+	 * size (in slots) for the access
+	 *
+	 * Range: uint8_t
+	 */
+	u8 mu_edca_ecw_min_max;
+
+	/* The MU EDCA timer (in microseconds) obtaining an EDCA TXOP
+	 * for STA using MU EDCA parameters
+	 *
+	 * Range: uint8_t
+	 */
+	u8 mu_edca_timer;
+} __packed;
+
+#define CONF_TX_MAX_TID_COUNT 8
+
+/* Allow TX BA on all TIDs but 6,7. These are currently reserved in the FW */
+#define CONF_TX_BA_ENABLED_TID_BITMAP 0x3F
+
+enum {
+	CONF_CHANNEL_TYPE_DCF = 0,   /* DC/LEGACY*/
+	CONF_CHANNEL_TYPE_EDCF = 1,  /* EDCA*/
+	CONF_CHANNEL_TYPE_HCCA = 2,  /* HCCA*/
+};
+
+enum {
+	CONF_PS_SCHEME_LEGACY = 0,
+	CONF_PS_SCHEME_UPSD_TRIGGER = 1,
+	CONF_PS_SCHEME_LEGACY_PSPOLL = 2,
+	CONF_PS_SCHEME_SAPSD = 3,
+};
+
+enum {
+	CONF_ACK_POLICY_LEGACY = 0,
+	CONF_ACK_POLICY_NO_ACK = 1,
+	CONF_ACK_POLICY_BLOCK = 2,
+};
+
+struct conf_tx_tid {
+	u8 queue_id;
+	u8 channel_type;
+	u8 tsid;
+	u8 ps_scheme;
+	u8 ack_policy;
+	u32 apsd_conf[2];
+} __packed;
+
+struct conf_tx_settings {
+	/* The TX ED value for TELEC Enable/Disable.
+	 *
+	 * Range: 0, 1
+	 */
+	u8 tx_energy_detection;
+
+	/* Configuration for rate classes for TX (currently only one
+	 * rate class supported). Used in non-AP mode.
+	 */
+	struct conf_tx_rate_class sta_rc_conf;
+
+	/* Configuration for access categories for TX rate control.
+	 */
+	u8 ac_conf_count;
+	/*struct conf_tx_ac_category ac_conf[CONF_TX_MAX_AC_COUNT];*/
+	struct conf_tx_ac_category ac_conf0;
+	struct conf_tx_ac_category ac_conf1;
+	struct conf_tx_ac_category ac_conf2;
+	struct conf_tx_ac_category ac_conf3;
+
+	/* AP-mode - allow this number of TX retries to a station before an
+	 * event is triggered from FW.
+	 * In AP-mode the hlids of unreachable stations are given in the
+	 * "sta_tx_retry_exceeded" member in the event mailbox.
+	 */
+	u8 max_tx_retries;
+
+	/* AP-mode - after this number of seconds a connected station is
+	 * considered inactive.
+	 */
+	u16 ap_aging_period;
+
+	/* Configuration for TID parameters.
+	 */
+	u8 tid_conf_count;
+	/* struct conf_tx_tid tid_conf[]; */
+	struct conf_tx_tid tid_conf0;
+	struct conf_tx_tid tid_conf1;
+	struct conf_tx_tid tid_conf2;
+	struct conf_tx_tid tid_conf3;
+	struct conf_tx_tid tid_conf4;
+	struct conf_tx_tid tid_conf5;
+	struct conf_tx_tid tid_conf6;
+	struct conf_tx_tid tid_conf7;
+
+	/* The TX fragmentation threshold.
+	 *
+	 * Range: uint16_t
+	 */
+	u16 frag_threshold;
+
+	/* Max time in msec the FW may delay frame TX-Complete interrupt.
+	 *
+	 * Range: uint16_t
+	 */
+	u16 tx_compl_timeout;
+
+	/* Completed TX packet count which requires to issue the TX-Complete
+	 * interrupt.
+	 *
+	 * Range: uint16_t
+	 */
+	u16 tx_compl_threshold;
+
+	/* The rate used for control messages and scanning on the 2.4GHz band
+	 *
+	 * Range: CONF_HW_BIT_RATE_* bit mask
+	 */
+	u32 basic_rate;
+
+	/* The rate used for control messages and scanning on the 5GHz band
+	 *
+	 * Range: CONF_HW_BIT_RATE_* bit mask
+	 */
+	u32 basic_rate_5;
+
+	/* TX retry limits for templates
+	 */
+	u8 tmpl_short_retry_limit;
+	u8 tmpl_long_retry_limit;
+
+	/* Time in ms for Tx watchdog timer to expire */
+	u32 tx_watchdog_timeout;
+
+	/* when a slow link has this much packets pending, it becomes a low
+	 * priority link, scheduling-wise
+	 */
+	u8 slow_link_thold;
+
+	/* when a fast link has this much packets pending, it becomes a low
+	 * priority link, scheduling-wise
+	 */
+	u8 fast_link_thold;
+} __packed;
+
+enum {
+	CONF_WAKE_UP_EVENT_BEACON    = 0x00, /* Wake on every Beacon */
+	CONF_WAKE_UP_EVENT_DTIM      = 0x01, /* Wake on every DTIM */
+	CONF_WAKE_UP_EVENT_N_DTIM    = 0x02, /* Wake every Nth DTIM */
+	CONF_WAKE_UP_EVENT_LIMIT     = CONF_WAKE_UP_EVENT_N_DTIM,
+	/* Not supported: */
+	CONF_WAKE_UP_EVENT_N_BEACONS = 0x03, /* Wake every Nth beacon */
+	CONF_WAKE_UP_EVENT_BITS_MASK = 0x0F
+};
+
+#define CONF_MAX_BCN_FILT_IE_COUNT 32
+
+#define CONF_BCN_RULE_PASS_ON_CHANGE         BIT(0)
+#define CONF_BCN_RULE_PASS_ON_APPEARANCE     BIT(1)
+
+#define CONF_BCN_IE_OUI_LEN    3
+#define CONF_BCN_IE_VER_LEN    2
+
+struct conf_bcn_filt_rule {
+	/* IE number to which to associate a rule.
+	 *
+	 * Range: uint8_t
+	 */
+	u8 ie;
+
+	/* Rule to associate with the specific ie.
+	 *
+	 * Range: CONF_BCN_RULE_PASS_ON_*
+	 */
+	u8 rule;
+
+	/* OUI for the vendor specifie IE (221)
+	 */
+	u8 oui[3];
+
+	/* Type for the vendor specifie IE (221)
+	 */
+	u8 type;
+
+	/* Version for the vendor specifie IE (221)
+	 */
+	u8 version[2];
+} __packed;
+
+enum conf_bcn_filt_mode {
+	CONF_BCN_FILT_MODE_DISABLED = 0,
+	CONF_BCN_FILT_MODE_ENABLED = 1
+};
+
+enum conf_bet_mode {
+	CONF_BET_MODE_DISABLE = 0,
+	CONF_BET_MODE_ENABLE = 1,
+};
+
+struct conf_conn_settings {
+	/* Enable or disable the beacon filtering.
+	 *
+	 * Range: CONF_BCN_FILT_MODE_*
+	 */
+	u8 bcn_filt_mode;
+
+	/* Configure Beacon filter pass-through rules.
+	 */
+	u8 bcn_filt_ie_count;
+	/*struct conf_bcn_filt_rule bcn_filt_ie[CONF_MAX_BCN_FILT_IE_COUNT];*/
+	/* struct conf_bcn_filt_rule bcn_filt_ie[32]; */
+	struct conf_bcn_filt_rule bcn_filt_ie0;
+	struct conf_bcn_filt_rule bcn_filt_ie1;
+	struct conf_bcn_filt_rule bcn_filt_ie2;
+	struct conf_bcn_filt_rule bcn_filt_ie3;
+	struct conf_bcn_filt_rule bcn_filt_ie4;
+	struct conf_bcn_filt_rule bcn_filt_ie5;
+	struct conf_bcn_filt_rule bcn_filt_ie6;
+	struct conf_bcn_filt_rule bcn_filt_ie7;
+	struct conf_bcn_filt_rule bcn_filt_ie8;
+	struct conf_bcn_filt_rule bcn_filt_ie9;
+	struct conf_bcn_filt_rule bcn_filt_ie10;
+	struct conf_bcn_filt_rule bcn_filt_ie11;
+	struct conf_bcn_filt_rule bcn_filt_ie12;
+	struct conf_bcn_filt_rule bcn_filt_ie13;
+	struct conf_bcn_filt_rule bcn_filt_ie14;
+	struct conf_bcn_filt_rule bcn_filt_ie15;
+	struct conf_bcn_filt_rule bcn_filt_ie16;
+	struct conf_bcn_filt_rule bcn_filt_ie17;
+	struct conf_bcn_filt_rule bcn_filt_ie18;
+	struct conf_bcn_filt_rule bcn_filt_ie19;
+	struct conf_bcn_filt_rule bcn_filt_ie20;
+	struct conf_bcn_filt_rule bcn_filt_ie21;
+	struct conf_bcn_filt_rule bcn_filt_ie22;
+	struct conf_bcn_filt_rule bcn_filt_ie23;
+	struct conf_bcn_filt_rule bcn_filt_ie24;
+	struct conf_bcn_filt_rule bcn_filt_ie25;
+	struct conf_bcn_filt_rule bcn_filt_ie26;
+	struct conf_bcn_filt_rule bcn_filt_ie27;
+	struct conf_bcn_filt_rule bcn_filt_ie28;
+	struct conf_bcn_filt_rule bcn_filt_ie29;
+	struct conf_bcn_filt_rule bcn_filt_ie30;
+	struct conf_bcn_filt_rule bcn_filt_ie31;
+
+	/* The number of consecutive beacons to lose, before the firmware
+	 * becomes out of synch.
+	 *
+	 * Range: uint32_t
+	 */
+	u32 synch_fail_thold;
+
+	/* After out-of-synch, the number of TU's to wait without a further
+	 * received beacon (or probe response) before issuing the BSS_EVENT_LOSE
+	 * event.
+	 *
+	 * Range: uint32_t
+	 */
+	u32 bss_lose_timeout;
+
+	/* Beacon receive timeout.
+	 *
+	 * Range: uint32_t
+	 */
+	u32 beacon_rx_timeout;
+
+	/* Broadcast receive timeout.
+	 *
+	 * Range: uint32_t
+	 */
+	u32 broadcast_timeout;
+
+	/* Enable/disable reception of broadcast packets in power save mode
+	 *
+	 * Range: 1 - enable, 0 - disable
+	 */
+	u8 rx_broadcast_in_ps;
+
+	/* Consecutive PS Poll failures before sending event to driver
+	 *
+	 * Range: uint8_t
+	 */
+	u8 ps_poll_threshold;
+
+	/* Configuration of signal average weights.
+	 */
+	struct conf_sig_weights sig_weights;
+
+	/* Specifies if beacon early termination procedure is enabled or
+	 * disabled.
+	 *
+	 * Range: CONF_BET_MODE_*
+	 */
+	u8 bet_enable;
+
+	/* Specifies the maximum number of consecutive beacons that may be
+	 * early terminated. After this number is reached at least one full
+	 * beacon must be correctly received in FW before beacon ET
+	 * resumes.
+	 *
+	 * Range 0 - 255
+	 */
+	u8 bet_max_consecutive;
+
+	/* Specifies the maximum number of times to try PSM entry if it fails
+	 * (if sending the appropriate null-func message fails.)
+	 *
+	 * Range 0 - 255
+	 */
+	u8 psm_entry_retries;
+
+	/* Specifies the maximum number of times to try PSM exit if it fails
+	 * (if sending the appropriate null-func message fails.)
+	 *
+	 * Range 0 - 255
+	 */
+	u8 psm_exit_retries;
+
+	/* Specifies the maximum number of times to try transmit the PSM entry
+	 * null-func frame for each PSM entry attempt
+	 *
+	 * Range 0 - 255
+	 */
+	u8 psm_entry_nullfunc_retries;
+
+	/* Specifies the dynamic PS timeout in ms that will be used
+	 * by the FW when in AUTO_PS mode
+	 */
+	u16 dynamic_ps_timeout;
+
+	/* Specifies whether dynamic PS should be disabled and PSM forced.
+	 * This is required for certain WiFi certification tests.
+	 */
+	u8 forced_ps;
+
+	/* Specifies the interval of the connection keep-alive null-func
+	 * frame in ms.
+	 *
+	 * Range: 1000 - 3600000
+	 */
+	u32 keep_alive_interval;
+
+	/* Maximum listen interval supported by the driver in units of beacons.
+	 *
+	 * Range: uint16_t
+	 */
+	u8 max_listen_interval;
+
+	/* Default sleep authorization for a new STA interface. This determines
+	 * whether we can go to ELP.
+	 */
+	u8 sta_sleep_auth;
+
+	/* Default RX BA Activity filter configuration
+	 */
+	u8 suspend_rx_ba_activity;
+} __packed;
+
+struct conf_itrim_settings {
+	/* enable dco itrim */
+	u8 enable;
+
+	/* moderation timeout in microsecs from the last TX */
+	u32 timeout;
+} __packed;
+
+enum conf_fast_wakeup {
+	CONF_FAST_WAKEUP_ENABLE,
+	CONF_FAST_WAKEUP_DISABLE,
+};
+
+struct conf_pm_config_settings {
+	/* Host clock settling time
+	 *
+	 * Range: 0 - 30000 us
+	 */
+	u32 host_clk_settling_time;
+
+	/* Host fast wakeup support
+	 *
+	 * Range: enum conf_fast_wakeup
+	 */
+	u8 host_fast_wakeup_support;
+} __packed;
+
+struct conf_roam_trigger_settings {
+	/* The minimum interval between two trigger events.
+	 *
+	 * Range: 0 - 60000 ms
+	 */
+	u16 trigger_pacing;
+
+	/* The weight for rssi/beacon average calculation
+	 *
+	 * Range: 0 - 255
+	 */
+	u8 avg_weight_rssi_beacon;
+
+	/* The weight for rssi/data frame average calculation
+	 *
+	 * Range: 0 - 255
+	 */
+	u8 avg_weight_rssi_data;
+
+	/* The weight for snr/beacon average calculation
+	 *
+	 * Range: 0 - 255
+	 */
+	u8 avg_weight_snr_beacon;
+
+	/* The weight for snr/data frame average calculation
+	 *
+	 * Range: 0 - 255
+	 */
+	u8 avg_weight_snr_data;
+} __packed;
+
+struct conf_scan_settings {
+	/* The minimum time to wait on each channel for active scans
+	 * This value will be used whenever there's a connected interface.
+	 *
+	 * Range: uint32_t tu/1000
+	 */
+	u32 min_dwell_time_active;
+
+	/* The maximum time to wait on each channel for active scans
+	 * This value will be currently used whenever there's a
+	 * connected interface. It shouldn't exceed 30000 (~30ms) to avoid
+	 * possible interference of voip traffic going on while scanning.
+	 *
+	 * Range: uint32_t tu/1000
+	 */
+	u32 max_dwell_time_active;
+
+	/* The minimum time to wait on each channel for active scans
+	 * when it's possible to have longer scan dwell times.
+	 * Currently this is used whenever we're idle on all interfaces.
+	 * Longer dwell times improve detection of networks within a
+	 * single scan.
+	 *
+	 * Range: uint32_t tu/1000
+	 */
+	u32 min_dwell_time_active_long;
+
+	/* The maximum time to wait on each channel for active scans
+	 * when it's possible to have longer scan dwell times.
+	 * See min_dwell_time_active_long
+	 *
+	 * Range: uint32_t tu/1000
+	 */
+	u32 max_dwell_time_active_long;
+
+	/* time to wait on the channel for passive scans (in TU/1000) */
+	u32 dwell_time_passive;
+
+	/* time to wait on the channel for DFS scans (in TU/1000) */
+	u32 dwell_time_dfs;
+
+	/* Number of probe requests to transmit on each active scan channel
+	 *
+	 * Range: uint8_t
+	 */
+	u16 num_probe_reqs;
+
+	/* Scan trigger (split scan) timeout. The FW will split the scan
+	 * operation into slices of the given time and allow the FW to schedule
+	 * other tasks in between.
+	 *
+	 * Range: uint32_t Microsecs
+	 */
+	u32 split_scan_timeout;
+} __packed;
+
+struct conf_sched_scan_settings {
+	/* The base time to wait on the channel for active scans (in TU/1000).
+	 * The minimum dwell time is calculated according to this:
+	 * min_dwell_time = base + num_of_probes_to_be_sent * delta_per_probe
+	 * The maximum dwell time is calculated according to this:
+	 * max_dwell_time = min_dwell_time + max_dwell_time_delta
+	 */
+	u32 base_dwell_time;
+
+	/* The delta between the min dwell time and max dwell time for
+	 * active scans (in TU/1000s). The max dwell time is used by the FW once
+	 * traffic is detected on the channel.
+	 */
+	u32 max_dwell_time_delta;
+
+	/* Delta added to min dwell time per each probe in 2.4 GHz (TU/1000) */
+	u32 dwell_time_delta_per_probe;
+
+	/* Delta added to min dwell time per each probe in 5 GHz (TU/1000) */
+	u32 dwell_time_delta_per_probe_5;
+
+	/* time to wait on the channel for passive scans (in TU/1000) */
+	u32 dwell_time_passive;
+
+	/* time to wait on the channel for DFS scans (in TU/1000) */
+	u32 dwell_time_dfs;
+
+	/* number of probe requests to send on each channel in active scans */
+	u8 num_probe_reqs;
+
+	/* RSSI threshold to be used for filtering */
+	s8 rssi_threshold;
+
+	/* SNR threshold to be used for filtering */
+	s8 snr_threshold;
+
+	/* number of short intervals scheduled scan cycles before
+	 * switching to long intervals
+	 */
+	u8 num_short_intervals;
+
+	/* interval between each long scheduled scan cycle (in ms) */
+	u16 long_interval;
+} __packed;
+
+struct conf_ht_setting {
+	u8 rx_ba_win_size;
+	u8 tx_ba_win_size;
+	u16 inactivity_timeout;
+
+	/* bitmap of enabled TIDs for TX BA sessions */
+	u8 tx_ba_tid_bitmap;
+
+	/* DEFAULT / WIDE / SISO20 */
+	u8 mode;
+} __packed;
+
+struct conf_memory_settings {
+	/* Number of stations supported in IBSS mode */
+	u8 num_stations;
+
+	/* Number of ssid profiles used in IBSS mode */
+	u8 ssid_profiles;
+
+	/* Number of memory buffers allocated to rx pool */
+	u8 rx_block_num;
+
+	/* Minimum number of blocks allocated to tx pool */
+	u8 tx_min_block_num;
+
+	/* Disable/Enable dynamic memory */
+	u8 dynamic_memory;
+
+	/* Minimum required free tx memory blocks in order to assure optimum
+	 * performance
+	 *
+	 * Range: 0-120
+	 */
+	u8 min_req_tx_blocks;
+
+	/* Minimum required free rx memory blocks in order to assure optimum
+	 * performance
+	 *
+	 * Range: 0-120
+	 */
+	u8 min_req_rx_blocks;
+
+	/* Minimum number of mem blocks (free+used) guaranteed for TX
+	 *
+	 * Range: 0-120
+	 */
+	u8 tx_min;
+} __packed;
+
+struct conf_rx_streaming_settings {
+	/* RX Streaming duration (in msec) from last tx/rx
+	 *
+	 * Range: uint32_t
+	 */
+	u32 duration;
+
+	/* Bitmap of tids to be polled during RX streaming.
+	 * (Note: it doesn't look like it really matters)
+	 *
+	 * Range: 0x1-0xff
+	 */
+	u8 queues;
+
+	/* RX Streaming interval.
+	 * (Note:this value is also used as the rx streaming timeout)
+	 * Range: 0 (disabled), 10 - 100
+	 */
+	u8 interval;
+
+	/* enable rx streaming also when there is no coex activity
+	 */
+	u8 always;
+} __packed;
+
+struct conf_fwlog {
+	/* Continuous or on-demand */
+	u8 mode;
+
+	/* Number of memory blocks dedicated for the FW logger
+	 *
+	 * Range: 2-16, or 0 to disable the FW logger
+	 */
+	u8 mem_blocks;
+
+	/* Minimum log level threshold */
+	u8 severity;
+
+	/* Include/exclude timestamps from the log messages */
+	u8 timestamp;
+
+	/* See enum cc33xx_fwlogger_output */
+	u8 output;
+
+	/* Regulates the frequency of log messages */
+	u8 threshold;
+} __packed;
+
+#define ACX_RATE_MGMT_NUM_OF_RATES 13
+struct conf_rate_policy_settings {
+	u16 rate_retry_score;
+	u16 per_add;
+	u16 per_th1;
+	u16 per_th2;
+	u16 max_per;
+	u8 inverse_curiosity_factor;
+	u8 tx_fail_low_th;
+	u8 tx_fail_high_th;
+	u8 per_alpha_shift;
+	u8 per_add_shift;
+	u8 per_beta1_shift;
+	u8 per_beta2_shift;
+	u8 rate_check_up;
+	u8 rate_check_down;
+	u8 rate_retry_policy[13];
+} __packed;
+
+struct conf_hangover_settings {
+	u32 recover_time;
+	u8 hangover_period;
+	u8 dynamic_mode;
+	u8 early_termination_mode;
+	u8 max_period;
+	u8 min_period;
+	u8 increase_delta;
+	u8 decrease_delta;
+	u8 quiet_time;
+	u8 increase_time;
+	u8 window_size;
+} __packed;
+
+enum {
+	CLOCK_CONFIG_16_2_M	= 1,
+	CLOCK_CONFIG_16_368_M,
+	CLOCK_CONFIG_16_8_M,
+	CLOCK_CONFIG_19_2_M,
+	CLOCK_CONFIG_26_M,
+	CLOCK_CONFIG_32_736_M,
+	CLOCK_CONFIG_33_6_M,
+	CLOCK_CONFIG_38_468_M,
+	CLOCK_CONFIG_52_M,
+
+	NUM_CLOCK_CONFIGS,
+};
+
+enum cc33xx_ht_mode {
+	/* Default - use MIMO, fallback to SISO20 */
+	HT_MODE_DEFAULT = 0,
+
+	/* Wide - use SISO40 */
+	HT_MODE_WIDE = 1,
+
+	/* Use SISO20 */
+	HT_MODE_SISO20 = 2,
+};
+
+struct conf_ap_sleep_settings {
+	/* Duty Cycle (20-80% of staying Awake) for IDLE AP
+	 * (0: disable)
+	 */
+	u8 idle_duty_cycle;
+	/* Duty Cycle (20-80% of staying Awake) for Connected AP
+	 * (0: disable)
+	 */
+	u8 connected_duty_cycle;
+	/* Maximum stations that are allowed to be connected to AP
+	 *  (255: no limit)
+	 */
+	u8 max_stations_thresh;
+	/* Timeout till enabling the Sleep Mechanism after data stops
+	 * [unit: 100 msec]
+	 */
+	u8 idle_conn_thresh;
+} __packed;
+
+#define CHANNELS_COUNT 39 /* 14 2.4GHz channels, 25 5GHz channels*/
+#define PER_CHANNEL_REG_RULE_BYTES 13
+#define REG_RULES_COUNT (CHANNELS_COUNT * PER_CHANNEL_REG_RULE_BYTES) /* 507 */
+
+/* TX Power limitation for a channel, used for reg domain */
+struct conf_channel_power_limit {
+	u32 reg_lim_0;
+	u32 reg_lim_1;
+	u32 reg_lim_2;
+	u8  reg_lim_3;
+} __packed;
+
+struct conf_coex_configuration {
+	/* Work without Coex HW
+	 *
+	 * Range: 1 - YES, 0 - NO
+	 */
+	u8 disable_coex;
+	/* Yes/No Choose if External SoC entity is connected
+	 *
+	 * Range: 1 - YES, 0 - NO
+	 */
+	u8 is_ext_soc_enable;
+	/* External SoC grant polarity
+	 *
+	 * 0 - Active Low
+	 *
+	 * 1 - Active High (Default)
+	 */
+	u8 ext_soc_grant_polarity;
+	/* External SoC priority polarity
+	 *
+	 * 0 - Active Low (Default)
+	 *
+	 * 1 - Active High
+	 */
+	u8 ext_soc_priority_polarity;
+	/* External SoC request polarity
+	 *
+	 * 0 - Active Low (Default)
+	 *
+	 * 1 - Active High
+	 */
+	u8 ext_soc_request_polarity;
+	u16 ext_soc_min_grant_time;
+	u16 ext_soc_max_grant_time;
+	/* Range: 0 - 20 us
+	 */
+	u8 ext_soc_t2_time;
+
+	u8 ext_soc_to_wifi_grant_delay;
+	u8 ext_soc_to_ble_grant_delay;
+} __packed;
+
+struct conf_iomux_configuration {
+	/* For any iomux pull value:
+	 * 1: Pull up
+	 * 2: Pull down
+	 * 3: Pull disable
+	 * ff: Default value set by HW
+	 * ANY other value is invalid
+	 */
+	u8 slow_clock_in_pull_val;
+	u8 sdio_clk_pull_val;
+	u8 sdio_cmd_pull_val;
+	u8 sdio_d0_pull_val;
+	u8 sdio_d1_pull_val;
+	u8 sdio_d2_pull_val;
+	u8 sdio_d3_pull_val;
+	u8 host_irq_wl_pull_val;
+	u8 uart1_tx_pull_val;
+	u8 uart1_rx_pull_val;
+	u8 uart1_cts_pull_val;
+	u8 uart1_rts_pull_val;
+	u8 coex_priority_pull_val;
+	u8 coex_req_pull_val;
+	u8 coex_grant_pull_val;
+	u8 host_irq_ble_pull_val;
+	u8 fast_clk_req_pull_val;
+	u8 ant_sel_pull_val;
+} __packed;
+
+struct conf_ant_diversity {
+	/* First beacons after antenna switch.
+	 * In this window we asses our satisfaction from the new antenna.
+	 */
+	u8 fast_switching_window;
+
+	/* Deltas above this threshold between the curiosity score and
+	 * the average RSSI will lead to antenna switch.
+	 */
+	u8 rssi_delta_for_switching;
+
+	/* Used in the first beacons after antenna switch:
+	 * Deltas above this threshold between the average RSSI and
+	 * the curiosity score will make us switch back the antennas.
+	 */
+	u8 rssi_delta_for_fast_switching;
+
+	/* Curiosity punishment in beacon timeout after an antenna switch.
+	 */
+	u8 curiosity_punish;
+
+	/* Curiosity raise in beacon timeout not after an antenna switch.
+	 */
+	u8 curiosity_raise;
+
+	/* Used for the average RSSI punishment in beacon timeout
+	 * not after antenna switch.
+	 */
+	u8 consecutive_missed_beacons_threshold;
+
+	/* Used in the curiosity metric.
+	 */
+	u8 compensation_log;
+
+	/* Used in the average RSSI metric.
+	 */
+	u8 log_alpha;
+
+	/* Curiosity initialization score.
+	 */
+	s8 initial_curiosity;
+
+	/* MR configuration: should the AP follow the STA antenna or use the default antenna.
+	 */
+	u8 ap_follows_sta;
+
+	/* MR configuration: should the BLE follow the STA antenna or use the default antenna.
+	 */
+	u8 ble_follows_sta;
+
+	/* The antenna to use when the diversity mechanism is not in charge.
+	 */
+	u8 default_antenna;
+} __packed;
+
+struct cc33xx_core_conf {
+	u8 enable_5ghz;
+	u8 enable_ble;
+	u8 enable_at_test_debug;
+	u8 disable_beamforming_fftp;
+	u32 ble_uart_baudrate;
+	u8 enable_flow_ctrl;
+	u8 listen_interval;
+	u8 wake_up_event;
+	u8 suspend_listen_interval;
+	u8 suspend_wake_up_event;
+	u8 per_channel_power_limit[507];
+	u32 internal_slowclk_wakeup_earlier;
+	u32 internal_slowclk_open_window_longer;
+	u32 external_slowclk_wakeup_earlier;
+	u32 external_slowclk_open_window_longer;
+	struct conf_coex_configuration coex_configuration;
+	/* Prevent HW recovery. FW will remain stuck. */
+	u8 no_recovery;
+	u8 disable_logger;
+	u8 mixed_mode_support;
+	u8 sram_ldo_voltage_trimming;
+	u32 xtal_settling_time_usec;
+	struct conf_ant_diversity ant_diversity;
+	struct conf_iomux_configuration iomux_configuration;
+} __packed;
+
+struct cc33xx_mac_conf {
+	u8 ps_scheme;
+	u8 he_enable;
+	u8 ap_max_num_stations;
+} __packed;
+
+struct cc33xx_phy_conf {
+	u8 insertion_loss_2_4ghz[2];
+	u8 insertion_loss_5ghz[2];
+	u8 reserved_0[2];
+	u8 ant_gain_2_4ghz[2];
+	u8 ant_gain_5ghz[2];
+	u8 reserved_1[2];
+	u8 ble_ch_lim_1m[40];
+	u8 ble_ch_lim_2m[40];
+	u8 one_time_calibration_only;
+	u8 is_diplexer_present;
+	u8 num_of_antennas;
+	u8 reg_domain;
+	u16 calib_period;
+} __packed;
+
+struct cc33xx_host_conf {
+	struct conf_rx_settings rx;
+	struct conf_tx_settings tx;
+	struct conf_conn_settings conn;
+	struct conf_itrim_settings itrim;
+	struct conf_pm_config_settings pm_config;
+	struct conf_roam_trigger_settings roam_trigger;
+	struct conf_scan_settings scan;
+	struct conf_sched_scan_settings sched_scan;
+	struct conf_ht_setting ht;
+	struct conf_memory_settings mem;
+	struct conf_rx_streaming_settings rx_streaming;
+	struct conf_fwlog fwlog;
+	struct conf_rate_policy_settings rate;
+	struct conf_hangover_settings hangover;
+	struct conf_ap_sleep_settings ap_sleep;
+
+} __packed;
+
+struct cc33xx_conf_file {
+	struct cc33xx_conf_header header;
+	struct cc33xx_phy_conf phy;
+	struct cc33xx_mac_conf mac;
+	struct cc33xx_core_conf core;
+	struct cc33xx_host_conf host_conf;
+} __packed;
+
+#endif
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/debug.h b/drivers/net/wireless/ti/cc33xx/debug.h
--- a/drivers/net/wireless/ti/cc33xx/debug.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/debug.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+#define DRIVER_NAME "cc33xx"
+#define DRIVER_PREFIX DRIVER_NAME ": "
+
+enum {
+	DEBUG_NONE		= 0,
+	DEBUG_IRQ		= BIT(0),
+	DEBUG_SPI		= BIT(1),
+	DEBUG_BOOT		= BIT(2),
+	DEBUG_CORE_STATUS	= BIT(3),
+	DEBUG_TESTMODE		= BIT(4),
+	DEBUG_EVENT		= BIT(5),
+	DEBUG_TX		= BIT(6),
+	DEBUG_RX		= BIT(7),
+	DEBUG_SCAN		= BIT(8),
+	DEBUG_CRYPT		= BIT(9),
+	DEBUG_PSM		= BIT(10),
+	DEBUG_MAC80211		= BIT(11),
+	DEBUG_CMD		= BIT(12),
+	DEBUG_ACX		= BIT(13),
+	DEBUG_SDIO		= BIT(14),
+	DEBUG_FILTERS		= BIT(15),
+	DEBUG_ADHOC		= BIT(16),
+	DEBUG_AP		= BIT(17),
+	DEBUG_PROBE		= BIT(18),
+	DEBUG_IO		= BIT(19),
+	DEBUG_MASTER		= (DEBUG_ADHOC | DEBUG_AP),
+	DEBUG_CC33xx		= BIT(20),
+	DEBUG_ALL		= GENMASK(31, 0),
+	DEBUG_NO_DATAPATH = (DEBUG_ALL & ~DEBUG_IRQ & ~DEBUG_TX & ~DEBUG_RX & ~DEBUG_CORE_STATUS),
+};
+
+extern u32 cc33xx_debug_level;
+
+#define DEBUG_DUMP_LIMIT 1024
+
+#define cc33xx_error(fmt, arg...) \
+	pr_err(DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
+
+#define cc33xx_warning(fmt, arg...) \
+	pr_warn(DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
+
+#define cc33xx_notice(fmt, arg...) \
+	pr_info(DRIVER_PREFIX fmt "\n", ##arg)
+
+#define cc33xx_info(fmt, arg...) \
+	pr_info(DRIVER_PREFIX fmt "\n", ##arg)
+
+/* define the debug macro differently if dynamic debug is supported */
+#if defined(CONFIG_DYNAMIC_DEBUG)
+#define cc33xx_debug(level, fmt, arg...) \
+	do { \
+		if (unlikely((level) & cc33xx_debug_level)) \
+			dynamic_pr_debug(DRIVER_PREFIX fmt "\n", ##arg); \
+	} while (0)
+#else
+#define cc33xx_debug(level, fmt, arg...) \
+	do { \
+		if (unlikely((level) & cc33xx_debug_level)) \
+			pr_debug(pr_fmt(DRIVER_PREFIX fmt "\n"), \
+			       ##arg); \
+	} while (0)
+#endif /* CONFIG_DYNAMIC_DEBUG */
+
+#define cc33xx_dump(level, prefix, buf, len)					\
+	do {									\
+		if ((level) & cc33xx_debug_level)				\
+			print_hex_dump_debug(DRIVER_PREFIX prefix,		\
+					DUMP_PREFIX_OFFSET, 16, 1,		\
+					buf,					\
+					min_t(size_t, len, DEBUG_DUMP_LIMIT),	\
+					0);					\
+	} while (0)
+
+#define cc33xx_dump_ascii(level, prefix, buf, len)				\
+	do {									\
+		if ((level) & cc33xx_debug_level)				\
+			print_hex_dump_debug(DRIVER_PREFIX prefix,		\
+					DUMP_PREFIX_OFFSET, 16, 1,		\
+					buf,					\
+					min_t(size_t, len, DEBUG_DUMP_LIMIT),	\
+					true);					\
+	} while (0)
+
+#endif /* __DEBUG_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/event.c b/drivers/net/wireless/ti/cc33xx/event.c
--- a/drivers/net/wireless/ti/cc33xx/event.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/event.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,362 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include "acx.h"
+#include "event.h"
+#include "ps.h"
+#include "io.h"
+#include "scan.h"
+
+#define CC33XX_WAIT_EVENT_FAST_POLL_COUNT 20
+
+struct cc33xx_event_mailbox {
+	__le32 events_vector;
+
+	u8 number_of_scan_results;
+	u8 number_of_sched_scan_results;
+
+	__le16 channel_switch_role_id_bitmap;
+
+	s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];
+
+	/* bitmap of removed links */
+	__le32 hlid_removed_bitmap;
+
+	/* rx ba constraint */
+	__le16 rx_ba_role_id_bitmap; /* 0xfff means any role. */
+	__le16 rx_ba_allowed_bitmap;
+
+	/* bitmap of roc completed (by role id) */
+	__le16 roc_completed_bitmap;
+
+	/* bitmap of stations (by role id) with bss loss */
+	__le16 bss_loss_bitmap;
+
+	/* bitmap of stations (by HLID) which exceeded max tx retries */
+	__le16 tx_retry_exceeded_bitmap;
+
+	/* time sync high msb*/
+	__le16 time_sync_tsf_high_msb;
+
+	/* bitmap of inactive stations (by HLID) */
+	__le16 inactive_sta_bitmap;
+
+	/* time sync high lsb*/
+	__le16 time_sync_tsf_high_lsb;
+
+	/* rx BA win size indicated by RX_BA_WIN_SIZE_CHANGE_EVENT_ID */
+	u8 rx_ba_role_id;
+	u8 rx_ba_link_id;
+	u8 rx_ba_win_size;
+	u8 padding;
+
+	/* smart config */
+	u8 sc_ssid_len;
+	u8 sc_pwd_len;
+	u8 sc_token_len;
+	u8 padding1;
+	u8 sc_ssid[32];
+	u8 sc_pwd[64];
+	u8 sc_token[32];
+
+	/* smart config sync channel */
+	u8 sc_sync_channel;
+	u8 sc_sync_band;
+
+	/* time sync low msb*/
+	__le16 time_sync_tsf_low_msb;
+
+	/* radar detect */
+	u8 radar_channel;
+	u8 radar_type;
+
+	/* time sync low lsb*/
+	__le16 time_sync_tsf_low_lsb;
+
+	u8 ble_event[260];
+
+} __packed;
+
+struct event_node {
+	struct llist_node node;
+	struct cc33xx_event_mailbox event_data;
+};
+
+void deffer_event(struct cc33xx *cc,
+		  const void *event_payload, size_t event_length)
+{
+	struct event_node *event_node;
+
+	if (WARN_ON(event_length != sizeof(event_node->event_data)))
+		return;
+
+	event_node = kzalloc(sizeof(*event_node), GFP_KERNEL);
+	if (WARN_ON(!event_node))
+		return;
+
+	memcpy(&event_node->event_data,
+	       event_payload, sizeof(event_node->event_data));
+
+	llist_add(&event_node->node, &cc->event_list);
+	queue_work(cc->freezable_wq, &cc->irq_deferred_work);
+}
+
+static inline struct llist_node *get_event_list(struct cc33xx *cc)
+{
+	struct llist_node *node;
+
+	node = llist_del_all(&cc->event_list);
+	if (!node)
+		return NULL;
+
+	return llist_reverse_order(node);
+}
+
+void flush_deferred_event_list(struct cc33xx *cc)
+{
+	struct event_node *event_node, *tmp;
+	struct llist_node *event_list;
+
+	event_list = get_event_list(cc);
+	llist_for_each_entry_safe(event_node, tmp, event_list, node) {
+		kfree(event_node);
+	}
+}
+
+static int wait_for_event_or_timeout(struct cc33xx *cc, u32 mask, bool *timeout)
+{
+	u32 event;
+	unsigned long timeout_time;
+	u16 poll_count = 0;
+	int ret = 0;
+	struct event_node *event_node, *tmp;
+	struct llist_node *event_list;
+	u32 vector;
+
+	*timeout = false;
+
+	timeout_time = jiffies + msecs_to_jiffies(CC33XX_EVENT_TIMEOUT);
+
+	do {
+		if (time_after(jiffies, timeout_time)) {
+			*timeout = true;
+			goto out;
+		}
+
+		poll_count++;
+		if (poll_count < CC33XX_WAIT_EVENT_FAST_POLL_COUNT)
+			usleep_range(50, 51);
+		else
+			usleep_range(1000, 5000);
+
+		vector = 0;
+		event_list = get_event_list(cc);
+		llist_for_each_entry_safe(event_node, tmp, event_list, node) {
+			vector |= le32_to_cpu(event_node->event_data.events_vector);
+		}
+
+		event  = vector & mask;
+	} while (!event);
+
+out:
+
+	return ret;
+}
+
+int cc33xx_wait_for_event(struct cc33xx *cc, enum cc33xx_wait_event event,
+			  bool *timeout)
+{
+	u32 local_event;
+
+	switch (event) {
+	case CC33XX_EVENT_PEER_REMOVE_COMPLETE:
+		local_event = PEER_REMOVE_COMPLETE_EVENT_ID;
+		break;
+
+	case CC33XX_EVENT_DFS_CONFIG_COMPLETE:
+		local_event = DFS_CHANNELS_CONFIG_COMPLETE_EVENT;
+		break;
+
+	default:
+		/* event not implemented */
+		return 0;
+	}
+	return wait_for_event_or_timeout(cc, local_event, timeout);
+}
+
+static void cc33xx_event_sched_scan_completed(struct cc33xx *cc, u8 status)
+{
+	if (cc->mac80211_scan_stopped) {
+		cc->mac80211_scan_stopped = false;
+	} else {
+		if (cc->sched_vif) {
+			ieee80211_sched_scan_stopped(cc->hw);
+			cc->sched_vif = NULL;
+		}
+	}
+}
+
+static void cc33xx_event_channel_switch(struct cc33xx *cc,
+					unsigned long roles_bitmap,
+				 bool success)
+{
+	struct cc33xx_vif *wlvif;
+	struct ieee80211_vif *vif;
+
+	cc33xx_for_each_wlvif(cc, wlvif) {
+		if (wlvif->role_id == CC33XX_INVALID_ROLE_ID ||
+		    !test_bit(wlvif->role_id, &roles_bitmap))
+			continue;
+
+		if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS,
+					&wlvif->flags))
+			continue;
+
+		vif = cc33xx_wlvif_to_vif(wlvif);
+
+		if (wlvif->bss_type == BSS_TYPE_STA_BSS) {
+			ieee80211_chswitch_done(vif, success, 0);
+			cancel_delayed_work(&wlvif->channel_switch_work);
+		} else {
+			set_bit(WLVIF_FLAG_BEACON_DISABLED, &wlvif->flags);
+			ieee80211_csa_finish(vif, 0);
+		}
+	}
+}
+
+static void cc33xx_disconnect_sta(struct cc33xx *cc, unsigned long sta_bitmap)
+{
+	u32 num_packets = cc->conf.host_conf.tx.max_tx_retries;
+	struct cc33xx_vif *wlvif;
+	struct ieee80211_vif *vif;
+	struct ieee80211_sta *sta;
+	const u8 *addr;
+	int h;
+
+	for_each_set_bit(h, &sta_bitmap, CC33XX_MAX_LINKS) {
+		bool found = false;
+		/* find the ap vif connected to this sta */
+		cc33xx_for_each_wlvif_ap(cc, wlvif) {
+			if (!test_bit(h, wlvif->ap.sta_hlid_map))
+				continue;
+			found = true;
+			break;
+		}
+		if (!found)
+			continue;
+
+		vif = cc33xx_wlvif_to_vif(wlvif);
+		addr = cc->links[h].addr;
+
+		rcu_read_lock();
+		sta = ieee80211_find_sta(vif, addr);
+		if (sta)
+			ieee80211_report_low_ack(sta, num_packets);
+
+		rcu_read_unlock();
+	}
+}
+
+static void cc33xx_event_max_tx_failure(struct cc33xx *cc,
+					unsigned long sta_bitmap)
+{
+	cc33xx_disconnect_sta(cc, sta_bitmap);
+}
+
+static void cc33xx_event_roc_complete(struct cc33xx *cc)
+{
+	if (cc->roc_vif)
+		ieee80211_ready_on_channel(cc->hw);
+}
+
+static void cc33xx_event_beacon_loss(struct cc33xx *cc,
+				     unsigned long roles_bitmap)
+{
+	/* We are HW_MONITOR device. On beacon loss - queue
+	 * connection loss work. Cancel it on REGAINED event.
+	 */
+	struct cc33xx_vif *wlvif;
+	struct ieee80211_vif *vif;
+	int delay = cc->conf.host_conf.conn.synch_fail_thold;
+
+	delay *= cc->conf.host_conf.conn.bss_lose_timeout;
+
+	cc33xx_for_each_wlvif_sta(cc, wlvif) {
+		if (wlvif->role_id == CC33XX_INVALID_ROLE_ID ||
+		    !test_bit(wlvif->role_id, &roles_bitmap))
+			continue;
+
+		vif = cc33xx_wlvif_to_vif(wlvif);
+
+		/* don't attempt roaming in case of p2p */
+		if (wlvif->p2p) {
+			ieee80211_connection_loss(vif);
+			continue;
+		}
+
+		/* if the work is already queued, it should take place.
+		 * We don't want to delay the connection loss
+		 * indication any more.
+		 */
+		ieee80211_queue_delayed_work(cc->hw,
+					     &wlvif->connection_loss_work,
+					     msecs_to_jiffies(delay));
+
+		ieee80211_cqm_beacon_loss_notify(vif, GFP_KERNEL);
+	}
+}
+
+void process_deferred_events(struct cc33xx *cc)
+{
+	struct event_node *event_node, *tmp;
+	struct llist_node *event_list;
+	u32 vector;
+
+	event_list = get_event_list(cc);
+
+	llist_for_each_entry_safe(event_node, tmp, event_list, node) {
+		struct cc33xx_event_mailbox *event_data;
+
+		event_data = &event_node->event_data;
+
+		vector = le32_to_cpu(event_node->event_data.events_vector);
+
+		if (vector & SCAN_COMPLETE_EVENT_ID) {
+			if (cc->scan_wlvif)
+				cc33xx_scan_completed(cc, cc->scan_wlvif);
+		}
+
+		if (vector & PERIODIC_SCAN_COMPLETE_EVENT_ID)
+			cc33xx_event_sched_scan_completed(cc, 1);
+
+		if (vector & BSS_LOSS_EVENT_ID) {
+			u16 bss_loss_bitmap = le16_to_cpu(event_data->bss_loss_bitmap);
+
+			cc33xx_event_beacon_loss(cc, bss_loss_bitmap);
+		}
+
+		if (vector & MAX_TX_FAILURE_EVENT_ID) {
+			u16 tx_retry_exceeded_bitmap =
+				le16_to_cpu(event_data->tx_retry_exceeded_bitmap);
+
+			cc33xx_event_max_tx_failure(cc, tx_retry_exceeded_bitmap);
+		}
+
+		if (vector & PERIODIC_SCAN_REPORT_EVENT_ID)
+			cc33xx_scan_sched_scan_results(cc);
+
+		if (vector & CHANNEL_SWITCH_COMPLETE_EVENT_ID) {
+			u16 channel_switch_role_id_bitmap =
+				le16_to_cpu(event_data->channel_switch_role_id_bitmap);
+
+			cc33xx_event_channel_switch(cc, channel_switch_role_id_bitmap, true);
+		}
+
+		if (vector & REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID)
+			cc33xx_event_roc_complete(cc);
+
+		kfree(event_node);
+	}
+}
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/event.h b/drivers/net/wireless/ti/cc33xx/event.h
--- a/drivers/net/wireless/ti/cc33xx/event.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/event.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __EVENT_H__
+#define __EVENT_H__
+
+/* Mbox events
+ *
+ * The event mechanism is based on a pair of event buffers (buffers A and
+ * B) at fixed locations in the target's memory. The host processes one
+ * buffer while the other buffer continues to collect events. If the host
+ * is not processing events, an interrupt is issued to signal that a buffer
+ * is ready. Once the host is done with processing events from one buffer,
+ * it signals the target (with an ACK interrupt) that the event buffer is
+ * free.
+ */
+
+enum {
+	RSSI_SNR_TRIGGER_0_EVENT_ID              = BIT(0),
+	RSSI_SNR_TRIGGER_1_EVENT_ID              = BIT(1),
+	RSSI_SNR_TRIGGER_2_EVENT_ID              = BIT(2),
+	RSSI_SNR_TRIGGER_3_EVENT_ID              = BIT(3),
+	RSSI_SNR_TRIGGER_4_EVENT_ID              = BIT(4),
+	RSSI_SNR_TRIGGER_5_EVENT_ID              = BIT(5),
+	RSSI_SNR_TRIGGER_6_EVENT_ID              = BIT(6),
+	RSSI_SNR_TRIGGER_7_EVENT_ID              = BIT(7),
+
+	EVENT_MBOX_ALL_EVENT_ID			 = 0x7fffffff,
+};
+
+enum {
+	SCAN_COMPLETE_EVENT_ID                   = BIT(8),
+	RADAR_DETECTED_EVENT_ID                  = BIT(9),
+	CHANNEL_SWITCH_COMPLETE_EVENT_ID         = BIT(10),
+	BSS_LOSS_EVENT_ID                        = BIT(11),
+	MAX_TX_FAILURE_EVENT_ID                  = BIT(12),
+	DUMMY_PACKET_EVENT_ID                    = BIT(13),
+	INACTIVE_STA_EVENT_ID                    = BIT(14),
+	PEER_REMOVE_COMPLETE_EVENT_ID            = BIT(15),
+	PERIODIC_SCAN_COMPLETE_EVENT_ID          = BIT(16),
+	BA_SESSION_RX_CONSTRAINT_EVENT_ID        = BIT(17),
+	REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID      = BIT(18),
+	DFS_CHANNELS_CONFIG_COMPLETE_EVENT       = BIT(19),
+	PERIODIC_SCAN_REPORT_EVENT_ID            = BIT(20),
+	RX_BA_WIN_SIZE_CHANGE_EVENT_ID           = BIT(21),
+	SMART_CONFIG_SYNC_EVENT_ID               = BIT(22),
+	SMART_CONFIG_DECODE_EVENT_ID             = BIT(23),
+	TIME_SYNC_EVENT_ID                       = BIT(24),
+	FW_LOGGER_INDICATION                     = BIT(25),
+};
+
+/* events the driver might want to wait for */
+enum cc33xx_wait_event {
+	CC33XX_EVENT_ROLE_STOP_COMPLETE,
+	CC33XX_EVENT_PEER_REMOVE_COMPLETE,
+	CC33XX_EVENT_DFS_CONFIG_COMPLETE
+};
+
+#define NUM_OF_RSSI_SNR_TRIGGERS 8
+
+struct cc33xx;
+
+int cc33xx_wait_for_event(struct cc33xx *cc, enum cc33xx_wait_event event,
+			  bool *timeout);
+void deffer_event(struct cc33xx *cc, const void *event_payload, size_t event_length);
+void process_deferred_events(struct cc33xx *cc);
+void flush_deferred_event_list(struct cc33xx *cc);
+
+#endif /* __EVENT_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/init.c b/drivers/net/wireless/ti/cc33xx/init.c
--- a/drivers/net/wireless/ti/cc33xx/init.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/init.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <linux/firmware.h>
+#include "acx.h"
+#include "cmd.h"
+#include "conf.h"
+#include "event.h"
+#include "tx.h"
+#include "init.h"
+
+static int cc33xx_init_phy_vif_config(struct cc33xx *cc,
+				      struct cc33xx_vif *wlvif)
+{
+	int ret;
+
+	ret = cc33xx_acx_slot(cc, wlvif, DEFAULT_SLOT_TIME);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int cc33xx_init_sta_beacon_filter(struct cc33xx *cc,
+					 struct cc33xx_vif *wlvif)
+{
+	int ret;
+
+	ret = cc33xx_acx_beacon_filter_table(cc, wlvif);
+	if (ret < 0)
+		return ret;
+
+	/* disable beacon filtering until we get the first beacon */
+	ret = cc33xx_acx_beacon_filter_opt(cc, wlvif, false);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int cc33xx_ap_init_templates(struct cc33xx *cc,
+				    struct ieee80211_vif *vif)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	int ret;
+
+	/* when operating as AP we want to receive external beacons for
+	 * configuring ERP protection.
+	 */
+	ret = cc33xx_acx_beacon_filter_opt(cc, wlvif, false);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static void cc33xx_set_ba_policies(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	/* Reset the BA RX indicators */
+	wlvif->ba_allowed = true;
+	cc->ba_rx_session_count = 0;
+
+	/* BA is supported in STA/AP modes */
+	wlvif->ba_support = (wlvif->bss_type != BSS_TYPE_AP_BSS &&
+				wlvif->bss_type != BSS_TYPE_STA_BSS);
+}
+
+/* vif-specifc initialization */
+static int cc33xx_init_sta_role(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	int ret = cc33xx_acx_group_address_tbl(cc, true, NULL, 0);
+
+	if (ret < 0)
+		return ret;
+
+	/* Beacon filtering */
+	ret = cc33xx_init_sta_beacon_filter(cc, wlvif);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+/* vif-specific initialization */
+static int cc33xx_init_ap_role(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	int ret;
+
+	/* initialize Tx power */
+	ret = cc33xx_acx_tx_power(cc, wlvif, wlvif->power_level);
+	if (ret < 0)
+		return ret;
+
+	if (cc->radar_debug_mode)
+		cc33xx_cmd_generic_cfg(cc, wlvif,
+				       CC33XX_CFG_FEATURE_RADAR_DEBUG,
+				       cc->radar_debug_mode, 0);
+
+	return 0;
+}
+
+int cc33xx_init_vif_specific(struct cc33xx *cc, struct ieee80211_vif *vif)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	struct conf_tx_settings *tx_settings = &cc->conf.host_conf.tx;
+	struct conf_tx_ac_category *conf_ac = &tx_settings->ac_conf0;
+	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
+	u8 ps_scheme = cc->conf.mac.ps_scheme;
+	int ret, i;
+
+	/* consider all existing roles before configuring psm. */
+
+	if (cc->ap_count == 0 && is_ap) { /* first AP */
+		ret = cc33xx_acx_sleep_auth(cc, CC33XX_PSM_ELP);
+		if (ret < 0)
+			return ret;
+
+		/* unmask ap events */
+		cc->event_mask |= cc->ap_event_mask;
+
+	/* first STA, no APs */
+	} else if (cc->sta_count == 0 && cc->ap_count == 0 && !is_ap) {
+		u8 sta_auth = cc->conf.host_conf.conn.sta_sleep_auth;
+		/* Configure for power according to debugfs */
+		if (sta_auth != CC33XX_PSM_ILLEGAL)
+			ret = cc33xx_acx_sleep_auth(cc, sta_auth);
+		/* Configure for ELP power saving */
+		else
+			ret = cc33xx_acx_sleep_auth(cc, CC33XX_PSM_ELP);
+
+		if (ret < 0)
+			return ret;
+	}
+
+	/* Mode specific init */
+	if (is_ap) {
+		ret = cc33xx_init_ap_role(cc, wlvif);
+		if (ret < 0)
+			return ret;
+	} else {
+		ret = cc33xx_init_sta_role(cc, wlvif);
+		if (ret < 0)
+			return ret;
+	}
+
+	cc33xx_init_phy_vif_config(cc, wlvif);
+
+	/* Default TID/AC configuration */
+	if (WARN_ON(tx_settings->ac_conf_count != tx_settings->tid_conf_count) ||
+	    WARN_ON(tx_settings->ac_conf_count != CONF_TX_MAX_AC_COUNT))
+		return -EINVAL;
+
+	for (i = 0; i < tx_settings->tid_conf_count; i++) {
+		/* If no ps poll is used, send legacy ps scheme in cmd */
+		if (ps_scheme == PS_SCHEME_NOPSPOLL)
+			ps_scheme = PS_SCHEME_LEGACY;
+
+		ret = cc33xx_tx_param_cfg(cc, wlvif, conf_ac->ac,
+					  conf_ac->cw_min, conf_ac->cw_max,
+					  conf_ac->aifsn, conf_ac->tx_op_limit,
+					  false, ps_scheme, conf_ac->is_mu_edca,
+					  conf_ac->mu_edca_aifs,
+					  conf_ac->mu_edca_ecw_min_max,
+					  conf_ac->mu_edca_timer);
+
+		if (ret < 0)
+			return ret;
+
+		conf_ac++;
+	}
+
+	/* Mode specific init - post mem init */
+	if (is_ap)
+		ret = cc33xx_ap_init_templates(cc, vif);
+
+	if (ret < 0)
+		return ret;
+
+	/* Configure initiator BA sessions policies */
+	cc33xx_set_ba_policies(cc, wlvif);
+
+	return 0;
+}
+
+int cc33xx_hw_init(struct cc33xx *cc)
+{
+	cc33xx_acx_init_mem_config(cc);
+
+	cc->last_fw_rls_idx = 0;
+	cc->partial_rx.status = CURR_RX_START;
+	return 0;
+}
+
+int cc33xx_download_ini_params_and_wait(struct cc33xx *cc)
+{
+	struct cc33xx_cmd_ini_params_download *cmd;
+	size_t command_size = ALIGN((sizeof(*cmd) + sizeof(cc->conf)), 4);
+	int ret;
+
+	cc33xx_set_max_buffer_size(cc, INI_MAX_BUFFER_SIZE);
+
+	cc33xx_debug(DEBUG_ACX,
+		     "Downloading INI configurations to FW, payload Length: %zu",
+		     sizeof(cc->conf));
+
+	cmd = kzalloc(command_size, GFP_KERNEL);
+	if (!cmd) {
+		cc33xx_set_max_buffer_size(cc, CMD_MAX_BUFFER_SIZE);
+		return -ENOMEM;
+	}
+
+	cmd->length = cpu_to_le32(sizeof(cc->conf));
+
+	/* copy INI file params payload */
+	memcpy((cmd->payload), &cc->conf, sizeof(cc->conf));
+
+	ret = cc33xx_cmd_send(cc, CMD_DOWNLOAD_INI_PARAMS,
+			      cmd, command_size, 0);
+	if (ret < 0) {
+		cc33xx_warning("download INI params to FW command sending failed: %d",
+			       ret);
+	} else {
+		cc33xx_debug(DEBUG_BOOT, "INI Params downloaded successfully");
+	}
+
+	cc33xx_set_max_buffer_size(cc, CMD_MAX_BUFFER_SIZE);
+	kfree(cmd);
+	return ret;
+}
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/init.h b/drivers/net/wireless/ti/cc33xx/init.h
--- a/drivers/net/wireless/ti/cc33xx/init.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/init.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __INIT_H__
+#define __INIT_H__
+
+#include "cc33xx.h"
+
+int cc33xx_hw_init(struct cc33xx *cc);
+int cc33xx_download_ini_params_and_wait(struct cc33xx *cc);
+int cc33xx_init_vif_specific(struct cc33xx *cc, struct ieee80211_vif *vif);
+
+#endif /* __INIT_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/io.c b/drivers/net/wireless/ti/cc33xx/io.c
--- a/drivers/net/wireless/ti/cc33xx/io.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/io.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include "cc33xx.h"
+#include "debug.h"
+#include "io.h"
+#include "tx.h"
+
+bool cc33xx_set_block_size(struct cc33xx *cc)
+{
+	if (cc->if_ops->set_block_size) {
+		cc->if_ops->set_block_size(cc->dev, CC33XX_BUS_BLOCK_SIZE);
+		cc33xx_debug(DEBUG_CC33xx,
+			     "Set BLKsize to %d", CC33XX_BUS_BLOCK_SIZE);
+		return true;
+	}
+
+	cc33xx_debug(DEBUG_CC33xx, "Could not set BLKsize");
+	return false;
+}
+
+void cc33xx_disable_interrupts_nosync(struct cc33xx *cc)
+{
+	cc->if_ops->disable_irq(cc->dev);
+}
+
+void cc33xx_irq(void *cookie);
+void cc33xx_enable_interrupts(struct cc33xx *cc)
+{
+	cc->if_ops->enable_irq(cc->dev);
+
+	cc33xx_irq(cc);
+}
+
+void cc33xx_io_reset(struct cc33xx *cc)
+{
+	if (cc->if_ops->reset)
+		cc->if_ops->reset(cc->dev);
+}
+
+void cc33xx_io_init(struct cc33xx *cc)
+{
+	if (cc->if_ops->init)
+		cc->if_ops->init(cc->dev);
+}
+
+/* Raw target IO, address is not translated */
+static int __must_check cc33xx_raw_write(struct cc33xx *cc, int addr,
+					 void *buf, size_t len, bool fixed)
+{
+	int ret;
+
+	if (test_bit(CC33XX_FLAG_IO_FAILED, &cc->flags) ||
+	    WARN_ON((test_bit(CC33XX_FLAG_IN_ELP, &cc->flags) &&
+		     addr != HW_ACCESS_ELP_CTRL_REG)))
+		return -EIO;
+
+	ret = cc->if_ops->write(cc->dev, addr, buf, len, fixed);
+	if (ret && cc->state != CC33XX_STATE_OFF)
+		set_bit(CC33XX_FLAG_IO_FAILED, &cc->flags);
+
+	return ret;
+}
+
+int __must_check cc33xx_raw_read(struct cc33xx *cc, int addr,
+				 void *buf, size_t len, bool fixed)
+{
+	int ret;
+
+	if (test_bit(CC33XX_FLAG_IO_FAILED, &cc->flags) ||
+	    WARN_ON((test_bit(CC33XX_FLAG_IN_ELP, &cc->flags) &&
+		     addr != HW_ACCESS_ELP_CTRL_REG)))
+		return -EIO;
+
+	ret = cc->if_ops->read(cc->dev, addr, buf, len, fixed);
+	if (ret && cc->state != CC33XX_STATE_OFF)
+		set_bit(CC33XX_FLAG_IO_FAILED, &cc->flags);
+
+	return ret;
+}
+
+int __must_check cc33xx_write(struct cc33xx *cc, int addr,
+			      void *buf, size_t len, bool fixed)
+{
+	return cc33xx_raw_write(cc, addr, buf, len, fixed);
+}
+
+void claim_core_status_lock(struct cc33xx *cc)
+{
+	/* When accessing core-status data (read or write) the transport lock
+	 * should be held.
+	 */
+	cc->if_ops->interface_claim(cc->dev);
+}
+
+void release_core_status_lock(struct cc33xx *cc)
+{
+	/* After accessing core-status data (read or write) the transport lock
+	 * should be released.
+	 */
+	cc->if_ops->interface_release(cc->dev);
+}
+
+void cc33xx_power_off(struct cc33xx *cc)
+{
+	int ret = 0;
+
+	if (!test_bit(CC33XX_FLAG_GPIO_POWER, &cc->flags))
+		return;
+
+	if (cc->if_ops->power)
+		ret = cc->if_ops->power(cc->dev, false);
+	if (!ret)
+		clear_bit(CC33XX_FLAG_GPIO_POWER, &cc->flags);
+}
+
+int cc33xx_power_on(struct cc33xx *cc)
+{
+	int ret = 0;
+
+	if (cc->if_ops->power)
+		ret = cc->if_ops->power(cc->dev, true);
+	if (ret == 0)
+		set_bit(CC33XX_FLAG_GPIO_POWER, &cc->flags);
+
+	return ret;
+}
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/io.h b/drivers/net/wireless/ti/cc33xx/io.h
--- a/drivers/net/wireless/ti/cc33xx/io.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/io.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __IO_H__
+#define __IO_H__
+
+struct cc33xx;
+
+void cc33xx_disable_interrupts_nosync(struct cc33xx *cc);
+void cc33xx_enable_interrupts(struct cc33xx *cc);
+void cc33xx_io_reset(struct cc33xx *cc);
+void cc33xx_io_init(struct cc33xx *cc);
+int __must_check cc33xx_raw_read(struct cc33xx *cc, int addr,
+				 void *buf, size_t len, bool fixed);
+int __must_check cc33xx_write(struct cc33xx *cc, int addr,
+			      void *buf, size_t len, bool fixed);
+void claim_core_status_lock(struct cc33xx *cc);
+void release_core_status_lock(struct cc33xx *cc);
+void cc33xx_power_off(struct cc33xx *cc);
+int cc33xx_power_on(struct cc33xx *cc);
+int cc33xx_translate_addr(struct cc33xx *cc, int addr);
+bool cc33xx_set_block_size(struct cc33xx *cc);
+
+#endif /* __IO_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/Kconfig b/drivers/net/wireless/ti/cc33xx/Kconfig
--- a/drivers/net/wireless/ti/cc33xx/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/Kconfig	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config CC33XX
+	tristate "TI CC33XX support"
+	depends on MAC80211
+	select FW_LOADER
+	help
+	  This module contains the main code for TI CC33XX WLAN chips. It abstracts
+	  hardware-specific differences among different chipset families.
+	  Each chipset family needs to implement its own lower-level module
+	  that will depend on this module for the common code.
+
+	  If you choose to build a module, it will be called cc33xx. Say N if
+	  unsure.
+
+config CC33XX_SDIO
+	tristate "TI CC33XX SDIO support"
+	depends on CC33XX && MMC
+	help
+	  This module adds support for the SDIO interface of adapters using
+	  TI CC33XX WLAN chipsets.  Select this if your platform is using
+	  the SDIO bus.
+
+	  If you choose to build a module, it'll be called cc33xx_sdio.
+	  Say N if unsure.
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/main.c b/drivers/net/wireless/ti/cc33xx/main.c
--- a/drivers/net/wireless/ti/cc33xx/main.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/main.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,5686 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/firmware.h>
+#include <linux/irq.h>
+#include <linux/pm_wakeirq.h>
+
+#include "../net/mac80211/ieee80211_i.h"
+
+#include "acx.h"
+#include "boot.h"
+#include "io.h"
+#include "tx.h"
+#include "ps.h"
+#include "init.h"
+#include "testmode.h"
+#include "scan.h"
+#include "event.h"
+
+#define CC33XX_FW_RX_PACKET_RAM (9 * 1024)
+static int no_recovery     = -1;
+
+u32 cc33xx_debug_level = DEBUG_NO_DATAPATH;
+
+/* HT cap appropriate for wide channels in 2Ghz */
+static struct ieee80211_sta_ht_cap cc33xx_siso40_ht_cap_2ghz = {
+	.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
+	       IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40 |
+	       IEEE80211_HT_CAP_GRN_FLD,
+	.ht_supported = true,
+	.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
+	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
+	.mcs = {
+		.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+		.rx_highest = cpu_to_le16(150),
+		.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
+	},
+};
+
+/* HT cap appropriate for wide channels in 5Ghz */
+static struct ieee80211_sta_ht_cap cc33xx_siso40_ht_cap_5ghz = {
+	.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
+	       IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+	       IEEE80211_HT_CAP_GRN_FLD,
+	.ht_supported = true,
+	.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
+	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
+	.mcs = {
+		.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+		.rx_highest = cpu_to_le16(150),
+		.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
+	},
+};
+
+/* HT cap appropriate for SISO 20 */
+static struct ieee80211_sta_ht_cap cc33xx_siso20_ht_cap = {
+	.cap = IEEE80211_HT_CAP_SGI_20 |
+	       IEEE80211_HT_CAP_MAX_AMSDU,
+	.ht_supported = true,
+	.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
+	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
+	.mcs = {
+		.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+		.rx_highest = cpu_to_le16(72),
+		.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
+	},
+};
+
+#ifdef CONFIG_MAC80211_MESH
+static const struct ieee80211_iface_limit cc33xx_iface_limits[] = {
+	{
+		.max = 2,
+		.types = BIT(NL80211_IFTYPE_STATION)
+		       | BIT(NL80211_IFTYPE_P2P_CLIENT),
+	},
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_GO)
+		       | BIT(NL80211_IFTYPE_MESH_POINT)
+	},
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_P2P_DEVICE),
+	},
+};
+
+static inline u16 cc33xx_wiphy_interface_modes(void)
+{
+	return BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_P2P_GO) |
+	       BIT(NL80211_IFTYPE_MESH_POINT) | BIT(NL80211_IFTYPE_AP) |
+	       BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_DEVICE);
+}
+#else
+static const struct ieee80211_iface_limit cc33xx_iface_limits[] = {
+	{
+		.max = 2,
+		.types = BIT(NL80211_IFTYPE_STATION)
+		       | BIT(NL80211_IFTYPE_P2P_CLIENT),
+	},
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_GO)
+	},
+	{
+		.max = 1,
+		.types = BIT(NL80211_IFTYPE_P2P_DEVICE),
+	},
+};
+
+static inline u16 cc33xx_wiphy_interface_modes(void)
+{
+	return BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_P2P_GO) |
+	       BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_AP) |
+	       BIT(NL80211_IFTYPE_P2P_DEVICE);
+}
+#endif /* CONFIG_MAC80211_MESH */
+
+static const struct ieee80211_iface_combination
+cc33xx_iface_combinations[] = {
+	{
+		.max_interfaces = 3,
+		.limits = cc33xx_iface_limits,
+		.n_limits = ARRAY_SIZE(cc33xx_iface_limits),
+		.num_different_channels = 2,
+	}
+};
+
+static const u8 cc33xx_rate_to_idx_2ghz[] = {
+	CONF_HW_RXTX_RATE_UNSUPPORTED,
+	0,              /* RATE_INDEX_1MBPS */
+	1,              /* RATE_INDEX_2MBPS */
+	2,              /* RATE_INDEX_5_5MBPS */
+	3,              /* RATE_INDEX_11MBPS */
+	4,              /* RATE_INDEX_6MBPS */
+	5,              /* RATE_INDEX_9MBPS */
+	6,              /* RATE_INDEX_12MBPS */
+	7,              /* RATE_INDEX_18MBPS */
+	8,              /* RATE_INDEX_24MBPS */
+	9,              /* RATE_INDEX_36MBPS */
+	10,            /* RATE_INDEX_48MBPS */
+	11,            /* RATE_INDEX_54MBPS */
+	0,              /* RATE_INDEX_MCS0 */
+	1,              /* RATE_INDEX_MCS1 */
+	2,              /* RATE_INDEX_MCS2 */
+	3,              /* RATE_INDEX_MCS3 */
+	4,              /* RATE_INDEX_MCS4 */
+	5,              /* RATE_INDEX_MCS5 */
+	6,              /* RATE_INDEX_MCS6 */
+	7               /* RATE_INDEX_MCS7 */
+};
+
+static const u8 cc33xx_rate_to_idx_5ghz[] = {
+	CONF_HW_RXTX_RATE_UNSUPPORTED,
+	CONF_HW_RXTX_RATE_UNSUPPORTED,              /* RATE_INDEX_1MBPS */
+	CONF_HW_RXTX_RATE_UNSUPPORTED,              /* RATE_INDEX_2MBPS */
+	CONF_HW_RXTX_RATE_UNSUPPORTED,              /* RATE_INDEX_5_5MBPS */
+	CONF_HW_RXTX_RATE_UNSUPPORTED,              /* RATE_INDEX_11MBPS */
+	0,              /* RATE_INDEX_6MBPS */
+	1,              /* RATE_INDEX_9MBPS */
+	2,              /* RATE_INDEX_12MBPS */
+	3,              /* RATE_INDEX_18MBPS */
+	4,              /* RATE_INDEX_24MBPS */
+	5,              /* RATE_INDEX_36MBPS */
+	6,              /* RATE_INDEX_48MBPS */
+	7,              /* RATE_INDEX_54MBPS */
+	0,              /* RATE_INDEX_MCS0 */
+	1,              /* RATE_INDEX_MCS1 */
+	2,              /* RATE_INDEX_MCS2 */
+	3,              /* RATE_INDEX_MCS3 */
+	4,              /* RATE_INDEX_MCS4 */
+	5,              /* RATE_INDEX_MCS5 */
+	6,              /* RATE_INDEX_MCS6 */
+	7               /* RATE_INDEX_MCS7 */
+};
+
+static const u8 *cc33xx_band_rate_to_idx[] = {
+	[NL80211_BAND_2GHZ] = cc33xx_rate_to_idx_2ghz,
+	[NL80211_BAND_5GHZ] = cc33xx_rate_to_idx_5ghz
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_rate cc33xx_rates[] = {
+	{ .bitrate = 10,
+	  .hw_value = CONF_HW_BIT_RATE_1MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_1MBPS, },
+	{ .bitrate = 20,
+	  .hw_value = CONF_HW_BIT_RATE_2MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_2MBPS,
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 55,
+	  .hw_value = CONF_HW_BIT_RATE_5_5MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_5_5MBPS,
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 110,
+	  .hw_value = CONF_HW_BIT_RATE_11MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_11MBPS,
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 60,
+	  .hw_value = CONF_HW_BIT_RATE_6MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_6MBPS, },
+	{ .bitrate = 90,
+	  .hw_value = CONF_HW_BIT_RATE_9MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_9MBPS, },
+	{ .bitrate = 120,
+	  .hw_value = CONF_HW_BIT_RATE_12MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_12MBPS, },
+	{ .bitrate = 180,
+	  .hw_value = CONF_HW_BIT_RATE_18MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_18MBPS, },
+	{ .bitrate = 240,
+	  .hw_value = CONF_HW_BIT_RATE_24MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_24MBPS, },
+	{ .bitrate = 360,
+	 .hw_value = CONF_HW_BIT_RATE_36MBPS,
+	 .hw_value_short = CONF_HW_BIT_RATE_36MBPS, },
+	{ .bitrate = 480,
+	  .hw_value = CONF_HW_BIT_RATE_48MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_48MBPS, },
+	{ .bitrate = 540,
+	  .hw_value = CONF_HW_BIT_RATE_54MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_channel cc33xx_channels[] = {
+	{ .hw_value = 1, .center_freq = 2412, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 2, .center_freq = 2417, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 3, .center_freq = 2422, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 4, .center_freq = 2427, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 5, .center_freq = 2432, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 6, .center_freq = 2437, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 7, .center_freq = 2442, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 8, .center_freq = 2447, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 9, .center_freq = 2452, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 10, .center_freq = 2457, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 11, .center_freq = 2462, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 12, .center_freq = 2467, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 13, .center_freq = 2472, .max_power = CC33XX_MAX_TXPWR },
+};
+
+static const struct ieee80211_sband_iftype_data iftype_data_2ghz[] = {{
+	.types_mask = BIT(NL80211_IFTYPE_STATION),
+	.he_cap = {
+		.has_he = true,
+		.he_cap_elem = {
+		.mac_cap_info[0] =
+			IEEE80211_HE_MAC_CAP0_HTC_HE |
+			IEEE80211_HE_MAC_CAP0_TWT_REQ,
+		.mac_cap_info[1] =
+			IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
+			IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
+		.mac_cap_info[2] =
+			IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP |
+			IEEE80211_HE_MAC_CAP2_ALL_ACK |
+			IEEE80211_HE_MAC_CAP2_TRS |
+			IEEE80211_HE_MAC_CAP2_BSR |
+			IEEE80211_HE_MAC_CAP2_ACK_EN,
+		.mac_cap_info[3] =
+			IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
+			IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS,
+		.mac_cap_info[4] =
+			IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU |
+			IEEE80211_HE_MAC_CAP4_NDP_FB_REP |
+			IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39,
+		.mac_cap_info[5] =
+			IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX,
+		.phy_cap_info[0] = 0,
+		.phy_cap_info[1] =
+			IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
+			IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US,
+		.phy_cap_info[2] =
+			IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US,
+		.phy_cap_info[3] =
+			IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_NO_DCM |
+			IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1 |
+			IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM |
+			IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1,
+		.phy_cap_info[4] =
+			IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
+			IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4,
+		.phy_cap_info[5] =
+			IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK |
+			IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK,
+		.phy_cap_info[6] =
+			IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU  |
+			IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU  |
+			IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB  |
+			IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB |
+			IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
+			IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE,
+		.phy_cap_info[7] =
+			IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI,
+		.phy_cap_info[8] =
+			IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
+			IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
+			IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI,
+		.phy_cap_info[9] =
+			IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |
+			IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
+			IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB |
+			IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US,
+		},
+		/* Set default Tx/Rx HE MCS NSS Support field.
+		 * Indicate support for up to 2 spatial streams and all
+		 * MCS, without any special cases
+		 */
+		.he_mcs_nss_supp = {
+			.rx_mcs_80 = cpu_to_le16(0xfffc),
+			.tx_mcs_80 = cpu_to_le16(0xfffc),
+			.rx_mcs_160 = cpu_to_le16(0xffff),
+			.tx_mcs_160 = cpu_to_le16(0xffff),
+			.rx_mcs_80p80 = cpu_to_le16(0xffff),
+			.tx_mcs_80p80 = cpu_to_le16(0xffff),
+		},
+		/* Set default PPE thresholds, with PPET16 set to 0,
+		 * PPET8 set to 7
+		 */
+		.ppe_thres = {0xff, 0xff, 0xff, 0xff},
+	},
+}};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_supported_band cc33xx_band_2ghz = {
+	.channels = cc33xx_channels,
+	.n_channels = ARRAY_SIZE(cc33xx_channels),
+	.bitrates = cc33xx_rates,
+	.n_bitrates = ARRAY_SIZE(cc33xx_rates),
+};
+
+/* 5 GHz data rates for cc33xx */
+static struct ieee80211_rate cc33xx_rates_5ghz[] = {
+	{ .bitrate = 60,
+	  .hw_value = CONF_HW_BIT_RATE_6MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_6MBPS, },
+	{ .bitrate = 90,
+	  .hw_value = CONF_HW_BIT_RATE_9MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_9MBPS, },
+	{ .bitrate = 120,
+	  .hw_value = CONF_HW_BIT_RATE_12MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_12MBPS, },
+	{ .bitrate = 180,
+	  .hw_value = CONF_HW_BIT_RATE_18MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_18MBPS, },
+	{ .bitrate = 240,
+	  .hw_value = CONF_HW_BIT_RATE_24MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_24MBPS, },
+	{ .bitrate = 360,
+	 .hw_value = CONF_HW_BIT_RATE_36MBPS,
+	 .hw_value_short = CONF_HW_BIT_RATE_36MBPS, },
+	{ .bitrate = 480,
+	  .hw_value = CONF_HW_BIT_RATE_48MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_48MBPS, },
+	{ .bitrate = 540,
+	  .hw_value = CONF_HW_BIT_RATE_54MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
+};
+
+/* 5 GHz band channels for cc33xx */
+static struct ieee80211_channel cc33xx_channels_5ghz[] = {
+	{ .hw_value = 36, .center_freq = 5180, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 40, .center_freq = 5200, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 44, .center_freq = 5220, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 48, .center_freq = 5240, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 52, .center_freq = 5260, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 56, .center_freq = 5280, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 60, .center_freq = 5300, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 64, .center_freq = 5320, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 100, .center_freq = 5500, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 104, .center_freq = 5520, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 108, .center_freq = 5540, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 112, .center_freq = 5560, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 116, .center_freq = 5580, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 120, .center_freq = 5600, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 124, .center_freq = 5620, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 128, .center_freq = 5640, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 132, .center_freq = 5660, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 136, .center_freq = 5680, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 140, .center_freq = 5700, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 149, .center_freq = 5745, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 153, .center_freq = 5765, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 157, .center_freq = 5785, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 161, .center_freq = 5805, .max_power = CC33XX_MAX_TXPWR },
+	{ .hw_value = 165, .center_freq = 5825, .max_power = CC33XX_MAX_TXPWR },
+};
+
+static const struct ieee80211_sband_iftype_data iftype_data_5ghz[] = {{
+	.types_mask = BIT(NL80211_IFTYPE_STATION),
+	.he_cap = {
+		.has_he = true,
+		.he_cap_elem = {
+		.mac_cap_info[0] =
+			IEEE80211_HE_MAC_CAP0_HTC_HE |
+			IEEE80211_HE_MAC_CAP0_TWT_REQ,
+		.mac_cap_info[1] =
+			IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
+			IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
+		.mac_cap_info[2] =
+			IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP |
+			IEEE80211_HE_MAC_CAP2_ALL_ACK |
+			IEEE80211_HE_MAC_CAP2_TRS |
+			IEEE80211_HE_MAC_CAP2_BSR |
+			IEEE80211_HE_MAC_CAP2_ACK_EN,
+		.mac_cap_info[3] =
+			IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
+			IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS,
+		.mac_cap_info[4] =
+			IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU |
+			IEEE80211_HE_MAC_CAP4_NDP_FB_REP |
+			IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39,
+		.mac_cap_info[5] =
+			IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX,
+		.phy_cap_info[0] = 0,
+		.phy_cap_info[1] =
+			IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
+			IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US,
+		.phy_cap_info[2] =
+			IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US,
+		.phy_cap_info[3] =
+			IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_NO_DCM |
+			IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1 |
+			IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM |
+			IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1,
+		.phy_cap_info[4] =
+			IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
+			IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4,
+		.phy_cap_info[5] =
+			IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK |
+			IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK,
+		.phy_cap_info[6] =
+			IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU  |
+			IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU  |
+			IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB  |
+			IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB |
+			IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
+			IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE,
+		.phy_cap_info[7] =
+			IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI,
+		.phy_cap_info[8] =
+			IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
+			IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
+			IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI,
+		.phy_cap_info[9] =
+			IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |
+			IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
+			IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB |
+			IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US,
+		},
+		/* Set default Tx/Rx HE MCS NSS Support field.
+		 * Indicate support for up to 2 spatial streams and all
+		 * MCS, without any special cases
+		 */
+		.he_mcs_nss_supp = {
+			.rx_mcs_80 = cpu_to_le16(0xfffc),
+			.tx_mcs_80 = cpu_to_le16(0xfffc),
+			.rx_mcs_160 = cpu_to_le16(0xffff),
+			.tx_mcs_160 = cpu_to_le16(0xffff),
+			.rx_mcs_80p80 = cpu_to_le16(0xffff),
+			.tx_mcs_80p80 = cpu_to_le16(0xffff),
+		},
+		/* Set default PPE thresholds, with PPET16 set to 0,
+		 * PPET8 set to 7
+		 */
+		.ppe_thres = {0xff, 0xff, 0xff, 0xff},
+	},
+}};
+
+static struct ieee80211_supported_band cc33xx_band_5ghz = {
+	.channels = cc33xx_channels_5ghz,
+	.n_channels = ARRAY_SIZE(cc33xx_channels_5ghz),
+	.bitrates = cc33xx_rates_5ghz,
+	.n_bitrates = ARRAY_SIZE(cc33xx_rates_5ghz),
+	.vht_cap = {
+		.vht_supported = true,
+		.cap = (IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 | (1 <<
+			IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT)),
+		.vht_mcs = {
+			.rx_mcs_map = cpu_to_le16(0xfffc),
+			.rx_highest = cpu_to_le16(7),
+			.tx_mcs_map = cpu_to_le16(0xfffc),
+			.tx_highest = cpu_to_le16(7),
+		},
+	},
+};
+
+static void __cc33xx_op_remove_interface(struct cc33xx *cc,
+					 struct ieee80211_vif *vif,
+					 bool reset_tx_queues);
+static void cc33xx_turn_off(struct cc33xx *cc);
+static void cc33xx_free_ap_keys(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+static int process_core_status(struct cc33xx *cc,
+			       struct core_status *core_status);
+static int cc33xx_setup(struct cc33xx *cc);
+
+static int cc33xx_set_authorized(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	int ret;
+
+	if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
+		return -EINVAL;
+
+	if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+		return 0;
+
+	if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags))
+		return 0;
+
+	ret = cc33xx_cmd_set_peer_state(cc, wlvif, wlvif->sta.hlid);
+	if (ret < 0)
+		return ret;
+
+	cc33xx_info("Association complete.");
+	return 0;
+}
+
+/* cc->mutex must be taken */
+void cc33xx_rearm_tx_watchdog_locked(struct cc33xx *cc)
+{
+	/* if the watchdog is not armed, don't do anything */
+	if (cc->tx_allocated_blocks == 0)
+		return;
+
+	cancel_delayed_work(&cc->tx_watchdog_work);
+	ieee80211_queue_delayed_work(cc->hw, &cc->tx_watchdog_work,
+				     msecs_to_jiffies(cc->conf.host_conf.tx.tx_watchdog_timeout));
+}
+
+static void cc33xx_sta_rc_update(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	/* sanity */
+	if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
+		return;
+
+	/* ignore the change before association */
+	if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+		return;
+
+	/* If we started out as wide, we can change the operation mode. If we
+	 * thought this was a 20mhz AP, we have to reconnect
+	 */
+	if (wlvif->sta.role_chan_type != NL80211_CHAN_HT40MINUS &&
+	    wlvif->sta.role_chan_type != NL80211_CHAN_HT40PLUS)
+		ieee80211_connection_loss(cc33xx_wlvif_to_vif(wlvif));
+}
+
+static void cc33xx_rc_update_work(struct work_struct *work)
+{
+	struct cc33xx_vif *wlvif = container_of(work, struct cc33xx_vif,
+						rc_update_work);
+	struct cc33xx *cc = wlvif->cc;
+	struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	if (!ieee80211_vif_is_mesh(vif))
+		cc33xx_sta_rc_update(cc, wlvif);
+
+out:
+	mutex_unlock(&cc->mutex);
+}
+
+static inline void cc33xx_tx_watchdog_work(struct work_struct *work)
+{
+	container_of(to_delayed_work(work), struct cc33xx, tx_watchdog_work);
+}
+
+static void cc33xx_adjust_conf(struct cc33xx *cc)
+{
+	if (no_recovery != -1)
+		cc->conf.core.no_recovery = (u8)no_recovery;
+}
+
+void cc33xx_flush_deferred_work(struct cc33xx *cc)
+{
+	struct sk_buff *skb;
+
+	/* Pass all received frames to the network stack */
+	while ((skb = skb_dequeue(&cc->deferred_rx_queue))) {
+		cc33xx_debug(DEBUG_RX, "%s: rx skb 0x%p", __func__, skb);
+		ieee80211_rx_ni(cc->hw, skb);
+	}
+
+	/* Return sent skbs to the network stack */
+	while ((skb = skb_dequeue(&cc->deferred_tx_queue)))
+		ieee80211_tx_status_ni(cc->hw, skb);
+}
+
+static void cc33xx_netstack_work(struct work_struct *work)
+{
+	struct cc33xx *cc = container_of(work, struct cc33xx, netstack_work);
+
+	do {
+		cc33xx_flush_deferred_work(cc);
+	} while (skb_queue_len(&cc->deferred_rx_queue));
+}
+
+static int cc33xx_irq_locked(struct cc33xx *cc)
+{
+	int ret = 0;
+	struct core_status *core_status_ptr;
+	u8 *rx_buf_ptr;
+	u16 rx_buf_len;
+	size_t read_data_len;
+	const size_t maximum_rx_packet_size = CC33XX_FW_RX_PACKET_RAM;
+	size_t rx_byte_count;
+	struct NAB_rx_header *NAB_rx_header;
+
+	process_deferred_events(cc);
+
+	claim_core_status_lock(cc);
+
+	rx_byte_count = (le32_to_cpu(cc->core_status->rx_status) & RX_BYTE_COUNT_MASK);
+	if (rx_byte_count != 0) {
+		const int read_headers_len = sizeof(struct core_status)
+			+ sizeof(struct NAB_rx_header);
+
+		/* Read aggressively as more data might be coming in */
+		rx_byte_count *= 2;
+
+		read_data_len = rx_byte_count + read_headers_len;
+
+		if (cc->max_transaction_len) { /* Used in SPI interface */
+			const int spi_alignment = sizeof(u32) - 1;
+
+			read_data_len = __ALIGN_MASK(read_data_len,
+						     spi_alignment);
+			read_data_len = min(read_data_len,
+					    cc->max_transaction_len);
+		} else { /* SDIO */
+			const int sdio_alignment = CC33XX_BUS_BLOCK_SIZE - 1;
+
+			read_data_len = __ALIGN_MASK(read_data_len,
+						     sdio_alignment);
+			read_data_len = min(read_data_len,
+					    maximum_rx_packet_size);
+		}
+
+		ret = cc33xx_raw_read(cc, NAB_DATA_ADDR, cc->aggr_buf,
+				      read_data_len, true);
+		if (ret < 0) {
+			release_core_status_lock(cc);
+			return ret;
+		}
+
+		core_status_ptr = (struct core_status *)((u8 *)cc->aggr_buf +
+				    read_data_len - sizeof(struct core_status));
+
+		memcpy(cc->core_status,
+		       core_status_ptr, sizeof(struct core_status));
+
+		process_core_status(cc, cc->core_status);
+
+		release_core_status_lock(cc);
+
+		NAB_rx_header = (struct NAB_rx_header *)cc->aggr_buf;
+		rx_buf_len = le16_to_cpu(NAB_rx_header->len) - 8;
+		if (rx_buf_len != 0) {
+			rx_buf_ptr = (u8 *)cc->aggr_buf + sizeof(struct NAB_rx_header);
+			cc33xx_rx(cc, rx_buf_ptr, rx_buf_len);
+		} else {
+			cc33xx_error("Rx buffer length is 0");
+			cc33xx_queue_recovery_work(cc);
+		}
+	} else {
+		release_core_status_lock(cc);
+	}
+
+	cc33xx_tx_immediate_complete(cc);
+
+	return ret;
+}
+
+static int read_core_status(struct cc33xx *cc, struct core_status *core_status)
+{
+	return cc33xx_raw_read(cc, NAB_STATUS_ADDR, core_status,
+			       sizeof(*core_status), false);
+}
+
+#define CTRL_TYPE_BITS 4
+static int get_type(struct control_info_descriptor *control_info_descriptor)
+{
+	u16 type_mask = GENMASK(CTRL_TYPE_BITS - 1, 0);
+
+	return le16_to_cpu(control_info_descriptor->type_and_length) & type_mask;
+}
+
+static unsigned int get_length(struct control_info_descriptor *control_info_descriptor)
+{
+	return le16_to_cpu(control_info_descriptor->type_and_length) >> CTRL_TYPE_BITS;
+}
+
+static int parse_control_message(struct cc33xx *cc,
+				 const u8 *buffer, size_t buffer_length)
+{
+	u8 *const end_of_payload = (u8 *const)buffer + buffer_length;
+	u8 *const start_of_payload = (u8 *const)buffer;
+	struct control_info_descriptor *control_info_descriptor;
+	const u8 *event_data, *cmd_result_data;
+	unsigned int ctrl_info_type, ctrl_info_length;
+
+	while (buffer < end_of_payload) {
+		control_info_descriptor =
+				(struct control_info_descriptor *)buffer;
+
+		ctrl_info_type = get_type(control_info_descriptor);
+		ctrl_info_length = get_length(control_info_descriptor);
+
+		cc33xx_debug(DEBUG_CMD, "Processing message type %d, len %d",
+			     ctrl_info_type, ctrl_info_length);
+
+		switch (ctrl_info_type) {
+		case CTRL_MSG_EVENT:
+			event_data = buffer + sizeof(*control_info_descriptor);
+
+			deffer_event(cc, event_data, ctrl_info_length);
+			break;
+
+		case CTRL_MSG_COMMND_COMPLETE:
+			cmd_result_data = buffer;
+			cmd_result_data += sizeof(*control_info_descriptor);
+
+			if (ctrl_info_length > sizeof(cc->command_result)) {
+				print_hex_dump(KERN_DEBUG, "message dump:",
+					       DUMP_PREFIX_OFFSET, 16, 1,
+					       cmd_result_data,
+					       ctrl_info_length, false);
+
+				WARN(1, "Error device response exceeds result buffer size");
+
+				goto message_parse_error;
+			}
+
+			memcpy(cc->command_result,
+			       cmd_result_data, ctrl_info_length);
+
+			cc->result_length = ctrl_info_length;
+
+			complete(&cc->command_complete);
+			break;
+
+		default:
+			print_hex_dump(KERN_DEBUG, "message dump:",
+				       DUMP_PREFIX_OFFSET, 16, 1,
+				start_of_payload, buffer_length, false);
+
+			WARN(1, "Error processing device message @ offset %zu",
+			     (size_t)(buffer - start_of_payload));
+
+			goto message_parse_error;
+		}
+
+		buffer += sizeof(*control_info_descriptor);
+		buffer += ctrl_info_length;
+	}
+
+	return 0;
+
+message_parse_error:
+	return -EIO;
+}
+
+static int read_control_message(struct cc33xx *cc, u8 *read_buffer,
+				size_t buffer_size)
+{
+	int ret;
+	size_t device_message_size;
+	struct NAB_header *nab_header;
+
+	ret = cc33xx_raw_read(cc, NAB_CONTROL_ADDR, read_buffer,
+			      buffer_size, false);
+
+	if (ret < 0) {
+		cc33xx_debug(DEBUG_CMD,
+			     "control read Error response 0x%x", ret);
+		return ret;
+	}
+
+	nab_header = (struct NAB_header *)read_buffer;
+
+	if (le32_to_cpu(nab_header->sync_pattern) != DEVICE_SYNC_PATTERN) {
+		cc33xx_error("Wrong device sync pattern: 0x%x",
+			     nab_header->sync_pattern);
+		return -EIO;
+	}
+
+	device_message_size = sizeof(*nab_header) + NAB_EXTRA_BYTES
+							+ le16_to_cpu(nab_header->len);
+
+	if (device_message_size > buffer_size) {
+		cc33xx_error("Invalid NAB length field: %x", nab_header->len);
+		return -EIO;
+	}
+
+	return le16_to_cpu(nab_header->len);
+}
+
+static int process_event_and_cmd_result(struct cc33xx *cc,
+					struct core_status *core_status)
+{
+	int ret;
+	u8 *read_buffer, *message;
+	const size_t buffer_size = CC33XX_CMD_MAX_SIZE;
+	size_t message_length;
+	struct core_status *new_core_status;
+	__le32 previous_hint;
+
+	read_buffer = kmalloc(buffer_size, GFP_KERNEL);
+	if (!read_buffer)
+		return -ENOMEM;
+
+	ret = read_control_message(cc, read_buffer, buffer_size);
+	if (ret < 0)
+		goto out;
+
+	message_length = ret - NAB_EXTRA_BYTES;
+	message = read_buffer + sizeof(struct NAB_header) + NAB_EXTRA_BYTES;
+	ret = parse_control_message(cc, message, message_length);
+	if (ret < 0)
+		goto out;
+
+	/* Each read transaction always carries an updated core status */
+	previous_hint = core_status->host_interrupt_status;
+	new_core_status = (struct core_status *)
+		(read_buffer + buffer_size - sizeof(struct core_status));
+	memcpy(core_status, new_core_status, sizeof(*core_status));
+	/* Host interrupt filed is clear-on-read and we do not want
+	 * to overrun previously unhandled bits.
+	 */
+	core_status->host_interrupt_status |= previous_hint;
+
+out:
+	kfree(read_buffer);
+	return ret;
+}
+
+static int verify_padding(struct core_status *core_status)
+{
+	unsigned int i;
+	const u32 valid_padding = 0x55555555;
+
+	for (i = 0; i < ARRAY_SIZE(core_status->block_pad); i++) {
+		if (le32_to_cpu(core_status->block_pad[i]) != valid_padding) {
+			cc33xx_error("Error in core status padding:");
+			print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16,
+				       1, core_status, sizeof(*core_status),
+				       false);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int process_core_status(struct cc33xx *cc,
+			       struct core_status *core_status)
+{
+	bool	core_status_idle;
+	u32	shadow_host_interrupt_status;
+	int	ret;
+
+	do {
+		core_status_idle = true;
+
+		shadow_host_interrupt_status =
+			le32_to_cpu(core_status->host_interrupt_status);
+
+		/* Interrupts are aggregated (ORed) in this filed with each
+		 * read operation from the device.
+		 */
+		core_status->host_interrupt_status = 0;
+
+		cc33xx_debug(DEBUG_IRQ,
+			     "HINT_STATUS: 0x%x, TSF: 0x%x, rx status: 0x%x",
+			     shadow_host_interrupt_status, core_status->tsf,
+			     core_status->rx_status);
+
+		if (shadow_host_interrupt_status & HINT_COMMAND_COMPLETE) {
+			ret = process_event_and_cmd_result(cc, core_status);
+			if (ret < 0) {
+				memset(core_status, 0, sizeof(*core_status));
+				return ret;
+			}
+			core_status_idle = false;
+		}
+
+		if ((le32_to_cpu(core_status->rx_status) & RX_BYTE_COUNT_MASK) != 0)
+			queue_work(cc->freezable_wq, &cc->irq_deferred_work);
+
+		if (core_status->fw_info.tx_result_queue_index != cc->last_fw_rls_idx)
+			queue_work(cc->freezable_wq, &cc->irq_deferred_work);
+
+		if (shadow_host_interrupt_status &  HINT_NEW_TX_RESULT)
+			queue_work(cc->freezable_wq, &cc->irq_deferred_work);
+
+		if (shadow_host_interrupt_status & BOOT_TIME_INTERRUPTS)
+			cc33xx_handle_boot_irqs(cc, shadow_host_interrupt_status);
+
+		if (shadow_host_interrupt_status & HINT_GENERAL_ERROR) {
+			cc33xx_error("FW is stuck, triggering recovery");
+			cc33xx_queue_recovery_work(cc);
+		}
+	} while (!core_status_idle);
+
+	return 0;
+}
+
+void cc33xx_irq(void *cookie)
+{
+	struct cc33xx *cc = cookie;
+	unsigned long flags;
+	int ret;
+
+	claim_core_status_lock(cc);
+
+	if (test_bit(CC33XX_FLAG_SUSPENDED, &cc->flags)) {
+		/* don't enqueue a work right now. mark it as pending */
+		set_bit(CC33XX_FLAG_PENDING_WORK, &cc->flags);
+		spin_lock_irqsave(&cc->cc_lock, flags);
+		cc33xx_disable_interrupts_nosync(cc);
+		pm_wakeup_hard_event(cc->dev);
+		spin_unlock_irqrestore(&cc->cc_lock, flags);
+		goto out;
+	}
+
+	ret = read_core_status(cc, cc->core_status);
+	if (unlikely(ret < 0)) {
+		cc33xx_error("IO error during core status read");
+		cc33xx_queue_recovery_work(cc);
+		goto out;
+	}
+
+	ret = verify_padding(cc->core_status);
+	if (unlikely(ret < 0)) {
+		cc33xx_queue_recovery_work(cc);
+		goto out;
+	}
+
+	process_core_status(cc, cc->core_status);
+
+out:
+	release_core_status_lock(cc);
+}
+
+struct vif_counter_data {
+	u8 counter;
+
+	struct ieee80211_vif *cur_vif;
+	bool cur_vif_running;
+};
+
+static void cc33xx_vif_count_iter(void *data, u8 *mac,
+				  struct ieee80211_vif *vif)
+{
+	struct vif_counter_data *counter = data;
+
+	counter->counter++;
+	if (counter->cur_vif == vif)
+		counter->cur_vif_running = true;
+}
+
+/* caller must not hold cc->mutex, as it might deadlock */
+static void cc33xx_get_vif_count(struct ieee80211_hw *hw,
+				 struct ieee80211_vif *cur_vif,
+				 struct vif_counter_data *data)
+{
+	memset(data, 0, sizeof(*data));
+	data->cur_vif = cur_vif;
+
+	ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+					    cc33xx_vif_count_iter, data);
+}
+
+void cc33xx_queue_recovery_work(struct cc33xx *cc)
+{
+	/* Avoid a recursive recovery */
+	if (cc->state == CC33XX_STATE_ON) {
+		cc->state = CC33XX_STATE_RESTARTING;
+		set_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS, &cc->flags);
+		ieee80211_queue_work(cc->hw, &cc->recovery_work);
+	}
+}
+
+static void cc33xx_save_freed_pkts(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				   u8 hlid, struct ieee80211_sta *sta)
+{
+	struct cc33xx_station *wl_sta;
+	u32 sqn_recovery_padding = CC33XX_TX_SQN_POST_RECOVERY_PADDING;
+
+	wl_sta = (void *)sta->drv_priv;
+	wl_sta->total_freed_pkts = cc->links[hlid].total_freed_pkts;
+
+	/* increment the initial seq number on recovery to account for
+	 * transmitted packets that we haven't yet got in the FW status
+	 */
+	if (wlvif->encryption_type == KEY_GEM)
+		sqn_recovery_padding = CC33XX_TX_SQN_POST_RECOVERY_PADDING_GEM;
+
+	if (test_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS, &cc->flags))
+		wl_sta->total_freed_pkts += sqn_recovery_padding;
+}
+
+static void cc33xx_save_freed_pkts_addr(struct cc33xx *cc,
+					struct cc33xx_vif *wlvif,
+					u8 hlid, const u8 *addr)
+{
+	struct ieee80211_sta *sta;
+	struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
+
+	if (WARN_ON(hlid == CC33XX_INVALID_LINK_ID ||
+		    is_zero_ether_addr(addr)))
+		return;
+
+	rcu_read_lock();
+	sta = ieee80211_find_sta(vif, addr);
+
+	if (sta)
+		cc33xx_save_freed_pkts(cc, wlvif, hlid, sta);
+
+	rcu_read_unlock();
+}
+
+static void cc33xx_recovery_work(struct work_struct *work)
+{
+	struct cc33xx *cc = container_of(work, struct cc33xx, recovery_work);
+	struct cc33xx_vif *wlvif;
+	struct ieee80211_vif *vif;
+
+	cc33xx_notice("CC33xx driver attempting recovery");
+
+	if (cc->conf.core.no_recovery) {
+		cc33xx_info("Recovery disabled by configuration, driver will not restart.");
+		return;
+	}
+
+	if (test_bit(CC33XX_FLAG_DRIVER_REMOVED, &cc->flags)) {
+		cc33xx_info("Driver being removed, recovery disabled");
+		return;
+	}
+
+	cc->state = CC33XX_STATE_RESTARTING;
+	set_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS, &cc->flags);
+
+	mutex_lock(&cc->mutex);
+	while (!list_empty(&cc->wlvif_list)) {
+		wlvif = list_first_entry(&cc->wlvif_list,
+					 struct cc33xx_vif, list);
+		vif = cc33xx_wlvif_to_vif(wlvif);
+
+		if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+			ieee80211_connection_loss(vif);
+
+		__cc33xx_op_remove_interface(cc, vif, false);
+	}
+	mutex_unlock(&cc->mutex);
+
+	cc33xx_turn_off(cc);
+	msleep(500);
+
+	mutex_lock(&cc->mutex);
+	cc33xx_init_fw(cc);
+	mutex_unlock(&cc->mutex);
+
+	ieee80211_restart_hw(cc->hw);
+
+	mutex_lock(&cc->mutex);
+	clear_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS, &cc->flags);
+	mutex_unlock(&cc->mutex);
+}
+
+static void irq_deferred_work(struct work_struct *work)
+{
+	int ret;
+	unsigned long flags;
+	struct cc33xx *cc =
+		container_of(work, struct cc33xx, irq_deferred_work);
+
+	mutex_lock(&cc->mutex);
+
+	ret = cc33xx_irq_locked(cc);
+	if (ret)
+		cc33xx_queue_recovery_work(cc);
+
+	spin_lock_irqsave(&cc->cc_lock, flags);
+	/* In case TX was not handled here, queue TX work */
+	clear_bit(CC33XX_FLAG_TX_PENDING, &cc->flags);
+	if (!test_bit(CC33XX_FLAG_FW_TX_BUSY, &cc->flags) &&
+	    cc33xx_tx_total_queue_count(cc) > 0)
+		ieee80211_queue_work(cc->hw, &cc->tx_work);
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+
+	mutex_unlock(&cc->mutex);
+}
+
+static void irq_wrapper(struct platform_device *pdev)
+{
+	struct cc33xx *cc = platform_get_drvdata(pdev);
+
+	cc33xx_irq(cc);
+}
+
+static int cc33xx_plt_init(struct cc33xx *cc)
+{
+	/* PLT init: Role enable + Role start + plt Init  */
+	int ret = 0;
+
+	/* Role enable */
+	u8  returned_role_id = CC33XX_INVALID_ROLE_ID;
+	u8 bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+	ret = cc33xx_cmd_role_enable(cc, bcast_addr,
+				     ROLE_TRANSCEIVER, &returned_role_id);
+	if (ret < 0) {
+		cc33xx_info("PLT init Role Enable FAILED! , PLT roleID is: %u ",
+			    returned_role_id);
+		goto out;
+	}
+
+	ret = cc33xx_cmd_role_start_transceiver(cc, returned_role_id);
+	if (ret < 0) {
+		cc33xx_info("PLT init Role Start FAILED! , PLT roleID is: %u ",
+			    returned_role_id);
+		cc33xx_cmd_role_disable(cc, &returned_role_id);
+		goto out;
+	}
+
+	cc->plt_role_id = returned_role_id;
+	ret = cc33xx_cmd_plt_enable(cc, returned_role_id);
+
+	if (ret >= 0) {
+		cc33xx_info("PLT init Role Start succeed!, PLT roleID is: %u ",
+			    returned_role_id);
+	} else {
+		cc33xx_info("PLT init Role Start FAILED! , PLT roleID is: %u ",
+			    returned_role_id);
+	}
+
+out:
+	return ret;
+}
+
+int cc33xx_plt_start(struct cc33xx *cc, const enum plt_mode plt_mode)
+{
+	int ret = 0;
+
+	mutex_lock(&cc->mutex);
+
+	if (plt_mode == PLT_ON && cc->plt_mode == PLT_ON) {
+		cc33xx_error("PLT already on");
+		ret = 0;
+		goto out;
+	}
+
+	cc33xx_notice("PLT start");
+
+	if (plt_mode != PLT_CHIP_AWAKE) {
+		ret = cc33xx_plt_init(cc);
+		if (ret < 0) {
+			cc33xx_error("PLT start failed");
+			goto out;
+		}
+	}
+
+	/* Indicate to lower levels that we are now in PLT mode */
+	cc->plt = true;
+	cc->plt_mode = plt_mode;
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+int cc33xx_plt_stop(struct cc33xx *cc)
+{
+	int ret = 0;
+
+	cc33xx_notice("PLT stop");
+
+	ret = cc33xx_cmd_role_stop_transceiver(cc);
+	if (ret < 0)
+		goto out;
+
+	ret = cc33xx_cmd_role_disable(cc, &cc->plt_role_id);
+	if (ret < 0)
+		goto out;
+	else
+		cc33xx_cmd_plt_disable(cc);
+
+	cc33xx_flush_deferred_work(cc);
+
+	flush_deferred_event_list(cc);
+
+	mutex_lock(&cc->mutex);
+	cc->plt = false;
+	cc->plt_mode = PLT_OFF;
+	cc->rx_counter = 0;
+	mutex_unlock(&cc->mutex);
+
+out:
+	return ret;
+}
+
+static void cc33xx_op_tx(struct ieee80211_hw *hw,
+			 struct ieee80211_tx_control *control,
+			 struct sk_buff *skb)
+{
+	struct cc33xx *cc = hw->priv;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_vif *vif = info->control.vif;
+	struct cc33xx_vif *wlvif = NULL;
+	enum cc33xx_queue_stop_reason stop_reason = CC33XX_QUEUE_STOP_REASON_WATERMARK;
+	unsigned long flags;
+	int q, mapping;
+	u8 hlid;
+
+	if (!vif) {
+		ieee80211_free_txskb(hw, skb);
+		return;
+	}
+
+	wlvif = cc33xx_vif_to_data(vif);
+	mapping = skb_get_queue_mapping(skb);
+	q = cc33xx_tx_get_queue(mapping);
+
+	hlid = cc33xx_tx_get_hlid(cc, wlvif, skb, control->sta);
+
+	spin_lock_irqsave(&cc->cc_lock, flags);
+
+	/* drop the packet if the link is invalid or the queue is stopped
+	 * for any reason but watermark. Watermark is a "soft"-stop so we
+	 * allow these packets through.
+	 */
+
+	if (hlid == CC33XX_INVALID_LINK_ID ||
+	    (!test_bit(hlid, wlvif->links_map)) ||
+	    (cc33xx_is_queue_stopped_locked(cc, wlvif, q) &&
+	    !cc33xx_is_queue_stopped_by_reason_locked(cc, wlvif, q,
+						      stop_reason))) {
+		cc33xx_debug(DEBUG_TX, "DROP skb hlid %d q %d ", hlid, q);
+		ieee80211_free_txskb(hw, skb);
+		goto out;
+	}
+
+	cc33xx_debug(DEBUG_TX, "queue skb hlid %d q %d len %d %p",
+		     hlid, q, skb->len, skb);
+	skb_queue_tail(&cc->links[hlid].tx_queue[q], skb);
+
+	cc->tx_queue_count[q]++;
+	wlvif->tx_queue_count[q]++;
+
+	/* The workqueue is slow to process the tx_queue and we need stop
+	 * the queue here, otherwise the queue will get too long.
+	 */
+	if (wlvif->tx_queue_count[q] >= CC33XX_TX_QUEUE_HIGH_WATERMARK &&
+	    !cc33xx_is_queue_stopped_by_reason_locked(cc, wlvif, q,
+						      stop_reason)) {
+		cc33xx_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q);
+		cc33xx_stop_queue_locked(cc, wlvif, q, stop_reason);
+	}
+
+	/* The chip specific setup must run before the first TX packet -
+	 * before that, the tx_work will not be initialized!
+	 */
+	if (!test_bit(CC33XX_FLAG_FW_TX_BUSY, &cc->flags) &&
+	    !test_bit(CC33XX_FLAG_TX_PENDING, &cc->flags)) {
+		cc33xx_debug(DEBUG_TX, "Triggering tx thread");
+		ieee80211_queue_work(cc->hw, &cc->tx_work);
+	} else {
+		cc33xx_debug(DEBUG_TX, "Not triggering tx thread cc->flags 0x%lx",
+			     cc->flags);
+	}
+
+out:
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+}
+
+/* The size of the dummy packet should be at least 1400 bytes. However, in
+ * order to minimize the number of bus transactions, aligning it to 512 bytes
+ * boundaries could be beneficial, performance wise
+ */
+#define TOTAL_TX_DUMMY_PACKET_SIZE (ALIGN(1400, 512))
+
+static struct sk_buff *cc33xx_alloc_dummy_packet(struct cc33xx *cc)
+{
+	struct sk_buff *skb;
+	struct ieee80211_hdr_3addr *hdr;
+	unsigned int dummy_packet_size;
+
+	dummy_packet_size = TOTAL_TX_DUMMY_PACKET_SIZE -
+			    sizeof(struct cc33xx_tx_hw_descr) - sizeof(*hdr);
+
+	skb = dev_alloc_skb(TOTAL_TX_DUMMY_PACKET_SIZE);
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, sizeof(struct cc33xx_tx_hw_descr));
+
+	hdr = skb_put_zero(skb, sizeof(*hdr));
+	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
+					 IEEE80211_STYPE_NULLFUNC |
+					 IEEE80211_FCTL_TODS);
+
+	skb_put_zero(skb, dummy_packet_size);
+
+	/* Dummy packets require the TID to be management */
+	skb->priority = CC33XX_TID_MGMT;
+
+	/* Initialize all fields that might be used */
+	skb_set_queue_mapping(skb, 0);
+	memset(IEEE80211_SKB_CB(skb), 0, sizeof(struct ieee80211_tx_info));
+
+	return skb;
+}
+
+static int cc33xx_validate_wowlan_pattern(struct cfg80211_pkt_pattern *p)
+{
+	int num_fields = 0, in_field = 0, fields_size = 0;
+	int i, pattern_len = 0;
+
+	if (!p->mask) {
+		cc33xx_warning("No mask in WoWLAN pattern");
+		return -EINVAL;
+	}
+
+	/* The pattern is broken up into segments of bytes at different offsets
+	 * that need to be checked by the FW filter. Each segment is called
+	 * a field in the FW API. We verify that the total number of fields
+	 * required for this pattern won't exceed FW limits (8)
+	 * as well as the total fields buffer won't exceed the FW limit.
+	 * Note that if there's a pattern which crosses Ethernet/IP header
+	 * boundary a new field is required.
+	 */
+	for (i = 0; i < p->pattern_len; i++) {
+		if (test_bit(i, (unsigned long *)p->mask)) {
+			if (!in_field) {
+				in_field = 1;
+				pattern_len = 1;
+			} else if (i == CC33XX_RX_FILTER_ETH_HEADER_SIZE) {
+				num_fields++;
+				fields_size += pattern_len +
+					RX_FILTER_FIELD_OVERHEAD;
+				pattern_len = 1;
+			} else {
+				pattern_len++;
+			}
+		} else if (in_field) {
+			in_field = 0;
+			fields_size += pattern_len + RX_FILTER_FIELD_OVERHEAD;
+			num_fields++;
+		}
+	}
+
+	if (in_field) {
+		fields_size += pattern_len + RX_FILTER_FIELD_OVERHEAD;
+		num_fields++;
+	}
+
+	if (num_fields > CC33XX_RX_FILTER_MAX_FIELDS) {
+		cc33xx_warning("RX Filter too complex. Too many segments");
+		return -EINVAL;
+	}
+
+	if (fields_size > CC33XX_RX_FILTER_MAX_FIELDS_SIZE) {
+		cc33xx_warning("RX filter pattern is too big");
+		return -E2BIG;
+	}
+
+	return 0;
+}
+
+static void cc33xx_rx_filter_free(struct cc33xx_rx_filter *filter)
+{
+	int i;
+
+	if (!filter)
+		return;
+
+	for (i = 0; i < filter->num_fields; i++)
+		kfree(filter->fields[i].pattern);
+
+	kfree(filter);
+}
+
+static int cc33xx_rx_filter_alloc_field(struct cc33xx_rx_filter *filter,
+					u16 offset, u8 flags,
+					const u8 *pattern, u8 len)
+{
+	struct cc33xx_rx_filter_field *field;
+
+	if (filter->num_fields == CC33XX_RX_FILTER_MAX_FIELDS) {
+		cc33xx_warning("Max fields per RX filter. can't alloc another");
+		return -EINVAL;
+	}
+
+	field = &filter->fields[filter->num_fields];
+
+	field->pattern = kzalloc(len, GFP_KERNEL);
+	if (!field->pattern)
+		return -ENOMEM;
+
+	filter->num_fields++;
+
+	field->offset = cpu_to_le16(offset);
+	field->flags = flags;
+	field->len = len;
+	memcpy(field->pattern, pattern, len);
+
+	return 0;
+}
+
+/* Allocates an RX filter returned through f
+ * which needs to be freed using rx_filter_free()
+ */
+static int
+cc33xx_convert_wowlan_pattern_to_rx_filter(struct cfg80211_pkt_pattern *p,
+					   struct cc33xx_rx_filter **f)
+{
+	int i, j, ret = 0;
+	struct cc33xx_rx_filter *filter;
+	u16 offset;
+	u8 flags, len;
+
+	filter = kzalloc(sizeof(*filter), GFP_KERNEL);
+	if (!filter) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	i = 0;
+	while (i < p->pattern_len) {
+		if (!test_bit(i, (unsigned long *)p->mask)) {
+			i++;
+			continue;
+		}
+
+		for (j = i; j < p->pattern_len; j++) {
+			if (!test_bit(j, (unsigned long *)p->mask))
+				break;
+
+			if (i < CC33XX_RX_FILTER_ETH_HEADER_SIZE &&
+			    j >= CC33XX_RX_FILTER_ETH_HEADER_SIZE)
+				break;
+		}
+
+		if (i < CC33XX_RX_FILTER_ETH_HEADER_SIZE) {
+			offset = i;
+			flags = CC33XX_RX_FILTER_FLAG_ETHERNET_HEADER;
+		} else {
+			offset = i - CC33XX_RX_FILTER_ETH_HEADER_SIZE;
+			flags = CC33XX_RX_FILTER_FLAG_IP_HEADER;
+		}
+
+		len = j - i;
+
+		ret = cc33xx_rx_filter_alloc_field(filter, offset, flags,
+						   &p->pattern[i], len);
+		if (ret)
+			goto err;
+
+		i = j;
+	}
+
+	filter->action = FILTER_SIGNAL;
+
+	*f = filter;
+	ret = 0;
+	goto out;
+
+err:
+	cc33xx_rx_filter_free(filter);
+	*f = NULL;
+out:
+	return ret;
+}
+
+static int cc33xx_configure_wowlan(struct cc33xx *cc,
+				   struct cfg80211_wowlan *wow)
+{
+	int i, ret;
+
+	if (!wow || (!wow->any && !wow->n_patterns)) {
+		if (wow)
+			cc33xx_warning("invalid wow configuration - set to pattern trigger without setting pattern");
+
+		ret = cc33xx_acx_default_rx_filter_enable(cc, 0,
+							  FILTER_SIGNAL);
+		if (ret)
+			goto out;
+
+		ret = cc33xx_rx_filter_clear_all(cc);
+		if (ret)
+			goto out;
+
+		return 0;
+	}
+
+	if (wow->any) {
+		ret = cc33xx_acx_default_rx_filter_enable(cc, 1,
+							  FILTER_SIGNAL);
+		if (ret)
+			goto out;
+
+		ret = cc33xx_rx_filter_clear_all(cc);
+		if (ret)
+			goto out;
+
+		return 0;
+	}
+
+	if (WARN_ON(wow->n_patterns > CC33XX_MAX_RX_FILTERS))
+		return -EINVAL;
+
+	/* Validate all incoming patterns before clearing current FW state */
+	for (i = 0; i < wow->n_patterns; i++) {
+		ret = cc33xx_validate_wowlan_pattern(&wow->patterns[i]);
+		if (ret) {
+			cc33xx_warning("Bad wowlan pattern %d", i);
+			return ret;
+		}
+	}
+
+	ret = cc33xx_acx_default_rx_filter_enable(cc, 0, FILTER_SIGNAL);
+	if (ret)
+		goto out;
+
+	ret = cc33xx_rx_filter_clear_all(cc);
+	if (ret)
+		goto out;
+
+	/* Translate WoWLAN patterns into filters */
+	for (i = 0; i < wow->n_patterns; i++) {
+		struct cfg80211_pkt_pattern *p;
+		struct cc33xx_rx_filter *filter = NULL;
+
+		p = &wow->patterns[i];
+
+		ret = cc33xx_convert_wowlan_pattern_to_rx_filter(p, &filter);
+		if (ret) {
+			cc33xx_warning("Failed to create an RX filter from wowlan pattern %d",
+				       i);
+			goto out;
+		}
+
+		ret = cc33xx_rx_filter_enable(cc, i, 1, filter);
+
+		cc33xx_rx_filter_free(filter);
+		if (ret)
+			goto out;
+	}
+
+	ret = cc33xx_acx_default_rx_filter_enable(cc, 1, FILTER_DROP);
+
+out:
+	return ret;
+}
+
+static int cc33xx_configure_suspend_sta(struct cc33xx *cc,
+					struct cc33xx_vif *wlvif,
+					struct cfg80211_wowlan *wow)
+{
+	struct cc33xx_core_conf *core_conf = &cc->conf.core;
+	int ret = 0;
+
+	if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+		goto out;
+
+	ret = cc33xx_configure_wowlan(cc, wow);
+	if (ret < 0)
+		goto out;
+
+	if (core_conf->suspend_wake_up_event == core_conf->wake_up_event &&
+	    core_conf->suspend_listen_interval == core_conf->listen_interval)
+		goto out;
+
+	ret = cc33xx_acx_wake_up_conditions(cc, wlvif,
+					    core_conf->suspend_wake_up_event,
+					    core_conf->suspend_listen_interval);
+
+	if (ret < 0)
+		cc33xx_error("suspend: set wake up conditions failed: %d", ret);
+out:
+	return ret;
+}
+
+static int cc33xx_configure_suspend_ap(struct cc33xx *cc,
+				       struct cc33xx_vif *wlvif,
+				       struct cfg80211_wowlan *wow)
+{
+	int ret = 0;
+
+	if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
+		goto out;
+
+	ret = cc33xx_acx_beacon_filter_opt(cc, wlvif, true);
+	if (ret < 0)
+		goto out;
+
+	ret = cc33xx_configure_wowlan(cc, wow);
+	if (ret < 0)
+		goto out;
+
+out:
+	return ret;
+}
+
+static int cc33xx_configure_suspend(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				    struct cfg80211_wowlan *wow)
+{
+	if (wlvif->bss_type == BSS_TYPE_STA_BSS)
+		return cc33xx_configure_suspend_sta(cc, wlvif, wow);
+
+	if (wlvif->bss_type == BSS_TYPE_AP_BSS)
+		return cc33xx_configure_suspend_ap(cc, wlvif, wow);
+
+	return 0;
+}
+
+static void cc33xx_configure_resume(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	int ret = 0;
+	bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
+	bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
+	struct cc33xx_core_conf *core_conf = &cc->conf.core;
+
+	if (!is_ap && !is_sta)
+		return;
+
+	if ((is_sta && !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) ||
+	    (is_ap && !test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)))
+		return;
+
+	cc33xx_configure_wowlan(cc, NULL);
+
+	if (is_sta) {
+		if (core_conf->suspend_wake_up_event == core_conf->wake_up_event &&
+		    core_conf->suspend_listen_interval == core_conf->listen_interval)
+			return;
+
+		ret = cc33xx_acx_wake_up_conditions(cc, wlvif,
+						    core_conf->wake_up_event,
+						    core_conf->listen_interval);
+
+		if (ret < 0)
+			cc33xx_error("resume: wake up conditions failed: %d",
+				     ret);
+
+	} else if (is_ap) {
+		ret = cc33xx_acx_beacon_filter_opt(cc, wlvif, false);
+	}
+}
+
+static int __maybe_unused cc33xx_op_suspend(struct ieee80211_hw *hw,
+					    struct cfg80211_wowlan *wow)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif;
+	unsigned long flags;
+	int ret = 0;
+
+	WARN_ON(!wow);
+
+	/* we want to perform the recovery before suspending */
+	if (test_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS, &cc->flags)) {
+		cc33xx_warning("postponing suspend to perform recovery");
+		return -EBUSY;
+	}
+
+	cc33xx_tx_flush(cc);
+
+	mutex_lock(&cc->mutex);
+
+	cc->keep_device_power = true;
+	cc33xx_for_each_wlvif(cc, wlvif) {
+		if (cc33xx_is_p2p_mgmt(wlvif))
+			continue;
+
+		ret = cc33xx_configure_suspend(cc, wlvif, wow);
+		if (ret < 0) {
+			mutex_unlock(&cc->mutex);
+			cc33xx_warning("couldn't prepare device to suspend");
+			return ret;
+		}
+	}
+
+	mutex_unlock(&cc->mutex);
+
+	if (ret < 0) {
+		cc33xx_warning("couldn't prepare device to suspend");
+		return ret;
+	}
+
+	flush_work(&cc->tx_work);
+
+	/* Cancel the watchdog even if above tx_flush failed. We will detect
+	 * it on resume anyway.
+	 */
+	cancel_delayed_work(&cc->tx_watchdog_work);
+
+	/* set suspended flag to avoid triggering a new threaded_irq
+	 * work.
+	 */
+	spin_lock_irqsave(&cc->cc_lock, flags);
+	set_bit(CC33XX_FLAG_SUSPENDED, &cc->flags);
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+
+	return 0;
+}
+
+static int __maybe_unused cc33xx_op_resume(struct ieee80211_hw *hw)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif;
+	unsigned long flags;
+	bool run_irq_work = false, pending_recovery;
+	int ret = 0;
+
+	WARN_ON(!cc->keep_device_power);
+
+	/* re-enable irq_work enqueuing, and call irq_work directly if
+	 * there is a pending work.
+	 */
+	spin_lock_irqsave(&cc->cc_lock, flags);
+	clear_bit(CC33XX_FLAG_SUSPENDED, &cc->flags);
+	run_irq_work = test_and_clear_bit(CC33XX_FLAG_PENDING_WORK, &cc->flags);
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+
+	mutex_lock(&cc->mutex);
+
+	/* test the recovery flag before calling any SDIO functions */
+	pending_recovery = test_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS,
+				    &cc->flags);
+
+	if (run_irq_work) {
+		cc33xx_debug(DEBUG_MAC80211, "Running postponed irq_work directly");
+
+		/* don't talk to the HW if recovery is pending */
+		if (!pending_recovery) {
+			ret = cc33xx_irq_locked(cc);
+			if (ret)
+				cc33xx_queue_recovery_work(cc);
+		}
+
+		cc33xx_enable_interrupts(cc);
+	}
+
+	if (pending_recovery) {
+		cc33xx_warning("queuing forgotten recovery on resume");
+		ieee80211_queue_work(cc->hw, &cc->recovery_work);
+		goto out;
+	}
+
+	cc33xx_for_each_wlvif(cc, wlvif) {
+		if (cc33xx_is_p2p_mgmt(wlvif))
+			continue;
+
+		cc33xx_configure_resume(cc, wlvif);
+	}
+
+out:
+	cc->keep_device_power = false;
+
+	/* Set a flag to re-init the watchdog on the first Tx after resume.
+	 * That way we avoid possible conditions where Tx-complete interrupts
+	 * fail to arrive and we perform a spurious recovery.
+	 */
+	set_bit(CC33XX_FLAG_REINIT_TX_WDOG, &cc->flags);
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+static int cc33xx_op_start(struct ieee80211_hw *hw)
+{
+	/* We have to delay the booting of the hardware because
+	 * we need to know the local MAC address before downloading and
+	 * initializing the firmware. The MAC address cannot be changed
+	 * after boot, and without the proper MAC address, the firmware
+	 * will not function properly.
+	 *
+	 * The MAC address is first known when the corresponding interface
+	 * is added. That is where we will initialize the hardware.
+	 */
+
+	return 0;
+}
+
+static void cc33xx_turn_off(struct cc33xx *cc)
+{
+	int i;
+
+	if (cc->state == CC33XX_STATE_OFF) {
+		if (test_and_clear_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS,
+				       &cc->flags))
+			cc33xx_enable_interrupts(cc);
+
+		return;
+	}
+
+	mutex_lock(&cc->mutex);
+
+	/* this must be before the cancel_work calls below, so that the work
+	 * functions don't perform further work.
+	 */
+	cc->state = CC33XX_STATE_OFF;
+
+	/* Use the nosync variant to disable interrupts, so the mutex could be
+	 * held while doing so without deadlocking.
+	 */
+	cc33xx_disable_interrupts_nosync(cc);
+
+	mutex_unlock(&cc->mutex);
+
+	if (!test_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS, &cc->flags))
+		cancel_work_sync(&cc->recovery_work);
+	cc33xx_flush_deferred_work(cc);
+	cancel_delayed_work_sync(&cc->scan_complete_work);
+	cancel_work_sync(&cc->netstack_work);
+	cancel_work_sync(&cc->tx_work);
+	cancel_work_sync(&cc->irq_deferred_work);
+	cancel_delayed_work_sync(&cc->tx_watchdog_work);
+
+	/* let's notify MAC80211 about the remaining pending TX frames */
+	mutex_lock(&cc->mutex);
+	cc33xx_tx_reset(cc);
+
+	cc33xx_power_off(cc);
+
+	cc->band = NL80211_BAND_2GHZ;
+
+	cc->rx_counter = 0;
+	cc->power_level = CC33XX_MAX_TXPWR;
+	cc->tx_blocks_available = 0;
+	cc->tx_allocated_blocks = 0;
+
+	cc->ap_fw_ps_map = 0;
+	cc->ap_ps_map = 0;
+	cc->sleep_auth = CC33XX_PSM_ILLEGAL;
+	memset(cc->roles_map, 0, sizeof(cc->roles_map));
+	memset(cc->links_map, 0, sizeof(cc->links_map));
+	memset(cc->roc_map, 0, sizeof(cc->roc_map));
+	memset(cc->session_ids, 0, sizeof(cc->session_ids));
+	memset(cc->rx_filter_enabled, 0, sizeof(cc->rx_filter_enabled));
+	cc->active_sta_count = 0;
+	cc->active_link_count = 0;
+	cc->ble_enable = 0;
+
+	/* The system link is always allocated */
+	cc->links[CC33XX_SYSTEM_HLID].allocated_pkts = 0;
+	cc->links[CC33XX_SYSTEM_HLID].prev_freed_pkts = 0;
+	__set_bit(CC33XX_SYSTEM_HLID, cc->links_map);
+
+	/* this is performed after the cancel_work calls and the associated
+	 * mutex_lock, so that cc33xx_op_add_interface does not accidentally
+	 * get executed before all these vars have been reset.
+	 */
+	cc->flags = 0;
+
+	for (i = 0; i < NUM_TX_QUEUES; i++)
+		cc->tx_allocated_pkts[i] = 0;
+
+	kfree(cc->target_mem_map);
+	cc->target_mem_map = NULL;
+
+	/* FW channels must be re-calibrated after recovery,
+	 * save current Reg-Domain channel configuration and clear it.
+	 */
+	memcpy(cc->reg_ch_conf_pending, cc->reg_ch_conf_last,
+	       sizeof(cc->reg_ch_conf_pending));
+	memset(cc->reg_ch_conf_last, 0, sizeof(cc->reg_ch_conf_last));
+
+	mutex_unlock(&cc->mutex);
+}
+
+static inline void cc33xx_op_stop(struct ieee80211_hw *hw, bool suspend) {}
+
+static void cc33xx_channel_switch_work(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+	struct cc33xx *cc;
+	struct ieee80211_vif *vif;
+	struct cc33xx_vif *wlvif;
+
+	dwork = to_delayed_work(work);
+	wlvif = container_of(dwork, struct cc33xx_vif, channel_switch_work);
+	cc = wlvif->cc;
+
+	cc33xx_info("channel switch failed (role_id: %d).", wlvif->role_id);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	/* check the channel switch is still ongoing */
+	if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags))
+		goto out;
+
+	vif = cc33xx_wlvif_to_vif(wlvif);
+	ieee80211_chswitch_done(vif, false, 0);
+
+	cc33xx_cmd_stop_channel_switch(cc, wlvif);
+
+out:
+	mutex_unlock(&cc->mutex);
+}
+
+static void cc33xx_connection_loss_work(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+	struct cc33xx *cc;
+	struct ieee80211_vif *vif;
+	struct cc33xx_vif *wlvif;
+
+	dwork = to_delayed_work(work);
+	wlvif = container_of(dwork, struct cc33xx_vif, connection_loss_work);
+	cc = wlvif->cc;
+
+	cc33xx_info("Connection loss work (role_id: %d).", wlvif->role_id);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	/* Call mac80211 connection loss */
+	if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+		goto out;
+
+	vif = cc33xx_wlvif_to_vif(wlvif);
+	ieee80211_connection_loss(vif);
+
+out:
+	mutex_unlock(&cc->mutex);
+}
+
+static void cc33xx_pending_auth_complete_work(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+	struct cc33xx *cc;
+	struct cc33xx_vif *wlvif;
+	unsigned long time_spare;
+
+	dwork = to_delayed_work(work);
+	wlvif = container_of(dwork, struct cc33xx_vif,
+			     pending_auth_complete_work);
+	cc = wlvif->cc;
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	/* Make sure a second really passed since the last auth reply. Maybe
+	 * a second auth reply arrived while we were stuck on the mutex.
+	 * Check for a little less than the timeout to protect from scheduler
+	 * irregularities.
+	 */
+	time_spare = msecs_to_jiffies(CC33XX_PEND_AUTH_ROC_TIMEOUT - 50);
+	time_spare += jiffies;
+	if (!time_after(time_spare, wlvif->pending_auth_reply_time))
+		goto out;
+
+	/* cancel the ROC if active */
+	cc33xx_debug(DEBUG_CMD,
+		     "pending_auth t/o expired - cancel ROC if active");
+
+	cc33xx_update_inconn_sta(cc, wlvif, NULL, false);
+
+out:
+	mutex_unlock(&cc->mutex);
+}
+
+static void cc33xx_roc_timeout_work(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+	struct cc33xx *cc;
+	struct cc33xx_vif *wlvif;
+	unsigned long time_spare;
+
+	dwork = to_delayed_work(work);
+	wlvif = container_of(dwork, struct cc33xx_vif, roc_timeout_work);
+	cc = wlvif->cc;
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	/* Make sure that requested timeout really passed. Maybe an association
+	 * completed and croc arrived while we were stuck on the mutex.
+	 * Check for a little less than the timeout to protect from scheduler
+	 * irregularities.
+	 */
+	time_spare = msecs_to_jiffies(CC33xx_PEND_ROC_COMPLETE_TIMEOUT - 50);
+	time_spare += jiffies;
+	if (!time_after(time_spare, wlvif->pending_auth_reply_time))
+		goto out;
+
+	if (test_bit(wlvif->role_id, cc->roc_map))
+		cc33xx_croc(cc, wlvif->role_id);
+
+out:
+	mutex_unlock(&cc->mutex);
+}
+
+static int cc33xx_allocate_rate_policy(struct cc33xx *cc, u8 *idx)
+{
+	u8 policy = find_first_zero_bit(cc->rate_policies_map,
+					CC33XX_MAX_RATE_POLICIES);
+	if (policy >= CC33XX_MAX_RATE_POLICIES)
+		return -EBUSY;
+
+	__set_bit(policy, cc->rate_policies_map);
+	*idx = policy;
+	return 0;
+}
+
+static void cc33xx_free_rate_policy(struct cc33xx *cc, u8 *idx)
+{
+	if (WARN_ON(*idx >= CC33XX_MAX_RATE_POLICIES))
+		return;
+
+	__clear_bit(*idx, cc->rate_policies_map);
+	*idx = CC33XX_MAX_RATE_POLICIES;
+}
+
+static u8 cc33xx_get_role_type(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
+
+	switch (wlvif->bss_type) {
+	case BSS_TYPE_AP_BSS:
+		if (wlvif->p2p)
+			return CC33XX_ROLE_P2P_GO;
+		else if (ieee80211_vif_is_mesh(vif))
+			return CC33XX_ROLE_MESH_POINT;
+		else
+			return CC33XX_ROLE_AP;
+
+	case BSS_TYPE_STA_BSS:
+		if (wlvif->p2p)
+			return CC33XX_ROLE_P2P_CL;
+		else
+			return CC33XX_ROLE_STA;
+
+	case BSS_TYPE_IBSS:
+		return CC33XX_ROLE_IBSS;
+
+	default:
+		cc33xx_error("invalid bss_type: %d", wlvif->bss_type);
+	}
+	return CC33XX_INVALID_ROLE_TYPE;
+}
+
+static int cc33xx_init_vif_data(struct cc33xx *cc, struct ieee80211_vif *vif)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	struct conf_tx_settings *tx_settings = &cc->conf.host_conf.tx;
+	int i;
+
+	/* clear everything but the persistent data */
+	memset(wlvif, 0, offsetof(struct cc33xx_vif, persistent));
+
+	switch (ieee80211_vif_type_p2p(vif)) {
+	case NL80211_IFTYPE_P2P_CLIENT:
+		wlvif->p2p = 1;
+		fallthrough;
+	case NL80211_IFTYPE_STATION:
+	case NL80211_IFTYPE_P2P_DEVICE:
+		wlvif->bss_type = BSS_TYPE_STA_BSS;
+		break;
+	case NL80211_IFTYPE_ADHOC:
+		wlvif->bss_type = BSS_TYPE_IBSS;
+		break;
+	case NL80211_IFTYPE_P2P_GO:
+		wlvif->p2p = 1;
+		fallthrough;
+	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_MESH_POINT:
+		wlvif->bss_type = BSS_TYPE_AP_BSS;
+		break;
+	default:
+		wlvif->bss_type = MAX_BSS_TYPE;
+		return -EOPNOTSUPP;
+	}
+
+	wlvif->role_id = CC33XX_INVALID_ROLE_ID;
+	wlvif->dev_role_id = CC33XX_INVALID_ROLE_ID;
+	wlvif->dev_hlid = CC33XX_INVALID_LINK_ID;
+
+	if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
+	    wlvif->bss_type == BSS_TYPE_IBSS) {
+		/* init sta/ibss data */
+		wlvif->sta.hlid = CC33XX_INVALID_LINK_ID;
+		cc33xx_allocate_rate_policy(cc, &wlvif->sta.basic_rate_idx);
+		cc33xx_allocate_rate_policy(cc, &wlvif->sta.ap_rate_idx);
+		cc33xx_allocate_rate_policy(cc, &wlvif->sta.p2p_rate_idx);
+		wlvif->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
+		wlvif->basic_rate = CONF_TX_RATE_MASK_BASIC;
+		wlvif->rate_set = CONF_TX_RATE_MASK_BASIC;
+	} else {
+		/* init ap data */
+		wlvif->ap.bcast_hlid = CC33XX_INVALID_LINK_ID;
+		wlvif->ap.global_hlid = CC33XX_INVALID_LINK_ID;
+		cc33xx_allocate_rate_policy(cc, &wlvif->ap.mgmt_rate_idx);
+		cc33xx_allocate_rate_policy(cc, &wlvif->ap.bcast_rate_idx);
+		for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++)
+			cc33xx_allocate_rate_policy(cc,
+						    &wlvif->ap.ucast_rate_idx[i]);
+		wlvif->basic_rate_set = CONF_TX_ENABLED_RATES;
+		/* TODO: check if basic_rate shouldn't be
+		 * cc33xx_tx_min_rate_get(cc, wlvif->basic_rate_set);
+		 * instead (the same thing for STA above).
+		 */
+		wlvif->basic_rate = CONF_TX_ENABLED_RATES;
+		/* TODO: this seems to be used only for STA, check it */
+		wlvif->rate_set = CONF_TX_ENABLED_RATES;
+	}
+
+	wlvif->bitrate_masks[NL80211_BAND_2GHZ] = tx_settings->basic_rate;
+	wlvif->bitrate_masks[NL80211_BAND_5GHZ] = tx_settings->basic_rate_5;
+	wlvif->beacon_int = CC33XX_DEFAULT_BEACON_INT;
+
+	/* mac80211 configures some values globally, while we treat them
+	 * per-interface. thus, on init, we have to copy them from cc
+	 */
+	wlvif->band = cc->band;
+	wlvif->power_level = cc->power_level;
+
+	INIT_WORK(&wlvif->rc_update_work, cc33xx_rc_update_work);
+	INIT_DELAYED_WORK(&wlvif->channel_switch_work,
+			  cc33xx_channel_switch_work);
+	INIT_DELAYED_WORK(&wlvif->connection_loss_work,
+			  cc33xx_connection_loss_work);
+	INIT_DELAYED_WORK(&wlvif->pending_auth_complete_work,
+			  cc33xx_pending_auth_complete_work);
+	INIT_DELAYED_WORK(&wlvif->roc_timeout_work,
+			  cc33xx_roc_timeout_work);
+	INIT_LIST_HEAD(&wlvif->list);
+
+	return 0;
+}
+
+struct cc33xx_hw_queue_iter_data {
+	unsigned long hw_queue_map[BITS_TO_LONGS(CC33XX_NUM_MAC_ADDRESSES)];
+
+	/* current vif */
+	struct ieee80211_vif *vif;
+
+	/* is the current vif among those iterated */
+	bool cur_running;
+};
+
+static void cc33xx_hw_queue_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+	struct cc33xx_hw_queue_iter_data *iter_data = data;
+
+	if (vif->type == NL80211_IFTYPE_P2P_DEVICE ||
+	    WARN_ON_ONCE(vif->hw_queue[0] == IEEE80211_INVAL_HW_QUEUE))
+		return;
+
+	if (iter_data->cur_running || vif == iter_data->vif) {
+		iter_data->cur_running = true;
+		return;
+	}
+
+	__set_bit(vif->hw_queue[0] / NUM_TX_QUEUES, iter_data->hw_queue_map);
+}
+
+static int cc33xx_allocate_hw_queue_base(struct cc33xx *cc,
+					 struct cc33xx_vif *wlvif)
+{
+	struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
+	struct cc33xx_hw_queue_iter_data iter_data = {};
+	int i, q_base;
+
+	if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
+		vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
+		return 0;
+	}
+
+	iter_data.vif = vif;
+
+	/* mark all bits taken by active interfaces */
+	ieee80211_iterate_active_interfaces_atomic(cc->hw,
+						   IEEE80211_IFACE_ITER_RESUME_ALL,
+					cc33xx_hw_queue_iter, &iter_data);
+
+	/* the current vif is already running in mac80211 (resume/recovery) */
+	if (iter_data.cur_running) {
+		wlvif->hw_queue_base = vif->hw_queue[0];
+		cc33xx_debug(DEBUG_MAC80211,
+			     "using pre-allocated hw queue base %d",
+			     wlvif->hw_queue_base);
+
+		/* interface type might have changed type */
+		goto adjust_cab_queue;
+	}
+
+	q_base = find_first_zero_bit(iter_data.hw_queue_map,
+				     CC33XX_NUM_MAC_ADDRESSES);
+	if (q_base >= CC33XX_NUM_MAC_ADDRESSES)
+		return -EBUSY;
+
+	wlvif->hw_queue_base = q_base * NUM_TX_QUEUES;
+	cc33xx_debug(DEBUG_MAC80211, "allocating hw queue base: %d",
+		     wlvif->hw_queue_base);
+
+	for (i = 0; i < NUM_TX_QUEUES; i++) {
+		cc->queue_stop_reasons[wlvif->hw_queue_base + i] = 0;
+		/* register hw queues in mac80211 */
+		vif->hw_queue[i] = wlvif->hw_queue_base + i;
+	}
+
+adjust_cab_queue:
+	/* the last places are reserved for cab queues per interface */
+	if (wlvif->bss_type == BSS_TYPE_AP_BSS) {
+		vif->cab_queue = NUM_TX_QUEUES * CC33XX_NUM_MAC_ADDRESSES +
+					wlvif->hw_queue_base / NUM_TX_QUEUES;
+	} else {
+		vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
+	}
+
+	return 0;
+}
+
+static int cc33xx_op_add_interface(struct ieee80211_hw *hw,
+				   struct ieee80211_vif *vif)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	struct vif_counter_data vif_count;
+	int ret = 0;
+	u8 role_type;
+
+	if (cc->plt) {
+		cc33xx_error("Adding Interface not allowed while in PLT mode");
+		return -EBUSY;
+	}
+
+	vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
+			     IEEE80211_VIF_SUPPORTS_UAPSD |
+			     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
+
+	cc33xx_get_vif_count(hw, vif, &vif_count);
+
+	mutex_lock(&cc->mutex);
+
+	/* in some very corner case HW recovery scenarios its possible to
+	 * get here before __cc33xx_op_remove_interface is complete, so
+	 * opt out if that is the case.
+	 */
+	if (test_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS, &cc->flags) ||
+	    test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = cc33xx_init_vif_data(cc, vif);
+	if (ret < 0)
+		goto out;
+
+	wlvif->cc = cc;
+	role_type = cc33xx_get_role_type(cc, wlvif);
+	if (role_type == CC33XX_INVALID_ROLE_TYPE) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = cc33xx_allocate_hw_queue_base(cc, wlvif);
+	if (ret < 0)
+		goto out;
+
+	if (!cc33xx_is_p2p_mgmt(wlvif)) {
+		ret = cc33xx_cmd_role_enable(cc, vif->addr,
+					     role_type, &wlvif->role_id);
+		if (ret < 0)
+			goto out;
+
+		ret = cc33xx_init_vif_specific(cc, vif);
+		if (ret < 0)
+			goto out;
+	} else {
+		ret = cc33xx_cmd_role_enable(cc, vif->addr, CC33XX_ROLE_DEVICE,
+					     &wlvif->dev_role_id);
+		if (ret < 0)
+			goto out;
+
+		/* needed mainly for configuring rate policies */
+		ret = cc33xx_acx_config_ps(cc, wlvif);
+		if (ret < 0)
+			goto out;
+	}
+
+	list_add(&wlvif->list, &cc->wlvif_list);
+	set_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags);
+
+	if (wlvif->bss_type == BSS_TYPE_AP_BSS)
+		cc->ap_count++;
+	else
+		cc->sta_count++;
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+static void __cc33xx_op_remove_interface(struct cc33xx *cc,
+					 struct ieee80211_vif *vif,
+					 bool reset_tx_queues)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	int i, ret;
+	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
+
+	if (!test_and_clear_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
+		return;
+
+	/* because of hardware recovery, we may get here twice */
+	if (cc->state == CC33XX_STATE_OFF)
+		return;
+
+	if (cc->scan.state != CC33XX_SCAN_STATE_IDLE &&
+	    cc->scan_wlvif == wlvif) {
+		struct cfg80211_scan_info info = {
+			.aborted = true,
+		};
+
+		/* Rearm the tx watchdog just before idling scan. This
+		 * prevents just-finished scans from triggering the watchdog
+		 */
+		cc33xx_rearm_tx_watchdog_locked(cc);
+
+		cc->scan.state = CC33XX_SCAN_STATE_IDLE;
+		memset(cc->scan.scanned_ch, 0, sizeof(cc->scan.scanned_ch));
+		cc->scan_wlvif = NULL;
+		cc->scan.req = NULL;
+		ieee80211_scan_completed(cc->hw, &info);
+	}
+
+	if (cc->sched_vif == wlvif)
+		cc->sched_vif = NULL;
+
+	if (cc->roc_vif == vif) {
+		cc->roc_vif = NULL;
+		ieee80211_remain_on_channel_expired(cc->hw);
+	}
+
+	if (!test_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS, &cc->flags)) {
+		/* disable active roles */
+
+		if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
+		    wlvif->bss_type == BSS_TYPE_IBSS) {
+			if (wlvif->dev_hlid != CC33XX_INVALID_LINK_ID)
+				cc33xx_stop_dev(cc, wlvif);
+		}
+
+		if (!cc33xx_is_p2p_mgmt(wlvif)) {
+			ret = cc33xx_cmd_role_disable(cc, &wlvif->role_id);
+			if (ret < 0)
+				goto deinit;
+		} else {
+			ret = cc33xx_cmd_role_disable(cc, &wlvif->dev_role_id);
+			if (ret < 0)
+				goto deinit;
+		}
+	}
+deinit:
+	cc33xx_tx_reset_wlvif(cc, wlvif);
+
+	/* clear all hlids (except system_hlid) */
+	wlvif->dev_hlid = CC33XX_INVALID_LINK_ID;
+
+	if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
+	    wlvif->bss_type == BSS_TYPE_IBSS) {
+		wlvif->sta.hlid = CC33XX_INVALID_LINK_ID;
+		cc33xx_free_rate_policy(cc, &wlvif->sta.basic_rate_idx);
+		cc33xx_free_rate_policy(cc, &wlvif->sta.ap_rate_idx);
+		cc33xx_free_rate_policy(cc, &wlvif->sta.p2p_rate_idx);
+	} else {
+		wlvif->ap.bcast_hlid = CC33XX_INVALID_LINK_ID;
+		wlvif->ap.global_hlid = CC33XX_INVALID_LINK_ID;
+		cc33xx_free_rate_policy(cc, &wlvif->ap.mgmt_rate_idx);
+		cc33xx_free_rate_policy(cc, &wlvif->ap.bcast_rate_idx);
+		for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++)
+			cc33xx_free_rate_policy(cc,
+						&wlvif->ap.ucast_rate_idx[i]);
+		cc33xx_free_ap_keys(cc, wlvif);
+	}
+
+	dev_kfree_skb(wlvif->probereq);
+	wlvif->probereq = NULL;
+	if (cc->last_wlvif == wlvif)
+		cc->last_wlvif = NULL;
+	list_del(&wlvif->list);
+	memset(wlvif->ap.sta_hlid_map, 0, sizeof(wlvif->ap.sta_hlid_map));
+	wlvif->role_id = CC33XX_INVALID_ROLE_ID;
+	wlvif->dev_role_id = CC33XX_INVALID_ROLE_ID;
+
+	if (is_ap)
+		cc->ap_count--;
+	else
+		cc->sta_count--;
+
+	/* Last AP, have more stations. Configure sleep auth according to STA.
+	 * Don't do thin on unintended recovery.
+	 */
+	if (test_bit(CC33XX_FLAG_RECOVERY_IN_PROGRESS, &cc->flags))
+		goto unlock;
+
+	/* mask ap events */
+	if (cc->ap_count == 0 && is_ap)
+		cc->event_mask &= ~cc->ap_event_mask;
+
+	if (cc->ap_count == 0 && is_ap && cc->sta_count) {
+		u8 sta_auth = cc->conf.host_conf.conn.sta_sleep_auth;
+		/* Configure for power according to debugfs */
+		if (sta_auth != CC33XX_PSM_ILLEGAL)
+			cc33xx_acx_sleep_auth(cc, sta_auth);
+		/* Configure for ELP power saving */
+		else
+			cc33xx_acx_sleep_auth(cc, CC33XX_PSM_ELP);
+	}
+
+unlock:
+	mutex_unlock(&cc->mutex);
+
+	cancel_work_sync(&wlvif->rc_update_work);
+	cancel_delayed_work_sync(&wlvif->connection_loss_work);
+	cancel_delayed_work_sync(&wlvif->channel_switch_work);
+	cancel_delayed_work_sync(&wlvif->pending_auth_complete_work);
+	cancel_delayed_work_sync(&wlvif->roc_timeout_work);
+
+	mutex_lock(&cc->mutex);
+}
+
+static void cc33xx_op_remove_interface(struct ieee80211_hw *hw,
+				       struct ieee80211_vif *vif)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	struct cc33xx_vif *iter;
+	struct vif_counter_data vif_count;
+
+	cc33xx_get_vif_count(hw, vif, &vif_count);
+	mutex_lock(&cc->mutex);
+
+	if (cc->state == CC33XX_STATE_OFF ||
+	    !test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
+		goto out;
+
+	/* cc->vif can be null here if someone shuts down the interface
+	 * just when hardware recovery has been started.
+	 */
+	cc33xx_for_each_wlvif(cc, iter) {
+		if (iter != wlvif)
+			continue;
+
+		__cc33xx_op_remove_interface(cc, vif, true);
+		break;
+	}
+	WARN_ON(iter != wlvif);
+
+out:
+	mutex_unlock(&cc->mutex);
+}
+
+static int cc33xx_op_change_interface(struct ieee80211_hw *hw,
+				      struct ieee80211_vif *vif,
+				      enum nl80211_iftype new_type, bool p2p)
+{
+	struct cc33xx *cc = hw->priv;
+	int ret;
+
+	set_bit(CC33XX_FLAG_VIF_CHANGE_IN_PROGRESS, &cc->flags);
+	cc33xx_op_remove_interface(hw, vif);
+
+	vif->type = new_type;
+	vif->p2p = p2p;
+	ret = cc33xx_op_add_interface(hw, vif);
+
+	clear_bit(CC33XX_FLAG_VIF_CHANGE_IN_PROGRESS, &cc->flags);
+	return ret;
+}
+
+static int cc33xx_join(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	int ret;
+	bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
+
+	/* One of the side effects of the JOIN command is that is clears
+	 * WPA/WPA2 keys from the chipset. Performing a JOIN while associated
+	 * to a WPA/WPA2 access point will therefore kill the data-path.
+	 * Currently the only valid scenario for JOIN during association
+	 * is on roaming, in which case we will also be given new keys.
+	 * Keep the below message for now, unless it starts bothering
+	 * users who really like to roam a lot :)
+	 */
+	if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+		cc33xx_info("JOIN while associated.");
+
+	/* clear encryption type */
+	wlvif->encryption_type = KEY_NONE;
+
+	if (is_ibss) {
+		ret = cc33xx_cmd_role_start_ibss(cc, wlvif);
+	} else {
+		if (cc->quirks & CC33XX_QUIRK_START_STA_FAILS) {
+			/* TODO: this is an ugly workaround for wl12xx fw
+			 * bug - we are not able to tx/rx after the first
+			 * start_sta, so make dummy start+stop calls,
+			 * and then call start_sta again.
+			 * this should be fixed in the fw.
+			 */
+			cc33xx_cmd_role_start_sta(cc, wlvif);
+			cc33xx_cmd_role_stop_sta(cc, wlvif);
+		}
+
+		ret = cc33xx_cmd_role_start_sta(cc, wlvif);
+	}
+
+	return ret;
+}
+
+static int cc33xx_ssid_set(struct cc33xx_vif *wlvif,
+			   struct sk_buff *skb, int offset)
+{
+	u8 ssid_len;
+	const u8 *ptr = cfg80211_find_ie(WLAN_EID_SSID, skb->data + offset,
+					 skb->len - offset);
+
+	if (!ptr) {
+		cc33xx_error("No SSID in IEs!");
+		return -ENOENT;
+	}
+
+	ssid_len = ptr[1];
+	if (ssid_len > IEEE80211_MAX_SSID_LEN) {
+		cc33xx_error("SSID is too long!");
+		return -EINVAL;
+	}
+
+	wlvif->ssid_len = ssid_len;
+	memcpy(wlvif->ssid, ptr + 2, ssid_len);
+	return 0;
+}
+
+static int cc33xx_set_ssid(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
+	struct sk_buff *skb;
+	int ieoffset;
+
+	/* we currently only support setting the ssid from the ap probe req */
+	if (wlvif->bss_type != BSS_TYPE_STA_BSS)
+		return -EINVAL;
+
+	skb = ieee80211_ap_probereq_get(cc->hw, vif);
+	if (!skb)
+		return -EINVAL;
+
+	ieoffset = offsetof(struct ieee80211_mgmt, u.probe_req.variable);
+	cc33xx_ssid_set(wlvif, skb, ieoffset);
+	dev_kfree_skb(skb);
+
+	return 0;
+}
+
+static int cc33xx_set_assoc(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			    struct ieee80211_bss_conf *bss_conf,
+			    struct ieee80211_sta *sta,
+			    struct ieee80211_vif *vif, u32 sta_rate_set)
+{
+	int ret;
+
+	wlvif->aid = vif->cfg.aid;
+	wlvif->channel_type = cfg80211_get_chandef_type(&bss_conf->chanreq.oper);
+	wlvif->beacon_int = bss_conf->beacon_int;
+	wlvif->wmm_enabled = bss_conf->qos;
+
+	wlvif->nontransmitted = bss_conf->nontransmitted;
+	cc33xx_debug(DEBUG_MAC80211, "set_assoc mbssid params: nonTxbssid: %d, idx: %d, max_ind: %d, trans_bssid: %pM, ema_ap: %d",
+		     bss_conf->nontransmitted, bss_conf->bssid_index,
+		     bss_conf->bssid_indicator, bss_conf->transmitter_bssid,
+		     bss_conf->ema_ap);
+	wlvif->bssid_index = bss_conf->bssid_index;
+	wlvif->bssid_indicator = bss_conf->bssid_indicator;
+	memcpy(wlvif->transmitter_bssid, bss_conf->transmitter_bssid, ETH_ALEN);
+
+	set_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags);
+
+	ret = cc33xx_assoc_info_cfg(cc, wlvif, sta, wlvif->aid);
+	if (ret < 0)
+		return ret;
+
+	if (sta_rate_set) {
+		wlvif->rate_set = cc33xx_tx_enabled_rates_get(cc, sta_rate_set,
+							      wlvif->band);
+	}
+
+	return ret;
+}
+
+static int cc33xx_unset_assoc(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	int ret;
+	bool sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
+
+	/* make sure we are connected (sta) joined */
+	if (sta && !test_and_clear_bit(WLVIF_FLAG_STA_ASSOCIATED,
+				       &wlvif->flags))
+		return false;
+
+	/* make sure we are joined (ibss) */
+	if (!sta && test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags))
+		return false;
+
+	if (sta) {
+		/* use defaults when not associated */
+		wlvif->aid = 0;
+
+		/* free probe-request template */
+		dev_kfree_skb(wlvif->probereq);
+		wlvif->probereq = NULL;
+
+		/* disable beacon filtering */
+		ret = cc33xx_acx_beacon_filter_opt(cc, wlvif, false);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) {
+		struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
+
+		cc33xx_cmd_stop_channel_switch(cc, wlvif);
+		ieee80211_chswitch_done(vif, false, 0);
+		cancel_delayed_work(&wlvif->channel_switch_work);
+	}
+
+	return 0;
+}
+
+static void cc33xx_set_band_rate(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	wlvif->basic_rate_set = wlvif->bitrate_masks[wlvif->band];
+	wlvif->rate_set = wlvif->basic_rate_set;
+}
+
+static void cc33xx_sta_handle_idle(struct cc33xx *cc,
+				   struct cc33xx_vif *wlvif, bool idle)
+{
+	bool cur_idle = !test_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
+
+	if (idle == cur_idle)
+		return;
+
+	if (idle) {
+		clear_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
+	} else {
+		/* The current firmware only supports sched_scan in idle */
+		if (cc->sched_vif == wlvif)
+			cc33xx_scan_sched_scan_stop(cc, wlvif);
+
+		set_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
+	}
+}
+
+static int cc33xx_config_vif(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			     struct ieee80211_conf *conf, u64 changed)
+{
+	int ret;
+
+	if (cc33xx_is_p2p_mgmt(wlvif))
+		return 0;
+
+	if (conf->power_level != wlvif->power_level &&
+	    (changed & IEEE80211_CONF_CHANGE_POWER)) {
+		ret = cc33xx_acx_tx_power(cc, wlvif, conf->power_level);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int cc33xx_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif;
+	struct ieee80211_conf *conf = &hw->conf;
+	int ret = 0;
+
+	cc33xx_debug(DEBUG_MAC80211,
+		     "mac80211 config psm %s power %d %s changed 0x%x",
+		     conf->flags & IEEE80211_CONF_PS ? "on" : "off",
+		     conf->power_level,
+		     conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use",
+		     changed);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	/* configure each interface */
+	cc33xx_for_each_wlvif(cc, wlvif) {
+		ret = cc33xx_config_vif(cc, wlvif, conf, changed);
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+struct cc33xx_filter_params {
+	bool enabled;
+	int mc_list_length;
+	u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN];
+};
+
+static u64 cc33xx_op_prepare_multicast(struct ieee80211_hw *hw,
+				       struct netdev_hw_addr_list *mc_list)
+{
+	struct cc33xx_filter_params *fp;
+	struct netdev_hw_addr *ha;
+
+	fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
+	if (!fp) {
+		cc33xx_error("Out of memory setting filters.");
+		return 0;
+	}
+
+	/* update multicast filtering parameters */
+	fp->mc_list_length = 0;
+	if (netdev_hw_addr_list_count(mc_list) > ACX_MC_ADDRESS_GROUP_MAX) {
+		fp->enabled = false;
+	} else {
+		fp->enabled = true;
+		netdev_hw_addr_list_for_each(ha, mc_list) {
+			memcpy(fp->mc_list[fp->mc_list_length],
+			       ha->addr, ETH_ALEN);
+			fp->mc_list_length++;
+		}
+	}
+
+	return (u64)(unsigned long)fp;
+}
+
+#define CC33XX_SUPPORTED_FILTERS (FIF_ALLMULTI)
+
+static void cc33xx_op_configure_filter(struct ieee80211_hw *hw,
+				       unsigned int changed,
+				       unsigned int *total, u64 multicast)
+{
+	struct cc33xx_filter_params *fp = (void *)(unsigned long)multicast;
+	struct cc33xx *cc = hw->priv;
+
+	mutex_lock(&cc->mutex);
+
+	*total &= CC33XX_SUPPORTED_FILTERS;
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	if (!fp)
+		cc33xx_acx_group_address_tbl(cc, false, NULL, 0);
+	else if (*total & FIF_ALLMULTI || !fp->enabled)
+		cc33xx_acx_group_address_tbl(cc, false, NULL, 0);
+	else
+		cc33xx_acx_group_address_tbl(cc, true, fp->mc_list, fp->mc_list_length);
+
+out:
+	mutex_unlock(&cc->mutex);
+	kfree(fp);
+}
+
+static int cc33xx_record_ap_key(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				u8 id, u8 key_type, u8 key_size, const u8 *key,
+				u8 hlid, u32 tx_seq_32,	u16 tx_seq_16)
+{
+	struct cc33xx_ap_key *ap_key;
+	int i;
+
+	if (key_size > MAX_KEY_SIZE)
+		return -EINVAL;
+
+	/* Find next free entry in ap_keys. Also check we are not replacing
+	 * an existing key.
+	 */
+	for (i = 0; i < MAX_NUM_KEYS; i++) {
+		if (!wlvif->ap.recorded_keys[i])
+			break;
+
+		if (wlvif->ap.recorded_keys[i]->id == id) {
+			cc33xx_warning("trying to record key replacement");
+			return -EINVAL;
+		}
+	}
+
+	if (i == MAX_NUM_KEYS)
+		return -EBUSY;
+
+	ap_key = kzalloc(sizeof(*ap_key), GFP_KERNEL);
+	if (!ap_key)
+		return -ENOMEM;
+
+	ap_key->id = id;
+	ap_key->key_type = key_type;
+	ap_key->key_size = key_size;
+	memcpy(ap_key->key, key, key_size);
+	ap_key->hlid = hlid;
+	ap_key->tx_seq_32 = tx_seq_32;
+	ap_key->tx_seq_16 = tx_seq_16;
+
+	wlvif->ap.recorded_keys[i] = ap_key;
+	return 0;
+}
+
+static void cc33xx_free_ap_keys(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	int i;
+
+	for (i = 0; i < MAX_NUM_KEYS; i++) {
+		kfree(wlvif->ap.recorded_keys[i]);
+		wlvif->ap.recorded_keys[i] = NULL;
+	}
+}
+
+static int cc33xx_ap_init_hwenc(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	int i, ret = 0;
+	struct cc33xx_ap_key *key;
+	bool wep_key_added = false;
+
+	for (i = 0; i < MAX_NUM_KEYS; i++) {
+		u8 hlid;
+
+		if (!wlvif->ap.recorded_keys[i])
+			break;
+
+		key = wlvif->ap.recorded_keys[i];
+		hlid = key->hlid;
+		if (hlid == CC33XX_INVALID_LINK_ID)
+			hlid = wlvif->ap.bcast_hlid;
+
+		ret = cc33xx_cmd_set_ap_key(cc, wlvif, KEY_ADD_OR_REPLACE,
+					    key->id, key->key_type,
+					    key->key_size, key->key, hlid,
+					    key->tx_seq_32, key->tx_seq_16);
+		if (ret < 0)
+			goto out;
+
+		if (key->key_type == KEY_WEP)
+			wep_key_added = true;
+	}
+
+	if (wep_key_added) {
+		ret = cc33xx_cmd_set_default_wep_key(cc, wlvif->default_key,
+						     wlvif->ap.bcast_hlid);
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	cc33xx_free_ap_keys(cc, wlvif);
+	return ret;
+}
+
+static int cc33xx_config_key(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			     u16 action, u8 id, u8 key_type, u8 key_size,
+			     const u8 *key, u32 tx_seq_32, u16 tx_seq_16,
+			     struct ieee80211_sta *sta)
+{
+	int ret;
+	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
+
+	if (is_ap) {
+		struct cc33xx_station *wl_sta;
+		u8 hlid;
+
+		if (sta) {
+			wl_sta = (struct cc33xx_station *)sta->drv_priv;
+			hlid = wl_sta->hlid;
+		} else {
+			hlid = wlvif->ap.bcast_hlid;
+		}
+
+		if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
+			/* We do not support removing keys after AP shutdown.
+			 * Pretend we do to make mac80211 happy.
+			 */
+			if (action != KEY_ADD_OR_REPLACE)
+				return 0;
+
+			ret = cc33xx_record_ap_key(cc, wlvif, id, key_type,
+						   key_size, key, hlid,
+						   tx_seq_32, tx_seq_16);
+		} else {
+			ret = cc33xx_cmd_set_ap_key(cc, wlvif, action, id,
+						    key_type, key_size, key,
+						    hlid, tx_seq_32, tx_seq_16);
+		}
+
+		if (ret < 0)
+			return ret;
+	} else {
+		const u8 *addr;
+		static const u8 bcast_addr[ETH_ALEN] = {
+			0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+		};
+
+		addr = sta ? sta->addr : bcast_addr;
+
+		if (is_zero_ether_addr(addr)) {
+			/* We dont support TX only encryption */
+			return -EOPNOTSUPP;
+		}
+
+		/* The cc33xx does not allow to remove unicast keys - they
+		 * will be cleared automatically on next CMD_JOIN. Ignore the
+		 * request silently, as we dont want the mac80211 to emit
+		 * an error message.
+		 */
+		if (action == KEY_REMOVE && !is_broadcast_ether_addr(addr))
+			return 0;
+
+		/* don't remove key if hlid was already deleted */
+		if (action == KEY_REMOVE &&
+		    wlvif->sta.hlid == CC33XX_INVALID_LINK_ID)
+			return 0;
+
+		ret = cc33xx_cmd_set_sta_key(cc, wlvif, action, id, key_type,
+					     key_size, key, addr, tx_seq_32,
+					     tx_seq_16);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int cc33xx_set_key(struct cc33xx *cc, enum set_key_cmd cmd,
+			  struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+			  struct ieee80211_key_conf *key_conf)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	int ret;
+	u32 tx_seq_32 = 0;
+	u16 tx_seq_16 = 0;
+	u8 key_type;
+	u8 hlid;
+
+	if (wlvif->bss_type == BSS_TYPE_AP_BSS) {
+		if (sta) {
+			struct cc33xx_station *wl_sta = (void *)sta->drv_priv;
+
+			hlid = wl_sta->hlid;
+		} else {
+			hlid = wlvif->ap.bcast_hlid;
+		}
+	} else {
+		hlid = wlvif->sta.hlid;
+	}
+
+	if (hlid != CC33XX_INVALID_LINK_ID) {
+		u64 tx_seq = cc->links[hlid].total_freed_pkts;
+
+		tx_seq_32 = CC33XX_TX_SECURITY_HI32(tx_seq);
+		tx_seq_16 = CC33XX_TX_SECURITY_LO16(tx_seq);
+	}
+
+	switch (key_conf->cipher) {
+	case WLAN_CIPHER_SUITE_WEP40:
+	case WLAN_CIPHER_SUITE_WEP104:
+		key_type = KEY_WEP;
+		key_conf->hw_key_idx = key_conf->keyidx;
+		break;
+	case WLAN_CIPHER_SUITE_TKIP:
+		key_type = KEY_TKIP;
+		key_conf->hw_key_idx = key_conf->keyidx;
+		break;
+	case WLAN_CIPHER_SUITE_CCMP:
+		key_type = KEY_AES;
+		key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
+		break;
+	case WLAN_CIPHER_SUITE_GCMP:
+		key_type = KEY_GCMP128;
+		key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
+		break;
+	case WLAN_CIPHER_SUITE_CCMP_256:
+		key_type = KEY_CCMP256;
+		key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
+		break;
+	case WLAN_CIPHER_SUITE_GCMP_256:
+		key_type = KEY_GCMP_256;
+		key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
+		break;
+	case WLAN_CIPHER_SUITE_AES_CMAC:
+		key_type = KEY_IGTK;
+		break;
+	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+		key_type = KEY_CMAC_256;
+		break;
+	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+		key_type =  KEY_GMAC_128;
+		break;
+	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+		key_type =  KEY_GMAC_256;
+		break;
+	case CC33XX_CIPHER_SUITE_GEM:
+		key_type = KEY_GEM;
+		break;
+	default:
+		cc33xx_error("Unknown key algo 0x%x", key_conf->cipher);
+
+		return -EOPNOTSUPP;
+	}
+
+	switch (cmd) {
+	case SET_KEY:
+		ret = cc33xx_config_key(cc, wlvif, KEY_ADD_OR_REPLACE,
+					key_conf->keyidx, key_type, key_conf->keylen,
+				 key_conf->key, tx_seq_32, tx_seq_16, sta);
+		if (ret < 0) {
+			cc33xx_error("Could not add or replace key");
+			return ret;
+		}
+
+		/* reconfiguring arp response if the unicast (or common)
+		 * encryption key type was changed
+		 */
+		if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
+		    (sta || key_type == KEY_WEP) &&
+		    wlvif->encryption_type != key_type) {
+			wlvif->encryption_type = key_type;
+			if (ret < 0) {
+				cc33xx_warning("build arp rsp failed: %d", ret);
+				return ret;
+			}
+		}
+		break;
+
+	case DISABLE_KEY:
+		ret = cc33xx_config_key(cc, wlvif, KEY_REMOVE, key_conf->keyidx,
+					key_type, key_conf->keylen,
+					key_conf->key, 0, 0, sta);
+		if (ret < 0) {
+			cc33xx_error("Could not remove key");
+			return ret;
+		}
+		break;
+
+	default:
+		cc33xx_error("Unsupported key cmd 0x%x", cmd);
+		return -EOPNOTSUPP;
+	}
+
+	return ret;
+}
+
+static int cc33xx_hw_set_key(struct cc33xx *cc, enum set_key_cmd cmd,
+			     struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+			  struct ieee80211_key_conf *key_conf)
+{
+	bool special_enc;
+	int ret;
+
+	special_enc = key_conf->cipher == CC33XX_CIPHER_SUITE_GEM ||
+		      key_conf->cipher == WLAN_CIPHER_SUITE_TKIP;
+
+	ret = cc33xx_set_key(cc, cmd, vif, sta, key_conf);
+	if (ret < 0)
+		goto out;
+
+	/* when adding the first or removing the last GEM/TKIP key,
+	 * we have to adjust the number of spare blocks.
+	 */
+	if (special_enc) {
+		if (cmd == SET_KEY) {
+			/* first key */
+			cc->extra_spare_key_count++;
+		} else if (cmd == DISABLE_KEY) {
+			/* last key */
+			cc->extra_spare_key_count--;
+		}
+	}
+
+out:
+	return ret;
+}
+
+static int cc33xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+			     struct ieee80211_vif *vif,
+			     struct ieee80211_sta *sta,
+			     struct ieee80211_key_conf *key_conf)
+{
+	struct cc33xx *cc = hw->priv;
+	int ret;
+	bool might_change_spare = key_conf->cipher == CC33XX_CIPHER_SUITE_GEM ||
+				key_conf->cipher == WLAN_CIPHER_SUITE_TKIP;
+
+	if (might_change_spare) {
+		/* stop the queues and flush to ensure the next packets are
+		 * in sync with FW spare block accounting
+		 */
+		cc33xx_stop_queues(cc, CC33XX_QUEUE_STOP_REASON_SPARE_BLK);
+		cc33xx_tx_flush(cc);
+	}
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON)) {
+		ret = -EAGAIN;
+		goto out_wake_queues;
+	}
+
+	ret = cc33xx_hw_set_key(cc, cmd, vif, sta, key_conf);
+
+out_wake_queues:
+	if (might_change_spare)
+		cc33xx_wake_queues(cc, CC33XX_QUEUE_STOP_REASON_SPARE_BLK);
+
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+static void cc33xx_op_set_default_key_idx(struct ieee80211_hw *hw,
+					  struct ieee80211_vif *vif,
+					  int key_idx)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+
+	cc33xx_debug(DEBUG_MAC80211,
+		     "mac80211 set default key idx %d", key_idx);
+
+	/* we don't handle unsetting of default key */
+	if (key_idx == -1)
+		return;
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out_unlock;
+
+	wlvif->default_key = key_idx;
+
+	/* the default WEP key needs to be configured at least once */
+	if (wlvif->encryption_type == KEY_WEP)
+		cc33xx_cmd_set_default_wep_key(cc, key_idx, wlvif->sta.hlid);
+
+out_unlock:
+	mutex_unlock(&cc->mutex);
+}
+
+static int cc33xx_op_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+			     struct ieee80211_scan_request *hw_req)
+{
+	struct cfg80211_scan_request *req = &hw_req->req;
+	struct cc33xx *cc = hw->priv;
+	int ret;
+	u8 *ssid = NULL;
+	size_t len = 0;
+
+	if (req->n_ssids) {
+		ssid = req->ssids[0].ssid;
+		len = req->ssids[0].ssid_len;
+	}
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON)) {
+		/* We cannot return -EBUSY here because cfg80211 will expect
+		 * a call to ieee80211_scan_completed if we do - in this case
+		 * there won't be any call.
+		 */
+		ret = -EAGAIN;
+		goto out;
+	}
+
+	/* fail if there is any role in ROC */
+	if (find_first_bit(cc->roc_map, CC33XX_MAX_ROLES) < CC33XX_MAX_ROLES) {
+		/* don't allow scanning right now */
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = cc33xx_scan(hw->priv, vif, ssid, len, req);
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+static void cc33xx_op_cancel_hw_scan(struct ieee80211_hw *hw,
+				     struct ieee80211_vif *vif)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	struct cfg80211_scan_info info = {
+		.aborted = true,
+	};
+	int ret;
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	if (cc->scan.state == CC33XX_SCAN_STATE_IDLE)
+		goto out;
+
+	if (cc->scan.state != CC33XX_SCAN_STATE_DONE) {
+		ret = cc33xx_scan_stop(cc, wlvif);
+		if (ret < 0)
+			goto out;
+	}
+
+	/* Rearm the tx watchdog just before idling scan. This
+	 * prevents just-finished scans from triggering the watchdog
+	 */
+	cc33xx_rearm_tx_watchdog_locked(cc);
+
+	cc->scan.state = CC33XX_SCAN_STATE_IDLE;
+	memset(cc->scan.scanned_ch, 0, sizeof(cc->scan.scanned_ch));
+	cc->scan_wlvif = NULL;
+	cc->scan.req = NULL;
+	ieee80211_scan_completed(cc->hw, &info);
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	cancel_delayed_work_sync(&cc->scan_complete_work);
+}
+
+static int cc33xx_op_sched_scan_start(struct ieee80211_hw *hw,
+				      struct ieee80211_vif *vif,
+				      struct cfg80211_sched_scan_request *req,
+				      struct ieee80211_scan_ies *ies)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	int ret;
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON)) {
+		ret = -EAGAIN;
+		goto out;
+	}
+
+	ret = cc33xx_sched_scan_start(cc, wlvif, req, ies);
+	if (ret < 0)
+		goto out;
+
+	cc->sched_vif = wlvif;
+
+out:
+	mutex_unlock(&cc->mutex);
+	return ret;
+}
+
+static int cc33xx_op_sched_scan_stop(struct ieee80211_hw *hw,
+				     struct ieee80211_vif *vif)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	/* command to stop periodic scan was sent from mac80211
+	 * mark than stop command is from mac80211 and release sched_vif
+	 */
+	cc->mac80211_scan_stopped = true;
+	cc->sched_vif = NULL;
+	cc33xx_scan_sched_scan_stop(cc, wlvif);
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return 0;
+}
+
+static int cc33xx_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
+{
+	return 0;
+}
+
+static int cc33xx_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+	return 0;
+}
+
+static int cc33xx_bss_erp_info_changed(struct cc33xx *cc,
+				       struct ieee80211_vif *vif,
+				       struct ieee80211_bss_conf *bss_conf,
+				       u64 changed)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	int ret = 0;
+
+	if (changed & BSS_CHANGED_ERP_SLOT) {
+		if (bss_conf->use_short_slot)
+			ret = cc33xx_acx_slot(cc, wlvif, SLOT_TIME_SHORT);
+		else
+			ret = cc33xx_acx_slot(cc, wlvif, SLOT_TIME_LONG);
+		if (ret < 0) {
+			cc33xx_warning("Set slot time failed %d", ret);
+			goto out;
+		}
+	}
+
+	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+		if (bss_conf->use_short_preamble)
+			cc33xx_acx_set_preamble(cc, wlvif, ACX_PREAMBLE_SHORT);
+		else
+			cc33xx_acx_set_preamble(cc, wlvif, ACX_PREAMBLE_LONG);
+	}
+
+	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+		if (bss_conf->use_cts_prot) {
+			ret = cc33xx_acx_cts_protect(cc, wlvif,
+						     CTSPROTECT_ENABLE);
+		} else {
+			ret = cc33xx_acx_cts_protect(cc, wlvif,
+						     CTSPROTECT_DISABLE);
+		}
+
+		if (ret < 0) {
+			cc33xx_warning("Set ctsprotect failed %d", ret);
+			goto out;
+		}
+	}
+
+out:
+	return ret;
+}
+
+static int cc33xx_set_beacon_template(struct cc33xx *cc,
+				      struct ieee80211_vif *vif, bool is_ap)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	int ret;
+	int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
+	struct sk_buff *beacon = ieee80211_beacon_get(cc->hw, vif, 0);
+
+	struct cc33xx_cmd_set_beacon_info *cmd;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (!beacon) {
+		ret = -EINVAL;
+		goto end_bcn;
+	}
+
+	ret = cc33xx_ssid_set(wlvif, beacon, ieoffset);
+	if (ret < 0)
+		goto end_bcn;
+
+	cmd->role_id =  wlvif->role_id;
+	cmd->beacon_len = cpu_to_le16(beacon->len);
+
+	memcpy(cmd->beacon, beacon->data, beacon->len);
+
+	ret = cc33xx_cmd_send(cc, CMD_AP_SET_BEACON_INFO, cmd, sizeof(*cmd), 0);
+	if (ret < 0)
+		goto end_bcn;
+
+end_bcn:
+	dev_kfree_skb(beacon);
+	kfree(cmd);
+out:
+	return ret;
+}
+
+static int cc33xx_bss_beacon_info_changed(struct cc33xx *cc,
+					  struct ieee80211_vif *vif,
+					  struct ieee80211_bss_conf *bss_conf,
+					  u32 changed)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
+	int ret = 0;
+
+	if (changed & BSS_CHANGED_BEACON_INT) {
+		cc33xx_debug(DEBUG_MASTER, "beacon interval updated: %d",
+			     bss_conf->beacon_int);
+
+		wlvif->beacon_int = bss_conf->beacon_int;
+	}
+
+	if (changed & BSS_CHANGED_BEACON) {
+		ret = cc33xx_set_beacon_template(cc, vif, is_ap);
+		if (ret < 0)
+			goto out;
+
+		if (test_and_clear_bit(WLVIF_FLAG_BEACON_DISABLED,
+				       &wlvif->flags)) {
+			ret = cmd_dfs_master_restart(cc, wlvif);
+			if (ret < 0)
+				goto out;
+		}
+	}
+out:
+	if (ret != 0)
+		cc33xx_error("beacon info change failed: %d", ret);
+
+	return ret;
+}
+
+/* AP mode changes */
+static void cc33xx_bss_info_changed_ap(struct cc33xx *cc,
+				       struct ieee80211_vif *vif,
+				       struct ieee80211_bss_conf *bss_conf,
+				       u64 changed)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	int ret = 0;
+
+	if (changed & BSS_CHANGED_BASIC_RATES) {
+		u32 rates = bss_conf->basic_rates;
+		u32 supported_rates = 0;
+
+		wlvif->basic_rate_set = cc33xx_tx_enabled_rates_get(cc, rates,
+								    wlvif->band);
+		wlvif->basic_rate = cc33xx_tx_min_rate_get(cc,
+							   wlvif->basic_rate_set);
+
+		supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES;
+		ret = cc33xx_update_ap_rates(cc, wlvif->role_id,
+					     wlvif->basic_rate_set,
+					     supported_rates);
+
+		ret = cc33xx_set_beacon_template(cc, vif, true);
+		if (ret < 0)
+			goto out;
+	}
+
+	ret = cc33xx_bss_beacon_info_changed(cc, vif, bss_conf, changed);
+	if (ret < 0)
+		goto out;
+
+	if (changed & BSS_CHANGED_BEACON_ENABLED) {
+		if (bss_conf->enable_beacon) {
+			if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
+				ret = cc33xx_cmd_role_start_ap(cc, wlvif);
+				if (ret < 0)
+					goto out;
+
+				ret = cc33xx_ap_init_hwenc(cc, wlvif);
+				if (ret < 0)
+					goto out;
+
+				set_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags);
+			}
+		} else {
+			if (test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
+				/* AP might be in ROC in case we have just
+				 * sent auth reply. handle it.
+				 */
+				if (test_bit(wlvif->role_id, cc->roc_map))
+					cc33xx_croc(cc, wlvif->role_id);
+
+				ret = cc33xx_cmd_role_stop_ap(cc, wlvif);
+				if (ret < 0)
+					goto out;
+
+				clear_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags);
+				clear_bit(WLVIF_FLAG_AP_PROBE_RESP_SET,
+					  &wlvif->flags);
+			}
+		}
+	}
+
+	ret = cc33xx_bss_erp_info_changed(cc, vif, bss_conf, changed);
+	if (ret < 0)
+		goto out;
+
+out:
+	return;
+}
+
+static int cc33xx_set_bssid(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			    struct ieee80211_bss_conf *bss_conf,
+			struct ieee80211_vif *vif,
+			u32 sta_rate_set)
+{
+	u32 rates;
+
+	cc33xx_debug(DEBUG_MAC80211, "changed_bssid: %pM, aid: %d, bcn_int: %d, brates: 0x%x sta_rate_set: 0x%x, nontx: %d",
+		     bss_conf->bssid, vif->cfg.aid, bss_conf->beacon_int,
+			bss_conf->basic_rates, sta_rate_set,
+			bss_conf->nontransmitted);
+
+	wlvif->beacon_int = bss_conf->beacon_int;
+	rates = bss_conf->basic_rates;
+	wlvif->basic_rate_set =	cc33xx_tx_enabled_rates_get(cc, rates,
+							    wlvif->band);
+	wlvif->basic_rate = cc33xx_tx_min_rate_get(cc, wlvif->basic_rate_set);
+
+	if (sta_rate_set) {
+		wlvif->rate_set = cc33xx_tx_enabled_rates_get(cc, sta_rate_set,
+							      wlvif->band);
+	}
+
+	wlvif->nontransmitted = bss_conf->nontransmitted;
+	cc33xx_debug(DEBUG_MAC80211, "changed_mbssid: nonTxbssid: %d, idx: %d, max_ind: %d, trans_bssid: %pM, ema_ap: %d",
+		     bss_conf->nontransmitted, bss_conf->bssid_index,
+		     bss_conf->bssid_indicator, bss_conf->transmitter_bssid,
+		     bss_conf->ema_ap);
+
+	if (bss_conf->nontransmitted) {
+		wlvif->bssid_index = bss_conf->bssid_index;
+		wlvif->bssid_indicator = bss_conf->bssid_indicator;
+		memcpy(wlvif->transmitter_bssid,
+		       bss_conf->transmitter_bssid,
+			ETH_ALEN);
+	}
+
+	/* we only support sched_scan while not connected */
+	if (cc->sched_vif == wlvif)
+		cc33xx_scan_sched_scan_stop(cc, wlvif);
+
+	cc33xx_set_ssid(cc, wlvif);
+
+	set_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
+
+	return 0;
+}
+
+static int cc33xx_clear_bssid(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	int ret;
+
+	/* revert back to minimum rates for the current band */
+	cc33xx_set_band_rate(cc, wlvif);
+	wlvif->basic_rate = cc33xx_tx_min_rate_get(cc, wlvif->basic_rate_set);
+
+	if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
+	    test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) {
+		ret = cc33xx_cmd_role_stop_sta(cc, wlvif);
+		if (ret < 0)
+			return ret;
+	}
+
+	clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
+	return 0;
+}
+
+static void cc33xx_sta_set_he(struct cc33xx *cc, struct cc33xx_vif *wlvif, bool has_he)
+{
+	struct cc33xx_vif *wlvif_itr;
+	u8 he_count = 0;
+
+	wlvif->sta_has_he = has_he;
+
+	if (has_he)
+		cc33xx_info("HE Enabled");
+	else
+		cc33xx_info("HE Disabled");
+
+	cc33xx_for_each_wlvif_sta(cc, wlvif_itr) {
+		/* check for all valid link id's */
+		if (wlvif_itr->role_id != 0xFF && wlvif_itr->sta_has_he)
+			he_count++;
+	}
+
+	/* There can't be two stations connected with HE supported links */
+	if (he_count > 1)
+		cc33xx_error("Both station interfaces has HE enabled!");
+}
+
+/* STA/IBSS mode changes */
+static void cc33xx_bss_info_changed_sta(struct cc33xx *cc,
+					struct ieee80211_vif *vif,
+					struct ieee80211_bss_conf *bss_conf,
+					u64 changed)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	bool do_join = false;
+	bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
+	bool ibss_joined = false;
+	u32 sta_rate_set = 0;
+	int ret;
+	struct ieee80211_sta *sta = NULL;
+	bool sta_exists = false;
+	struct ieee80211_sta_ht_cap sta_ht_cap;
+	struct ieee80211_sta_he_cap sta_he_cap;
+
+	if (is_ibss) {
+		ret = cc33xx_bss_beacon_info_changed(cc, vif,
+						     bss_conf, changed);
+		if (ret < 0)
+			goto out;
+	}
+
+	if (changed & BSS_CHANGED_IBSS) {
+		if (vif->cfg.ibss_joined) {
+			set_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags);
+			ibss_joined = true;
+		} else {
+			cc33xx_unset_assoc(cc, wlvif);
+			cc33xx_cmd_role_stop_sta(cc, wlvif);
+		}
+	}
+
+	if ((changed & BSS_CHANGED_BEACON_INT) && ibss_joined)
+		do_join = true;
+
+	/* Need to update the SSID (for filtering etc) */
+	if ((changed & BSS_CHANGED_BEACON) && ibss_joined)
+		do_join = true;
+
+	if ((changed & BSS_CHANGED_BEACON_ENABLED) && ibss_joined) {
+		cc33xx_debug(DEBUG_ADHOC, "ad-hoc beaconing: %s",
+			     bss_conf->enable_beacon ? "enabled" : "disabled");
+
+		do_join = true;
+	}
+
+	if (changed & BSS_CHANGED_IDLE && !is_ibss)
+		cc33xx_sta_handle_idle(cc, wlvif, vif->cfg.idle);
+
+	if (changed & BSS_CHANGED_CQM)
+		wlvif->rssi_thold = bss_conf->cqm_rssi_thold;
+
+	if (changed & (BSS_CHANGED_BSSID | BSS_CHANGED_HT | BSS_CHANGED_ASSOC)) {
+		rcu_read_lock();
+		sta = ieee80211_find_sta(vif, bss_conf->bssid);
+		if (sta) {
+			u8 *rx_mask = sta->deflink.ht_cap.mcs.rx_mask;
+
+			/* save the supp_rates of the ap */
+			sta_rate_set = sta->deflink.supp_rates[wlvif->band];
+			if (sta->deflink.ht_cap.ht_supported) {
+				sta_rate_set |=
+					(rx_mask[0] << HW_HT_RATES_OFFSET) |
+					(rx_mask[1] << HW_MIMO_RATES_OFFSET);
+			}
+			sta_ht_cap = sta->deflink.ht_cap;
+			sta_he_cap = sta->deflink.he_cap;
+			sta_exists = true;
+		}
+
+		rcu_read_unlock();
+	}
+
+	if (changed & BSS_CHANGED_BSSID) {
+		if (!is_zero_ether_addr(bss_conf->bssid)) {
+			ret = cc33xx_set_bssid(cc, wlvif,
+					       bss_conf, vif, sta_rate_set);
+			if (ret < 0)
+				goto out;
+
+			/* Need to update the BSSID (for filtering etc) */
+			do_join = true;
+		} else {
+			ret = cc33xx_clear_bssid(cc, wlvif);
+			if (ret < 0)
+				goto out;
+		}
+	}
+
+	if (changed & BSS_CHANGED_IBSS) {
+		cc33xx_debug(DEBUG_ADHOC, "ibss_joined: %d",
+			     vif->cfg.ibss_joined);
+
+		if (vif->cfg.ibss_joined) {
+			u32 rates = bss_conf->basic_rates;
+
+			wlvif->basic_rate_set =
+				cc33xx_tx_enabled_rates_get(cc, rates,
+							    wlvif->band);
+			wlvif->basic_rate =
+				cc33xx_tx_min_rate_get(cc,
+						       wlvif->basic_rate_set);
+
+			/* by default, use 11b + OFDM rates */
+			wlvif->rate_set = CONF_TX_IBSS_DEFAULT_RATES;
+		}
+	}
+
+	if ((changed & BSS_CHANGED_BEACON_INFO) && bss_conf->dtim_period) {
+		/* enable beacon filtering */
+		ret = cc33xx_acx_beacon_filter_opt(cc, wlvif, true);
+		if (ret < 0)
+			goto out;
+	}
+
+	ret = cc33xx_bss_erp_info_changed(cc, vif, bss_conf, changed);
+	if (ret < 0)
+		goto out;
+
+	if (do_join) {
+		ret = cc33xx_join(cc, wlvif);
+		if (ret < 0) {
+			cc33xx_warning("cmd join failed %d", ret);
+			goto out;
+		}
+	}
+
+	if (changed & BSS_CHANGED_ASSOC) {
+		if (vif->cfg.assoc) {
+			ret = cc33xx_set_assoc(cc, wlvif, bss_conf, sta, vif,
+					       sta_rate_set);
+			if (ret < 0)
+				goto out;
+
+			if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags))
+				cc33xx_set_authorized(cc, wlvif);
+
+			if (sta)
+				cc33xx_sta_set_he(cc, wlvif, sta->deflink.he_cap.has_he);
+
+		} else {
+			cc33xx_unset_assoc(cc, wlvif);
+		}
+	}
+
+	if (changed & BSS_CHANGED_PS) {
+		if (vif->cfg.ps &&
+		    test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
+		    !test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
+			int ps_mode;
+			char *ps_mode_str;
+
+			if (cc->conf.host_conf.conn.forced_ps) {
+				ps_mode = STATION_POWER_SAVE_MODE;
+				ps_mode_str = "forced";
+			} else {
+				ps_mode = STATION_AUTO_PS_MODE;
+				ps_mode_str = "auto";
+			}
+
+			cc33xx_debug(DEBUG_PSM, "%s ps enabled", ps_mode_str);
+
+			ret = cc33xx_ps_set_mode(cc, wlvif, ps_mode);
+			if (ret < 0)
+				cc33xx_warning("enter %s ps failed %d",
+					       ps_mode_str, ret);
+		} else if (!vif->cfg.ps && test_bit(WLVIF_FLAG_IN_PS,
+						     &wlvif->flags)) {
+			cc33xx_debug(DEBUG_PSM, "auto ps disabled");
+
+			ret = cc33xx_ps_set_mode(cc, wlvif,
+						 STATION_ACTIVE_MODE);
+			if (ret < 0)
+				cc33xx_warning("exit auto ps failed %d", ret);
+		}
+	}
+
+	/* Handle new association with HT. Do this after join. */
+	if (sta_exists) {
+		bool enabled = bss_conf->chanreq.oper.width !=
+						NL80211_CHAN_WIDTH_20_NOHT;
+		cc33xx_debug(DEBUG_CMD, "cc33xx_hw_set_peer_cap %x",
+			     wlvif->rate_set);
+		ret = cc33xx_acx_set_peer_cap(cc, &sta_ht_cap, &sta_he_cap,
+					      wlvif, enabled, wlvif->rate_set,
+					      wlvif->sta.hlid);
+		if (ret < 0) {
+			cc33xx_warning("Set ht cap failed %d", ret);
+			goto out;
+		}
+
+		if (enabled) {
+			ret = cc33xx_acx_set_ht_information(cc, wlvif,
+							    bss_conf->ht_operation_mode,
+						bss_conf->he_oper.params,
+						bss_conf->he_oper.nss_set);
+			if (ret < 0) {
+				cc33xx_warning("Set ht information failed %d",
+					       ret);
+				goto out;
+			}
+		}
+	}
+
+	/* Handle arp filtering. Done after join. */
+	if ((changed & BSS_CHANGED_ARP_FILTER) ||
+	    (!is_ibss && (changed & BSS_CHANGED_QOS))) {
+		__be32 addr = vif->cfg.arp_addr_list[0];
+
+		wlvif->sta.qos = bss_conf->qos;
+		WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS);
+
+		if (vif->cfg.arp_addr_cnt == 1 && vif->cfg.assoc) {
+			wlvif->ip_addr = addr;
+			/* The template should have been configured only upon
+			 * association. however, it seems that the correct ip
+			 * isn't being set (when sending), so we have to
+			 * reconfigure the template upon every ip change.
+			 */
+			if (ret < 0) {
+				cc33xx_warning("build arp rsp failed: %d", ret);
+				goto out;
+			}
+
+		} else {
+			wlvif->ip_addr = 0;
+		}
+
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	return;
+}
+
+static void cc33xx_op_bss_info_changed(struct ieee80211_hw *hw,
+				       struct ieee80211_vif *vif,
+				       struct ieee80211_bss_conf *bss_conf,
+				       u64 changed)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
+	int ret, set_power;
+
+	/* make sure to cancel pending disconnections if our association
+	 * state changed
+	 */
+	if (!is_ap && (changed & BSS_CHANGED_ASSOC))
+		cancel_delayed_work_sync(&wlvif->connection_loss_work);
+
+	if (is_ap && (changed & BSS_CHANGED_BEACON_ENABLED) &&
+	    !bss_conf->enable_beacon)
+		cc33xx_tx_flush(cc);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)))
+		goto out;
+
+	if ((changed & BSS_CHANGED_TXPOWER) && bss_conf->txpower != wlvif->power_level) {
+		/* bss_conf->txpower is initialized with a default value,
+		 * meaning the power has not been set and should be ignored, use
+		 * max value instead
+		 */
+		set_power = (bss_conf->txpower == INT_MIN) ?
+					   CC33XX_MAX_TXPWR : bss_conf->txpower;
+		ret = cc33xx_acx_tx_power(cc, wlvif, set_power);
+
+		if (ret < 0)
+			goto out;
+	}
+
+	if (is_ap)
+		cc33xx_bss_info_changed_ap(cc, vif, bss_conf, changed);
+	else
+		cc33xx_bss_info_changed_sta(cc, vif, bss_conf, changed);
+
+out:
+	mutex_unlock(&cc->mutex);
+}
+
+static int cc33xx_op_add_chanctx(struct ieee80211_hw *hw,
+				 struct ieee80211_chanctx_conf *ctx)
+{
+	cc33xx_debug(DEBUG_MAC80211, "mac80211 add chanctx %d (type %d)",
+		     ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
+		     cfg80211_get_chandef_type(&ctx->def));
+	return 0;
+}
+
+static void cc33xx_op_remove_chanctx(struct ieee80211_hw *hw,
+				     struct ieee80211_chanctx_conf *ctx)
+{
+	cc33xx_debug(DEBUG_MAC80211, "mac80211 remove chanctx %d (type %d)",
+		     ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
+		     cfg80211_get_chandef_type(&ctx->def));
+}
+
+static void cc33xx_op_change_chanctx(struct ieee80211_hw *hw,
+				     struct ieee80211_chanctx_conf *ctx,
+				     u32 changed)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif;
+	int channel = ieee80211_frequency_to_channel(ctx->def.chan->center_freq);
+
+	cc33xx_debug(DEBUG_MAC80211,
+		     "mac80211 change chanctx %d (type %d) changed 0x%x",
+		     channel, cfg80211_get_chandef_type(&ctx->def), changed);
+
+	mutex_lock(&cc->mutex);
+
+	cc33xx_for_each_wlvif(cc, wlvif) {
+		struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
+
+		rcu_read_lock();
+		if (rcu_access_pointer(vif->bss_conf.chanctx_conf) != ctx) {
+			rcu_read_unlock();
+			continue;
+		}
+		rcu_read_unlock();
+
+		/* start radar if needed */
+		if (changed & IEEE80211_CHANCTX_CHANGE_RADAR &&
+		    wlvif->bss_type == BSS_TYPE_AP_BSS &&
+		    ctx->radar_enabled && !wlvif->radar_enabled &&
+		    ctx->def.chan->dfs_state == NL80211_DFS_USABLE) {
+			cmd_set_cac(cc, wlvif, true);
+			wlvif->radar_enabled = true;
+		}
+	}
+
+	mutex_unlock(&cc->mutex);
+}
+
+static int cc33xx_op_assign_vif_chanctx(struct ieee80211_hw *hw,
+					struct ieee80211_vif *vif,
+					struct ieee80211_bss_conf *link_conf,
+					struct ieee80211_chanctx_conf *ctx)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	int channel = ieee80211_frequency_to_channel(ctx->def.chan->center_freq);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)))
+		goto out;
+
+	wlvif->band = ctx->def.chan->band;
+	wlvif->channel = channel;
+	wlvif->channel_type = cfg80211_get_chandef_type(&ctx->def);
+
+	/* update default rates according to the band */
+	cc33xx_set_band_rate(cc, wlvif);
+
+	if (ctx->radar_enabled && ctx->def.chan->dfs_state == NL80211_DFS_USABLE) {
+		cc33xx_debug(DEBUG_MAC80211, "Start radar detection");
+		cmd_set_cac(cc, wlvif, true);
+		wlvif->radar_enabled = true;
+	}
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return 0;
+}
+
+static void cc33xx_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
+					   struct ieee80211_vif *vif,
+					   struct ieee80211_bss_conf *link_conf,
+					   struct ieee80211_chanctx_conf *ctx)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+
+	cc33xx_tx_flush(cc);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)))
+		goto out;
+
+	if (wlvif->radar_enabled) {
+		cc33xx_debug(DEBUG_MAC80211, "Stop radar detection");
+		cmd_set_cac(cc, wlvif, false);
+		wlvif->radar_enabled = false;
+	}
+
+out:
+	mutex_unlock(&cc->mutex);
+}
+
+static int cc33xx_switch_vif_chan(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				  struct ieee80211_chanctx_conf *new_ctx)
+{
+	int channel = ieee80211_frequency_to_channel(new_ctx->def.chan->center_freq);
+
+	wlvif->band = new_ctx->def.chan->band;
+	wlvif->channel = channel;
+	wlvif->channel_type = cfg80211_get_chandef_type(&new_ctx->def);
+
+	if (wlvif->bss_type != BSS_TYPE_AP_BSS)
+		return 0;
+
+	WARN_ON(!test_bit(WLVIF_FLAG_BEACON_DISABLED, &wlvif->flags));
+
+	if (wlvif->radar_enabled) {
+		cmd_set_cac(cc, wlvif, false);
+		wlvif->radar_enabled = false;
+	}
+
+	/* start radar if needed */
+	if (new_ctx->radar_enabled) {
+		cmd_set_cac(cc, wlvif, true);
+		wlvif->radar_enabled = true;
+	}
+
+	return 0;
+}
+
+static int cc33xx_op_switch_vif_chanctx(struct ieee80211_hw *hw,
+					struct ieee80211_vif_chanctx_switch *vifs,
+					int n_vifs,
+					enum ieee80211_chanctx_switch_mode mode)
+{
+	struct cc33xx *cc = hw->priv;
+	int i, ret;
+
+	cc33xx_debug(DEBUG_MAC80211,
+		     "mac80211 switch chanctx n_vifs %d mode %d", n_vifs, mode);
+
+	mutex_lock(&cc->mutex);
+
+	for (i = 0; i < n_vifs; i++) {
+		struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vifs[i].vif);
+
+		ret = cc33xx_switch_vif_chan(cc, wlvif, vifs[i].new_ctx);
+		if (ret)
+			goto out;
+	}
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return 0;
+}
+
+static int cc33xx_op_conf_tx(struct ieee80211_hw *hw,
+			     struct ieee80211_vif *vif,
+			     unsigned int link_id, u16 queue,
+			     const struct ieee80211_tx_queue_params *params)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	u8 ps_scheme;
+	int ret = 0;
+
+	if (cc33xx_is_p2p_mgmt(wlvif))
+		return 0;
+
+	mutex_lock(&cc->mutex);
+
+	cc33xx_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
+
+	if (params->uapsd)
+		ps_scheme = CONF_PS_SCHEME_UPSD_TRIGGER;
+	else
+		ps_scheme = CONF_PS_SCHEME_LEGACY;
+
+	if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
+		goto out;
+
+	ret = cc33xx_tx_param_cfg(cc, wlvif, cc33xx_tx_get_queue(queue),
+				  params->cw_min, params->cw_max, params->aifs,
+			      params->txop << 5, params->acm, ps_scheme,
+			      params->mu_edca, params->mu_edca_param_rec.aifsn,
+			      params->mu_edca_param_rec.ecw_min_max,
+			      params->mu_edca_param_rec.mu_edca_timer);
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+static u64 cc33xx_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	u64 mactime = ULLONG_MAX;
+
+	cc33xx_debug(DEBUG_MAC80211, "mac80211 get tsf");
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	cc33xx_acx_tsf_info(cc, wlvif, &mactime);
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return mactime;
+}
+
+static int cc33xx_op_get_survey(struct ieee80211_hw *hw, int idx,
+				struct survey_info *survey)
+{
+	struct ieee80211_conf *conf = &hw->conf;
+
+	if (idx != 0)
+		return -ENOENT;
+
+	survey->channel = conf->chandef.chan;
+	survey->filled = 0;
+	return 0;
+}
+
+static int cc33xx_allocate_sta(struct cc33xx *cc,
+			       struct cc33xx_vif *wlvif,
+			     struct ieee80211_sta *sta)
+{
+	struct cc33xx_station *wl_sta;
+	int ret;
+
+	if (cc->active_sta_count >= CC33XX_MAX_AP_STATIONS) {
+		cc33xx_warning("could not allocate HLID - too much stations");
+		return -EBUSY;
+	}
+
+	wl_sta = (struct cc33xx_station *)sta->drv_priv;
+
+	ret = cc33xx_set_link(cc, wlvif, wl_sta->hlid);
+
+	if (ret < 0) {
+		cc33xx_warning("could not allocate HLID - too many links");
+		return -EBUSY;
+	}
+
+	/* use the previous security seq, if this is a recovery/resume */
+	cc->links[wl_sta->hlid].total_freed_pkts = wl_sta->total_freed_pkts;
+
+	set_bit(wl_sta->hlid, wlvif->ap.sta_hlid_map);
+	memcpy(cc->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN);
+	cc->active_sta_count++;
+	return 0;
+}
+
+void cc33xx_free_sta(struct cc33xx *cc, struct cc33xx_vif *wlvif, u8 hlid)
+{
+	if (!test_bit(hlid, wlvif->ap.sta_hlid_map))
+		return;
+
+	clear_bit(hlid, wlvif->ap.sta_hlid_map);
+	__clear_bit(hlid, &cc->ap_ps_map);
+	__clear_bit(hlid, &cc->ap_fw_ps_map);
+
+	/* save the last used PN in the private part of iee80211_sta,
+	 * in case of recovery/suspend
+	 */
+	cc33xx_save_freed_pkts_addr(cc, wlvif, hlid, cc->links[hlid].addr);
+
+	cc33xx_clear_link(cc, wlvif, &hlid);
+	cc->active_sta_count--;
+
+	/* rearm the tx watchdog when the last STA is freed - give the FW a
+	 * chance to return STA-buffered packets before complaining.
+	 */
+	if (cc->active_sta_count == 0)
+		cc33xx_rearm_tx_watchdog_locked(cc);
+}
+
+static int cc33xx_sta_add(struct cc33xx *cc,
+			  struct cc33xx_vif *wlvif,
+			  struct ieee80211_sta *sta)
+{
+	struct cc33xx_station *wl_sta;
+	int ret = 0;
+	u8 hlid;
+
+	cc33xx_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid);
+
+	wl_sta = (struct cc33xx_station *)sta->drv_priv;
+	ret = cc33xx_cmd_add_peer(cc, wlvif, sta, &hlid, 0);
+	if (ret < 0)
+		return ret;
+
+	wl_sta->hlid = hlid;
+	ret = cc33xx_allocate_sta(cc, wlvif, sta);
+
+	return ret;
+}
+
+static int cc33xx_sta_remove(struct cc33xx *cc,
+			     struct cc33xx_vif *wlvif,
+			     struct ieee80211_sta *sta)
+{
+	struct cc33xx_station *wl_sta;
+	int ret = 0, id;
+
+	cc33xx_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid);
+
+	wl_sta = (struct cc33xx_station *)sta->drv_priv;
+	id = wl_sta->hlid;
+	if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map)))
+		return -EINVAL;
+
+	ret = cc33xx_cmd_remove_peer(cc, wlvif, wl_sta->hlid);
+	if (ret < 0)
+		return ret;
+
+	cc33xx_free_sta(cc, wlvif, wl_sta->hlid);
+	return ret;
+}
+
+static void cc33xx_roc_if_possible(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	if (find_first_bit(cc->roc_map, CC33XX_MAX_ROLES) < CC33XX_MAX_ROLES)
+		return;
+
+	if (WARN_ON(wlvif->role_id == CC33XX_INVALID_ROLE_ID))
+		return;
+
+	cc33xx_roc(cc, wlvif, wlvif->role_id, wlvif->band, wlvif->channel);
+}
+
+/* when wl_sta is NULL, we treat this call as if coming from a
+ * pending auth reply.
+ * cc->mutex must be taken and the FW must be awake when the call
+ * takes place.
+ */
+void cc33xx_update_inconn_sta(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			      struct cc33xx_station *wl_sta, bool in_conn)
+{
+	cc33xx_debug(DEBUG_CMD, "update_inconn_sta: in_conn=%d count=%d, pending_auth=%d",
+		     in_conn,
+		     wlvif->inconn_count, wlvif->ap_pending_auth_reply);
+
+	if (in_conn) {
+		if (WARN_ON(wl_sta && wl_sta->in_connection))
+			return;
+
+		if (!wlvif->ap_pending_auth_reply && !wlvif->inconn_count) {
+			cc33xx_roc_if_possible(cc, wlvif);
+			if (test_bit(wlvif->role_id, cc->roc_map)) {
+				unsigned long roc_cmplt_jiffies =
+					msecs_to_jiffies(CC33xx_PEND_ROC_COMPLETE_TIMEOUT);
+
+				/* set timer on croc timeout */
+				wlvif->pending_auth_reply_time = jiffies;
+				cancel_delayed_work(&wlvif->roc_timeout_work);
+
+				cc33xx_debug(DEBUG_AP, "delay queue roc_timeout_work");
+
+				ieee80211_queue_delayed_work(cc->hw,
+							     &wlvif->roc_timeout_work,
+							     roc_cmplt_jiffies);
+			}
+		}
+
+		if (wl_sta) {
+			wl_sta->in_connection = true;
+			wlvif->inconn_count++;
+		} else {
+			wlvif->ap_pending_auth_reply = true;
+		}
+	} else {
+		if (wl_sta && !wl_sta->in_connection)
+			return;
+
+		if (WARN_ON(!wl_sta && !wlvif->ap_pending_auth_reply))
+			return;
+
+		if (WARN_ON(wl_sta && !wlvif->inconn_count))
+			return;
+
+		if (wl_sta) {
+			wl_sta->in_connection = false;
+			wlvif->inconn_count--;
+		} else {
+			wlvif->ap_pending_auth_reply = false;
+		}
+
+		if (!wlvif->inconn_count && !wlvif->ap_pending_auth_reply &&
+		    test_bit(wlvif->role_id, cc->roc_map)) {
+			cc33xx_croc(cc, wlvif->role_id);
+			/* remove timer for croc t/o */
+			cc33xx_debug(DEBUG_AP, "Cancel pending_roc timeout");
+			cancel_delayed_work(&wlvif->roc_timeout_work);
+		}
+	}
+}
+
+static int cc33xx_update_sta_state(struct cc33xx *cc,
+				   struct cc33xx_vif *wlvif,
+				   struct ieee80211_sta *sta,
+				   enum ieee80211_sta_state old_state,
+				   enum ieee80211_sta_state new_state)
+{
+	struct cc33xx_station *wl_sta;
+	bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
+	bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
+	int ret;
+
+	wl_sta = (struct cc33xx_station *)sta->drv_priv;
+
+	/* Add station (AP mode) */
+	if (is_ap && old_state == IEEE80211_STA_NOTEXIST && new_state == IEEE80211_STA_NONE) {
+		ret = cc33xx_sta_add(cc, wlvif, sta);
+		if (ret)
+			return ret;
+
+		cc33xx_update_inconn_sta(cc, wlvif, wl_sta, true);
+	}
+
+	/* Remove station (AP mode) */
+	if (is_ap && old_state == IEEE80211_STA_NONE && new_state == IEEE80211_STA_NOTEXIST) {
+		/* must not fail */
+		cc33xx_sta_remove(cc, wlvif, sta);
+
+		cc33xx_update_inconn_sta(cc, wlvif, wl_sta, false);
+	}
+
+	/* Authorize station (AP mode) */
+	if (is_ap && new_state == IEEE80211_STA_AUTHORIZED) {
+		/* reconfigure peer */
+		ret = cc33xx_cmd_add_peer(cc, wlvif, sta, NULL, true);
+		if (ret < 0)
+			return ret;
+
+		cc33xx_update_inconn_sta(cc, wlvif, wl_sta, false);
+	}
+
+	/* Authorize station */
+	if (is_sta && new_state == IEEE80211_STA_AUTHORIZED) {
+		set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
+		ret = cc33xx_set_authorized(cc, wlvif);
+		if (ret)
+			return ret;
+	}
+
+	if (is_sta && old_state == IEEE80211_STA_AUTHORIZED && new_state == IEEE80211_STA_ASSOC) {
+		clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
+		clear_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags);
+	}
+
+	/* save seq number on disassoc (suspend) */
+	if (is_sta && old_state == IEEE80211_STA_ASSOC && new_state == IEEE80211_STA_AUTH) {
+		cc33xx_save_freed_pkts(cc, wlvif, wlvif->sta.hlid, sta);
+		wlvif->total_freed_pkts = 0;
+	}
+
+	/* restore seq number on assoc (resume) */
+	if (is_sta && old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC)
+		wlvif->total_freed_pkts = wl_sta->total_freed_pkts;
+
+	/* clear ROCs on failure or authorization */
+	if (is_sta &&
+	    (new_state == IEEE80211_STA_AUTHORIZED ||
+	    new_state == IEEE80211_STA_NOTEXIST)) {
+		if (test_bit(wlvif->role_id, cc->roc_map))
+			cc33xx_croc(cc, wlvif->role_id);
+	}
+
+	if (is_sta && (old_state == IEEE80211_STA_NOTEXIST &&
+		       new_state == IEEE80211_STA_NONE)) {
+		if (find_first_bit(cc->roc_map,
+				   CC33XX_MAX_ROLES) >= CC33XX_MAX_ROLES) {
+			WARN_ON(wlvif->role_id == CC33XX_INVALID_ROLE_ID);
+			cc33xx_roc(cc, wlvif, wlvif->role_id,
+				   wlvif->band, wlvif->channel);
+		}
+	}
+
+	return 0;
+}
+
+static int cc33xx_op_sta_state(struct ieee80211_hw *hw,
+			       struct ieee80211_vif *vif,
+			       struct ieee80211_sta *sta,
+			       enum ieee80211_sta_state old_state,
+			       enum ieee80211_sta_state new_state)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	int ret;
+
+	cc33xx_debug(DEBUG_MAC80211, "mac80211 sta %d state=%d->%d",
+		     sta->aid, old_state, new_state);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = cc33xx_update_sta_state(cc, wlvif, sta, old_state, new_state);
+
+out:
+	mutex_unlock(&cc->mutex);
+	if (new_state < old_state)
+		return 0;
+	return ret;
+}
+
+static int cc33xx_op_ampdu_action(struct ieee80211_hw *hw,
+				  struct ieee80211_vif *vif,
+				  struct ieee80211_ampdu_params *params)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	int ret;
+	u8 hlid, *ba_bitmap;
+	struct ieee80211_sta *sta = params->sta;
+	enum ieee80211_ampdu_mlme_action action = params->action;
+	u16 tid = params->tid;
+	u16 *ssn = &params->ssn;
+
+	/* sanity check - the fields in FW are only 8bits wide */
+	if (WARN_ON(tid > 0xFF))
+		return -EOPNOTSUPP;
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON)) {
+		ret = -EAGAIN;
+		goto out;
+	}
+
+	if (wlvif->bss_type == BSS_TYPE_STA_BSS) {
+		hlid = wlvif->sta.hlid;
+	} else if (wlvif->bss_type == BSS_TYPE_AP_BSS) {
+		struct cc33xx_station *wl_sta;
+
+		wl_sta = (struct cc33xx_station *)sta->drv_priv;
+		hlid = wl_sta->hlid;
+	} else {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (hlid == CC33XX_INVALID_LINK_ID) {
+		ret = 0;
+		goto out;
+	}
+
+	if (WARN_ON(hlid >= CC33XX_MAX_LINKS)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ba_bitmap = &cc->links[hlid].ba_bitmap;
+
+	switch (action) {
+	case IEEE80211_AMPDU_RX_START:
+		if (!wlvif->ba_support || !wlvif->ba_allowed) {
+			ret = -EOPNOTSUPP;
+			break;
+		}
+
+		if (cc->ba_rx_session_count >= CC33XX_RX_BA_MAX_SESSIONS) {
+			ret = -EBUSY;
+			cc33xx_error("exceeded max RX BA sessions");
+			break;
+		}
+
+		if (*ba_bitmap & BIT(tid)) {
+			ret = -EINVAL;
+			cc33xx_error("cannot enable RX BA session on active tid: %d",
+				     tid);
+			break;
+		}
+
+		ret = cc33xx_acx_set_ba_receiver_session(cc, tid, *ssn,
+							 true, hlid,
+							 params->buf_size);
+
+		if (!ret) {
+			*ba_bitmap |= BIT(tid);
+			cc->ba_rx_session_count++;
+		}
+		break;
+
+	case IEEE80211_AMPDU_RX_STOP:
+		if (!(*ba_bitmap & BIT(tid))) {
+			/* this happens on reconfig - so only output a debug
+			 * message for now, and don't fail the function.
+			 */
+			cc33xx_debug(DEBUG_MAC80211,
+				     "no active RX BA session on tid: %d", tid);
+			ret = 0;
+			break;
+		}
+
+		ret = cc33xx_acx_set_ba_receiver_session(cc, tid, 0,
+							 false, hlid, 0);
+		if (!ret) {
+			*ba_bitmap &= ~BIT(tid);
+			cc->ba_rx_session_count--;
+		}
+		break;
+
+	/* The BA initiator session management in FW independently.
+	 * Falling break here on purpose for all TX APDU commands.
+	 */
+	case IEEE80211_AMPDU_TX_START:
+	case IEEE80211_AMPDU_TX_STOP_CONT:
+	case IEEE80211_AMPDU_TX_STOP_FLUSH:
+	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+	case IEEE80211_AMPDU_TX_OPERATIONAL:
+		ret = -EINVAL;
+		break;
+
+	default:
+		cc33xx_error("Incorrect ampdu action id=%x\n", action);
+		ret = -EINVAL;
+	}
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+static int cc33xx_set_bitrate_mask(struct ieee80211_hw *hw,
+				   struct ieee80211_vif *vif,
+				   const struct cfg80211_bitrate_mask *mask)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	struct cc33xx *cc = hw->priv;
+	int ret = 0;
+
+	cc33xx_debug(DEBUG_MAC80211, "mac80211 set_bitrate_mask 0x%x 0x%x",
+		     mask->control[NL80211_BAND_2GHZ].legacy,
+		mask->control[NL80211_BAND_5GHZ].legacy);
+
+	mutex_lock(&cc->mutex);
+
+	wlvif->bitrate_masks[0] = cc33xx_tx_enabled_rates_get(cc,
+							      mask->control[0].legacy, 0);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
+	    !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
+		cc33xx_set_band_rate(cc, wlvif);
+		wlvif->basic_rate = cc33xx_tx_min_rate_get(cc,
+							   wlvif->basic_rate_set);
+	}
+out:
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+static void cc33xx_op_channel_switch(struct ieee80211_hw *hw,
+				     struct ieee80211_vif *vif,
+				     struct ieee80211_channel_switch *ch_switch)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	int ret;
+
+	cc33xx_tx_flush(cc);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state == CC33XX_STATE_OFF)) {
+		if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+			ieee80211_chswitch_done(vif, false, 0);
+		goto out;
+	} else if (unlikely(cc->state != CC33XX_STATE_ON)) {
+		goto out;
+	}
+
+	/* TODO: change mac80211 to pass vif as param */
+
+	if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
+		unsigned long delay_usec;
+
+		ret = cmd_channel_switch(cc, wlvif, ch_switch);
+		if (ret)
+			goto out;
+
+		set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);
+
+		/* indicate failure 5 seconds after channel switch time */
+		delay_usec = ieee80211_tu_to_usec(wlvif->beacon_int) *
+							       ch_switch->count;
+		ieee80211_queue_delayed_work(hw, &wlvif->channel_switch_work,
+					     usecs_to_jiffies(delay_usec) +
+					     msecs_to_jiffies(5000));
+	}
+
+out:
+	mutex_unlock(&cc->mutex);
+}
+
+static inline void cc33xx_op_channel_switch_beacon(struct ieee80211_hw *hw,
+						   struct ieee80211_vif *vif,
+						   struct cfg80211_chan_def *chandef)
+{
+	cc33xx_error("AP channel switch is not supported");
+}
+
+static inline void cc33xx_op_flush(struct ieee80211_hw *hw,
+				   struct ieee80211_vif *vif,
+				   u32 queues, bool drop)
+{
+	cc33xx_tx_flush(hw->priv);
+}
+
+static int cc33xx_op_remain_on_channel(struct ieee80211_hw *hw,
+				       struct ieee80211_vif *vif,
+				       struct ieee80211_channel *chan,
+				       int duration,
+				       enum ieee80211_roc_type type)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	struct cc33xx *cc = hw->priv;
+	int channel, active_roc, ret = 0;
+
+	channel = ieee80211_frequency_to_channel(chan->center_freq);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	/* return EBUSY if we can't ROC right now */
+	active_roc = find_first_bit(cc->roc_map, CC33XX_MAX_ROLES);
+	if (cc->roc_vif || active_roc < CC33XX_MAX_ROLES) {
+		cc33xx_warning("active roc on role %d", active_roc);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	cc33xx_debug(DEBUG_MAC80211,
+		     "call cc33xx_start_dev, band = %d, channel = %d",
+		     chan->band, channel);
+	ret = cc33xx_start_dev(cc, wlvif, chan->band, channel);
+	if (ret < 0)
+		goto out;
+
+	cc->roc_vif = vif;
+	ieee80211_queue_delayed_work(hw, &cc->roc_complete_work,
+				     msecs_to_jiffies(duration));
+
+out:
+	mutex_unlock(&cc->mutex);
+	return ret;
+}
+
+static int __cc33xx_roc_completed(struct cc33xx *cc)
+{
+	struct cc33xx_vif *wlvif;
+	int ret;
+
+	/* already completed */
+	if (unlikely(!cc->roc_vif))
+		return 0;
+
+	wlvif = cc33xx_vif_to_data(cc->roc_vif);
+
+	if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
+		return -EBUSY;
+
+	ret = cc33xx_stop_dev(cc, wlvif);
+	if (ret < 0)
+		return ret;
+
+	cc->roc_vif = NULL;
+
+	return 0;
+}
+
+static int cc33xx_roc_completed(struct cc33xx *cc)
+{
+	int ret;
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = __cc33xx_roc_completed(cc);
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+static void cc33xx_roc_complete_work(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+	struct cc33xx *cc;
+	int ret;
+
+	dwork = to_delayed_work(work);
+	cc = container_of(dwork, struct cc33xx, roc_complete_work);
+
+	ret = cc33xx_roc_completed(cc);
+	if (!ret)
+		ieee80211_remain_on_channel_expired(cc->hw);
+}
+
+static int cc33xx_op_cancel_remain_on_channel(struct ieee80211_hw *hw,
+					      struct ieee80211_vif *vif)
+{
+	struct cc33xx *cc = hw->priv;
+
+	cc33xx_tx_flush(cc);
+
+	/* we can't just flush_work here, because it might deadlock
+	 * (as we might get called from the same workqueue)
+	 */
+	cancel_delayed_work_sync(&cc->roc_complete_work);
+	cc33xx_roc_completed(cc);
+
+	return 0;
+}
+
+static void cc33xx_op_sta_rc_update(struct ieee80211_hw *hw,
+				    struct ieee80211_vif *vif,
+				    struct ieee80211_sta *sta,
+				    u32 changed)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+
+	if (!(changed & IEEE80211_RC_BW_CHANGED))
+		return;
+
+	/* this callback is atomic, so schedule a new work */
+	wlvif->rc_update_bw = sta->deflink.bandwidth;
+	memcpy(&wlvif->rc_ht_cap, &sta->deflink.ht_cap, sizeof(sta->deflink.ht_cap));
+	ieee80211_queue_work(hw, &wlvif->rc_update_work);
+}
+
+static void cc33xx_op_sta_statistics(struct ieee80211_hw *hw,
+				     struct ieee80211_vif *vif,
+				     struct ieee80211_sta *sta,
+				     struct station_info *sinfo)
+{
+	struct cc33xx *cc = hw->priv;
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	s8 rssi_dbm;
+	int ret;
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	ret = cc33xx_acx_average_rssi(cc, wlvif, &rssi_dbm);
+	if (ret < 0)
+		goto out;
+
+	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
+	sinfo->signal = rssi_dbm;
+
+	ret = cc33xx_acx_get_tx_rate(cc, wlvif, sinfo);
+	if (ret < 0)
+		goto out;
+
+out:
+	mutex_unlock(&cc->mutex);
+}
+
+static u32 cc33xx_op_get_expected_throughput(struct ieee80211_hw *hw,
+					     struct ieee80211_sta *sta)
+{
+	struct cc33xx_station *wl_sta = (struct cc33xx_station *)sta->drv_priv;
+	struct cc33xx *cc = hw->priv;
+	u8 hlid = wl_sta->hlid;
+
+	/* return in units of Kbps */
+	return (cc->links[hlid].fw_rate_mbps * 1000);
+}
+
+static bool cc33xx_tx_frames_pending(struct ieee80211_hw *hw)
+{
+	struct cc33xx *cc = hw->priv;
+	bool ret = false;
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	/* packets are considered pending if in the TX queue or the FW */
+	ret = (cc33xx_tx_total_queue_count(cc) > 0) || (cc->tx_frames_cnt > 0);
+out:
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+#ifdef CONFIG_PM
+
+static const struct wiphy_wowlan_support cc33xx_wowlan_support = {
+	.flags = WIPHY_WOWLAN_ANY,
+	.n_patterns = CC33XX_MAX_RX_FILTERS,
+	.pattern_min_len = 1,
+	.pattern_max_len = CC33XX_RX_FILTER_MAX_PATTERN_SIZE,
+};
+
+static void setup_wake_irq(struct cc33xx *cc)
+{
+	struct platform_device *pdev = cc->pdev;
+	struct cc33xx_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+
+	struct resource *res;
+	int ret;
+
+	device_init_wakeup(cc->dev, true);
+
+	if (pdev_data->pwr_in_suspend)
+		cc->hw->wiphy->wowlan = &cc33xx_wowlan_support;
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (res) {
+		cc->wakeirq = res->start;
+		ret = dev_pm_set_dedicated_wake_irq(cc->dev, cc->wakeirq);
+		if (ret)
+			cc->wakeirq = -ENODEV;
+	} else {
+		cc->wakeirq = -ENODEV;
+	}
+
+	cc->keep_device_power = true;
+}
+#else
+
+static inline void setup_wake_irq(struct cc33xx *cc)
+{
+	cc->keep_device_power = true;
+}
+
+#endif /* CONFIG_PM */
+
+static const struct ieee80211_ops cc33xx_ops = {
+	.start = cc33xx_op_start,
+	.stop = cc33xx_op_stop,
+	.add_interface = cc33xx_op_add_interface,
+	.remove_interface = cc33xx_op_remove_interface,
+	.change_interface = cc33xx_op_change_interface,
+#ifdef CONFIG_PM
+	.suspend = cc33xx_op_suspend,
+	.resume = cc33xx_op_resume,
+#endif
+	.config = cc33xx_op_config,
+	.prepare_multicast = cc33xx_op_prepare_multicast,
+	.configure_filter = cc33xx_op_configure_filter,
+	.tx = cc33xx_op_tx,
+	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
+	.set_key = cc33xx_op_set_key,
+	.hw_scan = cc33xx_op_hw_scan,
+	.cancel_hw_scan = cc33xx_op_cancel_hw_scan,
+	.sched_scan_start = cc33xx_op_sched_scan_start,
+	.sched_scan_stop = cc33xx_op_sched_scan_stop,
+	.bss_info_changed = cc33xx_op_bss_info_changed,
+	.set_frag_threshold = cc33xx_op_set_frag_threshold,
+	.set_rts_threshold = cc33xx_op_set_rts_threshold,
+	.conf_tx = cc33xx_op_conf_tx,
+	.get_tsf = cc33xx_op_get_tsf,
+	.get_survey = cc33xx_op_get_survey,
+	.sta_state = cc33xx_op_sta_state,
+	.ampdu_action = cc33xx_op_ampdu_action,
+	.tx_frames_pending = cc33xx_tx_frames_pending,
+	.set_bitrate_mask = cc33xx_set_bitrate_mask,
+	.set_default_unicast_key = cc33xx_op_set_default_key_idx,
+	.channel_switch = cc33xx_op_channel_switch,
+	.channel_switch_beacon = cc33xx_op_channel_switch_beacon,
+	.flush = cc33xx_op_flush,
+	.remain_on_channel = cc33xx_op_remain_on_channel,
+	.cancel_remain_on_channel = cc33xx_op_cancel_remain_on_channel,
+	.add_chanctx = cc33xx_op_add_chanctx,
+	.remove_chanctx = cc33xx_op_remove_chanctx,
+	.change_chanctx = cc33xx_op_change_chanctx,
+	.assign_vif_chanctx = cc33xx_op_assign_vif_chanctx,
+	.unassign_vif_chanctx = cc33xx_op_unassign_vif_chanctx,
+	.switch_vif_chanctx = cc33xx_op_switch_vif_chanctx,
+	.sta_rc_update = cc33xx_op_sta_rc_update,
+	.sta_statistics = cc33xx_op_sta_statistics,
+	.get_expected_throughput = cc33xx_op_get_expected_throughput,
+	CFG80211_TESTMODE_CMD(cc33xx_tm_cmd)
+};
+
+u8 cc33xx_rate_to_idx(struct cc33xx *cc, u8 rate, enum nl80211_band band)
+{
+	u8 idx;
+
+	if (WARN_ON(band >= 2))
+		return 0;
+
+	if (unlikely(rate > CONF_HW_RATE_INDEX_MAX)) {
+		cc33xx_error("Illegal RX rate from HW: %d", rate);
+		return 0;
+	}
+
+	idx = cc33xx_band_rate_to_idx[band][rate];
+	if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) {
+		cc33xx_error("Unsupported RX rate from HW: %d", rate);
+		return 0;
+	}
+
+	return idx;
+}
+
+static void cc33xx_derive_mac_addresses(struct cc33xx *cc)
+{
+	const u8 zero_mac[ETH_ALEN] = {0};
+	u8 base_addr[ETH_ALEN];
+	u8 bd_addr[ETH_ALEN];
+	bool use_nvs = false;
+	bool use_efuse = false;
+	bool use_random = false;
+
+	if (cc->nvs_mac_addr_len != ETH_ALEN) {
+		if (unlikely(cc->nvs_mac_addr_len > 0))
+			cc33xx_warning("NVS MAC address present but has a wrong size, ignoring.");
+
+		if (!ether_addr_equal(zero_mac, cc->efuse_mac_address)) {
+			use_efuse = true;
+			ether_addr_copy(base_addr, cc->efuse_mac_address);
+			cc33xx_debug(DEBUG_BOOT,
+				     "MAC address derived from EFUSE");
+		} else {
+			use_random = true;
+			eth_random_addr(base_addr);
+			cc33xx_warning("No EFUSE / NVS data, using random locally administered address.");
+		}
+	} else {
+		u8 *nvs_addr = cc->nvs_mac_addr;
+		const u8 efuse_magic_addr[ETH_ALEN] = {
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+		const u8 random_magic_addr[ETH_ALEN] = {
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
+
+		/* In NVS, addresses 00-00-00-00-00-00 and 00-00-00-00-00-01
+		 * have special meaning:
+		 */
+
+		if (ether_addr_equal(nvs_addr, efuse_magic_addr)) {
+			use_efuse = true;
+			ether_addr_copy(base_addr, cc->efuse_mac_address);
+			cc33xx_debug(DEBUG_BOOT,
+				     "NVS file selects address from EFUSE");
+		} else if (ether_addr_equal(nvs_addr, random_magic_addr)) {
+			use_random = true;
+			eth_random_addr(base_addr);
+			cc33xx_debug(DEBUG_BOOT,
+				     "NVS file sets random MAC address");
+		} else {
+			use_nvs = true;
+			ether_addr_copy(base_addr, nvs_addr);
+			cc33xx_debug(DEBUG_BOOT,
+				     "NVS file sets explicit MAC address");
+		}
+	}
+
+	if (use_nvs || use_efuse) {
+		u8 oui_laa_bit = BIT(1);
+		u8 oui_multicast_bit = BIT(0);
+
+		base_addr[0] &= ~oui_multicast_bit;
+
+		ether_addr_copy(cc->addresses[0].addr, base_addr);
+		ether_addr_copy(cc->addresses[1].addr, base_addr);
+		ether_addr_copy(cc->addresses[2].addr, base_addr);
+		ether_addr_copy(bd_addr, base_addr);
+
+		cc->addresses[1].addr[0] |= oui_laa_bit;
+		cc->addresses[2].addr[0] |= oui_laa_bit;
+
+		eth_addr_inc(cc->addresses[2].addr);
+		eth_addr_inc(bd_addr);
+	} else if (use_random) {
+		ether_addr_copy(cc->addresses[0].addr, base_addr);
+		ether_addr_copy(cc->addresses[1].addr, base_addr);
+		ether_addr_copy(cc->addresses[2].addr, base_addr);
+		ether_addr_copy(bd_addr, base_addr);
+
+		eth_addr_inc(bd_addr);
+		eth_addr_inc(cc->addresses[1].addr);
+		eth_addr_inc(cc->addresses[1].addr);
+		eth_addr_inc(cc->addresses[2].addr);
+		eth_addr_inc(cc->addresses[2].addr);
+		eth_addr_inc(cc->addresses[2].addr);
+	} else {
+		WARN_ON(1);
+	}
+
+	cc->hw->wiphy->n_addresses = CC33XX_NUM_MAC_ADDRESSES;
+	cc->hw->wiphy->addresses = cc->addresses;
+
+	cmd_set_bd_addr(cc, bd_addr);
+}
+
+static int cc33xx_register_hw(struct cc33xx *cc)
+{
+	int ret;
+
+	if (cc->mac80211_registered)
+		return 0;
+
+	cc33xx_derive_mac_addresses(cc);
+
+	ret = ieee80211_register_hw(cc->hw);
+	if (ret < 0) {
+		cc33xx_error("unable to register mac80211 hw: %d", ret);
+		goto out;
+	}
+
+	cc->mac80211_registered = true;
+
+out:
+	return ret;
+}
+
+static void cc33xx_unregister_hw(struct cc33xx *cc)
+{
+	if (cc->plt)
+		cc33xx_plt_stop(cc);
+
+	ieee80211_unregister_hw(cc->hw);
+	cc->mac80211_registered = false;
+}
+
+static int cc33xx_init_ieee80211(struct cc33xx *cc)
+{
+	unsigned int i;
+
+	if (cc->conf.core.mixed_mode_support) {
+		static const u32 cipher_suites[] = {
+			WLAN_CIPHER_SUITE_CCMP,
+			WLAN_CIPHER_SUITE_AES_CMAC,
+			WLAN_CIPHER_SUITE_TKIP,
+			WLAN_CIPHER_SUITE_GCMP,
+			WLAN_CIPHER_SUITE_GCMP_256,
+			WLAN_CIPHER_SUITE_BIP_GMAC_128,
+			WLAN_CIPHER_SUITE_BIP_GMAC_256,
+		};
+		cc->hw->wiphy->cipher_suites = cipher_suites;
+		cc->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
+	} else {
+		static const u32 cipher_suites[] = {
+			WLAN_CIPHER_SUITE_CCMP,
+			WLAN_CIPHER_SUITE_AES_CMAC,
+			WLAN_CIPHER_SUITE_GCMP,
+			WLAN_CIPHER_SUITE_GCMP_256,
+			WLAN_CIPHER_SUITE_BIP_GMAC_128,
+			WLAN_CIPHER_SUITE_BIP_GMAC_256,
+		};
+		cc->hw->wiphy->cipher_suites = cipher_suites;
+		cc->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+	}
+
+	/* The tx descriptor buffer */
+	cc->hw->extra_tx_headroom = CC33XX_TX_EXTRA_HEADROOM;
+
+	if (cc->quirks & CC33XX_QUIRK_TKIP_HEADER_SPACE)
+		cc->hw->extra_tx_headroom += CC33XX_EXTRA_SPACE_TKIP;
+
+	/* unit us */
+	/* FIXME: find a proper value */
+	cc->hw->max_listen_interval =
+				cc->conf.host_conf.conn.max_listen_interval;
+
+	ieee80211_hw_set(cc->hw, SUPPORT_FAST_XMIT);
+	ieee80211_hw_set(cc->hw, CHANCTX_STA_CSA);
+	ieee80211_hw_set(cc->hw, QUEUE_CONTROL);
+	ieee80211_hw_set(cc->hw, TX_AMPDU_SETUP_IN_HW);
+	ieee80211_hw_set(cc->hw, AMPDU_AGGREGATION);
+	ieee80211_hw_set(cc->hw, AP_LINK_PS);
+	ieee80211_hw_set(cc->hw, SPECTRUM_MGMT);
+	ieee80211_hw_set(cc->hw, REPORTS_TX_ACK_STATUS);
+	ieee80211_hw_set(cc->hw, CONNECTION_MONITOR);
+	ieee80211_hw_set(cc->hw, HAS_RATE_CONTROL);
+	ieee80211_hw_set(cc->hw, SUPPORTS_DYNAMIC_PS);
+	ieee80211_hw_set(cc->hw, SIGNAL_DBM);
+	ieee80211_hw_set(cc->hw, SUPPORTS_PS);
+	ieee80211_hw_set(cc->hw, SUPPORTS_TX_FRAG);
+	ieee80211_hw_set(cc->hw, SUPPORTS_MULTI_BSSID);
+	ieee80211_hw_set(cc->hw, SUPPORTS_AMSDU_IN_AMPDU);
+
+	cc->hw->wiphy->interface_modes = cc33xx_wiphy_interface_modes();
+
+	cc->hw->wiphy->max_scan_ssids = 1;
+	cc->hw->wiphy->max_sched_scan_ssids = 16;
+	cc->hw->wiphy->max_match_sets = 16;
+	/* Maximum length of elements in scanning probe request templates
+	 * should be the maximum length possible for a template, without
+	 * the IEEE80211 header of the template
+	 */
+	cc->hw->wiphy->max_scan_ie_len = CC33XX_CMD_TEMPL_MAX_SIZE -
+			sizeof(struct ieee80211_header);
+
+	cc->hw->wiphy->max_sched_scan_reqs = 1;
+	cc->hw->wiphy->max_sched_scan_ie_len = CC33XX_CMD_TEMPL_MAX_SIZE -
+		sizeof(struct ieee80211_header);
+
+	cc->hw->wiphy->max_remain_on_channel_duration = 30000;
+
+	cc->hw->wiphy->features |= NL80211_FEATURE_AP_SCAN;
+
+	/* clear channel flags from the previous usage
+	 * and restore max_power & max_antenna_gain values.
+	 */
+	for (i = 0; i < ARRAY_SIZE(cc33xx_channels); i++) {
+		cc33xx_band_2ghz.channels[i].flags = 0;
+		cc33xx_band_2ghz.channels[i].max_power = CC33XX_MAX_TXPWR;
+		cc33xx_band_2ghz.channels[i].max_antenna_gain = 0;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(cc33xx_channels_5ghz); i++) {
+		cc33xx_band_5ghz.channels[i].flags = 0;
+		cc33xx_band_5ghz.channels[i].max_power = CC33XX_MAX_TXPWR;
+		cc33xx_band_5ghz.channels[i].max_antenna_gain = 0;
+	}
+
+	/* Enable/Disable He based on conf file params */
+	if (!cc->conf.mac.he_enable) {
+		cc33xx_band_2ghz.iftype_data = NULL;
+		cc33xx_band_2ghz.n_iftype_data = 0;
+
+		cc33xx_band_5ghz.iftype_data = NULL;
+		cc33xx_band_5ghz.n_iftype_data = 0;
+	}
+
+	/* We keep local copies of the band structs because we need to
+	 * modify them on a per-device basis.
+	 */
+	memcpy(&cc->bands[NL80211_BAND_2GHZ], &cc33xx_band_2ghz,
+	       sizeof(cc33xx_band_2ghz));
+	memcpy(&cc->bands[NL80211_BAND_2GHZ].ht_cap,
+	       &cc->ht_cap[NL80211_BAND_2GHZ],
+	       sizeof(*cc->ht_cap));
+
+	memcpy(&cc->bands[NL80211_BAND_5GHZ], &cc33xx_band_5ghz,
+	       sizeof(cc33xx_band_5ghz));
+	memcpy(&cc->bands[NL80211_BAND_5GHZ].ht_cap,
+	       &cc->ht_cap[NL80211_BAND_5GHZ],
+	       sizeof(*cc->ht_cap));
+
+	ieee80211_set_sband_iftype_data(&cc->bands[NL80211_BAND_2GHZ], iftype_data_2ghz);
+	ieee80211_set_sband_iftype_data(&cc->bands[NL80211_BAND_5GHZ], iftype_data_5ghz);
+
+	cc->hw->wiphy->bands[NL80211_BAND_2GHZ] =
+		&cc->bands[NL80211_BAND_2GHZ];
+
+	if (!cc->disable_5g && cc->conf.core.enable_5ghz)
+		cc->hw->wiphy->bands[NL80211_BAND_5GHZ] =
+			&cc->bands[NL80211_BAND_5GHZ];
+
+	/* allow 4 queues per mac address we support +
+	 * 1 cab queue per mac + one global offchannel Tx queue
+	 */
+	cc->hw->queues = (NUM_TX_QUEUES + 1) * CC33XX_NUM_MAC_ADDRESSES + 1;
+
+	/* the last queue is the offchannel queue */
+	cc->hw->offchannel_tx_hw_queue = cc->hw->queues - 1;
+	cc->hw->max_rates = 1;
+
+	/* allowed interface combinations */
+	cc->hw->wiphy->iface_combinations = cc33xx_iface_combinations;
+	cc->hw->wiphy->n_iface_combinations = ARRAY_SIZE(cc33xx_iface_combinations);
+
+	SET_IEEE80211_DEV(cc->hw, cc->dev);
+
+	cc->hw->sta_data_size = sizeof(struct cc33xx_station);
+	cc->hw->vif_data_size = sizeof(struct cc33xx_vif);
+
+	cc->hw->max_rx_aggregation_subframes = cc->conf.host_conf.ht.rx_ba_win_size;
+
+	/* For all ps schemes don't use UAPSD, except for UAPSD scheme
+	 * As these are the currently supportedd PS schemes, use the default
+	 * legacy otherwise
+	 */
+	if (cc->conf.mac.ps_scheme == PS_SCHEME_UPSD_TRIGGER) {
+		cc->hw->uapsd_queues = IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK;
+	} else if ((cc->conf.mac.ps_scheme != PS_SCHEME_LEGACY) &&
+		   (cc->conf.mac.ps_scheme != PS_SCHEME_NOPSPOLL)) {
+		cc->hw->uapsd_queues = 0;
+		cc->conf.mac.ps_scheme = PS_SCHEME_LEGACY;
+	} else {
+		cc->hw->uapsd_queues = 0;
+	}
+
+	return 0;
+}
+
+#define create_high_prio_freezable_workqueue(name)			\
+	alloc_workqueue("%s", __WQ_LEGACY | WQ_FREEZABLE | WQ_UNBOUND |	\
+			WQ_MEM_RECLAIM | WQ_HIGHPRI, 1, (name))
+
+static struct ieee80211_hw *cc33xx_alloc_hw(u32 aggr_buf_size)
+{
+	struct ieee80211_hw *hw;
+	struct cc33xx *cc;
+	int i, j;
+	unsigned int order;
+
+	hw = ieee80211_alloc_hw(sizeof(*cc), &cc33xx_ops);
+	if (!hw) {
+		cc33xx_error("could not alloc ieee80211_hw");
+		goto err_hw_alloc;
+	}
+
+	cc = hw->priv;
+	memset(cc, 0, sizeof(*cc));
+
+	INIT_LIST_HEAD(&cc->wlvif_list);
+
+	cc->hw = hw;
+
+	/* cc->num_links is not configured yet, so just use CC33XX_MAX_LINKS.
+	 * we don't allocate any additional resource here, so that's fine.
+	 */
+	for (i = 0; i < NUM_TX_QUEUES; i++)
+		for (j = 0; j < CC33XX_MAX_LINKS; j++)
+			skb_queue_head_init(&cc->links[j].tx_queue[i]);
+
+	skb_queue_head_init(&cc->deferred_rx_queue);
+	skb_queue_head_init(&cc->deferred_tx_queue);
+
+	init_llist_head(&cc->event_list);
+
+	INIT_WORK(&cc->netstack_work, cc33xx_netstack_work);
+	INIT_WORK(&cc->tx_work, cc33xx_tx_work);
+	INIT_WORK(&cc->recovery_work, cc33xx_recovery_work);
+	INIT_WORK(&cc->irq_deferred_work, irq_deferred_work);
+	INIT_DELAYED_WORK(&cc->scan_complete_work, cc33xx_scan_complete_work);
+	INIT_DELAYED_WORK(&cc->roc_complete_work, cc33xx_roc_complete_work);
+	INIT_DELAYED_WORK(&cc->tx_watchdog_work, cc33xx_tx_watchdog_work);
+
+	cc->freezable_netstack_wq = create_freezable_workqueue("cc33xx_netstack_wq");
+	if (!cc->freezable_netstack_wq)
+		goto err_hw_alloc;
+
+	cc->freezable_wq = create_high_prio_freezable_workqueue("cc33xx_wq");
+	if (!cc->freezable_wq)
+		goto err_ns_wq;
+
+	cc->rx_counter = 0;
+	cc->power_level = CC33XX_MAX_TXPWR;
+	cc->band = NL80211_BAND_2GHZ;
+	cc->flags = 0;
+	cc->sleep_auth = CC33XX_PSM_ILLEGAL;
+
+	cc->ap_ps_map = 0;
+	cc->ap_fw_ps_map = 0;
+	cc->quirks = 0;
+	cc->active_sta_count = 0;
+	cc->active_link_count = 0;
+	cc->fwlog_size = 0;
+
+	/* The system link is always allocated */
+	__set_bit(CC33XX_SYSTEM_HLID, cc->links_map);
+
+	memset(cc->tx_frames_map, 0, sizeof(cc->tx_frames_map));
+	for (i = 0; i < CC33XX_NUM_TX_DESCRIPTORS; i++)
+		cc->tx_frames[i] = NULL;
+
+	spin_lock_init(&cc->cc_lock);
+
+	cc->state = CC33XX_STATE_OFF;
+	mutex_init(&cc->mutex);
+	mutex_init(&cc->flush_mutex);
+	init_completion(&cc->nvs_loading_complete);
+
+	order = get_order(aggr_buf_size);
+	cc->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
+	if (!cc->aggr_buf)
+		goto err_all_wq;
+
+	cc->aggr_buf_size = aggr_buf_size;
+
+	cc->dummy_packet = cc33xx_alloc_dummy_packet(cc);
+	if (!cc->dummy_packet)
+		goto err_aggr;
+
+	/* Allocate one page for the FW log */
+	cc->fwlog = (u8 *)get_zeroed_page(GFP_KERNEL);
+	if (!cc->fwlog)
+		goto err_dummy_packet;
+
+	cc->buffer_32 = kmalloc(sizeof(*cc->buffer_32), GFP_KERNEL);
+	if (!cc->buffer_32)
+		goto err_fwlog;
+
+	cc->core_status = kzalloc(sizeof(*cc->core_status), GFP_KERNEL);
+	if (!cc->core_status)
+		goto err_buf32;
+
+	return hw;
+
+err_buf32:
+	kfree(cc->buffer_32);
+
+err_fwlog:
+	free_page((unsigned long)cc->fwlog);
+
+err_dummy_packet:
+	dev_kfree_skb(cc->dummy_packet);
+
+err_aggr:
+	free_pages((unsigned long)cc->aggr_buf, order);
+
+err_all_wq:
+	destroy_workqueue(cc->freezable_wq);
+
+err_ns_wq:
+	destroy_workqueue(cc->freezable_netstack_wq);
+
+err_hw_alloc:
+	return NULL;
+}
+
+static int cc33xx_free_hw(struct cc33xx *cc)
+{
+	/* Unblock any fwlog readers */
+	mutex_lock(&cc->mutex);
+	cc->fwlog_size = -1;
+	mutex_unlock(&cc->mutex);
+
+	kfree(cc->buffer_32);
+	kfree(cc->core_status);
+	free_page((unsigned long)cc->fwlog);
+	dev_kfree_skb(cc->dummy_packet);
+	free_pages((unsigned long)cc->aggr_buf, get_order(cc->aggr_buf_size));
+
+	kfree(cc->nvs_mac_addr);
+	cc->nvs_mac_addr = NULL;
+
+	destroy_workqueue(cc->freezable_wq);
+	destroy_workqueue(cc->freezable_netstack_wq);
+	flush_deferred_event_list(cc);
+
+	ieee80211_free_hw(cc->hw);
+
+	return 0;
+}
+
+static int cc33xx_identify_chip(struct cc33xx *cc)
+{
+	int ret = 0;
+
+	cc->quirks |= CC33XX_QUIRK_RX_BLOCKSIZE_ALIGN |
+		      CC33XX_QUIRK_TX_BLOCKSIZE_ALIGN |
+		      CC33XX_QUIRK_NO_SCHED_SCAN_WHILE_CONN |
+		      CC33XX_QUIRK_TX_PAD_LAST_FRAME |
+		      CC33XX_QUIRK_DUAL_PROBE_TMPL;
+
+	if (cc->if_ops->get_max_transaction_len)
+		cc->max_transaction_len =
+			cc->if_ops->get_max_transaction_len(cc->dev);
+	else
+		cc->max_transaction_len = 0;
+
+	return ret;
+}
+
+static int read_version_info(struct cc33xx *cc)
+{
+	int ret;
+
+	ret = cc33xx_acx_init_get_fw_versions(cc);
+	if (ret < 0) {
+		cc33xx_error("Get FW version FAILED!");
+		return ret;
+	}
+
+	cc33xx_debug(DEBUG_BOOT, "Wireless firmware version %u.%u.%u.%u",
+		     cc->fw_ver->major_version,
+		     cc->fw_ver->minor_version,
+		     cc->fw_ver->api_version,
+		     cc->fw_ver->build_version);
+
+	cc33xx_debug(DEBUG_BOOT, "Wireless PHY version %u.%u.%u.%u.%u.%u",
+		     cc->fw_ver->phy_version[5],
+		     cc->fw_ver->phy_version[4],
+		     cc->fw_ver->phy_version[3],
+		     cc->fw_ver->phy_version[2],
+		     cc->fw_ver->phy_version[1],
+		     cc->fw_ver->phy_version[0]);
+
+	return 0;
+}
+
+static void cc33xx_nvs_cb(const struct firmware *fw, void *context)
+{
+	struct cc33xx *cc = context;
+	struct platform_device *pdev = cc->pdev;
+	struct cc33xx_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+
+	int ret;
+
+	if (fw) {
+		cc->nvs_mac_addr = kmemdup(fw->data, fw->size, GFP_KERNEL);
+		if (!cc->nvs_mac_addr) {
+			cc33xx_error("Could not allocate nvs data");
+			goto out;
+		}
+		cc->nvs_mac_addr_len = fw->size;
+	} else if (pdev_data->family->nvs_name) {
+		cc33xx_debug(DEBUG_BOOT, "Could not get nvs file %s",
+			     pdev_data->family->nvs_name);
+		cc->nvs_mac_addr = NULL;
+		cc->nvs_mac_addr_len = 0;
+	} else {
+		cc->nvs_mac_addr = NULL;
+		cc->nvs_mac_addr_len = 0;
+	}
+
+	ret = cc33xx_setup(cc);
+	if (ret < 0)
+		goto out_free_nvs;
+
+	BUILD_BUG_ON(CC33XX_NUM_TX_DESCRIPTORS > CC33XX_MAX_TX_DESCRIPTORS);
+
+	/* adjust some runtime configuration parameters */
+	cc33xx_adjust_conf(cc);
+
+	cc->if_ops = pdev_data->if_ops;
+	cc->if_ops->set_irq_handler(cc->dev, irq_wrapper);
+
+	cc33xx_power_off(cc);
+
+	setup_wake_irq(cc);
+
+	ret = cc33xx_init_fw(cc);
+	if (ret < 0) {
+		cc33xx_error("FW download failed");
+		cc33xx_power_off(cc);
+		goto out_irq;
+	}
+
+	ret = cc33xx_identify_chip(cc);
+	if (ret < 0)
+		goto out_irq;
+
+	ret = read_version_info(cc);
+	if (ret < 0)
+		goto out_irq;
+
+	ret = cc33xx_init_ieee80211(cc);
+	if (ret)
+		goto out_irq;
+
+	ret = cc33xx_register_hw(cc);
+	if (ret)
+		goto out_irq;
+
+	cc->initialized = true;
+	goto out;
+
+out_irq:
+	if (cc->wakeirq >= 0)
+		dev_pm_clear_wake_irq(cc->dev);
+	device_init_wakeup(cc->dev, false);
+
+out_free_nvs:
+	kfree(cc->nvs_mac_addr);
+
+out:
+	release_firmware(fw);
+	complete_all(&cc->nvs_loading_complete);
+	cc33xx_debug(DEBUG_CC33xx, "%s complete", __func__);
+}
+
+static int cc33xx_load_ini_bin_file(struct device *dev,
+				    struct cc33xx_conf_file *conf,
+				    const char *file)
+{
+	struct cc33xx_conf_file *conf_file;
+	const struct firmware *fw;
+	int ret;
+
+	ret = request_firmware(&fw, file, dev);
+	if (ret < 0) {
+		cc33xx_error("could not get configuration binary %s: %d",
+			     file, ret);
+		return ret;
+	}
+
+	if (fw->size != CC33X_CONF_SIZE) {
+		cc33xx_error("%s configuration binary size is wrong, expected %zu got %zu",
+			     file, CC33X_CONF_SIZE,
+			     fw->size);
+		ret = -EINVAL;
+		goto out_release;
+	}
+
+	conf_file = (struct cc33xx_conf_file *)fw->data;
+
+	if (conf_file->header.magic != cpu_to_le32(CC33XX_CONF_MAGIC)) {
+		cc33xx_error("conf file magic number mismatch, expected 0x%0x got 0x%0x",
+			     CC33XX_CONF_MAGIC, conf_file->header.magic);
+		ret = -EINVAL;
+		goto out_release;
+	}
+
+	memcpy(conf, conf_file, sizeof(*conf));
+
+out_release:
+	release_firmware(fw);
+	return ret;
+}
+
+static int cc33xx_ini_bin_init(struct cc33xx *cc, struct device *dev)
+{
+	struct platform_device *pdev = cc->pdev;
+	struct cc33xx_platdev_data *pdata = dev_get_platdata(&pdev->dev);
+
+	if (cc33xx_load_ini_bin_file(dev, &cc->conf,
+				     pdata->family->cfg_name) < 0)
+		cc33xx_warning("falling back to default config");
+
+	return 0;
+}
+
+static inline void cc33xx_set_ht_cap(struct cc33xx *cc, enum nl80211_band band,
+				     struct ieee80211_sta_ht_cap *ht_cap)
+{
+	memcpy(&cc->ht_cap[band], ht_cap, sizeof(*ht_cap));
+}
+
+static int cc33xx_setup(struct cc33xx *cc)
+{
+	int ret;
+
+	BUILD_BUG_ON(CC33XX_MAX_AP_STATIONS > CC33XX_MAX_LINKS);
+
+	ret = cc33xx_ini_bin_init(cc, cc->dev);
+	if (ret < 0)
+		return ret;
+
+	if (cc->conf.host_conf.ht.mode == HT_MODE_DEFAULT) {
+		cc33xx_set_ht_cap(cc, NL80211_BAND_2GHZ,
+				  &cc33xx_siso40_ht_cap_2ghz);
+
+		/* 5Ghz is always wide */
+		cc33xx_set_ht_cap(cc, NL80211_BAND_5GHZ,
+				  &cc33xx_siso40_ht_cap_5ghz);
+	} else if (cc->conf.host_conf.ht.mode == HT_MODE_WIDE) {
+		cc33xx_set_ht_cap(cc, NL80211_BAND_2GHZ,
+				  &cc33xx_siso40_ht_cap_2ghz);
+		cc33xx_set_ht_cap(cc, NL80211_BAND_5GHZ,
+				  &cc33xx_siso40_ht_cap_5ghz);
+	} else if (cc->conf.host_conf.ht.mode == HT_MODE_SISO20) {
+		cc33xx_set_ht_cap(cc, NL80211_BAND_2GHZ, &cc33xx_siso20_ht_cap);
+		cc33xx_set_ht_cap(cc, NL80211_BAND_5GHZ, &cc33xx_siso20_ht_cap);
+	}
+
+	cc->event_mask = BSS_LOSS_EVENT_ID | SCAN_COMPLETE_EVENT_ID |
+			 RADAR_DETECTED_EVENT_ID | RSSI_SNR_TRIGGER_0_EVENT_ID |
+			 PERIODIC_SCAN_COMPLETE_EVENT_ID |
+			 PERIODIC_SCAN_REPORT_EVENT_ID | DUMMY_PACKET_EVENT_ID |
+			 PEER_REMOVE_COMPLETE_EVENT_ID |
+			 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
+			 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
+			 CHANNEL_SWITCH_COMPLETE_EVENT_ID |
+			 DFS_CHANNELS_CONFIG_COMPLETE_EVENT |
+			 SMART_CONFIG_SYNC_EVENT_ID | INACTIVE_STA_EVENT_ID |
+			 SMART_CONFIG_DECODE_EVENT_ID | TIME_SYNC_EVENT_ID |
+			 FW_LOGGER_INDICATION | RX_BA_WIN_SIZE_CHANGE_EVENT_ID;
+
+	cc->ap_event_mask = MAX_TX_FAILURE_EVENT_ID;
+
+	return 0;
+}
+
+static int cc33xx_probe(struct platform_device *pdev)
+{
+	struct cc33xx *cc;
+	struct ieee80211_hw *hw;
+	struct cc33xx_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+	const char *nvs_name;
+	int ret;
+
+	if (!pdev_data) {
+		cc33xx_error("can't access platform data");
+		return -EINVAL;
+	}
+
+	hw = cc33xx_alloc_hw(CC33XX_AGGR_BUFFER_SIZE);
+	if (!hw) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	cc = hw->priv;
+	cc->dev = &pdev->dev;
+	cc->pdev = pdev;
+	platform_set_drvdata(pdev, cc);
+
+	if (pdev_data->family && pdev_data->family->nvs_name) {
+		nvs_name = pdev_data->family->nvs_name;
+		ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
+					      nvs_name, &pdev->dev, GFP_KERNEL,
+					      cc, cc33xx_nvs_cb);
+		if (ret < 0) {
+			cc33xx_error("request_firmware_nowait failed for %s: %d",
+				     nvs_name, ret);
+			complete_all(&cc->nvs_loading_complete);
+		}
+	} else {
+		cc33xx_nvs_cb(NULL, cc);
+		cc33xx_error("Invalid platform data entry");
+		ret = -EINVAL;
+	}
+
+out:
+	return ret;
+}
+
+static void cc33xx_remove(struct platform_device *pdev)
+{
+	struct cc33xx_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+	struct cc33xx *cc = platform_get_drvdata(pdev);
+
+	set_bit(CC33XX_FLAG_DRIVER_REMOVED, &cc->flags);
+
+	cc->dev->driver->pm = NULL;
+
+	if (pdev_data->family && pdev_data->family->nvs_name)
+		wait_for_completion(&cc->nvs_loading_complete);
+
+	if (!cc->initialized)
+		goto out;
+
+	if (cc->wakeirq >= 0) {
+		dev_pm_clear_wake_irq(cc->dev);
+		cc->wakeirq = -ENODEV;
+	}
+
+	device_init_wakeup(cc->dev, false);
+	cc33xx_unregister_hw(cc);
+	cc33xx_turn_off(cc);
+
+out:
+	cc33xx_free_hw(cc);
+}
+
+static const struct platform_device_id cc33xx_id_table[] = {
+	{ "cc33xx", 0 },
+	{  }
+};
+MODULE_DEVICE_TABLE(platform, cc33xx_id_table);
+
+static struct platform_driver cc33xx_driver = {
+	.probe		= cc33xx_probe,
+	.remove		= cc33xx_remove,
+	.id_table	= cc33xx_id_table,
+	.driver = {
+		.name	= "cc33xx_driver",
+	}
+};
+
+module_platform_driver(cc33xx_driver);
+
+module_param_named(debug_level, cc33xx_debug_level, uint, 0600);
+MODULE_PARM_DESC(debug_level, "cc33xx debugging level");
+
+module_param(no_recovery, int, 0600);
+MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck.");
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Texas Instruments CC33xx WLAN driver");
+MODULE_AUTHOR("Michael Nemanov <michael.nemanov@ti.com>");
+MODULE_AUTHOR("Sabeeh Khan <sabeeh-khan@ti.com>");
+
+MODULE_FIRMWARE(SECOND_LOADER_NAME);
+MODULE_FIRMWARE(FW_NAME);
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/Makefile b/drivers/net/wireless/ti/cc33xx/Makefile
--- a/drivers/net/wireless/ti/cc33xx/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/Makefile	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+
+cc33xx-objs		= main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
+					boot.o init.o scan.o
+
+cc33xx_sdio-objs	= sdio.o
+
+cc33xx-$(CONFIG_NL80211_TESTMODE)	+= testmode.o
+obj-$(CONFIG_CC33XX)				+= cc33xx.o
+obj-$(CONFIG_CC33XX_SDIO)			+= cc33xx_sdio.o
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/ps.c b/drivers/net/wireless/ti/cc33xx/ps.c
--- a/drivers/net/wireless/ti/cc33xx/ps.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/ps.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include "ps.h"
+#include "tx.h"
+#include "debug.h"
+
+int cc33xx_ps_set_mode(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+		       enum cc33xx_cmd_ps_mode_e mode)
+{
+	int ret;
+	u16 timeout = cc->conf.host_conf.conn.dynamic_ps_timeout;
+
+	switch (mode) {
+	case STATION_AUTO_PS_MODE:
+	case STATION_POWER_SAVE_MODE:
+		ret = cc33xx_cmd_ps_mode(cc, wlvif, mode, timeout);
+		if (ret < 0)
+			return ret;
+
+		set_bit(WLVIF_FLAG_IN_PS, &wlvif->flags);
+		break;
+
+	case STATION_ACTIVE_MODE:
+		ret = cc33xx_cmd_ps_mode(cc, wlvif, mode, 0);
+		if (ret < 0)
+			return ret;
+
+		clear_bit(WLVIF_FLAG_IN_PS, &wlvif->flags);
+		break;
+
+	default:
+		cc33xx_warning("trying to set ps to unsupported mode %d", mode);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void cc33xx_ps_filter_frames(struct cc33xx *cc, u8 hlid)
+{
+	int i;
+	struct sk_buff *skb;
+	struct ieee80211_tx_info *info;
+	unsigned long flags;
+	int filtered[NUM_TX_QUEUES];
+	struct cc33xx_link *lnk = &cc->links[hlid];
+
+	/* filter all frames currently in the low level queues for this hlid */
+	for (i = 0; i < NUM_TX_QUEUES; i++) {
+		filtered[i] = 0;
+		while ((skb = skb_dequeue(&lnk->tx_queue[i]))) {
+			filtered[i]++;
+
+			if (WARN_ON(cc33xx_is_dummy_packet(cc, skb)))
+				continue;
+
+			info = IEEE80211_SKB_CB(skb);
+			info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+			info->status.rates[0].idx = -1;
+			ieee80211_tx_status_ni(cc->hw, skb);
+		}
+	}
+
+	spin_lock_irqsave(&cc->cc_lock, flags);
+	for (i = 0; i < NUM_TX_QUEUES; i++) {
+		cc->tx_queue_count[i] -= filtered[i];
+		if (lnk->wlvif)
+			lnk->wlvif->tx_queue_count[i] -= filtered[i];
+	}
+
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+	cc33xx_handle_tx_low_watermark(cc);
+}
+
+void cc33xx_ps_link_start(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			  u8 hlid, bool clean_queues)
+{
+	struct ieee80211_sta *sta;
+	struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
+
+	if (WARN_ON_ONCE(wlvif->bss_type != BSS_TYPE_AP_BSS))
+		return;
+
+	if (!test_bit(hlid, wlvif->ap.sta_hlid_map) ||
+	    test_bit(hlid, &cc->ap_ps_map))
+		return;
+
+	rcu_read_lock();
+	sta = ieee80211_find_sta(vif, cc->links[hlid].addr);
+	if (!sta) {
+		cc33xx_error("could not find sta %pM for starting ps",
+			     cc->links[hlid].addr);
+		rcu_read_unlock();
+		return;
+	}
+
+	ieee80211_sta_ps_transition_ni(sta, true);
+	rcu_read_unlock();
+
+	/* do we want to filter all frames from this link's queues? */
+	if (clean_queues)
+		cc33xx_ps_filter_frames(cc, hlid);
+
+	__set_bit(hlid, &cc->ap_ps_map);
+}
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/ps.h b/drivers/net/wireless/ti/cc33xx/ps.h
--- a/drivers/net/wireless/ti/cc33xx/ps.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/ps.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __PS_H__
+#define __PS_H__
+
+#include "acx.h"
+
+int cc33xx_ps_set_mode(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+		       enum cc33xx_cmd_ps_mode_e mode);
+void cc33xx_ps_link_start(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			  u8 hlid, bool clean_queues);
+
+#endif /* __PS_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/rx.c b/drivers/net/wireless/ti/cc33xx/rx.c
--- a/drivers/net/wireless/ti/cc33xx/rx.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/rx.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,388 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include "acx.h"
+#include "rx.h"
+#include "tx.h"
+#include "io.h"
+
+#define RSSI_LEVEL_BITMASK	0x7F
+#define ANT_DIVERSITY_BITMASK	BIT(7)
+#define ANT_DIVERSITY_SHIFT		7
+
+/* Construct the rx status structure for upper layers */
+static void cc33xx_rx_status(struct cc33xx *cc,
+			     struct cc33xx_rx_descriptor *desc,
+			     struct ieee80211_rx_status *status,
+			     u8 beacon, u8 probe_rsp)
+{
+	memset(status, 0, sizeof(struct ieee80211_rx_status));
+
+	if ((desc->flags & CC33XX_RX_DESC_BAND_MASK) == CC33XX_RX_DESC_BAND_BG)
+		status->band = NL80211_BAND_2GHZ;
+	else if ((desc->flags & CC33XX_RX_DESC_BAND_MASK) == CC33XX_RX_DESC_BAND_J)
+		status->band = NL80211_BAND_2GHZ;
+	else if ((desc->flags & CC33XX_RX_DESC_BAND_MASK) == CC33XX_RX_DESC_BAND_A)
+		status->band = NL80211_BAND_5GHZ;
+	else
+		status->band = NL80211_BAND_5GHZ; /* todo -Should be 6GHZ when added */
+
+	status->rate_idx = cc33xx_rate_to_idx(cc, desc->rate, status->band);
+
+	if (desc->frame_format == CC33xx_VHT)
+		status->encoding = RX_ENC_VHT;
+	else if ((desc->frame_format == CC33xx_HT_MF) ||
+		 (desc->frame_format == CC33xx_HT_GF))
+		status->encoding = RX_ENC_HT;
+	else if ((desc->frame_format == CC33xx_B_SHORT) ||
+		 (desc->frame_format == CC33xx_B_LONG) ||
+		(desc->frame_format == CC33xx_LEGACY_OFDM))
+		status->encoding = RX_ENC_LEGACY;
+	else
+		status->encoding = RX_ENC_HE;
+
+	/* Read the signal level and antenna diversity indication.
+	 * The msb in the signal level is always set as it is a
+	 * negative number.
+	 * The antenna indication is the msb of the rssi.
+	 */
+	status->signal = ((desc->rssi & RSSI_LEVEL_BITMASK) | BIT(7));
+	status->antenna = ((desc->rssi & ANT_DIVERSITY_BITMASK) >> ANT_DIVERSITY_SHIFT);
+	status->freq = ieee80211_channel_to_frequency(desc->channel,
+						      status->band);
+
+	if (desc->flags & CC33XX_RX_DESC_ENCRYPT_MASK) {
+		u8 desc_err_code = desc->status & CC33XX_RX_DESC_STATUS_MASK;
+
+		/* Frame is sent to driver with the IV (for PN replay check)
+		 * but without the MIC
+		 */
+		status->flag |=  RX_FLAG_MMIC_STRIPPED |
+				 RX_FLAG_DECRYPTED | RX_FLAG_MIC_STRIPPED;
+
+		if (unlikely(desc_err_code & CC33XX_RX_DESC_MIC_FAIL)) {
+			status->flag |= RX_FLAG_MMIC_ERROR;
+			cc33xx_warning("Michael MIC error. Desc: 0x%x",
+				       desc_err_code);
+		}
+	}
+
+	if (beacon || probe_rsp)
+		status->boottime_ns = ktime_get_boottime_ns();
+
+	if (beacon)
+		cc33xx_set_pending_regdomain_ch(cc, (u16)desc->channel,
+						status->band);
+	status->nss = 1;
+}
+
+/* Copy part\ all of the descriptor. Allocate skb, or drop corrupted packet
+ */
+static int cc33xx_rx_get_packet_descriptor(struct cc33xx *cc, u8 *raw_buffer_ptr,
+					   u16 *raw_buffer_len)
+{
+	u16 missing_desc_bytes;
+	u16 available_desc_bytes;
+	u16 pkt_data_len;
+	struct sk_buff *skb;
+	u16 prev_buffer_len = *raw_buffer_len;
+
+	missing_desc_bytes = sizeof(struct cc33xx_rx_descriptor);
+	missing_desc_bytes -= cc->partial_rx.handled_bytes;
+	available_desc_bytes = min(*raw_buffer_len, missing_desc_bytes);
+	memcpy(((u8 *)(&cc->partial_rx.desc)) + cc->partial_rx.handled_bytes,
+	       raw_buffer_ptr, available_desc_bytes);
+
+	/* If descriptor was not completed */
+	if (available_desc_bytes != missing_desc_bytes) {
+		cc->partial_rx.handled_bytes += *raw_buffer_len;
+		cc->partial_rx.status = CURR_RX_DESC;
+		*raw_buffer_len = 0;
+		goto out;
+	} else {
+		cc->partial_rx.handled_bytes += available_desc_bytes;
+		*raw_buffer_len -= available_desc_bytes;
+	}
+
+	/* Descriptor was fully copied */
+	pkt_data_len = cc->partial_rx.original_bytes;
+	pkt_data_len -=	sizeof(struct cc33xx_rx_descriptor);
+
+	if (unlikely(cc->partial_rx.desc.status & CC33XX_RX_DESC_DECRYPT_FAIL)) {
+		cc33xx_warning("corrupted packet in RX: status: 0x%x len: %d",
+			       cc->partial_rx.desc.status & CC33XX_RX_DESC_STATUS_MASK,
+			pkt_data_len);
+
+		/* If frame can be fully dropped */
+		if (pkt_data_len <= *raw_buffer_len) {
+			*raw_buffer_len -=  pkt_data_len;
+			cc->partial_rx.status = CURR_RX_START;
+		} else {
+			cc->partial_rx.handled_bytes += *raw_buffer_len;
+			cc->partial_rx.status = CURR_RX_DROP;
+			*raw_buffer_len = 0;
+		}
+		goto out;
+	}
+
+	skb = __dev_alloc_skb(pkt_data_len, GFP_KERNEL);
+	if (!skb) {
+		cc33xx_error("Couldn't allocate RX frame");
+		/* If frame can be fully dropped */
+		if (pkt_data_len <= *raw_buffer_len) {
+			*raw_buffer_len -=  pkt_data_len;
+			cc->partial_rx.status = CURR_RX_START;
+		} else {
+		/* Dropped partial frame */
+			cc->partial_rx.handled_bytes += *raw_buffer_len;
+			cc->partial_rx.status = CURR_RX_DROP;
+			*raw_buffer_len = 0;
+		}
+		goto out;
+	}
+
+	cc->partial_rx.skb = skb;
+	cc->partial_rx.status = CURR_RX_DATA;
+
+out:
+	/* Function return the amount of consumed bytes */
+	return (prev_buffer_len - *raw_buffer_len);
+}
+
+/* Copy part or all of the packet's data. push skb to queue if possible */
+static int cc33xx_rx_get_packet_data(struct cc33xx *cc, u8 *raw_buffer_ptr,
+				     u16 *raw_buffer_len)
+{
+	u16 missing_data_bytes;
+	u16 available_data_bytes;
+	u32 defer_count;
+	enum cc33xx_rx_buf_align rx_align;
+	u16 extra_bytes;
+	struct ieee80211_hdr *hdr;
+	u8 beacon = 0;
+	u8 is_probe_resp = 0;
+	u16 seq_num;
+	u16 prev_buffer_len = *raw_buffer_len;
+
+	missing_data_bytes = cc->partial_rx.original_bytes;
+	missing_data_bytes -= cc->partial_rx.handled_bytes;
+	available_data_bytes = min(missing_data_bytes, *raw_buffer_len);
+
+	skb_put_data(cc->partial_rx.skb, raw_buffer_ptr, available_data_bytes);
+
+	/* Check if we didn't manage to copy the entire packet - got out,
+	 * continue next time
+	 */
+	if (available_data_bytes != missing_data_bytes) {
+		cc->partial_rx.handled_bytes += *raw_buffer_len;
+		cc->partial_rx.status = CURR_RX_DATA;
+		*raw_buffer_len = 0;
+		goto out;
+	} else {
+		*raw_buffer_len -=  available_data_bytes;
+	}
+
+	/* Data fully copied */
+
+	rx_align = cc->partial_rx.desc.header_alignment;
+	if (rx_align == CC33XX_RX_BUF_PADDED)
+		skb_pull(cc->partial_rx.skb, RX_BUF_ALIGN);
+
+	extra_bytes = cc->partial_rx.desc.pad_len;
+	if (extra_bytes != 0)
+		skb_trim(cc->partial_rx.skb,
+			 cc->partial_rx.skb->len - extra_bytes);
+
+	hdr = (struct ieee80211_hdr *)cc->partial_rx.skb->data;
+
+	if (ieee80211_is_beacon(hdr->frame_control))
+		beacon = 1;
+	if (ieee80211_is_probe_resp(hdr->frame_control))
+		is_probe_resp = 1;
+
+	cc33xx_rx_status(cc, &cc->partial_rx.desc,
+			 IEEE80211_SKB_RXCB(cc->partial_rx.skb),
+			 beacon, is_probe_resp);
+
+	seq_num = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
+	cc33xx_debug(DEBUG_RX, "rx skb 0x%p: %d B %s seq %d link id %d",
+		     cc->partial_rx.skb,
+		     cc->partial_rx.skb->len - cc->partial_rx.desc.pad_len,
+		     beacon ? "beacon" : "", seq_num, cc->partial_rx.desc.hlid);
+
+	cc33xx_debug(DEBUG_RX, "rx frame. frame type 0x%x, frame length 0x%x, frame address 0x%lx",
+		     hdr->frame_control, cc->partial_rx.skb->len,
+		     (unsigned long)cc->partial_rx.skb->data);
+
+	/* Adding frame to queue */
+	skb_queue_tail(&cc->deferred_rx_queue, cc->partial_rx.skb);
+	cc->rx_counter++;
+	cc->partial_rx.status = CURR_RX_START;
+
+	/* Make sure the deferred queues don't get too long */
+	defer_count = skb_queue_len(&cc->deferred_tx_queue);
+	defer_count += skb_queue_len(&cc->deferred_rx_queue);
+	if (defer_count >= CC33XX_RX_QUEUE_MAX_LEN)
+		cc33xx_flush_deferred_work(cc);
+	else
+		queue_work(cc->freezable_netstack_wq, &cc->netstack_work);
+
+out:
+	return (prev_buffer_len - *raw_buffer_len);
+}
+
+static int cc33xx_rx_drop_packet_data(struct cc33xx *cc, u8 *raw_buffer_ptr,
+				      u16 *raw_buffer_len)
+{
+	u16 prev_buffer_len = *raw_buffer_len;
+
+	/* Can we drop the entire frame ? */
+	if (*raw_buffer_len >=
+		(cc->partial_rx.original_bytes - cc->partial_rx.handled_bytes)) {
+		*raw_buffer_len -= cc->partial_rx.original_bytes -
+				cc->partial_rx.handled_bytes;
+		cc->partial_rx.handled_bytes = 0;
+		cc->partial_rx.status = CURR_RX_START;
+	} else {
+		cc->partial_rx.handled_bytes += *raw_buffer_len;
+		*raw_buffer_len = 0;
+	}
+
+	return (prev_buffer_len - *raw_buffer_len);
+}
+
+/* Handle single packet from the RX buffer. We don't have to be aligned to
+ * packet boundary (buffer may start \ end in the middle of packet)
+ */
+static void cc33xx_rx_handle_packet(struct cc33xx *cc, u8 *raw_buffer_ptr,
+				    u16 *raw_buffer_len)
+{
+	struct cc33xx_rx_descriptor *desc;
+	u16 consumed_bytes;
+
+	if (cc->partial_rx.status == CURR_RX_START) {
+		WARN_ON(*raw_buffer_len < 2);
+		desc = (struct cc33xx_rx_descriptor *)raw_buffer_ptr;
+		cc->partial_rx.original_bytes = le16_to_cpu(desc->length);
+		cc->partial_rx.handled_bytes = 0;
+		cc->partial_rx.status = CURR_RX_DESC;
+
+		cc33xx_debug(DEBUG_RX, "rx frame. desc length 0x%x, alignment 0x%x, padding 0x%x",
+			     desc->length, desc->header_alignment, desc->pad_len);
+	}
+
+	/* start \ continue copy descriptor */
+	if (cc->partial_rx.status == CURR_RX_DESC) {
+		consumed_bytes = cc33xx_rx_get_packet_descriptor(cc,
+								 raw_buffer_ptr,
+								 raw_buffer_len);
+		raw_buffer_ptr += consumed_bytes;
+	}
+
+	/* Check if we are in the middle of dropped packet */
+	if (unlikely(cc->partial_rx.status == CURR_RX_DROP)) {
+		consumed_bytes = cc33xx_rx_drop_packet_data(cc, raw_buffer_ptr,
+							    raw_buffer_len);
+		raw_buffer_ptr += consumed_bytes;
+	}
+
+	/* start \ continue copy descriptor */
+	if (cc->partial_rx.status == CURR_RX_DATA) {
+		consumed_bytes = cc33xx_rx_get_packet_data(cc, raw_buffer_ptr,
+							   raw_buffer_len);
+		raw_buffer_ptr += consumed_bytes;
+	}
+}
+
+/* It is assumed that SDIO buffer was read prior to this function (data buffer
+ * is read along with the status). The RX function gets pointer to the RX data
+ * and its length. This buffer may contain unknown number of packets, separated
+ * by hif descriptor and 0-3 bytes padding if required.
+ * The last packet may be truncated in the middle, and should be saved for next
+ * iteration.
+ */
+int cc33xx_rx(struct cc33xx *cc, u8 *rx_buf_ptr, u16 rx_buf_len)
+{
+	u16 local_rx_buffer_len = rx_buf_len;
+	u16 pkt_offset = 0;
+	u16 consumed_bytes;
+	u16 prev_rx_buf_len;
+
+	/* Split data into separate packets */
+	while (local_rx_buffer_len > 0) {
+		cc33xx_debug(DEBUG_RX, "start loop. buffer length %d",
+			     local_rx_buffer_len);
+
+		/* the handle data call can only fail in memory-outage
+		 * conditions, in that case the received frame will just
+		 * be dropped.
+		 */
+		prev_rx_buf_len = local_rx_buffer_len;
+		cc33xx_rx_handle_packet(cc, rx_buf_ptr + pkt_offset,
+					&local_rx_buffer_len);
+		consumed_bytes = prev_rx_buf_len - local_rx_buffer_len;
+
+		pkt_offset +=  consumed_bytes;
+
+		cc33xx_debug(DEBUG_RX, "end rx loop. buffer length %d, packet counter %d, current packet status %d",
+			     local_rx_buffer_len, cc->rx_counter,
+			     cc->partial_rx.status);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+int cc33xx_rx_filter_enable(struct cc33xx *cc, int index, bool enable,
+			    struct cc33xx_rx_filter *filter)
+{
+	int ret;
+
+	if (!!test_bit(index, cc->rx_filter_enabled) == enable) {
+		cc33xx_warning("Request to enable an already enabled rx filter %d",
+			       index);
+		return 0;
+	}
+
+	ret = cc33xx_acx_set_rx_filter(cc, index, enable, filter);
+
+	if (ret) {
+		cc33xx_error("Failed to %s rx data filter %d (err=%d)",
+			     enable ? "enable" : "disable", index, ret);
+		return ret;
+	}
+
+	if (enable)
+		__set_bit(index, cc->rx_filter_enabled);
+	else
+		__clear_bit(index, cc->rx_filter_enabled);
+
+	return 0;
+}
+
+int cc33xx_rx_filter_clear_all(struct cc33xx *cc)
+{
+	int i, ret = 0;
+
+	for (i = 0; i < CC33XX_MAX_RX_FILTERS; i++) {
+		if (!test_bit(i, cc->rx_filter_enabled))
+			continue;
+		ret = cc33xx_rx_filter_enable(cc, i, 0, NULL);
+		if (ret)
+			goto out;
+	}
+
+out:
+	return ret;
+}
+#else
+int cc33xx_rx_filter_enable(struct cc33xx *cc, int index, bool enable,
+			    struct cc33xx_rx_filter *filter)
+{
+	return 0;
+}
+
+int cc33xx_rx_filter_clear_all(struct cc33xx *cc) { return 0; }
+#endif /* CONFIG_PM */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/rx.h b/drivers/net/wireless/ti/cc33xx/rx.h
--- a/drivers/net/wireless/ti/cc33xx/rx.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/rx.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __RX_H__
+#define __RX_H__
+
+/* RX Descriptor flags:
+ *
+ * Bits 0-1 - band
+ * Bit  2   - STBC
+ * Bit  3   - A-MPDU
+ * Bit  4   - HT
+ * Bits 5-7 - encryption
+ */
+#define CC33XX_RX_DESC_BAND_MASK    0x03
+#define CC33XX_RX_DESC_ENCRYPT_MASK 0xE0
+
+#define CC33XX_RX_DESC_BAND_BG      0x00
+#define CC33XX_RX_DESC_BAND_J       0x01
+#define CC33XX_RX_DESC_BAND_A       0x02
+
+/* RX Descriptor status
+ *
+ * Bits 0-2 - error code
+ * Bits 3-5 - process_id tag (AP mode FW)
+ * Bits 6-7 - reserved
+ */
+enum {
+	CC33XX_RX_DESC_SUCCESS		= 0x00,
+	CC33XX_RX_DESC_DECRYPT_FAIL	= 0x01,
+	CC33XX_RX_DESC_MIC_FAIL		= 0x02,
+	CC33XX_RX_DESC_STATUS_MASK	= 0x07
+};
+
+/* Account for the padding inserted by the FW in case of RX_ALIGNMENT
+ * or for fixing alignment in case the packet wasn't aligned.
+ */
+#define RX_BUF_ALIGN                 2
+
+/* Describes the alignment state of a Rx buffer */
+enum cc33xx_rx_buf_align {
+	CC33XX_RX_BUF_ALIGNED,
+	CC33XX_RX_BUF_UNALIGNED,
+	CC33XX_RX_BUF_PADDED,
+};
+
+enum cc33xx_rx_curr_status {
+	CURR_RX_START,
+	CURR_RX_DROP,
+	CURR_RX_DESC,
+	CURR_RX_DATA
+};
+
+struct cc33xx_rx_descriptor {
+	__le16 length;
+	u8  header_alignment;
+	u8  status;
+	__le32 timestamp;
+
+	u8  flags;
+	u8  rate;
+	u8  channel;
+	s8  rssi;
+	u8  snr;
+
+	u8  hlid;
+	u8  pad_len;
+	u8  frame_format;
+} __packed;
+
+struct partial_rx_frame {
+	struct sk_buff *skb;
+	struct cc33xx_rx_descriptor desc;
+	u16 handled_bytes;
+	u16 original_bytes; /* including descriptor */
+	enum cc33xx_rx_curr_status status;
+};
+
+int cc33xx_rx(struct cc33xx *cc, u8 *rx_buf_ptr, u16 rx_buf_len);
+int cc33xx_rx_filter_enable(struct cc33xx *cc, int index, bool enable,
+			    struct cc33xx_rx_filter *filter);
+int cc33xx_rx_filter_clear_all(struct cc33xx *cc);
+
+#endif /* __RX_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/scan.c b/drivers/net/wireless/ti/cc33xx/scan.c
--- a/drivers/net/wireless/ti/cc33xx/scan.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/scan.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,900 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include "cc33xx.h"
+#include "debug.h"
+#include "cmd.h"
+#include "scan.h"
+#include "tx.h"
+#include "conf.h"
+
+#define CC33XX_SCAN_TIMEOUT	30000 /* msec */
+
+#define MAX_CHANNELS_2GHZ			14
+#define MAX_CHANNELS_4GHZ			4
+#define MAX_CHANNELS_5GHZ			32
+#define CONN_SCAN_MAX_CHANNELS_ALL_BANDS	46
+
+#define SCHED_SCAN_MAX_SSIDS	16
+
+#define CONN_SCAN_MAX_BAND		2
+#define SCAN_MAX_SCHED_SCAN_PLANS	12
+
+#define SCAN_CHANNEL_FLAGS_DFS		BIT(0)
+
+struct conn_scan_ch_params {
+	__le16 min_duration;
+	__le16 max_duration;
+	__le16 passive_duration;
+
+	u8  channel;
+	u8  tx_power_att;
+
+	/* bit 0: DFS channel; bit 1: DFS enabled */
+	u8  flags;
+
+	u8  padding[3];
+} __packed;
+
+enum {
+	SCAN_SSID_TYPE_PUBLIC = 0,
+	SCAN_SSID_TYPE_HIDDEN = 1,
+};
+
+enum scan_request_type {
+	SCAN_REQUEST_NONE,
+	SCAN_REQUEST_CONNECT_PERIODIC_SCAN,
+	SCAN_REQUEST_ONE_SHOT,
+	SCAN_REQUEST_SURVEY_SCAN,
+	SCAN_NUM_OF_REQUEST_TYPE
+};
+
+enum {
+	SCAN_SSID_FILTER_ANY      = 0,
+	SCAN_SSID_FILTER_SPECIFIC = 1,
+	SCAN_SSID_FILTER_LIST     = 2,
+	SCAN_SSID_FILTER_DISABLED = 3
+};
+
+enum {
+	SCAN_TYPE_SEARCH	= 0,
+	SCAN_TYPE_PERIODIC	= 1,
+	SCAN_TYPE_TRACKING	= 2,
+};
+
+struct cc33xx_ssid {
+	u8 type;
+	u8 len;
+	u8 ssid[IEEE80211_MAX_SSID_LEN];
+	u8 padding[2];
+} __packed;
+
+struct cc33xx_cmd_ssid_list {
+	struct cc33xx_cmd_header header;
+
+	u8 role_id;
+	u8 scan_type;
+	u8 n_ssids;
+	struct cc33xx_ssid ssids[SCHED_SCAN_MAX_SSIDS];
+	u8 padding;
+} __packed;
+
+struct conn_scan_dwell_info {
+	__le16  min_duration;
+	__le16  max_duration;
+	__le16  passive_duration;
+} __packed;
+
+struct conn_scan_ch_info {
+	u8   channel;
+	u8   tx_power_att;
+	u8   flags;
+} __packed;
+
+struct scan_one_shot_info {
+	u8  passive[CONN_SCAN_MAX_BAND];
+	u8  active[CONN_SCAN_MAX_BAND];
+	u8  dfs;
+
+	struct conn_scan_ch_info    channel_list[CONN_SCAN_MAX_CHANNELS_ALL_BANDS];
+	struct conn_scan_dwell_info dwell_info[CONN_SCAN_MAX_BAND];
+	u8  reserved;
+};
+
+struct sched_scan_plan_cmd {
+	u32 interval;
+	u32 iterations;
+};
+
+struct scan_periodic_info {
+	struct sched_scan_plan_cmd  sched_scan_plans[SCAN_MAX_SCHED_SCAN_PLANS];
+	u16 sched_scan_plans_num;
+
+	u8 passive[CONN_SCAN_MAX_BAND];
+	u8 active[CONN_SCAN_MAX_BAND];
+	u8 dfs;
+
+	struct conn_scan_ch_info      channel_list[CONN_SCAN_MAX_CHANNELS_ALL_BANDS];
+	struct conn_scan_dwell_info   dwell_info[CONN_SCAN_MAX_BAND];
+} __packed;
+
+struct scan_param {
+	union {
+		struct scan_one_shot_info    one_shot;
+		struct scan_periodic_info    periodic;
+	} u;
+} __packed;
+
+struct cc33xx_cmd_scan_params {
+	struct cc33xx_cmd_header header;
+	u8 scan_type;
+	u8 role_id;
+
+	struct scan_param   params;
+	s8 rssi_threshold; /* for filtering (in dBm) */
+	s8 snr_threshold;  /* for filtering (in dB) */
+
+	u8 bssid[ETH_ALEN];
+	u8 padding[2];
+
+	u8 ssid_from_list; /* use ssid from configured ssid list */
+	u8 filter;         /* forward only results with matching ssids */
+
+	u8 num_of_ssids;
+} __packed;
+
+#define MAX_EXTRA_IES_LEN 512
+
+struct cc33xx_cmd_set_ies {
+	struct cc33xx_cmd_header header;
+	u8 scan_type;
+	u8 role_id;
+	__le16 len;
+	u8                   data[MAX_EXTRA_IES_LEN];
+} __packed;
+
+struct cc33xx_cmd_scan_stop {
+	struct cc33xx_cmd_header header;
+
+	u8 scan_type;
+	u8 role_id;
+	u8 is_ET;
+	u8 padding;
+} __packed;
+
+struct cc33xx_scan_channels {
+	u8 passive[CONN_SCAN_MAX_BAND]; /* number of passive scan channels */
+	u8 active[CONN_SCAN_MAX_BAND];  /* number of active scan channels */
+	u8 dfs;		   /* number of dfs channels in 5ghz */
+	u8 passive_active; /* number of passive before active channels 2.4ghz */
+
+	struct conn_scan_ch_params channels_2[MAX_CHANNELS_2GHZ];
+	struct conn_scan_ch_params channels_5[MAX_CHANNELS_5GHZ];
+	struct conn_scan_ch_params channels_4[MAX_CHANNELS_4GHZ];
+};
+
+static void cc33xx_adjust_channels(struct scan_param *scan_param,
+				   struct cc33xx_scan_channels *cmd_channels,
+				   enum scan_request_type scan_type)
+{
+	struct conn_scan_ch_info	*ch_info_list;
+	struct conn_scan_dwell_info	*dwell_info;
+	struct conn_scan_ch_params	*channel;
+	struct conn_scan_ch_params	*ch_params_list;
+
+	u8 *passive;
+	u8 *dfs;
+	u8 *active;
+	int i, j;
+	u8 band;
+
+	if (scan_type == SCAN_REQUEST_CONNECT_PERIODIC_SCAN) {
+		ch_info_list	= scan_param->u.periodic.channel_list;
+		dwell_info	= scan_param->u.periodic.dwell_info;
+		active		= (u8 *)&scan_param->u.periodic.active;
+		passive		= (u8 *)&scan_param->u.periodic.passive;
+		dfs		= (u8 *)&scan_param->u.periodic.dfs;
+	} else {
+		ch_info_list	= scan_param->u.one_shot.channel_list;
+		dwell_info	= scan_param->u.one_shot.dwell_info;
+		active		= (u8 *)&scan_param->u.one_shot.active;
+		passive		= (u8 *)&scan_param->u.one_shot.passive;
+		dfs		= (u8 *)&scan_param->u.one_shot.dfs;
+	}
+
+	memcpy(passive, cmd_channels->passive, sizeof(cmd_channels->passive));
+	memcpy(active, cmd_channels->active, sizeof(cmd_channels->active));
+	*dfs = cmd_channels->dfs;
+
+	ch_params_list = cmd_channels->channels_2;
+	for (i = 0; i < MAX_CHANNELS_2GHZ; ++i) {
+		ch_info_list[i].channel	= ch_params_list[i].channel;
+		ch_info_list[i].flags = ch_params_list[i].flags;
+		ch_info_list[i].tx_power_att = ch_params_list[i].tx_power_att;
+	}
+
+	channel = &ch_params_list[0];
+	band = NL80211_BAND_2GHZ;
+	dwell_info[band].min_duration     = channel->min_duration;
+	dwell_info[band].max_duration     = channel->max_duration;
+	dwell_info[band].passive_duration = channel->passive_duration;
+
+	ch_params_list = cmd_channels->channels_5;
+	for (j = 0; j < MAX_CHANNELS_5GHZ; ++i, ++j) {
+		ch_info_list[i].channel = ch_params_list[j].channel;
+		ch_info_list[i].flags = ch_params_list[j].flags;
+		ch_info_list[i].tx_power_att = ch_params_list[j].tx_power_att;
+	}
+
+	channel = &ch_params_list[0];
+	band = NL80211_BAND_5GHZ;
+	dwell_info[band].min_duration     = channel->min_duration;
+	dwell_info[band].max_duration     = channel->max_duration;
+	dwell_info[band].passive_duration = channel->passive_duration;
+}
+
+static int cc33xx_cmd_build_probe_req(struct cc33xx *cc,
+				      struct cc33xx_vif *wlvif, u8 role_id,
+				      u8 scan_type, const u8 *ssid,
+				      size_t ssid_len, const u8 *ie0,
+				      size_t ie0_len, const u8 *ie1,
+				      size_t ie1_len, bool sched_scan)
+{
+	struct ieee80211_vif *vif = cc33xx_wlvif_to_vif(wlvif);
+	struct sk_buff *skb = NULL;
+	struct cc33xx_cmd_set_ies *cmd;
+	int ret;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	skb = ieee80211_probereq_get(cc->hw, vif->addr, ssid,
+				     ssid_len, ie0_len + ie1_len);
+	if (!skb) {
+		ret = -ENOMEM;
+		goto out_free;
+	}
+
+	if (ie0_len)
+		skb_put_data(skb, ie0, ie0_len);
+
+	if (ie1_len)
+		skb_put_data(skb, ie1, ie1_len);
+
+	cmd->scan_type = scan_type;
+	cmd->role_id = role_id;
+
+	cmd->len = cpu_to_le16(skb->len - sizeof(struct ieee80211_hdr_3addr));
+
+	if (skb->data) {
+		memcpy(cmd->data,
+		       skb->data + sizeof(struct ieee80211_hdr_3addr), le16_to_cpu(cmd->len));
+	}
+
+	usleep_range(10000, 11000);
+	ret = cc33xx_cmd_send(cc, CMD_SET_PROBE_IE, cmd, sizeof(*cmd), 0);
+
+	if (ret < 0) {
+		cc33xx_warning("cmd set_template failed: %d", ret);
+		goto out_free;
+	}
+
+out_free:
+	dev_kfree_skb(skb);
+	kfree(cmd);
+out:
+	return ret;
+}
+
+static void cc33xx_started_vifs_iter(void *data, u8 *mac,
+				     struct ieee80211_vif *vif)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+	bool active = false;
+	int *count = (int *)data;
+
+	/* count active interfaces according to interface type.
+	 * checking only bss_conf.idle is bad for some cases, e.g.
+	 * we don't want to count sta in p2p_find as active interface.
+	 */
+	switch (wlvif->bss_type) {
+	case BSS_TYPE_STA_BSS:
+		if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+			active = true;
+		break;
+
+	case BSS_TYPE_AP_BSS:
+		if (wlvif->cc->active_sta_count > 0)
+			active = true;
+		break;
+
+	default:
+		break;
+	}
+
+	if (active)
+		(*count)++;
+}
+
+static int cc33xx_count_started_vifs(struct cc33xx *cc)
+{
+	int count = 0;
+
+	ieee80211_iterate_active_interfaces_atomic(cc->hw,
+						   IEEE80211_IFACE_ITER_RESUME_ALL,
+						   cc33xx_started_vifs_iter,
+						   &count);
+	return count;
+}
+
+static int cc33xx_scan_get_channels(struct cc33xx *cc,
+				    struct ieee80211_channel *req_channels[],
+				    u32 n_channels, u32 n_ssids,
+				    struct conn_scan_ch_params *channels,
+				    u32 band, bool radar, bool passive,
+				    unsigned int start, unsigned int max_channels,
+				    u8 *n_pactive_ch, int scan_type)
+{
+	unsigned int i, j;
+	u32 flags;
+	bool force_passive = !n_ssids;
+	u32 min_dwell_time_active, max_dwell_time_active;
+	u32 dwell_time_passive, dwell_time_dfs;
+	struct conn_scan_ch_params *ch;
+	struct ieee80211_channel *req_ch;
+
+	/* configure dwell times according to scan type */
+	if (scan_type == SCAN_TYPE_SEARCH) {
+		struct conf_scan_settings *c = &cc->conf.host_conf.scan;
+		bool active_vif_exists = !!cc33xx_count_started_vifs(cc);
+
+		min_dwell_time_active = active_vif_exists ?
+						c->min_dwell_time_active :
+						c->min_dwell_time_active_long;
+		max_dwell_time_active = active_vif_exists ?
+						c->max_dwell_time_active :
+						c->max_dwell_time_active_long;
+		dwell_time_passive = c->dwell_time_passive;
+		dwell_time_dfs = c->dwell_time_dfs;
+	} else {
+		struct conf_sched_scan_settings *c =
+					&cc->conf.host_conf.sched_scan;
+		u32 delta_per_probe;
+
+		delta_per_probe = (band == NL80211_BAND_5GHZ) ?
+					c->dwell_time_delta_per_probe_5 :
+					c->dwell_time_delta_per_probe;
+
+		min_dwell_time_active = c->base_dwell_time +
+			 n_ssids * c->num_probe_reqs * delta_per_probe;
+
+		max_dwell_time_active = min_dwell_time_active;
+		max_dwell_time_active += c->max_dwell_time_delta;
+		dwell_time_passive = c->dwell_time_passive;
+		dwell_time_dfs = c->dwell_time_dfs;
+	}
+
+	min_dwell_time_active = DIV_ROUND_UP(min_dwell_time_active, 1000);
+	max_dwell_time_active = DIV_ROUND_UP(max_dwell_time_active, 1000);
+	dwell_time_passive = DIV_ROUND_UP(dwell_time_passive, 1000);
+	dwell_time_dfs = DIV_ROUND_UP(dwell_time_dfs, 1000);
+
+	for (i = 0, j = start; i < n_channels && j < max_channels; i++) {
+		flags = req_channels[i]->flags;
+		ch = &channels[j];
+		req_ch = req_channels[i];
+
+		if (force_passive)
+			flags |= IEEE80211_CHAN_NO_IR;
+
+		if (req_ch->band == band && !(flags & IEEE80211_CHAN_DISABLED) &&
+		    (!!(flags & IEEE80211_CHAN_RADAR) == radar) &&
+		    /* if radar is set, we ignore the passive flag */
+		    (radar || !!(flags & IEEE80211_CHAN_NO_IR) == passive)) {
+			if (flags & IEEE80211_CHAN_RADAR) {
+				ch->flags |= SCAN_CHANNEL_FLAGS_DFS;
+
+				ch->passive_duration =
+					cpu_to_le16(dwell_time_dfs);
+			} else {
+				ch->passive_duration =
+					cpu_to_le16(dwell_time_passive);
+			}
+
+			ch->min_duration = cpu_to_le16(min_dwell_time_active);
+			ch->max_duration = cpu_to_le16(max_dwell_time_active);
+
+			ch->tx_power_att = req_ch->max_power;
+			ch->channel = req_ch->hw_value;
+
+			if (n_pactive_ch && band == NL80211_BAND_2GHZ &&
+			    ch->channel >= 12 && ch->channel <= 14 &&
+			    (flags & IEEE80211_CHAN_NO_IR) && !force_passive) {
+				/* pactive channels treated as DFS */
+				ch->flags = SCAN_CHANNEL_FLAGS_DFS;
+
+				/* n_pactive_ch is counted down from the end of
+				 * the passive channel list
+				 */
+				(*n_pactive_ch)++;
+				cc33xx_debug(DEBUG_SCAN, "n_pactive_ch = %d",
+					     *n_pactive_ch);
+			}
+
+			cc33xx_debug(DEBUG_SCAN, "freq %d, ch. %d, flags 0x%x, power %d, min/max_dwell %d/%d%s%s",
+				     req_ch->center_freq, req_ch->hw_value,
+				     req_ch->flags, req_ch->max_power,
+				     min_dwell_time_active,
+				     max_dwell_time_active,
+				     flags & IEEE80211_CHAN_RADAR ? ", DFS" : "",
+				     flags & IEEE80211_CHAN_NO_IR ? ", NO-IR" : "");
+			j++;
+		}
+	}
+
+	return j - start;
+}
+
+static bool cc33xx_set_scan_chan_params(struct cc33xx *cc,
+					struct cc33xx_scan_channels *cfg,
+					struct ieee80211_channel *channels[],
+					u32 n_channels, u32 n_ssids,
+					int scan_type)
+{
+	u8 n_pactive_ch = 0;
+
+	cfg->passive[0] = cc33xx_scan_get_channels(cc, channels, n_channels,
+						   n_ssids, cfg->channels_2,
+						   NL80211_BAND_2GHZ, false,
+						   true, 0, MAX_CHANNELS_2GHZ,
+						   &n_pactive_ch, scan_type);
+
+	cfg->active[0] = cc33xx_scan_get_channels(cc, channels, n_channels,
+						  n_ssids, cfg->channels_2,
+						  NL80211_BAND_2GHZ, false,
+						  false, cfg->passive[0],
+						  MAX_CHANNELS_2GHZ,
+						  &n_pactive_ch, scan_type);
+
+	cfg->passive[1] = cc33xx_scan_get_channels(cc, channels, n_channels,
+						   n_ssids, cfg->channels_5,
+						   NL80211_BAND_5GHZ, false,
+						   true, 0, MAX_CHANNELS_5GHZ,
+						   &n_pactive_ch, scan_type);
+
+	cfg->dfs = cc33xx_scan_get_channels(cc, channels, n_channels, n_ssids,
+					    cfg->channels_5, NL80211_BAND_5GHZ,
+					    true, true, cfg->passive[1],
+					    MAX_CHANNELS_5GHZ, &n_pactive_ch,
+					    scan_type);
+
+	cfg->active[1] = cc33xx_scan_get_channels(cc, channels, n_channels,
+						  n_ssids, cfg->channels_5,
+						  NL80211_BAND_5GHZ, false,
+						  false,
+						  cfg->passive[1] + cfg->dfs,
+						  MAX_CHANNELS_5GHZ,
+						  &n_pactive_ch, scan_type);
+
+	cfg->passive_active = n_pactive_ch;
+
+	cc33xx_debug(DEBUG_SCAN, "2.4GHz: active %d passive %d",
+		     cfg->active[0], cfg->passive[0]);
+	cc33xx_debug(DEBUG_SCAN, "5GHz: active %d passive %d",
+		     cfg->active[1], cfg->passive[1]);
+	cc33xx_debug(DEBUG_SCAN, "DFS: %d", cfg->dfs);
+
+	return  cfg->passive[0] || cfg->active[0] || cfg->passive[1] ||
+		cfg->active[1] || cfg->dfs;
+}
+
+static int cc33xx_scan_send(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			    struct cfg80211_scan_request *req)
+{
+	struct cc33xx_cmd_scan_params *cmd;
+	struct cc33xx_scan_channels *cmd_channels = NULL;
+	struct cc33xx_ssid *cmd_ssid;
+	u16 alloc_size;
+	int ret;
+	int i;
+
+	alloc_size =  sizeof(*cmd) + (sizeof(struct cc33xx_ssid) * req->n_ssids);
+	cmd = kzalloc(alloc_size, GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* scan on the dev role if the regular one is not started */
+	if (cc33xx_is_p2p_mgmt(wlvif))
+		cmd->role_id = wlvif->dev_role_id;
+	else
+		cmd->role_id = wlvif->role_id;
+
+	if (WARN_ON(cmd->role_id == CC33XX_INVALID_ROLE_ID)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	cmd->scan_type = SCAN_REQUEST_ONE_SHOT;
+	cmd->rssi_threshold = -127;
+	cmd->snr_threshold = 0;
+
+	for (i = 0; i < ETH_ALEN; i++)
+		cmd->bssid[i] = req->bssid[i];
+	cmd->ssid_from_list = 0;
+	cmd->filter = 0;
+	WARN_ON(req->n_ssids > 1);
+
+	/* configure channels */
+	cmd_channels = kzalloc(sizeof(*cmd_channels), GFP_KERNEL);
+	if (!cmd_channels) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cc33xx_set_scan_chan_params(cc, cmd_channels, req->channels,
+				    req->n_channels, req->n_ssids,
+				    SCAN_TYPE_SEARCH);
+
+	cc33xx_adjust_channels(&cmd->params, cmd_channels, cmd->scan_type);
+	if (req->n_ssids > 0) {
+		cmd->ssid_from_list = 1;
+		cmd->num_of_ssids = req->n_ssids;
+		cmd_ssid = (struct cc33xx_ssid *)((u8 *)cmd + sizeof(*cmd));
+
+		cmd_ssid->len = req->ssids[0].ssid_len;
+		memcpy(cmd_ssid->ssid, req->ssids[0].ssid, cmd_ssid->len);
+		cmd_ssid->type = (req->ssids[0].ssid_len) ?
+				SCAN_SSID_TYPE_HIDDEN : SCAN_SSID_TYPE_PUBLIC;
+	}
+
+	ret = cc33xx_cmd_build_probe_req(cc, wlvif, cmd->role_id, cmd->scan_type,
+					 req->ssids ? req->ssids[0].ssid : NULL,
+					 req->ssids ? req->ssids[0].ssid_len : 0,
+					 req->ie, req->ie_len, NULL, 0, false);
+	if (ret < 0) {
+		cc33xx_error("PROBE request template failed");
+		goto out;
+	}
+
+	cc33xx_dump(DEBUG_SCAN, "SCAN: ", cmd, alloc_size);
+
+	ret = cc33xx_cmd_send(cc, CMD_SCAN, cmd, alloc_size, 0);
+	if (ret < 0) {
+		cc33xx_error("SCAN failed");
+		goto out;
+	}
+
+out:
+	kfree(cmd_channels);
+	kfree(cmd);
+	return ret;
+}
+
+static int cc33xx_scan_sched_scan_ssid_list(struct cc33xx *cc,
+					    struct cc33xx_vif *wlvif,
+					struct cfg80211_sched_scan_request *req,
+					    struct cc33xx_cmd_ssid_list *cmd)
+{
+	struct cfg80211_match_set *sets = req->match_sets;
+	struct cfg80211_ssid *ssids = req->ssids;
+	int ret = 0, i, j, n_match_ssids = 0;
+
+	/* count the match sets that contain SSIDs */
+	for (i = 0; i < req->n_match_sets; i++) {
+		if (sets[i].ssid.ssid_len > 0)
+			n_match_ssids++;
+	}
+
+	/* No filter, no ssids or only bcast ssid */
+	if (!n_match_ssids && (!req->n_ssids ||
+			       (req->n_ssids == 1 && req->ssids[0].ssid_len == 0)))
+		goto out;
+
+	cmd->role_id = wlvif->role_id;
+	if (!n_match_ssids) {
+		/* No filter, with ssids */
+
+		for (i = 0; i < req->n_ssids; i++) {
+			cmd->ssids[cmd->n_ssids].type = (ssids[i].ssid_len) ?
+				SCAN_SSID_TYPE_HIDDEN : SCAN_SSID_TYPE_PUBLIC;
+			cmd->ssids[cmd->n_ssids].len = ssids[i].ssid_len;
+			memcpy(cmd->ssids[cmd->n_ssids].ssid, ssids[i].ssid,
+			       ssids[i].ssid_len);
+			cmd->n_ssids++;
+		}
+	} else {
+		/* Add all SSIDs from the filters */
+		for (i = 0; i < req->n_match_sets; i++) {
+			/* ignore sets without SSIDs */
+			if (!sets[i].ssid.ssid_len)
+				continue;
+
+			cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_PUBLIC;
+			cmd->ssids[cmd->n_ssids].len = sets[i].ssid.ssid_len;
+			memcpy(cmd->ssids[cmd->n_ssids].ssid,
+			       sets[i].ssid.ssid, sets[i].ssid.ssid_len);
+			cmd->n_ssids++;
+		}
+		if (req->n_ssids > 1 || (req->n_ssids == 1 && req->ssids[0].ssid_len > 0)) {
+			/* Mark all the SSIDs passed in the SSID list as HIDDEN,
+			 * so they're used in probe requests.
+			 */
+			for (i = 0; i < req->n_ssids; i++) {
+				if (!req->ssids[i].ssid_len)
+					continue;
+
+				for (j = 0; j < cmd->n_ssids; j++) {
+					if (req->ssids[i].ssid_len == cmd->ssids[j].len &&
+					    !memcmp(req->ssids[i].ssid,
+						    cmd->ssids[j].ssid,
+						    req->ssids[i].ssid_len)) {
+						cmd->ssids[j].type =
+							SCAN_SSID_TYPE_HIDDEN;
+						break;
+					}
+				}
+				/* Fail if SSID isn't present in the filters */
+				if (j == cmd->n_ssids) {
+					ret = -EINVAL;
+					goto out;
+				}
+			}
+		}
+	}
+
+	return cmd->n_ssids;
+out:
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int cc33xx_sched_scan_start(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			    struct cfg80211_sched_scan_request *req,
+			    struct ieee80211_scan_ies *ies)
+{
+	struct cc33xx_cmd_scan_params *cmd;
+	struct cc33xx_cmd_ssid_list *ssid_list;
+	struct cc33xx_scan_channels *cmd_channels = NULL;
+	struct conf_sched_scan_settings *c = &cc->conf.host_conf.sched_scan;
+	int ret;
+	int n_ssids = 0;
+	int alloc_size = sizeof(*cmd);
+
+	ssid_list = kzalloc(sizeof(*ssid_list), GFP_KERNEL);
+	if (!ssid_list) {
+		ret = -ENOMEM;
+		goto out_ssid_free;
+	}
+
+	n_ssids = cc33xx_scan_sched_scan_ssid_list(cc, wlvif, req, ssid_list);
+	if (n_ssids < 0)
+		return n_ssids;
+
+	if (n_ssids <= 5) {
+		alloc_size += (n_ssids * sizeof(struct cc33xx_ssid));
+	} else { /* n_ssids > 5 */
+		ssid_list->scan_type = SCAN_REQUEST_CONNECT_PERIODIC_SCAN;
+		ret = cc33xx_cmd_send(cc, CMD_CONNECTION_SCAN_SSID_CFG,
+				      ssid_list, sizeof(*ssid_list), 0);
+		if (ret < 0) {
+			cc33xx_error("cmd sched scan ssid list failed");
+			goto out_ssid_free;
+		}
+	}
+
+	cmd = kzalloc(alloc_size, GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out_free;
+	}
+
+	cmd->role_id = wlvif->role_id;
+
+	if (WARN_ON(cmd->role_id == CC33XX_INVALID_ROLE_ID)) {
+		ret = -EINVAL;
+		goto out_free;
+	}
+
+	cmd->scan_type = SCAN_REQUEST_CONNECT_PERIODIC_SCAN;
+	cmd->rssi_threshold = c->rssi_threshold;
+	cmd->snr_threshold = c->snr_threshold;
+
+	cmd->filter = 1;
+	cmd->num_of_ssids = n_ssids;
+
+	cc33xx_debug(DEBUG_CMD, "ssid list num of n_ssids %d", n_ssids);
+	if (n_ssids > 0 && n_ssids <= 5) {
+		cmd->ssid_from_list = 1;
+		memcpy((u8 *)cmd + sizeof(*cmd), ssid_list->ssids,
+		       n_ssids * sizeof(struct cc33xx_ssid));
+	}
+
+	cmd_channels = kzalloc(sizeof(*cmd_channels), GFP_KERNEL);
+	if (!cmd_channels) {
+		ret = -ENOMEM;
+		goto out_free;
+	}
+
+	/* configure channels */
+	cc33xx_set_scan_chan_params(cc, cmd_channels, req->channels,
+				    req->n_channels, req->n_ssids,
+				    SCAN_TYPE_PERIODIC);
+	cc33xx_adjust_channels(&cmd->params, cmd_channels, cmd->scan_type);
+
+	memcpy(cmd->params.u.periodic.sched_scan_plans, req->scan_plans,
+	       sizeof(struct sched_scan_plan_cmd) * req->n_scan_plans);
+
+	cmd->params.u.periodic.sched_scan_plans_num = req->n_scan_plans;
+
+	cc33xx_debug(DEBUG_SCAN,
+		     "interval[0]: %d, iterations[0]: %d, num_plans: %d",
+		     cmd->params.u.periodic.sched_scan_plans[0].interval,
+		     cmd->params.u.periodic.sched_scan_plans[0].iterations,
+		     cmd->params.u.periodic.sched_scan_plans_num);
+
+	ret = cc33xx_cmd_build_probe_req(cc, wlvif, cmd->role_id, cmd->scan_type,
+					 req->ssids ? req->ssids[0].ssid : NULL,
+					 req->ssids ? req->ssids[0].ssid_len : 0,
+					 ies->ies[NL80211_BAND_2GHZ],
+					 ies->len[NL80211_BAND_2GHZ],
+					 ies->common_ies,
+					 ies->common_ie_len, true);
+
+	if (ret < 0) {
+		cc33xx_error("PROBE request template failed");
+		goto out_free;
+	}
+
+	cc33xx_dump(DEBUG_SCAN, "SCAN: ", cmd, alloc_size);
+
+	ret = cc33xx_cmd_send(cc, CMD_SCAN, cmd, alloc_size, 0);
+	if (ret < 0) {
+		cc33xx_error("SCAN failed");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd_channels);
+	kfree(cmd);
+
+out_ssid_free:
+	kfree(ssid_list);
+
+	return ret;
+}
+
+static int __cc33xx_scan_stop(struct cc33xx *cc,
+			      struct cc33xx_vif *wlvif, u8 scan_type)
+{
+	struct cc33xx_cmd_scan_stop *stop;
+	int ret;
+
+	stop = kzalloc(sizeof(*stop), GFP_KERNEL);
+	if (!stop)
+		return -ENOMEM;
+
+	stop->role_id = wlvif->role_id;
+	stop->scan_type = scan_type;
+
+	ret = cc33xx_cmd_send(cc, CMD_STOP_SCAN, stop, sizeof(*stop), 0);
+	if (ret < 0) {
+		cc33xx_error("failed to send sched scan stop command");
+		goto out_free;
+	}
+
+out_free:
+	kfree(stop);
+	return ret;
+}
+
+void cc33xx_scan_sched_scan_stop(struct cc33xx *cc,
+				 struct cc33xx_vif *wlvif)
+{
+	__cc33xx_scan_stop(cc, wlvif, SCAN_REQUEST_CONNECT_PERIODIC_SCAN);
+}
+
+static int cc33xx_scan_start(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			     struct cfg80211_scan_request *req)
+{
+	return cc33xx_scan_send(cc, wlvif, req);
+}
+
+int cc33xx_scan_stop(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	return __cc33xx_scan_stop(cc, wlvif, SCAN_REQUEST_ONE_SHOT);
+}
+
+void cc33xx_scan_complete_work(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+	struct cc33xx *cc;
+	struct cfg80211_scan_info info = {
+		.aborted = false,
+	};
+
+	dwork = to_delayed_work(work);
+	cc = container_of(dwork, struct cc33xx, scan_complete_work);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		goto out;
+
+	if (cc->scan.state == CC33XX_SCAN_STATE_IDLE)
+		goto out;
+
+	/* Rearm the tx watchdog just before idling scan. This
+	 * prevents just-finished scans from triggering the watchdog
+	 */
+	cc33xx_rearm_tx_watchdog_locked(cc);
+
+	cc->scan.state = CC33XX_SCAN_STATE_IDLE;
+	memset(cc->scan.scanned_ch, 0, sizeof(cc->scan.scanned_ch));
+	cc->scan.req = NULL;
+	cc->scan_wlvif = NULL;
+
+	if (cc->scan.failed) {
+		cc33xx_info("Scan completed due to error.");
+		cc33xx_queue_recovery_work(cc);
+	}
+
+	cc33xx_cmd_regdomain_config_locked(cc);
+
+	ieee80211_scan_completed(cc->hw, &info);
+
+out:
+	mutex_unlock(&cc->mutex);
+}
+
+int cc33xx_scan(struct cc33xx *cc, struct ieee80211_vif *vif, const u8 *ssid,
+		size_t ssid_len, struct cfg80211_scan_request *req)
+{
+	struct cc33xx_vif *wlvif = cc33xx_vif_to_data(vif);
+
+	if (cc->scan.state != CC33XX_SCAN_STATE_IDLE)
+		return -EBUSY;
+
+	cc->scan.state = CC33XX_SCAN_STATE_2GHZ_ACTIVE;
+
+	if (ssid_len && ssid) {
+		cc->scan.ssid_len = ssid_len;
+		memcpy(cc->scan.ssid, ssid, ssid_len);
+	} else {
+		cc->scan.ssid_len = 0;
+	}
+
+	cc->scan_wlvif = wlvif;
+	cc->scan.req = req;
+	memset(cc->scan.scanned_ch, 0, sizeof(cc->scan.scanned_ch));
+
+	/* we assume failure so that timeout scenarios are handled correctly */
+	cc->scan.failed = true;
+	ieee80211_queue_delayed_work(cc->hw, &cc->scan_complete_work,
+				     msecs_to_jiffies(CC33XX_SCAN_TIMEOUT));
+
+	cc33xx_scan_start(cc, wlvif, req);
+
+	return 0;
+}
+
+inline void cc33xx_scan_sched_scan_results(struct cc33xx *cc)
+{
+	ieee80211_sched_scan_results(cc->hw);
+}
+
+void cc33xx_scan_completed(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	cc->scan.failed = false;
+	cancel_delayed_work(&cc->scan_complete_work);
+	ieee80211_queue_delayed_work(cc->hw, &cc->scan_complete_work,
+				     msecs_to_jiffies(0));
+}
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/scan.h b/drivers/net/wireless/ti/cc33xx/scan.h
--- a/drivers/net/wireless/ti/cc33xx/scan.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/scan.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __SCAN_H__
+#define __SCAN_H__
+
+#include "cc33xx.h"
+
+enum {
+	CC33XX_SCAN_STATE_IDLE,
+	CC33XX_SCAN_STATE_2GHZ_ACTIVE,
+	CC33XX_SCAN_STATE_2GHZ_PASSIVE,
+	CC33XX_SCAN_STATE_5GHZ_ACTIVE,
+	CC33XX_SCAN_STATE_5GHZ_PASSIVE,
+	CC33XX_SCAN_STATE_DONE
+};
+
+int cc33xx_scan_stop(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+void cc33xx_scan_completed(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+int cc33xx_sched_scan_start(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			    struct cfg80211_sched_scan_request *req,
+			    struct ieee80211_scan_ies *ies);
+void cc33xx_scan_sched_scan_stop(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+
+int cc33xx_scan(struct cc33xx *cc, struct ieee80211_vif *vif,
+		const u8 *ssid, size_t ssid_len,
+		struct cfg80211_scan_request *req);
+void cc33xx_scan_complete_work(struct work_struct *work);
+void cc33xx_scan_sched_scan_results(struct cc33xx *cc);
+
+#endif /* __CC33XX_SCAN_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/sdio.c b/drivers/net/wireless/ti/cc33xx/sdio.c
--- a/drivers/net/wireless/ti/cc33xx/sdio.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/sdio.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,530 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/host.h>
+#include <linux/gpio.h>
+#include <linux/pm_runtime.h>
+#include <linux/of_irq.h>
+
+#include "cc33xx.h"
+#include "io.h"
+
+#ifndef SDIO_VENDOR_ID_TI
+#define SDIO_VENDOR_ID_TI		0x0097
+#endif
+
+#define SDIO_DEVICE_ID_CC33XX_NO_EFUSE	0x4076
+#define SDIO_DEVICE_ID_TI_CC33XX	0x4077
+
+struct cc33xx_sdio_glue {
+	struct device *dev;
+	struct platform_device *core;
+};
+
+static void cc33xx_sdio_claim(struct device *child)
+{
+	struct cc33xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+	struct sdio_func *func = dev_to_sdio_func(glue->dev);
+
+	sdio_claim_host(func);
+}
+
+static void cc33xx_sdio_release(struct device *child)
+{
+	struct cc33xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+	struct sdio_func *func = dev_to_sdio_func(glue->dev);
+
+	sdio_release_host(func);
+}
+
+static void cc33xx_sdio_set_block_size(struct device *child,
+				       unsigned int blksz)
+{
+	struct cc33xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+	struct sdio_func *func = dev_to_sdio_func(glue->dev);
+
+	sdio_claim_host(func);
+	sdio_set_block_size(func, blksz);
+	sdio_release_host(func);
+}
+
+static int __must_check cc33xx_sdio_raw_read(struct device *child, int addr,
+					     void *buf, size_t len, bool fixed)
+{
+	int ret;
+	struct cc33xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+	struct sdio_func *func = dev_to_sdio_func(glue->dev);
+
+	sdio_claim_host(func);
+
+	if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) {
+		((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
+		dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n",
+			addr, ((u8 *)buf)[0]);
+	} else {
+		if (fixed)
+			ret = sdio_readsb(func, buf, addr, len);
+		else
+			ret = sdio_memcpy_fromio(func, buf, addr, len);
+
+		dev_dbg(child->parent, "sdio read 53 addr 0x%x, %zu bytes\n",
+			addr, len);
+	}
+
+	sdio_release_host(func);
+
+	if (WARN_ON(ret))
+		dev_err(child->parent, "sdio read failed (%d)\n", ret);
+
+	return ret;
+}
+
+static int __must_check cc33xx_sdio_raw_write(struct device *child, int addr,
+					      void *buf, size_t len, bool fixed)
+{
+	int ret;
+	struct cc33xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+	struct sdio_func *func = dev_to_sdio_func(glue->dev);
+
+	sdio_claim_host(func);
+
+	if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) {
+		sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
+	} else {
+		if (fixed)
+			ret = sdio_writesb(func, addr, buf, len);
+		else
+			ret = sdio_memcpy_toio(func, addr, buf, len);
+	}
+
+	sdio_release_host(func);
+
+	if (WARN_ON(ret))
+		dev_err(child->parent, "sdio write failed (%d)\n", ret);
+
+	return ret;
+}
+
+static int cc33xx_sdio_power_on(struct cc33xx_sdio_glue *glue)
+{
+	int ret;
+	struct sdio_func *func = dev_to_sdio_func(glue->dev);
+	struct mmc_card *card = func->card;
+
+	ret = pm_runtime_get_sync(&card->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&card->dev);
+		dev_err(glue->dev, "%s: failed to get_sync(%d)\n",
+			__func__, ret);
+
+		return ret;
+	}
+
+	sdio_claim_host(func);
+	sdio_enable_func(func);
+	sdio_release_host(func);
+
+	return 0;
+}
+
+static int cc33xx_sdio_power_off(struct cc33xx_sdio_glue *glue)
+{
+	struct sdio_func *func = dev_to_sdio_func(glue->dev);
+	struct mmc_card *card = func->card;
+
+	sdio_claim_host(func);
+	sdio_disable_func(func);
+	sdio_release_host(func);
+
+	/* Let runtime PM know the card is powered off */
+	pm_runtime_put(&card->dev);
+	return 0;
+}
+
+static int cc33xx_sdio_set_power(struct device *child, bool enable)
+{
+	struct cc33xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+
+	if (enable)
+		return cc33xx_sdio_power_on(glue);
+	else
+		return cc33xx_sdio_power_off(glue);
+}
+
+/**
+ *	inband_irq_handler - Called from the MMC subsystem when the
+ *	function's IRQ is signaled.
+ *	@func: an SDIO function of the card
+ *
+ *	Note that the host is already claimed when handler is invoked.
+ */
+static void inband_irq_handler(struct sdio_func *func)
+{
+	struct cc33xx_sdio_glue *glue = sdio_get_drvdata(func);
+	struct platform_device *pdev = glue->core;
+	struct cc33xx_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+
+	if (WARN_ON(!pdev_data->irq_handler))
+		return;
+
+	pdev_data->irq_handler(pdev);
+}
+
+static void cc33xx_enable_async_interrupt(struct sdio_func *func)
+{
+	u8 reg_val;
+	const int CCCR_REG_16_ADDR = 0x16;
+	const int ENABLE_ASYNC_IRQ_BIT = BIT(1);
+
+	reg_val = sdio_f0_readb(func, CCCR_REG_16_ADDR, NULL);
+	reg_val |= ENABLE_ASYNC_IRQ_BIT;
+	sdio_f0_writeb(func, reg_val, CCCR_REG_16_ADDR, NULL);
+}
+
+static void cc33xx_sdio_enable_irq(struct device *child)
+{
+	struct cc33xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+	struct sdio_func *func = dev_to_sdio_func(glue->dev);
+
+	sdio_claim_host(func);
+	cc33xx_enable_async_interrupt(func);
+	sdio_claim_irq(func, inband_irq_handler);
+	sdio_release_host(func);
+}
+
+static void cc33xx_sdio_disable_irq(struct device *child)
+{
+	struct cc33xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+	struct sdio_func *func = dev_to_sdio_func(glue->dev);
+
+	sdio_claim_host(func);
+	sdio_release_irq(func);
+	sdio_release_host(func);
+}
+
+static void cc33xx_enable_line_irq(struct device *child)
+{
+	struct cc33xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+	struct platform_device *pdev = glue->core;
+	struct cc33xx_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+
+	enable_irq(pdev_data->gpio_irq_num);
+}
+
+static void cc33xx_disable_line_irq(struct device *child)
+{
+	struct cc33xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+	struct platform_device *pdev = glue->core;
+	struct cc33xx_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+
+	disable_irq_nosync(pdev_data->gpio_irq_num);
+}
+
+static void cc33xx_set_irq_handler(struct device *child, void *handler)
+{
+	struct cc33xx_sdio_glue *glue = dev_get_drvdata(child->parent);
+	struct platform_device *pdev = glue->core;
+	struct cc33xx_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+
+	pdev_data->irq_handler = handler;
+}
+
+static const struct cc33xx_if_operations sdio_ops_gpio_irq = {
+	.interface_claim	= cc33xx_sdio_claim,
+	.interface_release	= cc33xx_sdio_release,
+	.read			= cc33xx_sdio_raw_read,
+	.write			= cc33xx_sdio_raw_write,
+	.power			= cc33xx_sdio_set_power,
+	.set_block_size	= cc33xx_sdio_set_block_size,
+	.set_irq_handler	= cc33xx_set_irq_handler,
+	.disable_irq		= cc33xx_disable_line_irq,
+	.enable_irq		= cc33xx_enable_line_irq,
+};
+
+static const struct cc33xx_if_operations sdio_ops_inband_irq = {
+	.interface_claim	= cc33xx_sdio_claim,
+	.interface_release	= cc33xx_sdio_release,
+	.read			= cc33xx_sdio_raw_read,
+	.write			= cc33xx_sdio_raw_write,
+	.power			= cc33xx_sdio_set_power,
+	.set_block_size	= cc33xx_sdio_set_block_size,
+	.set_irq_handler	= cc33xx_set_irq_handler,
+	.disable_irq		= cc33xx_sdio_disable_irq,
+	.enable_irq		= cc33xx_sdio_enable_irq,
+};
+
+#ifdef CONFIG_OF
+static const struct cc33xx_family_data cc33xx_data = {
+	.name = "cc33xx",
+	.cfg_name = "ti-connectivity/cc33xx-conf.bin",
+	.nvs_name = "ti-connectivity/cc33xx-nvs.bin",
+};
+
+static const struct of_device_id cc33xx_sdio_of_match_table[] = {
+	{ .compatible = "ti,cc3300", .data = &cc33xx_data },
+	{ }
+};
+
+static int cc33xx_probe_of(struct device *dev, int *irq, int *wakeirq,
+			   struct cc33xx_platdev_data *pdev_data)
+{
+	struct device_node *np = dev->of_node;
+	const struct of_device_id *of_id;
+
+	of_id = of_match_node(cc33xx_sdio_of_match_table, np);
+	if (!of_id)
+		return -ENODEV;
+
+	pdev_data->family = of_id->data;
+
+	*irq = irq_of_parse_and_map(np, 0);
+
+	*wakeirq = irq_of_parse_and_map(np, 1);
+
+	return 0;
+}
+#else
+static int cc33xx_probe_of(struct device *dev, int *irq, int *wakeirq,
+			   struct cc33xx_platdev_data *pdev_data)
+{
+	return -ENODATA;
+}
+#endif /* CONFIG_OF */
+
+static irqreturn_t gpio_irq_hard_handler(int irq, void *cookie)
+{
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t gpio_irq_thread_handler(int irq, void *cookie)
+{
+	struct sdio_func *func = cookie;
+	struct cc33xx_sdio_glue *glue = sdio_get_drvdata(func);
+	struct platform_device *pdev = glue->core;
+	struct cc33xx_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+
+	if (WARN_ON(!pdev_data->irq_handler))
+		return IRQ_HANDLED;
+
+	pdev_data->irq_handler(pdev);
+
+	return IRQ_HANDLED;
+}
+
+static int sdio_cc33xx_probe(struct sdio_func *func,
+			     const struct sdio_device_id *id)
+{
+	struct cc33xx_platdev_data *pdev_data;
+	struct cc33xx_sdio_glue *glue;
+	struct resource res[1];
+	mmc_pm_flag_t mmcflags;
+	int ret = -ENOMEM;
+	int gpio_irq, wakeirq, irq_flags;
+
+	/* We are only able to handle the wlan function */
+	if (func->num != 0x02)
+		return -ENODEV;
+
+	pdev_data = devm_kzalloc(&func->dev, sizeof(*pdev_data), GFP_KERNEL);
+	if (!pdev_data)
+		return -ENOMEM;
+
+	glue = devm_kzalloc(&func->dev, sizeof(*glue), GFP_KERNEL);
+	if (!glue)
+		return -ENOMEM;
+
+	glue->dev = &func->dev;
+
+	/* Grab access to FN0 for ELP reg. */
+	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
+
+	/* Use block mode for transferring over one block size of data */
+	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+
+	ret = cc33xx_probe_of(&func->dev, &gpio_irq, &wakeirq, pdev_data);
+	if (ret)
+		goto out;
+
+	/* if sdio can keep power while host is suspended, enable wow */
+	mmcflags = sdio_get_host_pm_caps(func);
+
+	sdio_set_drvdata(func, glue);
+
+	/* Tell PM core that we don't need the card to be powered now */
+	pm_runtime_put_noidle(&func->dev);
+
+	glue->core = platform_device_alloc("cc33xx", PLATFORM_DEVID_AUTO);
+	if (!glue->core) {
+		dev_err(glue->dev, "can't allocate platform_device");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	glue->core->dev.parent = &func->dev;
+
+	if (gpio_irq) {
+		irq_flags = irqd_get_trigger_type(irq_get_irq_data(gpio_irq));
+
+		irq_set_status_flags(gpio_irq, IRQ_NOAUTOEN);
+
+		if (irq_flags & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW))
+			irq_flags |= IRQF_ONESHOT;
+
+		ret = request_threaded_irq(gpio_irq, gpio_irq_hard_handler,
+					   gpio_irq_thread_handler,
+					   irq_flags, glue->core->name, func);
+		if (ret) {
+			dev_err(glue->dev, "can't register GPIO IRQ handler\n");
+			goto out_dev_put;
+		}
+
+		pdev_data->gpio_irq_num = gpio_irq;
+
+		if ((mmcflags & MMC_PM_KEEP_POWER) &&
+		    (enable_irq_wake(gpio_irq) == 0))
+			pdev_data->pwr_in_suspend = true;
+
+		pdev_data->if_ops = &sdio_ops_gpio_irq;
+	} else {
+		pdev_data->if_ops = &sdio_ops_inband_irq;
+	}
+
+	if (wakeirq > 0) {
+		res[0].start = wakeirq;
+		res[0].flags = IORESOURCE_IRQ |
+			irqd_get_trigger_type(irq_get_irq_data(wakeirq));
+		res[0].name = "wakeirq";
+
+		ret = platform_device_add_resources(glue->core, res, 1);
+		if (ret) {
+			dev_err(glue->dev, "can't add resources\n");
+			goto out_dev_put;
+		}
+	}
+
+	ret = platform_device_add_data(glue->core, pdev_data,
+				       sizeof(*pdev_data));
+	if (ret) {
+		dev_err(glue->dev, "can't add platform data\n");
+		goto out_dev_put;
+	}
+
+	ret = platform_device_add(glue->core);
+	if (ret) {
+		dev_err(glue->dev, "can't add platform device\n");
+		goto out_dev_put;
+	}
+	return 0;
+
+out_dev_put:
+	platform_device_put(glue->core);
+
+	if (pdev_data->gpio_irq_num)
+		free_irq(pdev_data->gpio_irq_num, func);
+
+out:
+	return ret;
+}
+
+static void sdio_cc33xx_remove(struct sdio_func *func)
+{
+	struct cc33xx_sdio_glue *glue = sdio_get_drvdata(func);
+	struct platform_device *pdev = glue->core;
+	struct cc33xx_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+
+	/* Undo decrement done above in sdio_cc33xx_probe */
+	pm_runtime_get_noresume(&func->dev);
+
+	platform_device_unregister(glue->core);
+
+	if (pdev_data->gpio_irq_num) {
+		free_irq(pdev_data->gpio_irq_num, func);
+		if (pdev_data->pwr_in_suspend)
+			disable_irq_wake(pdev_data->gpio_irq_num);
+	} else {
+		sdio_claim_host(func);
+		sdio_release_irq(func);
+		sdio_release_host(func);
+	}
+}
+
+#ifdef CONFIG_PM
+static int cc33xx_suspend(struct device *dev)
+{
+	/* Tell MMC/SDIO core it's OK to power down the card
+	 * (if it isn't already), but not to remove it completely
+	 */
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	struct cc33xx_sdio_glue *glue = sdio_get_drvdata(func);
+	struct cc33xx *cc = platform_get_drvdata(glue->core);
+	mmc_pm_flag_t sdio_flags;
+	int ret = 0;
+
+	if (!cc) {
+		dev_err(dev, "no wilink module was probed\n");
+		goto out;
+	}
+
+	dev_dbg(dev, "cc33xx suspend. keep_device_power: %d\n",
+		cc->keep_device_power);
+
+	if (cc->keep_device_power) {
+		sdio_flags = sdio_get_host_pm_caps(func);
+
+		if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
+			dev_err(dev, "can't keep power while host is suspended\n");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/* keep power while host suspended */
+		ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+		if (ret) {
+			dev_err(dev, "error while trying to keep power\n");
+			goto out;
+		}
+	}
+out:
+	return ret;
+}
+
+static int cc33xx_resume(struct device *dev)
+{
+	return 0;
+}
+
+static const struct dev_pm_ops cc33xx_sdio_pm_ops = {
+	.suspend	= cc33xx_suspend,
+	.resume		= cc33xx_resume,
+};
+#endif
+
+static const struct sdio_device_id cc33xx_devices[] = {
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_CC33XX) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_CC33XX_NO_EFUSE) },
+	{}
+};
+
+MODULE_DEVICE_TABLE(sdio, cc33xx_devices);
+
+static struct sdio_driver cc33xx_sdio_driver = {
+	.name		= "cc33xx_sdio",
+	.id_table	= cc33xx_devices,
+	.probe		= sdio_cc33xx_probe,
+	.remove		= sdio_cc33xx_remove,
+#ifdef CONFIG_PM
+	.drv = {
+		.pm = &cc33xx_sdio_pm_ops,
+	},
+#endif /* CONFIG_PM */
+};
+
+module_sdio_driver(cc33xx_sdio_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("SDIO transport for Texas Instruments CC33xx WLAN driver");
+MODULE_AUTHOR("Michael Nemanov <michael.nemanov@ti.com>");
+MODULE_AUTHOR("Sabeeh Khan <sabeeh-khan@ti.com>");
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/testmode.c b/drivers/net/wireless/ti/cc33xx/testmode.c
--- a/drivers/net/wireless/ti/cc33xx/testmode.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/testmode.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,349 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <net/genetlink.h>
+
+#include "cc33xx.h"
+#include "acx.h"
+#include "io.h"
+#include "testmode.h"
+
+#define CC33XX_TM_MAX_DATA_LENGTH 1024
+
+enum cc33xx_tm_commands {
+	CC33XX_TM_CMD_UNSPEC,
+	CC33XX_TM_CMD_TEST,
+	CC33XX_TM_CMD_INTERROGATE,
+	CC33XX_TM_CMD_CONFIGURE,
+	CC33XX_TM_CMD_NVS_PUSH,		/* Not in use. Keep to not break ABI */
+	CC33XX_TM_CMD_SET_PLT_MODE,
+	CC33XX_TM_CMD_RECOVER,		/* Not in use. Keep to not break ABI */
+	CC33XX_TM_CMD_GET_MAC,
+
+	__CC33XX_TM_CMD_AFTER_LAST
+};
+
+enum cc33xx_tm_attrs {
+	CC33XX_TM_ATTR_UNSPEC,
+	CC33XX_TM_ATTR_CMD_ID,
+	CC33XX_TM_ATTR_ANSWER,
+	CC33XX_TM_ATTR_DATA,
+	CC33XX_TM_ATTR_IE_ID,
+	CC33XX_TM_ATTR_PLT_MODE,
+
+	__CC33XX_TM_ATTR_AFTER_LAST
+};
+
+#define CC33XX_TM_ATTR_MAX (__CC33XX_TM_ATTR_AFTER_LAST - 1)
+
+static struct nla_policy cc33xx_tm_policy[CC33XX_TM_ATTR_MAX + 1] = {
+	[CC33XX_TM_ATTR_CMD_ID] =	{ .type = NLA_U32 },
+	[CC33XX_TM_ATTR_ANSWER] =	{ .type = NLA_U8 },
+	[CC33XX_TM_ATTR_DATA] =		{ .type = NLA_BINARY,
+					  .len = CC33XX_TM_MAX_DATA_LENGTH },
+	[CC33XX_TM_ATTR_IE_ID] =	{ .type = NLA_U32 },
+	[CC33XX_TM_ATTR_PLT_MODE] =	{ .type = NLA_U32 },
+};
+
+static int cc33xx_tm_cmd_test(struct cc33xx *cc, struct nlattr *tb[])
+{
+	int ret, len;
+	u16 buf_len;
+	struct sk_buff *skb;
+	void *buf;
+	u8 answer = 0;
+
+	if (!tb[CC33XX_TM_ATTR_DATA])
+		return -EINVAL;
+
+	buf = nla_data(tb[CC33XX_TM_ATTR_DATA]);
+	buf_len = nla_len(tb[CC33XX_TM_ATTR_DATA]);
+
+	if (tb[CC33XX_TM_ATTR_ANSWER])
+		answer = nla_get_u8(tb[CC33XX_TM_ATTR_ANSWER]);
+
+	if (buf_len > sizeof(struct cc33xx_command))
+		return -EMSGSIZE;
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = cc33xx_cmd_test(cc, buf, buf_len, answer);
+	if (ret < 0) {
+		cc33xx_warning("testmode cmd test failed: %d", ret);
+		goto out;
+	}
+
+	if (answer) {
+		/* If we got bip calibration answer print radio status */
+		struct cc33xx_cmd_cal_p2g *params =
+			(struct cc33xx_cmd_cal_p2g *)buf;
+		s16 radio_status = (s16)le16_to_cpu(params->radio_status);
+
+		if (params->test.id == TEST_CMD_P2G_CAL && radio_status < 0)
+			cc33xx_warning("testmode cmd: radio status=%d",
+				       radio_status);
+		else
+			cc33xx_info("testmode cmd: radio status=%d",
+				    radio_status);
+
+		len = nla_total_size(buf_len);
+		skb = cfg80211_testmode_alloc_reply_skb(cc->hw->wiphy, len);
+		if (!skb) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		if (nla_put(skb, CC33XX_TM_ATTR_DATA, buf_len, buf)) {
+			kfree_skb(skb);
+			ret = -EMSGSIZE;
+			goto out;
+		}
+
+		ret = cfg80211_testmode_reply(skb);
+	}
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+static int cc33xx_tm_cmd_interrogate(struct cc33xx *cc, struct nlattr *tb[])
+{
+	int ret;
+	struct cc33xx_command *cmd;
+	struct sk_buff *skb;
+	u8 ie_id;
+
+	if (!tb[CC33XX_TM_ATTR_IE_ID])
+		return -EINVAL;
+
+	ie_id = nla_get_u8(tb[CC33XX_TM_ATTR_IE_ID]);
+
+	mutex_lock(&cc->mutex);
+
+	if (unlikely(cc->state != CC33XX_STATE_ON)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = cc33xx_cmd_debug_inter(cc, ie_id, cmd,
+				     sizeof(struct acx_header), sizeof(*cmd));
+	if (ret < 0) {
+		cc33xx_warning("testmode cmd interrogate failed: %d", ret);
+		goto out_free;
+	}
+
+	skb = cfg80211_testmode_alloc_reply_skb(cc->hw->wiphy, sizeof(*cmd));
+	if (!skb) {
+		ret = -ENOMEM;
+		goto out_free;
+	}
+
+	if (nla_put(skb, CC33XX_TM_ATTR_DATA, sizeof(*cmd), cmd)) {
+		kfree_skb(skb);
+		ret = -EMSGSIZE;
+		goto out_free;
+	}
+
+	ret = cfg80211_testmode_reply(skb);
+	if (ret < 0)
+		goto out_free;
+
+out_free:
+	kfree(cmd);
+
+out:
+	mutex_unlock(&cc->mutex);
+
+	return ret;
+}
+
+static int cc33xx_tm_cmd_configure(struct cc33xx *cc, struct nlattr *tb[])
+{
+	int ret;
+	u16 buf_len;
+	void *buf;
+	u8 ie_id;
+
+	if (!tb[CC33XX_TM_ATTR_DATA])
+		return -EINVAL;
+	if (!tb[CC33XX_TM_ATTR_IE_ID])
+		return -EINVAL;
+
+	ie_id = nla_get_u8(tb[CC33XX_TM_ATTR_IE_ID]);
+	buf = nla_data(tb[CC33XX_TM_ATTR_DATA]);
+	buf_len = nla_len(tb[CC33XX_TM_ATTR_DATA]);
+
+	if (buf_len > sizeof(struct cc33xx_command))
+		return -EMSGSIZE;
+
+	mutex_lock(&cc->mutex);
+	ret = cc33xx_cmd_debug(cc, ie_id, buf, buf_len);
+	mutex_unlock(&cc->mutex);
+
+	if (ret < 0) {
+		cc33xx_warning("testmode cmd configure failed: %d", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int cc33xx_tm_detect_fem(struct cc33xx *cc, struct nlattr *tb[])
+{
+	/* return FEM type */
+	int ret, len;
+	struct sk_buff *skb;
+
+	ret = cc33xx_plt_start(cc, PLT_FEM_DETECT);
+	if (ret < 0)
+		goto out;
+
+	mutex_lock(&cc->mutex);
+
+	len = nla_total_size(sizeof(cc->fem_manuf));
+	skb = cfg80211_testmode_alloc_reply_skb(cc->hw->wiphy, len);
+	if (!skb) {
+		ret = -ENOMEM;
+		goto out_mutex;
+	}
+
+	if (nla_put(skb, CC33XX_TM_ATTR_DATA, sizeof(cc->fem_manuf),
+		    &cc->fem_manuf)) {
+		kfree_skb(skb);
+		ret = -EMSGSIZE;
+		goto out_mutex;
+	}
+
+	ret = cfg80211_testmode_reply(skb);
+
+out_mutex:
+	mutex_unlock(&cc->mutex);
+
+	/* We always stop plt after DETECT mode */
+	cc33xx_plt_stop(cc);
+out:
+	return ret;
+}
+
+static int cc33xx_tm_cmd_set_plt_mode(struct cc33xx *cc, struct nlattr *tb[])
+{
+	u32 val;
+	int ret;
+
+	if (!tb[CC33XX_TM_ATTR_PLT_MODE])
+		return -EINVAL;
+
+	val = nla_get_u32(tb[CC33XX_TM_ATTR_PLT_MODE]);
+
+	switch (val) {
+	case PLT_OFF:
+		ret = cc33xx_plt_stop(cc);
+		break;
+	case PLT_ON:
+	case PLT_CHIP_AWAKE:
+		ret = cc33xx_plt_start(cc, val);
+		break;
+	case PLT_FEM_DETECT:
+		ret = cc33xx_tm_detect_fem(cc, tb);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int cc33xx_tm_cmd_get_mac(struct cc33xx *cc, struct nlattr *tb[])
+{
+	struct sk_buff *skb;
+	u8 zero_mac[ETH_ALEN] = {0};
+	int ret = 0;
+
+	mutex_lock(&cc->mutex);
+
+	if (!cc->plt) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (memcmp(zero_mac, cc->efuse_mac_address, ETH_ALEN) == 0) {
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
+
+	skb = cfg80211_testmode_alloc_reply_skb(cc->hw->wiphy, ETH_ALEN);
+	if (!skb) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (nla_put(skb, CC33XX_TM_ATTR_DATA,
+		    ETH_ALEN, cc->efuse_mac_address)) {
+		kfree_skb(skb);
+		ret = -EMSGSIZE;
+		goto out;
+	}
+
+	ret = cfg80211_testmode_reply(skb);
+	if (ret < 0)
+		goto out;
+
+out:
+	mutex_unlock(&cc->mutex);
+	return ret;
+}
+
+int cc33xx_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		  void *data, int len)
+{
+	struct cc33xx *cc = hw->priv;
+	struct nlattr *tb[CC33XX_TM_ATTR_MAX + 1];
+	u32 nla_cmd;
+	int err;
+
+	err = nla_parse_deprecated(tb, CC33XX_TM_ATTR_MAX, data, len,
+				   cc33xx_tm_policy, NULL);
+	if (err)
+		return err;
+
+	if (!tb[CC33XX_TM_ATTR_CMD_ID])
+		return -EINVAL;
+
+	nla_cmd = nla_get_u32(tb[CC33XX_TM_ATTR_CMD_ID]);
+
+	/* Only SET_PLT_MODE is allowed in case of mode PLT_CHIP_AWAKE */
+	if (cc->plt_mode == PLT_CHIP_AWAKE &&
+	    nla_cmd != CC33XX_TM_CMD_SET_PLT_MODE)
+		return -EOPNOTSUPP;
+
+	switch (nla_cmd) {
+	case CC33XX_TM_CMD_TEST:
+		return cc33xx_tm_cmd_test(cc, tb);
+	case CC33XX_TM_CMD_INTERROGATE:
+		return cc33xx_tm_cmd_interrogate(cc, tb);
+	case CC33XX_TM_CMD_CONFIGURE:
+		return cc33xx_tm_cmd_configure(cc, tb);
+	case CC33XX_TM_CMD_SET_PLT_MODE:
+		return cc33xx_tm_cmd_set_plt_mode(cc, tb);
+	case CC33XX_TM_CMD_GET_MAC:
+		return cc33xx_tm_cmd_get_mac(cc, tb);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/testmode.h b/drivers/net/wireless/ti/cc33xx/testmode.h
--- a/drivers/net/wireless/ti/cc33xx/testmode.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/testmode.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __TESTMODE_H__
+#define __TESTMODE_H__
+
+int cc33xx_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		  void *data, int len);
+
+#endif /* __TESTMODE_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/tx.c b/drivers/net/wireless/ti/cc33xx/tx.c
--- a/drivers/net/wireless/ti/cc33xx/tx.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/tx.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,1409 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include "acx.h"
+#include "debug.h"
+#include "io.h"
+#include "ps.h"
+#include "tx.h"
+#include "cc33xx.h"
+
+static int cc33xx_set_default_wep_key(struct cc33xx *cc,
+				      struct cc33xx_vif *wlvif, u8 id)
+{
+	int ret;
+	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
+
+	if (is_ap)
+		ret = cc33xx_cmd_set_default_wep_key(cc, id,
+						     wlvif->ap.bcast_hlid);
+	else
+		ret = cc33xx_cmd_set_default_wep_key(cc, id, wlvif->sta.hlid);
+
+	if (ret < 0)
+		return ret;
+
+	cc33xx_debug(DEBUG_CRYPT, "default wep key idx: %d", (int)id);
+	return 0;
+}
+
+static int cc33xx_alloc_tx_id(struct cc33xx *cc, struct sk_buff *skb)
+{
+	int id;
+
+	id = find_first_zero_bit(cc->tx_frames_map, CC33XX_NUM_TX_DESCRIPTORS);
+	if (id >= CC33XX_NUM_TX_DESCRIPTORS)
+		return -EBUSY;
+
+	__set_bit(id, cc->tx_frames_map);
+	cc->tx_frames[id] = skb;
+	cc->tx_frames_cnt++;
+	cc33xx_debug(DEBUG_TX, "alloc desc ID. id - %d, frames count %d",
+		     id, cc->tx_frames_cnt);
+	return id;
+}
+
+void cc33xx_free_tx_id(struct cc33xx *cc, int id)
+{
+	if (__test_and_clear_bit(id, cc->tx_frames_map)) {
+		if (unlikely(cc->tx_frames_cnt == CC33XX_NUM_TX_DESCRIPTORS))
+			clear_bit(CC33XX_FLAG_FW_TX_BUSY, &cc->flags);
+
+		cc->tx_frames[id] = NULL;
+		cc->tx_frames_cnt--;
+	}
+	cc33xx_debug(DEBUG_TX, "free desc ID. id - %d, frames count %d",
+		     id, cc->tx_frames_cnt);
+}
+EXPORT_SYMBOL(cc33xx_free_tx_id);
+
+static void cc33xx_tx_ap_update_inconnection_sta(struct cc33xx *cc,
+						 struct cc33xx_vif *wlvif,
+						 struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr;
+
+	hdr = (struct ieee80211_hdr *)(skb->data +
+				       sizeof(struct cc33xx_tx_hw_descr));
+	if (!ieee80211_is_auth(hdr->frame_control))
+		return;
+
+	/* ROC for 1 second on the AP channel for completing the connection.
+	 * Note the ROC will be continued by the update_sta_state callbacks
+	 * once the station reaches the associated state.
+	 */
+	cc33xx_update_inconn_sta(cc, wlvif, NULL, true);
+	wlvif->pending_auth_reply_time = jiffies;
+	cancel_delayed_work(&wlvif->pending_auth_complete_work);
+	ieee80211_queue_delayed_work(cc->hw,
+				     &wlvif->pending_auth_complete_work,
+				msecs_to_jiffies(CC33XX_PEND_AUTH_ROC_TIMEOUT));
+}
+
+static void cc33xx_tx_regulate_link(struct cc33xx *cc,
+				    struct cc33xx_vif *wlvif,
+				    u8 hlid)
+{
+	bool fw_ps;
+	u8 tx_pkts;
+
+	if (WARN_ON(!test_bit(hlid, wlvif->links_map)))
+		return;
+
+	fw_ps = test_bit(hlid, &cc->ap_fw_ps_map);
+	tx_pkts = cc->links[hlid].allocated_pkts;
+
+	/* if in FW PS and there is enough data in FW we can put the link
+	 * into high-level PS and clean out its TX queues.
+	 * Make an exception if this is the only connected link. In this
+	 * case FW-memory congestion is less of a problem.
+	 * Note that a single connected STA means 2*ap_count + 1 active links,
+	 * since we must account for the global and broadcast AP links
+	 * for each AP. The "fw_ps" check assures us the other link is a STA
+	 * connected to the AP. Otherwise the FW would not set the PSM bit.
+	 */
+	if (cc->active_link_count > (cc->ap_count * 2 + 1) && fw_ps &&
+	    tx_pkts >= CC33XX_PS_STA_MAX_PACKETS)
+		cc33xx_ps_link_start(cc, wlvif, hlid, true);
+}
+
+inline bool cc33xx_is_dummy_packet(struct cc33xx *cc, struct sk_buff *skb)
+{
+	return cc->dummy_packet == skb;
+}
+EXPORT_SYMBOL(cc33xx_is_dummy_packet);
+
+static u8 cc33xx_tx_get_hlid_ap(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				struct sk_buff *skb, struct ieee80211_sta *sta)
+{
+	struct ieee80211_hdr *hdr;
+
+	if (sta) {
+		struct cc33xx_station *wl_sta;
+
+		wl_sta = (struct cc33xx_station *)sta->drv_priv;
+		return wl_sta->hlid;
+	}
+
+	if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
+		return CC33XX_SYSTEM_HLID;
+
+	hdr = (struct ieee80211_hdr *)skb->data;
+	if (is_multicast_ether_addr(ieee80211_get_DA(hdr)))
+		return wlvif->ap.bcast_hlid;
+	else
+		return wlvif->ap.global_hlid;
+}
+
+u8 cc33xx_tx_get_hlid(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+		      struct sk_buff *skb, struct ieee80211_sta *sta)
+{
+	struct ieee80211_tx_info *control;
+
+	if (wlvif->bss_type == BSS_TYPE_AP_BSS)
+		return cc33xx_tx_get_hlid_ap(cc, wlvif, skb, sta);
+
+	control = IEEE80211_SKB_CB(skb);
+	if (control->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
+		return wlvif->dev_hlid;
+
+	return wlvif->sta.hlid;
+}
+
+unsigned int cc33xx_calc_packet_alignment(struct cc33xx *cc,
+					  unsigned int packet_length)
+{
+	if ((cc->quirks & CC33XX_QUIRK_TX_PAD_LAST_FRAME) ||
+	    !(cc->quirks & CC33XX_QUIRK_TX_BLOCKSIZE_ALIGN))
+		return ALIGN(packet_length, CC33XX_TX_ALIGN_TO);
+	else
+		return ALIGN(packet_length, CC33XX_BUS_BLOCK_SIZE);
+}
+EXPORT_SYMBOL(cc33xx_calc_packet_alignment);
+
+static u32 cc33xx_calc_tx_blocks(struct cc33xx *cc, u32 len, u32 spare_blks)
+{
+	u32 blk_size = CC33XX_TX_HW_BLOCK_SIZE;
+	/* In CC33xx the packet will be stored along with its internal descriptor.
+	 * the descriptor is not part of the host transaction, but should be
+	 * considered as part of the allocate memory blocks in the device
+	 */
+	len = len + CC33xx_INTERNAL_DESC_SIZE;
+	return (len + blk_size - 1) / blk_size + spare_blks;
+}
+
+static inline void cc33xx_set_tx_desc_blocks(struct cc33xx *cc,
+					     struct cc33xx_tx_hw_descr *desc,
+					     u32 blks, u32 spare_blks)
+{
+	desc->cc33xx_mem.total_mem_blocks = blks;
+}
+
+static void cc33xx_set_tx_desc_data_len(struct cc33xx *cc,
+					struct cc33xx_tx_hw_descr *desc,
+					struct sk_buff *skb)
+{
+	desc->length = cpu_to_le16(skb->len);
+
+	/* if only the last frame is to be padded, we unset this bit on Tx */
+	if (cc->quirks & CC33XX_QUIRK_TX_PAD_LAST_FRAME)
+		desc->cc33xx_mem.ctrl = CC33XX_TX_CTRL_NOT_PADDED;
+	else
+		desc->cc33xx_mem.ctrl = 0;
+
+	cc33xx_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d  len: %d life: %d mem: %d",
+		     desc->hlid, le16_to_cpu(desc->length),
+		     le16_to_cpu(desc->life_time),
+		     desc->cc33xx_mem.total_mem_blocks);
+}
+
+static int cc33xx_get_spare_blocks(struct cc33xx *cc, bool is_gem)
+{
+	/* If we have keys requiring extra spare, indulge them */
+	if (cc->extra_spare_key_count)
+		return CC33XX_TX_HW_EXTRA_BLOCK_SPARE;
+
+	return CC33XX_TX_HW_BLOCK_SPARE;
+}
+
+int cc33xx_tx_get_queue(int queue)
+{
+	switch (queue) {
+	case 0:
+		return CONF_TX_AC_VO;
+	case 1:
+		return CONF_TX_AC_VI;
+	case 2:
+		return CONF_TX_AC_BE;
+	case 3:
+		return CONF_TX_AC_BK;
+	default:
+		return CONF_TX_AC_BE;
+	}
+}
+
+static int cc33xx_tx_allocate(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			      struct sk_buff *skb, u32 extra, u32 buf_offset,
+			      u8 hlid, bool is_gem,
+			      struct NAB_tx_header *nab_cmd)
+{
+	struct cc33xx_tx_hw_descr *desc;
+	u32 total_blocks;
+	int id, ret = -EBUSY, ac;
+	u32 spare_blocks;
+	u32 total_skb_len = skb->len + extra;
+	/* Add NAB command required for CC33xx architecture */
+	u32 total_len = sizeof(struct NAB_tx_header);
+
+	total_skb_len += sizeof(struct cc33xx_tx_hw_descr);
+	total_len += total_skb_len;
+
+	cc33xx_debug(DEBUG_TX, "cc->tx_blocks_available %d",
+		     cc->tx_blocks_available);
+
+	if (buf_offset + total_len > cc->aggr_buf_size)
+		return -EAGAIN;
+
+	spare_blocks = cc33xx_get_spare_blocks(cc, is_gem);
+
+	/* allocate free identifier for the packet */
+	id = cc33xx_alloc_tx_id(cc, skb);
+	if (id < 0)
+		return id;
+
+	/* memblocks should not include nab descriptor */
+	total_blocks = cc33xx_calc_tx_blocks(cc, total_skb_len, spare_blocks);
+	cc33xx_debug(DEBUG_TX, "total blocks %d", total_blocks);
+
+	if (total_blocks <= cc->tx_blocks_available) {
+		/**
+		 * In CC33XX the packet starts with NAB command,
+		 * only then the descriptor.
+		 */
+		nab_cmd->sync = cpu_to_le32(HOST_SYNC_PATTERN);
+		nab_cmd->opcode = cpu_to_le16(NAB_SEND_CMD);
+
+		/**
+		 * length should include the following 4 bytes
+		 * of the NAB command.
+		 */
+		nab_cmd->len = cpu_to_le16(total_len -
+						sizeof(struct NAB_header));
+		nab_cmd->desc_length = cpu_to_le16(total_len -
+						sizeof(struct NAB_tx_header));
+		nab_cmd->sd = 0;
+		nab_cmd->flags = NAB_SEND_FLAGS;
+
+		desc = skb_push(skb, total_skb_len - skb->len);
+
+		cc33xx_set_tx_desc_blocks(cc, desc, total_blocks, spare_blocks);
+
+		desc->id = id;
+
+		cc33xx_debug(DEBUG_TX,
+			     "tx allocate id %u skb 0x%p tx_memblocks %d",
+			     id, skb, desc->cc33xx_mem.total_mem_blocks);
+
+		cc->tx_blocks_available -= total_blocks;
+		cc->tx_allocated_blocks += total_blocks;
+
+		/* If the FW was empty before, arm the Tx watchdog. Also do
+		 * this on the first Tx after resume, as we always cancel the
+		 * watchdog on suspend.
+		 */
+		if (cc->tx_allocated_blocks == total_blocks ||
+		    test_and_clear_bit(CC33XX_FLAG_REINIT_TX_WDOG, &cc->flags))
+			cc33xx_rearm_tx_watchdog_locked(cc);
+
+		ac = cc33xx_tx_get_queue(skb_get_queue_mapping(skb));
+		desc->ac = ac;
+		cc->tx_allocated_pkts[ac]++;
+
+		if (test_bit(hlid, cc->links_map))
+			cc->links[hlid].allocated_pkts++;
+
+		ret = 0;
+
+		cc33xx_debug(DEBUG_TX,
+			     "tx_allocate: size: %d, blocks: %d, id: %d",
+			     total_len, total_blocks, id);
+	} else {
+		cc33xx_free_tx_id(cc, id);
+	}
+
+	return ret;
+}
+
+static void cc33xx_tx_fill_hdr(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			       struct sk_buff *skb, u32 extra,
+			       struct ieee80211_tx_info *control, u8 hlid)
+{
+	struct cc33xx_tx_hw_descr *desc;
+	int ac, rate_idx;
+	u16 tx_attr = 0;
+	__le16 frame_control;
+	struct ieee80211_hdr *hdr;
+	u8 *frame_start;
+	bool is_dummy;
+
+	desc = (struct cc33xx_tx_hw_descr *)skb->data;
+
+	frame_start = (u8 *)(desc + 1);
+	hdr = (struct ieee80211_hdr *)(frame_start + extra);
+	frame_control = hdr->frame_control;
+
+	/* relocate space for security header */
+	if (extra) {
+		int hdrlen = ieee80211_hdrlen(frame_control);
+
+		memmove(frame_start, hdr, hdrlen);
+		skb_set_network_header(skb, skb_network_offset(skb) + extra);
+	}
+
+	is_dummy = cc33xx_is_dummy_packet(cc, skb);
+	if (is_dummy || !wlvif || wlvif->bss_type != BSS_TYPE_AP_BSS)
+		desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU);
+	else
+		desc->life_time = cpu_to_le16(TX_HW_AP_MODE_PKT_LIFETIME_TU);
+
+	/* queue */
+	ac = cc33xx_tx_get_queue(skb_get_queue_mapping(skb));
+	desc->tid = skb->priority;
+
+	if (is_dummy) {
+		/* FW expects the dummy packet to have an invalid session id -
+		 * any session id that is different than the one set in the join
+		 */
+		tx_attr = (SESSION_COUNTER_INVALID <<
+			   TX_HW_ATTR_OFST_SESSION_COUNTER) &
+			   TX_HW_ATTR_SESSION_COUNTER;
+
+		tx_attr |= TX_HW_ATTR_TX_DUMMY_REQ;
+	} else if (wlvif) {
+		u8 session_id = cc->session_ids[hlid];
+
+		if (cc->quirks & CC33XX_QUIRK_AP_ZERO_SESSION_ID &&
+		    wlvif->bss_type == BSS_TYPE_AP_BSS)
+			session_id = 0;
+
+		/* configure the tx attributes */
+		tx_attr = session_id << TX_HW_ATTR_OFST_SESSION_COUNTER;
+	}
+
+	desc->hlid = hlid;
+	if (is_dummy || !wlvif) {
+		rate_idx = 0;
+	} else if (wlvif->bss_type != BSS_TYPE_AP_BSS) {
+		/* if the packets are data packets
+		 * send them with AP rate policies (EAPOLs are an exception),
+		 * otherwise use default basic rates
+		 */
+		if (skb->protocol == cpu_to_be16(ETH_P_PAE))
+			rate_idx = wlvif->sta.basic_rate_idx;
+		else if (control->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
+			rate_idx = wlvif->sta.p2p_rate_idx;
+		else if (ieee80211_is_data(frame_control))
+			rate_idx = wlvif->sta.ap_rate_idx;
+		else
+			rate_idx = wlvif->sta.basic_rate_idx;
+	} else {
+		if (hlid == wlvif->ap.global_hlid)
+			rate_idx = wlvif->ap.mgmt_rate_idx;
+		else if (hlid == wlvif->ap.bcast_hlid ||
+			 skb->protocol == cpu_to_be16(ETH_P_PAE) ||
+			 !ieee80211_is_data(frame_control))
+			/* send non-data, bcast and EAPOLs using the
+			 * min basic rate
+			 */
+			rate_idx = wlvif->ap.bcast_rate_idx;
+		else
+			rate_idx = wlvif->ap.ucast_rate_idx[ac];
+	}
+
+	tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
+
+	/* for WEP shared auth - no fw encryption is needed */
+	if (ieee80211_is_auth(frame_control) &&
+	    ieee80211_has_protected(frame_control))
+		tx_attr |= TX_HW_ATTR_HOST_ENCRYPT;
+
+	/* send EAPOL frames as voice */
+	if (control->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)
+		tx_attr |= TX_HW_ATTR_EAPOL_FRAME;
+
+	desc->tx_attr = cpu_to_le16(tx_attr);
+
+	cc33xx_set_tx_desc_data_len(cc, desc, skb);
+}
+
+/* caller must hold cc->mutex */
+static int cc33xx_prepare_tx_frame(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				   struct sk_buff *skb, u32 buf_offset, u8 hlid)
+{
+	struct ieee80211_tx_info *info;
+	u32 extra = 0;
+	int ret = 0;
+	u32 total_len;
+	bool is_dummy;
+	bool is_gem = false;
+	struct NAB_tx_header nab_cmd;
+
+	if (!skb) {
+		cc33xx_error("discarding null skb");
+		return -EINVAL;
+	}
+
+	if (hlid == CC33XX_INVALID_LINK_ID) {
+		cc33xx_error("invalid hlid. dropping skb 0x%p", skb);
+		return -EINVAL;
+	}
+
+	info = IEEE80211_SKB_CB(skb);
+
+	is_dummy = cc33xx_is_dummy_packet(cc, skb);
+
+	if ((cc->quirks & CC33XX_QUIRK_TKIP_HEADER_SPACE) &&
+	    info->control.hw_key &&
+	    info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
+		extra = CC33XX_EXTRA_SPACE_TKIP;
+
+	if (info->control.hw_key) {
+		bool is_wep;
+		u8 idx = info->control.hw_key->hw_key_idx;
+		u32 cipher = info->control.hw_key->cipher;
+
+		is_wep = (cipher == WLAN_CIPHER_SUITE_WEP40) ||
+			 (cipher == WLAN_CIPHER_SUITE_WEP104);
+
+		if (WARN_ON(is_wep && wlvif && wlvif->default_key != idx)) {
+			ret = cc33xx_set_default_wep_key(cc, wlvif, idx);
+			if (ret < 0)
+				return ret;
+			wlvif->default_key = idx;
+		}
+
+		is_gem = (cipher == CC33XX_CIPHER_SUITE_GEM);
+	}
+
+	/* Add 4 bytes gap, may be filled later on by the PMAC. */
+	extra += IEEE80211_HT_CTL_LEN;
+	ret = cc33xx_tx_allocate(cc, wlvif, skb, extra, buf_offset, hlid,
+				 is_gem, &nab_cmd);
+	cc33xx_debug(DEBUG_TX, "cc33xx_tx_allocate %d", ret);
+
+	if (ret < 0)
+		return ret;
+
+	cc33xx_tx_fill_hdr(cc, wlvif, skb, extra, info, hlid);
+
+	if (!is_dummy && wlvif && wlvif->bss_type == BSS_TYPE_AP_BSS) {
+		cc33xx_tx_ap_update_inconnection_sta(cc, wlvif, skb);
+		cc33xx_tx_regulate_link(cc, wlvif, hlid);
+	}
+
+	/* The length of each packet is stored in terms of
+	 * words. Thus, we must pad the skb data to make sure its
+	 * length is aligned.  The number of padding bytes is computed
+	 * and set in cc33xx_tx_fill_hdr.
+	 * In special cases, we want to align to a specific block size
+	 * (eg. for wl128x with SDIO we align to 256).
+	 */
+	total_len = cc33xx_calc_packet_alignment(cc, skb->len);
+
+	memcpy(cc->aggr_buf + buf_offset,
+	       &nab_cmd, sizeof(struct NAB_tx_header));
+	memcpy(cc->aggr_buf + buf_offset + sizeof(struct NAB_tx_header),
+	       skb->data, skb->len);
+	memset(cc->aggr_buf + buf_offset + sizeof(struct NAB_tx_header)
+		+ skb->len, 0, total_len - skb->len);
+
+	/* Revert side effects in the dummy packet skb, so it can be reused */
+	if (is_dummy)
+		skb_pull(skb, sizeof(struct cc33xx_tx_hw_descr));
+
+	return (total_len + sizeof(struct NAB_tx_header));
+}
+
+u32 cc33xx_tx_enabled_rates_get(struct cc33xx *cc, u32 rate_set,
+				enum nl80211_band rate_band)
+{
+	struct ieee80211_supported_band *band;
+	u32 enabled_rates = 0;
+	int bit;
+
+	band = cc->hw->wiphy->bands[rate_band];
+	for (bit = 0; bit < band->n_bitrates; bit++) {
+		if (rate_set & 0x1)
+			enabled_rates |= band->bitrates[bit].hw_value;
+		rate_set >>= 1;
+	}
+
+	/* MCS rates indication are on bits 16 - 31 */
+	rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates;
+
+	for (bit = 0; bit < 16; bit++) {
+		if (rate_set & 0x1)
+			enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit);
+		rate_set >>= 1;
+	}
+
+	return enabled_rates;
+}
+
+static inline int cc33xx_tx_get_mac80211_queue(struct cc33xx_vif *wlvif,
+					       int queue)
+{
+	int mac_queue = wlvif->hw_queue_base;
+
+	switch (queue) {
+	case CONF_TX_AC_VO:
+		return mac_queue + 0;
+	case CONF_TX_AC_VI:
+		return mac_queue + 1;
+	case CONF_TX_AC_BE:
+		return mac_queue + 2;
+	case CONF_TX_AC_BK:
+		return mac_queue + 3;
+	default:
+		return mac_queue + 2;
+	}
+}
+
+static void cc33xx_wake_queue(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			      u8 queue, enum cc33xx_queue_stop_reason reason)
+{
+	unsigned long flags;
+	int hwq = cc33xx_tx_get_mac80211_queue(wlvif, queue);
+
+	spin_lock_irqsave(&cc->cc_lock, flags);
+
+	/* queue should not be clear for this reason */
+	WARN_ON_ONCE(!test_and_clear_bit(reason, &cc->queue_stop_reasons[hwq]));
+
+	if (cc->queue_stop_reasons[hwq])
+		goto out;
+
+	ieee80211_wake_queue(cc->hw, hwq);
+
+out:
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+}
+
+void cc33xx_handle_tx_low_watermark(struct cc33xx *cc)
+{
+	int i;
+	struct cc33xx_vif *wlvif;
+
+	cc33xx_for_each_wlvif(cc, wlvif) {
+		for (i = 0; i < NUM_TX_QUEUES; i++) {
+			if (cc33xx_is_queue_stopped_by_reason(cc, wlvif, i,
+							      CC33XX_QUEUE_STOP_REASON_WATERMARK) &&
+			    wlvif->tx_queue_count[i] <=
+					CC33XX_TX_QUEUE_LOW_WATERMARK)
+				/* firmware buffer has space, restart queues */
+				cc33xx_wake_queue(cc, wlvif, i,
+						  CC33XX_QUEUE_STOP_REASON_WATERMARK);
+		}
+	}
+}
+
+static int cc33xx_select_ac(struct cc33xx *cc)
+{
+	int i, q = -1, ac;
+	u32 min_pkts = 0xffffffff;
+
+	/* Find a non-empty ac where:
+	 * 1. There are packets to transmit
+	 * 2. The FW has the least allocated blocks
+	 *
+	 * We prioritize the ACs according to VO>VI>BE>BK
+	 */
+	for (i = 0; i < NUM_TX_QUEUES; i++) {
+		ac = cc33xx_tx_get_queue(i);
+		if (cc->tx_queue_count[ac] &&
+		    cc->tx_allocated_pkts[ac] < min_pkts) {
+			q = ac;
+			min_pkts = cc->tx_allocated_pkts[q];
+		}
+	}
+
+	return q;
+}
+
+static struct sk_buff *cc33xx_lnk_dequeue(struct cc33xx *cc,
+					  struct cc33xx_link *lnk, u8 q)
+{
+	struct sk_buff *skb;
+	unsigned long flags;
+
+	skb = skb_dequeue(&lnk->tx_queue[q]);
+	if (skb) {
+		spin_lock_irqsave(&cc->cc_lock, flags);
+		WARN_ON_ONCE(cc->tx_queue_count[q] <= 0);
+		cc->tx_queue_count[q]--;
+		if (lnk->wlvif) {
+			WARN_ON_ONCE(lnk->wlvif->tx_queue_count[q] <= 0);
+			lnk->wlvif->tx_queue_count[q]--;
+		}
+		spin_unlock_irqrestore(&cc->cc_lock, flags);
+	}
+
+	return skb;
+}
+
+static bool cc33xx_lnk_high_prio(struct cc33xx *cc, u8 hlid,
+				 struct cc33xx_link *lnk)
+{
+	u8 thold;
+	struct core_fw_status *core_fw_status = &cc->core_status->fw_info;
+	unsigned long suspend_bitmap, fast_bitmap, ps_bitmap;
+
+	suspend_bitmap = le32_to_cpu(core_fw_status->link_suspend_bitmap);
+	fast_bitmap = le32_to_cpu(core_fw_status->link_fast_bitmap);
+	ps_bitmap = le32_to_cpu(core_fw_status->link_ps_bitmap);
+
+	/* suspended links are never high priority */
+	if (test_bit(hlid, &suspend_bitmap))
+		return false;
+
+	/* the priority thresholds are taken from FW */
+	if (test_bit(hlid, &fast_bitmap) && !test_bit(hlid, &ps_bitmap))
+		thold = core_fw_status->tx_fast_link_prio_threshold;
+	else
+		thold = core_fw_status->tx_slow_link_prio_threshold;
+
+	return lnk->allocated_pkts < thold;
+}
+
+static bool cc33xx_lnk_low_prio(struct cc33xx *cc, u8 hlid,
+				struct cc33xx_link *lnk)
+{
+	u8 thold;
+	struct core_fw_status *core_fw_status = &cc->core_status->fw_info;
+	unsigned long suspend_bitmap, fast_bitmap, ps_bitmap;
+
+	suspend_bitmap = le32_to_cpu(core_fw_status->link_suspend_bitmap);
+	fast_bitmap = le32_to_cpu(core_fw_status->link_fast_bitmap);
+	ps_bitmap = le32_to_cpu(core_fw_status->link_ps_bitmap);
+
+	if (test_bit(hlid, &suspend_bitmap))
+		thold = core_fw_status->tx_suspend_threshold;
+	else if (test_bit(hlid, &fast_bitmap) && !test_bit(hlid, &ps_bitmap))
+		thold = core_fw_status->tx_fast_stop_threshold;
+	else
+		thold = core_fw_status->tx_slow_stop_threshold;
+
+	return lnk->allocated_pkts < thold;
+}
+
+static struct sk_buff *cc33xx_lnk_dequeue_high_prio(struct cc33xx *cc,
+						    u8 hlid, u8 ac,
+						    u8 *low_prio_hlid)
+{
+	struct cc33xx_link *lnk = &cc->links[hlid];
+
+	if (!cc33xx_lnk_high_prio(cc, hlid, lnk)) {
+		if (*low_prio_hlid == CC33XX_INVALID_LINK_ID &&
+		    !skb_queue_empty(&lnk->tx_queue[ac]) &&
+		    cc33xx_lnk_low_prio(cc, hlid, lnk))
+			/* we found the first non-empty low priority queue */
+			*low_prio_hlid = hlid;
+
+		return NULL;
+	}
+
+	return cc33xx_lnk_dequeue(cc, lnk, ac);
+}
+
+static struct sk_buff *cc33xx_vif_dequeue_high_prio(struct cc33xx *cc,
+						    struct cc33xx_vif *wlvif,
+						    u8 ac, u8 *hlid,
+						    u8 *low_prio_hlid)
+{
+	struct sk_buff *skb = NULL;
+	int i, h, start_hlid;
+
+	/* start from the link after the last one */
+	start_hlid = (wlvif->last_tx_hlid + 1) % CC33XX_MAX_LINKS;
+
+	/* dequeue according to AC, round robin on each link */
+	for (i = 0; i < CC33XX_MAX_LINKS; i++) {
+		h = (start_hlid + i) % CC33XX_MAX_LINKS;
+
+		/* only consider connected stations */
+		if (!test_bit(h, wlvif->links_map))
+			continue;
+
+		skb = cc33xx_lnk_dequeue_high_prio(cc, h, ac, low_prio_hlid);
+		if (!skb)
+			continue;
+
+		wlvif->last_tx_hlid = h;
+		break;
+	}
+
+	if (!skb)
+		wlvif->last_tx_hlid = 0;
+
+	*hlid = wlvif->last_tx_hlid;
+	return skb;
+}
+
+static struct sk_buff *cc33xx_skb_dequeue(struct cc33xx *cc, u8 *hlid)
+{
+	unsigned long flags;
+	struct cc33xx_vif *wlvif = cc->last_wlvif;
+	struct sk_buff *skb = NULL;
+	int ac;
+	u8 low_prio_hlid = CC33XX_INVALID_LINK_ID;
+
+	ac = cc33xx_select_ac(cc);
+	if (ac < 0)
+		goto out;
+
+	/* continue from last wlvif (round robin) */
+	if (wlvif) {
+		cc33xx_for_each_wlvif_continue(cc, wlvif) {
+			if (!wlvif->tx_queue_count[ac])
+				continue;
+
+			skb = cc33xx_vif_dequeue_high_prio(cc, wlvif, ac, hlid,
+							   &low_prio_hlid);
+			if (!skb)
+				continue;
+
+			cc->last_wlvif = wlvif;
+			break;
+		}
+	}
+
+	/* dequeue from the system HLID before the restarting wlvif list */
+	if (!skb) {
+		skb = cc33xx_lnk_dequeue_high_prio(cc, CC33XX_SYSTEM_HLID,
+						   ac, &low_prio_hlid);
+		if (skb) {
+			*hlid = CC33XX_SYSTEM_HLID;
+			cc->last_wlvif = NULL;
+		}
+	}
+
+	/* Do a new pass over the wlvif list. But no need to continue
+	 * after last_wlvif. The previous pass should have found it.
+	 */
+	if (!skb) {
+		cc33xx_for_each_wlvif(cc, wlvif) {
+			if (!wlvif->tx_queue_count[ac])
+				goto next;
+
+			skb = cc33xx_vif_dequeue_high_prio(cc, wlvif, ac, hlid,
+							   &low_prio_hlid);
+			if (skb) {
+				cc->last_wlvif = wlvif;
+				break;
+			}
+
+next:
+			if (wlvif == cc->last_wlvif)
+				break;
+		}
+	}
+
+	/* no high priority skbs found - but maybe a low priority one? */
+	if (!skb && low_prio_hlid != CC33XX_INVALID_LINK_ID) {
+		struct cc33xx_link *lnk = &cc->links[low_prio_hlid];
+
+		skb = cc33xx_lnk_dequeue(cc, lnk, ac);
+
+		WARN_ON(!skb); /* we checked this before */
+		*hlid = low_prio_hlid;
+
+		/* ensure proper round robin in the vif/link levels */
+		cc->last_wlvif = lnk->wlvif;
+		if (lnk->wlvif)
+			lnk->wlvif->last_tx_hlid = low_prio_hlid;
+	}
+
+out:
+	if (!skb &&
+	    test_and_clear_bit(CC33XX_FLAG_DUMMY_PACKET_PENDING, &cc->flags)) {
+		int q;
+
+		skb = cc->dummy_packet;
+		*hlid = CC33XX_SYSTEM_HLID;
+		q = cc33xx_tx_get_queue(skb_get_queue_mapping(skb));
+		spin_lock_irqsave(&cc->cc_lock, flags);
+		WARN_ON_ONCE(cc->tx_queue_count[q] <= 0);
+		cc->tx_queue_count[q]--;
+		spin_unlock_irqrestore(&cc->cc_lock, flags);
+	}
+
+	return skb;
+}
+
+static void cc33xx_skb_queue_head(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				  struct sk_buff *skb, u8 hlid)
+{
+	unsigned long flags;
+	int q = cc33xx_tx_get_queue(skb_get_queue_mapping(skb));
+
+	if (cc33xx_is_dummy_packet(cc, skb)) {
+		set_bit(CC33XX_FLAG_DUMMY_PACKET_PENDING, &cc->flags);
+	} else {
+		skb_queue_head(&cc->links[hlid].tx_queue[q], skb);
+
+		/* make sure we dequeue the same packet next time */
+		wlvif->last_tx_hlid = (hlid + CC33XX_MAX_LINKS - 1) %
+				      CC33XX_MAX_LINKS;
+	}
+
+	spin_lock_irqsave(&cc->cc_lock, flags);
+	cc->tx_queue_count[q]++;
+	if (wlvif)
+		wlvif->tx_queue_count[q]++;
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+}
+
+static inline bool cc33xx_tx_is_data_present(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+
+	return ieee80211_is_data_present(hdr->frame_control);
+}
+
+/* Returns failure values only in case of failed bus ops within this function.
+ * cc33xx_prepare_tx_frame retvals won't be returned in order to avoid
+ * triggering recovery by higher layers when not necessary.
+ * In case a FW command fails within cc33xx_prepare_tx_frame fails a recovery
+ * will be queued in cc33xx_cmd_send. -EAGAIN/-EBUSY from prepare_tx_frame
+ * can occur and are legitimate so don't propagate. -EINVAL will emit a WARNING
+ * within prepare_tx_frame code but there's nothing we should do about those
+ * as well.
+ */
+int cc33xx_tx_work_locked(struct cc33xx *cc)
+{
+	struct cc33xx_vif *wlvif;
+	struct sk_buff *skb;
+	struct cc33xx_tx_hw_descr *desc;
+	u32 buf_offset = 0, last_len = 0;
+	u32 transfer_len = 0;
+	u32 padding_size = 0;
+	bool sent_packets = false;
+	unsigned long active_hlids[BITS_TO_LONGS(CC33XX_MAX_LINKS)] = {0};
+	int ret = 0;
+	int bus_ret = 0;
+	u8 hlid;
+
+	memset(cc->aggr_buf, 0, 0x300);
+	if (unlikely(cc->state != CC33XX_STATE_ON))
+		return 0;
+
+	while ((skb = cc33xx_skb_dequeue(cc, &hlid))) {
+		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+		bool has_data = false;
+
+		cc33xx_debug(DEBUG_TX, "skb dequeue skb: 0x%p data %#lx head %#lx tail %#lx end %#lx",
+			     skb,
+			     (unsigned long)skb->data, (unsigned long)skb->head,
+			     (unsigned long)skb->tail, (unsigned long)skb->end);
+		wlvif = NULL;
+		if (!cc33xx_is_dummy_packet(cc, skb))
+			wlvif = cc33xx_vif_to_data(info->control.vif);
+		else
+			hlid = CC33XX_SYSTEM_HLID;
+
+		has_data = wlvif && cc33xx_tx_is_data_present(skb);
+		ret = cc33xx_prepare_tx_frame(cc, wlvif, skb, buf_offset,
+					      hlid);
+
+		if (ret == -EAGAIN) {
+			/* Aggregation buffer is full.
+			 * Flush buffer and try again.
+			 */
+			cc33xx_skb_queue_head(cc, wlvif, skb, hlid);
+
+			transfer_len = __ALIGN_MASK(buf_offset,
+						    CC33XX_BUS_BLOCK_SIZE * 2 - 1);
+
+			padding_size = transfer_len - buf_offset;
+			memset(cc->aggr_buf + buf_offset, 0x33, padding_size);
+
+			cc33xx_debug(DEBUG_TX, "sdio transaction length: %d ",
+				     transfer_len);
+
+			bus_ret = cc33xx_write(cc, NAB_DATA_ADDR, cc->aggr_buf,
+					       transfer_len, true);
+			if (bus_ret < 0)
+				goto out;
+
+			sent_packets = true;
+			buf_offset = 0;
+			continue;
+		} else if (ret == -EBUSY) {
+			/* Firmware buffer is full.
+			 * Queue back last skb, and stop aggregating.
+			 */
+			cc33xx_skb_queue_head(cc, wlvif, skb, hlid);
+			/* No work left, avoid scheduling redundant tx work */
+			set_bit(CC33XX_FLAG_FW_TX_BUSY, &cc->flags);
+			goto out_ack;
+		} else if (ret < 0) {
+			if (cc33xx_is_dummy_packet(cc, skb))
+				/* fw still expects dummy packet,
+				 * so re-enqueue it
+				 */
+				cc33xx_skb_queue_head(cc, wlvif, skb, hlid);
+			else
+				ieee80211_free_txskb(cc->hw, skb);
+			goto out_ack;
+		}
+
+		last_len = ret;
+		buf_offset += last_len;
+
+		if (has_data) {
+			desc = (struct cc33xx_tx_hw_descr *)skb->data;
+			__set_bit(desc->hlid, active_hlids);
+		}
+	}
+
+out_ack:
+	if (buf_offset) {
+		transfer_len = __ALIGN_MASK(buf_offset,
+					    CC33XX_BUS_BLOCK_SIZE * 2 - 1);
+
+		padding_size = transfer_len - buf_offset;
+		memset(cc->aggr_buf + buf_offset, 0x33, padding_size);
+
+		cc33xx_debug(DEBUG_TX, "sdio transaction (926) length: %d ",
+			     transfer_len);
+
+		bus_ret = cc33xx_write(cc, NAB_DATA_ADDR, cc->aggr_buf,
+				       transfer_len, true);
+		if (bus_ret < 0)
+			goto out;
+
+		sent_packets = true;
+	}
+
+	if (sent_packets)
+		cc33xx_handle_tx_low_watermark(cc);
+
+out:
+	return bus_ret;
+}
+
+void cc33xx_tx_work(struct work_struct *work)
+{
+	struct cc33xx *cc = container_of(work, struct cc33xx, tx_work);
+	int ret;
+
+	mutex_lock(&cc->mutex);
+
+	ret = cc33xx_tx_work_locked(cc);
+	if (ret < 0) {
+		cc33xx_queue_recovery_work(cc);
+		goto out;
+	}
+
+out:
+	mutex_unlock(&cc->mutex);
+}
+
+void cc33xx_tx_reset_link_queues(struct cc33xx *cc, u8 hlid)
+{
+	struct sk_buff *skb;
+	int i;
+	unsigned long flags;
+	struct ieee80211_tx_info *info;
+	int total[NUM_TX_QUEUES];
+	struct cc33xx_link *lnk = &cc->links[hlid];
+
+	for (i = 0; i < NUM_TX_QUEUES; i++) {
+		total[i] = 0;
+		while ((skb = skb_dequeue(&lnk->tx_queue[i]))) {
+			cc33xx_debug(DEBUG_TX, "link freeing skb 0x%p", skb);
+
+			if (!cc33xx_is_dummy_packet(cc, skb)) {
+				info = IEEE80211_SKB_CB(skb);
+				info->status.rates[0].idx = -1;
+				info->status.rates[0].count = 0;
+				ieee80211_tx_status_ni(cc->hw, skb);
+			}
+
+			total[i]++;
+		}
+	}
+
+	spin_lock_irqsave(&cc->cc_lock, flags);
+	for (i = 0; i < NUM_TX_QUEUES; i++) {
+		cc->tx_queue_count[i] -= total[i];
+		if (lnk->wlvif)
+			lnk->wlvif->tx_queue_count[i] -= total[i];
+	}
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+
+	cc33xx_handle_tx_low_watermark(cc);
+}
+
+/* caller must hold cc->mutex and TX must be stopped */
+void cc33xx_tx_reset_wlvif(struct cc33xx *cc, struct cc33xx_vif *wlvif)
+{
+	int i;
+
+	/* TX failure */
+	for_each_set_bit(i, wlvif->links_map, CC33XX_MAX_LINKS) {
+		if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
+		    i != wlvif->ap.bcast_hlid &&
+		    i != wlvif->ap.global_hlid) {
+			/* this calls cc33xx_clear_link */
+			cc33xx_free_sta(cc, wlvif, i);
+		} else {
+			u8 hlid = i;
+
+			cc33xx_clear_link(cc, wlvif, &hlid);
+		}
+	}
+
+	wlvif->last_tx_hlid = 0;
+
+	for (i = 0; i < NUM_TX_QUEUES; i++)
+		wlvif->tx_queue_count[i] = 0;
+}
+
+int cc33xx_tx_total_queue_count(struct cc33xx *cc)
+{
+	int i, count = 0;
+
+	for (i = 0; i < NUM_TX_QUEUES; i++)
+		count += cc->tx_queue_count[i];
+
+	return count;
+}
+
+/* caller must hold cc->mutex and TX must be stopped */
+void cc33xx_tx_reset(struct cc33xx *cc)
+{
+	int i;
+	struct sk_buff *skb;
+	struct ieee80211_tx_info *info;
+
+	/* only reset the queues if something bad happened */
+	if (cc33xx_tx_total_queue_count(cc) != 0) {
+		for (i = 0; i < CC33XX_MAX_LINKS; i++)
+			cc33xx_tx_reset_link_queues(cc, i);
+
+		for (i = 0; i < NUM_TX_QUEUES; i++)
+			cc->tx_queue_count[i] = 0;
+	}
+
+	/* Make sure the driver is at a consistent state, in case this
+	 * function is called from a context other than interface removal.
+	 * This call will always wake the TX queues.
+	 */
+	cc33xx_handle_tx_low_watermark(cc);
+
+	for (i = 0; i < CC33XX_NUM_TX_DESCRIPTORS; i++) {
+		if (!cc->tx_frames[i])
+			continue;
+
+		skb = cc->tx_frames[i];
+		cc33xx_free_tx_id(cc, i);
+		cc33xx_debug(DEBUG_TX, "freeing skb 0x%p", skb);
+
+		if (!cc33xx_is_dummy_packet(cc, skb)) {
+			/* Remove private headers before passing the skb to
+			 * mac80211
+			 */
+			info = IEEE80211_SKB_CB(skb);
+			skb_pull(skb, sizeof(struct cc33xx_tx_hw_descr));
+			if ((cc->quirks & CC33XX_QUIRK_TKIP_HEADER_SPACE) &&
+			    info->control.hw_key &&
+			    info->control.hw_key->cipher ==
+			    WLAN_CIPHER_SUITE_TKIP) {
+				int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+
+				memmove(skb->data + CC33XX_EXTRA_SPACE_TKIP,
+					skb->data, hdrlen);
+				skb_pull(skb, CC33XX_EXTRA_SPACE_TKIP);
+			}
+
+			info->status.rates[0].idx = -1;
+			info->status.rates[0].count = 0;
+
+			ieee80211_tx_status_ni(cc->hw, skb);
+		}
+	}
+}
+
+#define CC33XX_TX_FLUSH_TIMEOUT 500000
+
+/* caller must *NOT* hold cc->mutex */
+void cc33xx_tx_flush(struct cc33xx *cc)
+{
+	unsigned long timeout, start_time;
+	int i;
+
+	start_time = jiffies;
+	timeout = start_time + usecs_to_jiffies(CC33XX_TX_FLUSH_TIMEOUT);
+
+	/* only one flush should be in progress, for consistent queue state */
+	mutex_lock(&cc->flush_mutex);
+
+	mutex_lock(&cc->mutex);
+	if (cc->tx_frames_cnt == 0 && cc33xx_tx_total_queue_count(cc) == 0) {
+		mutex_unlock(&cc->mutex);
+		goto out;
+	}
+
+	cc33xx_stop_queues(cc, CC33XX_QUEUE_STOP_REASON_FLUSH);
+
+	while (!time_after(jiffies, timeout)) {
+		cc33xx_debug(DEBUG_MAC80211, "flushing tx buffer: %d %d",
+			     cc->tx_frames_cnt,
+			     cc33xx_tx_total_queue_count(cc));
+
+		/* force Tx and give the driver some time to flush data */
+		mutex_unlock(&cc->mutex);
+		if (cc33xx_tx_total_queue_count(cc))
+			cc33xx_tx_work(&cc->tx_work);
+		msleep(20);
+		mutex_lock(&cc->mutex);
+
+		if (cc->tx_frames_cnt == 0 && cc33xx_tx_total_queue_count(cc) == 0) {
+			cc33xx_debug(DEBUG_MAC80211, "tx flush took %d ms",
+				     jiffies_to_msecs(jiffies - start_time));
+			goto out_wake;
+		}
+	}
+
+	cc33xx_warning("Unable to flush all TX buffers, timed out (timeout %d ms",
+		       CC33XX_TX_FLUSH_TIMEOUT / 1000);
+
+	/* forcibly flush all Tx buffers on our queues */
+	for (i = 0; i < CC33XX_MAX_LINKS; i++)
+		cc33xx_tx_reset_link_queues(cc, i);
+
+out_wake:
+	cc33xx_wake_queues(cc, CC33XX_QUEUE_STOP_REASON_FLUSH);
+	mutex_unlock(&cc->mutex);
+out:
+	mutex_unlock(&cc->flush_mutex);
+}
+
+u32 cc33xx_tx_min_rate_get(struct cc33xx *cc, u32 rate_set)
+{
+	if (WARN_ON(!rate_set))
+		return 0;
+
+	return BIT(__ffs(rate_set));
+}
+
+void cc33xx_stop_queue_locked(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			      u8 queue, enum cc33xx_queue_stop_reason reason)
+{
+	int hwq = cc33xx_tx_get_mac80211_queue(wlvif, queue);
+	bool stopped = !!cc->queue_stop_reasons[hwq];
+
+	/* queue should not be stopped for this reason */
+	WARN_ON_ONCE(test_and_set_bit(reason, &cc->queue_stop_reasons[hwq]));
+
+	if (stopped)
+		return;
+
+	ieee80211_stop_queue(cc->hw, hwq);
+}
+
+void cc33xx_stop_queues(struct cc33xx *cc,
+			enum cc33xx_queue_stop_reason reason)
+{
+	int i;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cc->cc_lock, flags);
+
+	/* mark all possible queues as stopped */
+	for (i = 0; i < CC33XX_NUM_MAC_ADDRESSES * NUM_TX_QUEUES; i++) {
+		WARN_ON_ONCE(test_and_set_bit(reason,
+					      &cc->queue_stop_reasons[i]));
+	}
+
+	/* use the global version to make sure all vifs in mac80211 we don't
+	 * know are stopped.
+	 */
+	ieee80211_stop_queues(cc->hw);
+
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+}
+
+void cc33xx_wake_queues(struct cc33xx *cc,
+			enum cc33xx_queue_stop_reason reason)
+{
+	int i;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cc->cc_lock, flags);
+
+	/* mark all possible queues as awake */
+	for (i = 0; i < CC33XX_NUM_MAC_ADDRESSES * NUM_TX_QUEUES; i++) {
+		WARN_ON_ONCE(!test_and_clear_bit(reason,
+						 &cc->queue_stop_reasons[i]));
+	}
+
+	/* use the global version to make sure all vifs in mac80211 we don't
+	 * know are woken up.
+	 */
+	ieee80211_wake_queues(cc->hw);
+
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+}
+
+bool cc33xx_is_queue_stopped_by_reason(struct cc33xx *cc,
+				       struct cc33xx_vif *wlvif, u8 queue,
+				       enum cc33xx_queue_stop_reason reason)
+{
+	unsigned long flags;
+	bool stopped;
+
+	spin_lock_irqsave(&cc->cc_lock, flags);
+	stopped = cc33xx_is_queue_stopped_by_reason_locked(cc, wlvif, queue,
+							   reason);
+	spin_unlock_irqrestore(&cc->cc_lock, flags);
+
+	return stopped;
+}
+
+bool cc33xx_is_queue_stopped_by_reason_locked(struct cc33xx *cc,
+					      struct cc33xx_vif *wlvif, u8 queue,
+				       enum cc33xx_queue_stop_reason reason)
+{
+	int hwq = cc33xx_tx_get_mac80211_queue(wlvif, queue);
+
+	assert_spin_locked(&cc->cc_lock);
+	return test_bit(reason, &cc->queue_stop_reasons[hwq]);
+}
+
+bool cc33xx_is_queue_stopped_locked(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				    u8 queue)
+{
+	int hwq = cc33xx_tx_get_mac80211_queue(wlvif, queue);
+
+	assert_spin_locked(&cc->cc_lock);
+	return !!cc->queue_stop_reasons[hwq];
+}
+
+static void cc33xx_tx_complete_packet(struct cc33xx *cc, u8 tx_stat_byte,
+				      struct core_fw_status *core_fw_status)
+{
+	struct ieee80211_tx_info *info;
+	struct sk_buff *skb;
+	int id = tx_stat_byte & CC33XX_TX_STATUS_DESC_ID_MASK;
+	bool tx_success;
+	struct cc33xx_tx_hw_descr *tx_desc;
+	u16 desc_session_idx;
+
+	/* check for id legality */
+	if (unlikely(id >= CC33XX_NUM_TX_DESCRIPTORS ||
+		     !cc->tx_frames[id])) {
+		cc33xx_warning("illegal id in tx completion: %d", id);
+
+		print_hex_dump(KERN_DEBUG, "fw_info local:",
+			       DUMP_PREFIX_OFFSET, 16, 4, (u8 *)(core_fw_status),
+			       sizeof(struct core_fw_status), false);
+
+		cc33xx_queue_recovery_work(cc);
+		return;
+	}
+
+	/* a zero bit indicates Tx success */
+	tx_success = !(tx_stat_byte & BIT(CC33XX_TX_STATUS_STAT_BIT_IDX));
+
+	skb = cc->tx_frames[id];
+	info = IEEE80211_SKB_CB(skb);
+	tx_desc = (struct cc33xx_tx_hw_descr *)skb->data;
+
+	if (cc33xx_is_dummy_packet(cc, skb)) {
+		cc33xx_free_tx_id(cc, id);
+		return;
+	}
+
+	/* update the TX status info */
+	if (tx_success && !(info->flags & IEEE80211_TX_CTL_NO_ACK))
+		info->flags |= IEEE80211_TX_STAT_ACK;
+
+	info->status.rates[0].count = 1; /* no data about retries */
+	info->status.ack_signal = -1;
+
+	if (!tx_success)
+		cc->stats.retry_count++;
+
+	/* remove private header from packet */
+	skb_pull(skb, sizeof(struct cc33xx_tx_hw_descr));
+
+	/* remove TKIP header space if present */
+	if ((cc->quirks & CC33XX_QUIRK_TKIP_HEADER_SPACE) &&
+	    info->control.hw_key &&
+	    info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
+		int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+
+		memmove(skb->data + CC33XX_EXTRA_SPACE_TKIP, skb->data, hdrlen);
+		skb_pull(skb, CC33XX_EXTRA_SPACE_TKIP);
+	}
+
+	cc33xx_debug(DEBUG_TX,
+		     "tx status id %u skb 0x%p success %d, tx_memblocks %d",
+		     id, skb, tx_success, tx_desc->cc33xx_mem.total_mem_blocks);
+
+	/**
+	 * in order to update the memory management
+	 * we should have total_blocks, ac, and hlid
+	 */
+	cc->tx_blocks_available += tx_desc->cc33xx_mem.total_mem_blocks;
+	cc->tx_allocated_blocks -= tx_desc->cc33xx_mem.total_mem_blocks;
+	/* per queue */
+
+	/* prevent wrap-around in freed-packets counter */
+	cc->tx_allocated_pkts[tx_desc->ac]--;
+
+	/* per link */
+	desc_session_idx = (le16_to_cpu(tx_desc->tx_attr) & TX_HW_ATTR_SESSION_COUNTER) >>
+					TX_HW_ATTR_OFST_SESSION_COUNTER;
+
+	if (cc->session_ids[tx_desc->hlid] == desc_session_idx)
+		cc->links[tx_desc->hlid].allocated_pkts--;
+
+	cc33xx_free_tx_id(cc, id);
+
+	/* new mem blocks are available now */
+	clear_bit(CC33XX_FLAG_FW_TX_BUSY, &cc->flags);
+
+	/* return the packet to the stack */
+	skb_queue_tail(&cc->deferred_tx_queue, skb);
+	queue_work(cc->freezable_wq, &cc->netstack_work);
+}
+
+void cc33xx_tx_immediate_complete(struct cc33xx *cc)
+{
+	u8 tx_result_queue_index;
+	struct core_fw_status core_fw_status;
+	u8 i;
+
+	claim_core_status_lock(cc);
+	memcpy(&core_fw_status, &cc->core_status->fw_info,
+	       sizeof(struct core_fw_status));
+
+	tx_result_queue_index = cc->core_status->fw_info.tx_result_queue_index;
+	/* Lock guarantees we shadow tx_result_queue_index NOT during
+	 * an active transaction. Subsequent references to fw_info can be done
+	 * without locking as long we do not pass this index.
+	 */
+	release_core_status_lock(cc);
+
+	cc33xx_debug(DEBUG_TX, "last released desc = %d, current idx = %d",
+		     cc->last_fw_rls_idx, tx_result_queue_index);
+
+	/* nothing to do here */
+	if (cc->last_fw_rls_idx == tx_result_queue_index)
+		return;
+
+	/* freed Tx descriptors */
+
+	if (tx_result_queue_index >= TX_RESULT_QUEUE_SIZE) {
+		cc33xx_error("invalid desc release index %d",
+			     tx_result_queue_index);
+		WARN_ON(1);
+		return;
+	}
+
+	cc33xx_debug(DEBUG_TX, "TX result queue! priv last fw idx %d, current resut index %d ",
+		     cc->last_fw_rls_idx, tx_result_queue_index);
+
+	for (i = cc->last_fw_rls_idx; i != tx_result_queue_index;
+	     i = (i + 1) % TX_RESULT_QUEUE_SIZE) {
+		cc33xx_tx_complete_packet(cc, core_fw_status.tx_result_queue[i],
+					  &core_fw_status);
+	}
+
+	cc->last_fw_rls_idx = tx_result_queue_index;
+}
diff -Naur --no-dereference a/drivers/net/wireless/ti/cc33xx/tx.h b/drivers/net/wireless/ti/cc33xx/tx.h
--- a/drivers/net/wireless/ti/cc33xx/tx.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/ti/cc33xx/tx.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#ifndef __TX_H__
+#define __TX_H__
+
+#define CC33XX_TX_HW_BLOCK_SPARE        1
+/* for special cases - namely, TKIP and GEM */
+#define CC33XX_TX_HW_EXTRA_BLOCK_SPARE  2
+#define CC33XX_TX_HW_BLOCK_SIZE         256
+
+#define CC33XX_TX_STATUS_DESC_ID_MASK    0x7F
+#define CC33XX_TX_STATUS_STAT_BIT_IDX    7
+
+/* Indicates this TX HW frame is not padded to SDIO block size */
+#define CC33XX_TX_CTRL_NOT_PADDED	BIT(7)
+
+#define TX_HW_MGMT_PKT_LIFETIME_TU       2000
+#define TX_HW_AP_MODE_PKT_LIFETIME_TU    8000
+
+#define TX_HW_ATTR_SESSION_COUNTER       (BIT(2) | BIT(3) | BIT(4))
+#define TX_HW_ATTR_TX_DUMMY_REQ          BIT(13)
+#define TX_HW_ATTR_HOST_ENCRYPT          BIT(14)
+#define TX_HW_ATTR_EAPOL_FRAME           BIT(15)
+
+#define TX_HW_ATTR_OFST_SESSION_COUNTER  2
+#define TX_HW_ATTR_OFST_RATE_POLICY      5
+
+#define CC33XX_TX_ALIGN_TO 4
+#define CC33XX_EXTRA_SPACE_TKIP 4
+#define CC33XX_EXTRA_SPACE_AES  8
+#define CC33XX_EXTRA_SPACE_MAX  8
+
+#define CC33XX_TX_EXTRA_HEADROOM	\
+		(sizeof(struct cc33xx_tx_hw_descr) + IEEE80211_HT_CTL_LEN)
+
+/* Used for management frames and dummy packets */
+#define CC33XX_TID_MGMT 7
+
+/* stop a ROC for pending authentication reply after this time (ms) */
+#define CC33XX_PEND_AUTH_ROC_TIMEOUT     1000
+#define CC33xx_PEND_ROC_COMPLETE_TIMEOUT 2000
+
+struct cc33xx_tx_mem {
+	/* Total number of memory blocks allocated by the host for
+	 * this packet.
+	 */
+	u8 total_mem_blocks;
+
+	/* control bits
+	 */
+	u8 ctrl;
+} __packed;
+
+/* On cc33xx based devices, when TX packets are aggregated, each packet
+ * size must be aligned to the SDIO block size. The maximum block size
+ * is bounded by the type of the padded bytes field that is sent to the
+ * FW. The HW maximum block size is 256 bytes. We use 128 to utilize the
+ * SDIO built-in busy signal when the FIFO is full.
+ */
+#define CC33XX_BUS_BLOCK_SIZE 128
+
+struct cc33xx_tx_hw_descr {
+	/* Length of packet in words, including descriptor+header+data */
+	__le16 length;
+
+	struct cc33xx_tx_mem cc33xx_mem;
+
+	/* Packet identifier used also in the Tx-Result. */
+	u8 id;
+	/* The packet TID value (as User-Priority) */
+	u8 tid;
+	/* host link ID (HLID) */
+	u8 hlid;
+	u8 ac;
+	/* Max delay in TUs until transmission. The last device time the
+	 * packet can be transmitted is: start_time + (1024 * life_time)
+	 */
+	__le16 life_time;
+	/* Bitwise fields - see TX_ATTR... definitions above. */
+	__le16 tx_attr;
+} __packed;
+
+struct cc33xx_tx_hw_res_descr {
+	/* Packet Identifier - same value used in the Tx descriptor.*/
+	u8 id;
+	/* The status of the transmission, indicating success or one of
+	 * several possible reasons for failure.
+	 */
+	u8 status;
+	/* Total air access duration including all retrys and overheads.*/
+	__le16 medium_usage;
+	/* The time passed from host xfer to Tx-complete.*/
+	__le32 fw_handling_time;
+	/* Total media delay
+	 * (from 1st EDCA AIFS counter until TX Complete).
+	 */
+	__le32 medium_delay;
+	/* LS-byte of last TKIP seq-num (saved per AC for recovery). */
+	u8 tx_security_sequence_number_lsb;
+	/* Retry count - number of transmissions without successful ACK.*/
+	u8 ack_failures;
+	/* The rate that succeeded getting ACK
+	 * (Valid only if status=SUCCESS).
+	 */
+	u8 rate_class_index;
+	/* for 4-byte alignment. */
+	u8 spare;
+} __packed;
+
+enum cc33xx_queue_stop_reason {
+	CC33XX_QUEUE_STOP_REASON_WATERMARK,
+	CC33XX_QUEUE_STOP_REASON_FW_RESTART,
+	CC33XX_QUEUE_STOP_REASON_FLUSH,
+	CC33XX_QUEUE_STOP_REASON_SPARE_BLK, /* 18xx specific */
+};
+
+int cc33xx_tx_get_queue(int queue);
+int cc33xx_tx_total_queue_count(struct cc33xx *cc);
+void cc33xx_tx_immediate_complete(struct cc33xx *cc);
+void cc33xx_tx_work(struct work_struct *work);
+int cc33xx_tx_work_locked(struct cc33xx *cc);
+void cc33xx_tx_reset_wlvif(struct cc33xx *cc, struct cc33xx_vif *wlvif);
+void cc33xx_tx_reset(struct cc33xx *cc);
+void cc33xx_tx_flush(struct cc33xx *cc);
+u8 cc33xx_rate_to_idx(struct cc33xx *cc, u8 rate, enum nl80211_band band);
+u32 cc33xx_tx_enabled_rates_get(struct cc33xx *cc, u32 rate_set,
+				enum nl80211_band rate_band);
+u32 cc33xx_tx_min_rate_get(struct cc33xx *cc, u32 rate_set);
+u8 cc33xx_tx_get_hlid(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+		      struct sk_buff *skb, struct ieee80211_sta *sta);
+void cc33xx_tx_reset_link_queues(struct cc33xx *cc, u8 hlid);
+void cc33xx_handle_tx_low_watermark(struct cc33xx *cc);
+bool cc33xx_is_dummy_packet(struct cc33xx *cc, struct sk_buff *skb);
+unsigned int cc33xx_calc_packet_alignment(struct cc33xx *cc,
+					  unsigned int packet_length);
+void cc33xx_free_tx_id(struct cc33xx *cc, int id);
+void cc33xx_stop_queue_locked(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+			      u8 queue, enum cc33xx_queue_stop_reason reason);
+void cc33xx_stop_queues(struct cc33xx *cc,
+			enum cc33xx_queue_stop_reason reason);
+void cc33xx_wake_queues(struct cc33xx *cc,
+			enum cc33xx_queue_stop_reason reason);
+bool cc33xx_is_queue_stopped_by_reason(struct cc33xx *cc,
+				       struct cc33xx_vif *wlvif, u8 queue,
+				       enum cc33xx_queue_stop_reason reason);
+bool cc33xx_is_queue_stopped_by_reason_locked(struct cc33xx *cc,
+					      struct cc33xx_vif *wlvif,
+					      u8 queue,
+					 enum cc33xx_queue_stop_reason reason);
+bool cc33xx_is_queue_stopped_locked(struct cc33xx *cc, struct cc33xx_vif *wlvif,
+				    u8 queue);
+
+/* from main.c */
+void cc33xx_free_sta(struct cc33xx *cc, struct cc33xx_vif *wlvif, u8 hlid);
+void cc33xx_rearm_tx_watchdog_locked(struct cc33xx *cc);
+
+#endif /* __TX_H__ */
diff -Naur --no-dereference a/drivers/net/wireless/ti/Kconfig b/drivers/net/wireless/ti/Kconfig
--- a/drivers/net/wireless/ti/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/wireless/ti/Kconfig	2025-10-23 09:30:40.286462238 -0400
@@ -14,6 +14,7 @@
 source "drivers/net/wireless/ti/wl1251/Kconfig"
 source "drivers/net/wireless/ti/wl12xx/Kconfig"
 source "drivers/net/wireless/ti/wl18xx/Kconfig"
+source "drivers/net/wireless/ti/cc33xx/Kconfig"
 
 # keep last for automatic dependencies
 source "drivers/net/wireless/ti/wlcore/Kconfig"
diff -Naur --no-dereference a/drivers/net/wireless/ti/Makefile b/drivers/net/wireless/ti/Makefile
--- a/drivers/net/wireless/ti/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/net/wireless/ti/Makefile	2025-10-23 09:30:40.286462238 -0400
@@ -3,3 +3,4 @@
 obj-$(CONFIG_WL12XX)			+= wl12xx/
 obj-$(CONFIG_WL1251)			+= wl1251/
 obj-$(CONFIG_WL18XX)			+= wl18xx/
+obj-$(CONFIG_CC33XX)			+= cc33xx/
diff -Naur --no-dereference a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
--- a/drivers/pci/controller/cadence/pci-j721e.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/pci/controller/cadence/pci-j721e.c	2025-10-23 09:30:40.286462238 -0400
@@ -387,6 +387,13 @@
 	.max_lanes = 4,
 };
 
+static const struct j721e_pcie_data j722s_pcie_rc_data = {
+	.mode = PCI_MODE_RC,
+	.linkdown_irq_regfield = J7200_LINK_DOWN,
+	.byte_access_allowed = true,
+	.max_lanes = 1,
+};
+
 static const struct of_device_id of_j721e_pcie_match[] = {
 	{
 		.compatible = "ti,j721e-pcie-host",
@@ -420,6 +427,10 @@
 		.compatible = "ti,j784s4-pcie-ep",
 		.data = &j784s4_pcie_ep_data,
 	},
+	{
+		.compatible = "ti,j722s-pcie-host",
+		.data = &j722s_pcie_rc_data,
+	},
 	{},
 };
 
diff -Naur --no-dereference a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
--- a/drivers/phy/cadence/cdns-dphy.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/phy/cadence/cdns-dphy.c	2025-10-23 09:30:40.286462238 -0400
@@ -55,14 +55,6 @@
 #define DPHY_PSM_CFG_FROM_REG		BIT(0)
 #define DPHY_PSM_CLK_DIV(x)		((x) << 1)
 
-#define DSI_HBP_FRAME_OVERHEAD		12
-#define DSI_HSA_FRAME_OVERHEAD		14
-#define DSI_HFP_FRAME_OVERHEAD		6
-#define DSI_HSS_VSS_VSE_FRAME_OVERHEAD	4
-#define DSI_BLANKING_FRAME_OVERHEAD	6
-#define DSI_NULL_FRAME_OVERHEAD		6
-#define DSI_EOT_PKT_SIZE		4
-
 #define DPHY_TX_J721E_WIZ_PLL_CTRL	0xF04
 #define DPHY_TX_J721E_WIZ_STATUS	0xF08
 #define DPHY_TX_J721E_WIZ_RST_CTRL	0xF0C
@@ -79,6 +71,7 @@
 	u8 pll_ipdiv;
 	u8 pll_opdiv;
 	u16 pll_fbdiv;
+	u32 hs_clk_rate;
 	unsigned int nlanes;
 };
 
@@ -98,6 +91,8 @@
 				 enum cdns_dphy_clk_lane_cfg cfg);
 	void (*set_pll_cfg)(struct cdns_dphy *dphy,
 			    const struct cdns_dphy_cfg *cfg);
+	void (*wait_for_pll_lock)(struct cdns_dphy *dphy);
+	void (*wait_for_cmn_ready)(struct cdns_dphy *dphy);
 	unsigned long (*get_wakeup_time_ns)(struct cdns_dphy *dphy);
 };
 
@@ -116,10 +111,9 @@
 	870, 950, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2500
 };
 
-static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
-				     struct cdns_dphy_cfg *cfg,
-				     struct phy_configure_opts_mipi_dphy *opts,
-				     unsigned int *dsi_hfp_ext)
+static int cdns_dphy_get_pll_cfg(struct cdns_dphy *dphy,
+				 struct cdns_dphy_cfg *cfg,
+				 struct phy_configure_opts_mipi_dphy *opts)
 {
 	unsigned long pll_ref_hz = clk_get_rate(dphy->pll_ref_clk);
 	u64 dlane_bps;
@@ -154,6 +148,9 @@
 					  cfg->pll_ipdiv,
 					  pll_ref_hz);
 
+	cfg->hs_clk_rate = div_u64((u64)pll_ref_hz * cfg->pll_fbdiv,
+				   2 * cfg->pll_opdiv * cfg->pll_ipdiv);
+
 	return 0;
 }
 
@@ -191,6 +188,18 @@
 	return dphy->ops->get_wakeup_time_ns(dphy);
 }
 
+static void cdns_dphy_wait_for_pll_lock(struct cdns_dphy *dphy)
+{
+	if (dphy->ops->wait_for_pll_lock)
+		dphy->ops->wait_for_pll_lock(dphy);
+}
+
+static void cdns_dphy_wait_for_cmn_ready(struct cdns_dphy *dphy)
+{
+	if (dphy->ops->wait_for_cmn_ready)
+		dphy->ops->wait_for_cmn_ready(dphy);
+}
+
 static unsigned long cdns_dphy_ref_get_wakeup_time_ns(struct cdns_dphy *dphy)
 {
 	/* Default wakeup time is 800 ns (in a simulated environment). */
@@ -212,7 +221,7 @@
 	writel(DPHY_CMN_FBDIV_FROM_REG |
 	       DPHY_CMN_FBDIV_VAL(fbdiv_low, fbdiv_high),
 	       dphy->regs + DPHY_CMN_FBDIV);
-	writel(DPHY_CMN_PWM_HIGH(6) | DPHY_CMN_PWM_LOW(0x101) |
+	writel(readl(dphy->regs + DPHY_CMN_PWM) | DPHY_CMN_PWM_HIGH(6) | DPHY_CMN_PWM_LOW(0x101) |
 	       DPHY_CMN_PWM_DIV(0x8),
 	       dphy->regs + DPHY_CMN_PWM);
 }
@@ -232,13 +241,11 @@
 static void cdns_dphy_j721e_set_pll_cfg(struct cdns_dphy *dphy,
 					const struct cdns_dphy_cfg *cfg)
 {
-	u32 status;
-
 	/*
 	 * set the PWM and PLL Byteclk divider settings to recommended values
 	 * which is same as that of in ref ops
 	 */
-	writel(DPHY_CMN_PWM_HIGH(6) | DPHY_CMN_PWM_LOW(0x101) |
+	writel(readl(dphy->regs + DPHY_CMN_PWM) | DPHY_CMN_PWM_HIGH(6) | DPHY_CMN_PWM_LOW(0x101) |
 	       DPHY_CMN_PWM_DIV(0x8),
 	       dphy->regs + DPHY_CMN_PWM);
 
@@ -249,13 +256,25 @@
 
 	writel(DPHY_TX_J721E_WIZ_LANE_RSTB,
 	       dphy->regs + DPHY_TX_J721E_WIZ_RST_CTRL);
+}
 
-	readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_PLL_CTRL, status,
-			   (status & DPHY_TX_WIZ_PLL_LOCK), 0, POLL_TIMEOUT_US);
+static void cdns_dphy_j721e_wait_for_pll_lock(struct cdns_dphy *dphy)
+{
+	u32 status;
 
-	readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_STATUS, status,
-			   (status & DPHY_TX_WIZ_O_CMN_READY), 0,
-			   POLL_TIMEOUT_US);
+	if (readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_PLL_CTRL, status,
+			       status & DPHY_TX_WIZ_PLL_LOCK, 0, POLL_TIMEOUT_US))
+		dev_err(&dphy->phy->dev, "Timed out waiting for DPHY PLL lock assertion\n");
+}
+
+static void cdns_dphy_j721e_wait_for_cmn_ready(struct cdns_dphy *dphy)
+{
+	u32 status;
+
+	if (readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_STATUS, status,
+			       status & DPHY_TX_WIZ_O_CMN_READY, 0,
+			       POLL_TIMEOUT_US))
+		dev_err(&dphy->phy->dev, "Timed out waiting for o_cmn_ready assertion\n");
 }
 
 static void cdns_dphy_j721e_set_psm_div(struct cdns_dphy *dphy, u8 div)
@@ -278,6 +297,8 @@
 	.get_wakeup_time_ns = cdns_dphy_j721e_get_wakeup_time_ns,
 	.set_pll_cfg = cdns_dphy_j721e_set_pll_cfg,
 	.set_psm_div = cdns_dphy_j721e_set_psm_div,
+	.wait_for_pll_lock = cdns_dphy_j721e_wait_for_pll_lock,
+	.wait_for_cmn_ready = cdns_dphy_j721e_wait_for_cmn_ready,
 };
 
 static int cdns_dphy_config_from_opts(struct phy *phy,
@@ -285,18 +306,17 @@
 				      struct cdns_dphy_cfg *cfg)
 {
 	struct cdns_dphy *dphy = phy_get_drvdata(phy);
-	unsigned int dsi_hfp_ext = 0;
 	int ret;
 
 	ret = phy_mipi_dphy_config_validate(opts);
 	if (ret)
 		return ret;
 
-	ret = cdns_dsi_get_dphy_pll_cfg(dphy, cfg,
-					opts, &dsi_hfp_ext);
+	ret = cdns_dphy_get_pll_cfg(dphy, cfg, opts);
 	if (ret)
 		return ret;
 
+	opts->hs_clk_rate = cfg->hs_clk_rate;
 	opts->wakeup = cdns_dphy_get_wakeup_time_ns(dphy) / 1000;
 
 	return 0;
@@ -384,9 +404,12 @@
 	clk_prepare_enable(dphy->pll_ref_clk);
 
 	/* Start TX state machine. */
-	writel(DPHY_CMN_SSM_EN | DPHY_CMN_TX_MODE_EN,
+	writel(readl(dphy->regs + DPHY_CMN_SSM) | DPHY_CMN_SSM_EN | DPHY_CMN_TX_MODE_EN,
 	       dphy->regs + DPHY_CMN_SSM);
 
+	cdns_dphy_wait_for_pll_lock(dphy);
+	cdns_dphy_wait_for_cmn_ready(dphy);
+
 	return 0;
 }
 
diff -Naur --no-dereference a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
--- a/drivers/phy/cadence/phy-cadence-torrent.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/phy/cadence/phy-cadence-torrent.c	2025-10-23 09:30:40.286462238 -0400
@@ -197,6 +197,7 @@
 #define RX_SDCAL1_INIT_TMR		0x004CU
 #define RX_SDCAL1_ITER_TMR		0x004DU
 #define RX_CDRLF_CNFG			0x0080U
+#define RX_CDRLF_CNFG2			0x0081U
 #define RX_CDRLF_CNFG3			0x0082U
 #define RX_SIGDET_HL_FILT_TMR		0x0090U
 #define RX_REE_GCSM1_CTRL		0x0108U
@@ -204,6 +205,8 @@
 #define RX_REE_GCSM1_EQENM_PH2		0x010AU
 #define RX_REE_GCSM2_CTRL		0x0110U
 #define RX_REE_PERGCSM_CTRL		0x0118U
+#define RX_REE_PEAK_UTHR		0x0142U
+#define RX_REE_PEAK_LTHR		0x0143U
 #define RX_REE_ATTEN_THR		0x0149U
 #define RX_REE_TAP1_CLIP		0x0171U
 #define RX_REE_TAP2TON_CLIP		0x0172U
@@ -212,6 +215,7 @@
 #define RX_DIAG_DFE_CTRL		0x01E0U
 #define RX_DIAG_DFE_AMP_TUNE_2		0x01E2U
 #define RX_DIAG_DFE_AMP_TUNE_3		0x01E3U
+#define RX_DIAG_REE_DAC_CTRL		0x01E4U
 #define RX_DIAG_NQST_CTRL		0x01E5U
 #define RX_DIAG_SIGDET_TUNE		0x01E8U
 #define RX_DIAG_PI_RATE			0x01F4U
@@ -295,6 +299,7 @@
 	TYPE_QSGMII,
 	TYPE_USB,
 	TYPE_USXGMII,
+	TYPE_PCIE_ML,
 };
 
 enum cdns_torrent_ref_clk {
@@ -693,6 +698,7 @@
 	case TYPE_DP:
 		return "DisplayPort";
 	case TYPE_PCIE:
+	case TYPE_PCIE_ML:
 		return "PCIe";
 	case TYPE_SGMII:
 		return "SGMII";
@@ -2478,6 +2484,7 @@
 	enum cdns_torrent_ssc_mode ssc;
 	struct regmap *regmap;
 	u32 num_regs, num_protocols, protocol;
+	u32 num_pcie_links = 0;
 
 	num_protocols = hweight32(cdns_phy->protocol_bitmask);
 	/* Maximum 2 protocols are supported */
@@ -2510,6 +2517,44 @@
 
 		phy_t1 = fns(cdns_phy->protocol_bitmask, 0);
 		phy_t2 = fns(cdns_phy->protocol_bitmask, 1);
+
+		/*
+		 * PCIe Multilink configuration can be supported along with a
+		 * non-PCIe protocol. The existing limitation associated with
+		 * the standalone PCIe Multilink configuration still remains,
+		 * implying that there can be only two links (subnodes) of the
+		 * PHY type PCIe which constitute the PCIe Multilink.
+		 *
+		 * Such configurations are handled by introducing a new protocol
+		 * namely TYPE_PCIE_ML. Both of the PCIe links which have the
+		 * protocol as TYPE_PCIE shall be treated as though the protocol
+		 * corresponding to them is TYPE_PCIE_ML only for the sake of
+		 * configuring the SERDES.
+		 *
+		 * PCIe Multilink configuration can be identified by checking if
+		 * there are exactly two links with phy_type set to TYPE_PCIE.
+		 * phy_t1 and phy_t2 are modified in such cases to support the
+		 * PCIe Multilink configuration with a non-PCIe protocol.
+		 */
+		for (node = 0; node < cdns_phy->nsubnodes; node++) {
+			if (cdns_phy->phys[node].phy_type == TYPE_PCIE)
+				num_pcie_links++;
+		}
+
+		if (num_pcie_links > 2) {
+			dev_err(dev, "cannot support PCIe Multilink with %u PCIe links\n",
+				num_pcie_links);
+			return -EINVAL;
+		} else if (num_pcie_links == 2) {
+			phy_t1 = TYPE_PCIE_ML;
+			for (node = 0; node < cdns_phy->nsubnodes; node++) {
+				if (cdns_phy->phys[node].phy_type == TYPE_PCIE) {
+					cdns_phy->phys[node].phy_type = TYPE_PCIE_ML;
+					continue;
+				}
+				phy_t2 = cdns_phy->phys[node].phy_type;
+			}
+		}
 	}
 
 	/**
@@ -2676,6 +2721,11 @@
 		}
 	}
 
+	/* Restore TYPE_PCIE_ML to TYPE_PCIE to be compatible with suspend-resume */
+	for (node = 0; node < cdns_phy->nsubnodes; node++)
+		if (cdns_phy->phys[node].phy_type == TYPE_PCIE_ML)
+			cdns_phy->phys[node].phy_type = TYPE_PCIE;
+
 	/* Take the PHY out of reset */
 	ret = reset_control_deassert(cdns_phy->phy_rst);
 	if (ret)
@@ -3088,15 +3138,14 @@
 	}
 
 	if (cdns_phy->nsubnodes > 1)
-		dev_dbg(dev, "Multi-link: %s (%d lanes) & %s (%d lanes)",
-			cdns_torrent_get_phy_type(cdns_phy->phys[0].phy_type),
-			cdns_phy->phys[0].num_lanes,
-			cdns_torrent_get_phy_type(cdns_phy->phys[1].phy_type),
-			cdns_phy->phys[1].num_lanes);
+		dev_dbg(dev, "Multi link configuration:\n");
 	else
-		dev_dbg(dev, "Single link: %s (%d lanes)",
-			cdns_torrent_get_phy_type(cdns_phy->phys[0].phy_type),
-			cdns_phy->phys[0].num_lanes);
+		dev_dbg(dev, "Single link configuration:\n");
+
+	for (i = 0; i < cdns_phy->nsubnodes; i++)
+		dev_dbg(dev, "%s (%d lanes)",
+			cdns_torrent_get_phy_type(cdns_phy->phys[i].phy_type),
+			cdns_phy->phys[i].num_lanes);
 
 	return 0;
 
@@ -3131,6 +3180,132 @@
 	cdns_torrent_clk_cleanup(cdns_phy);
 }
 
+/* Multilink PCIe and USB Same SSC link configuration */
+static const struct cdns_reg_pairs ml_pcie_usb_link_cmn_regs[] = {
+	{0x0002, PHY_PLL_CFG},
+	{0x8600, CMN_PDIAG_PLL0_CLK_SEL_M0}
+};
+
+static const struct cdns_reg_pairs ml_pcie_usb_xcvr_diag_ln_regs[] = {
+	{0x0100, XCVR_DIAG_HSCLK_SEL},
+	{0x0013, XCVR_DIAG_HSCLK_DIV},
+	{0x0812, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static const struct cdns_reg_pairs usb_ml_pcie_xcvr_diag_ln_regs[] = {
+	{0x0041, XCVR_DIAG_PLLDRC_CTRL},
+};
+
+static const struct cdns_torrent_vals ml_pcie_usb_link_cmn_vals = {
+	.reg_pairs = ml_pcie_usb_link_cmn_regs,
+	.num_regs = ARRAY_SIZE(ml_pcie_usb_link_cmn_regs),
+};
+
+static const struct cdns_torrent_vals ml_pcie_usb_xcvr_diag_ln_vals = {
+	.reg_pairs = ml_pcie_usb_xcvr_diag_ln_regs,
+	.num_regs = ARRAY_SIZE(ml_pcie_usb_xcvr_diag_ln_regs),
+};
+
+static const struct cdns_torrent_vals usb_ml_pcie_xcvr_diag_ln_vals = {
+	.reg_pairs = usb_ml_pcie_xcvr_diag_ln_regs,
+	.num_regs = ARRAY_SIZE(usb_ml_pcie_xcvr_diag_ln_regs),
+};
+
+/* Multi link PCIe configuration */
+static const struct cdns_reg_pairs ml_pcie_link_cmn_regs[] = {
+	{0x0002, PHY_PLL_CFG},
+	{0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0}
+};
+
+static const struct cdns_reg_pairs ml_pcie_xcvr_diag_ln_regs[] = {
+	{0x0100, XCVR_DIAG_HSCLK_SEL},
+	{0x0001, XCVR_DIAG_HSCLK_DIV},
+	{0x0812, XCVR_DIAG_PLLDRC_CTRL}
+};
+
+static const struct cdns_torrent_vals ml_pcie_link_cmn_vals = {
+	.reg_pairs = ml_pcie_link_cmn_regs,
+	.num_regs = ARRAY_SIZE(ml_pcie_link_cmn_regs),
+};
+
+static const struct cdns_torrent_vals ml_pcie_xcvr_diag_ln_vals = {
+	.reg_pairs = ml_pcie_xcvr_diag_ln_regs,
+	.num_regs = ARRAY_SIZE(ml_pcie_xcvr_diag_ln_regs),
+};
+
+/* Multi link PCIe, 100 MHz Ref clk, no SSC */
+static const struct cdns_reg_pairs ml_pcie_100_no_ssc_cmn_regs[] = {
+	{0x0003, CMN_PLL0_VCOCAL_TCTRL},
+	{0x0003, CMN_PLL1_VCOCAL_TCTRL}
+};
+
+static const struct cdns_reg_pairs ml_pcie_100_no_ssc_rx_ln_regs[] = {
+	{0x0019, RX_REE_TAP1_CLIP},
+	{0x0019, RX_REE_TAP2TON_CLIP},
+	{0x0008, RX_REE_PEAK_UTHR},
+	{0x018E, RX_CDRLF_CNFG},
+	{0x2E33, RX_CDRLF_CNFG2},
+	{0x0001, RX_DIAG_ACYA},
+	{0x0C21, RX_DIAG_DFE_AMP_TUNE_2},
+	{0x0002, RX_DIAG_DFE_AMP_TUNE_3},
+	{0x0005, RX_DIAG_REE_DAC_CTRL}
+};
+
+static const struct cdns_torrent_vals ml_pcie_100_no_ssc_cmn_vals = {
+	.reg_pairs = ml_pcie_100_no_ssc_cmn_regs,
+	.num_regs = ARRAY_SIZE(ml_pcie_100_no_ssc_cmn_regs),
+};
+
+static const struct cdns_torrent_vals ml_pcie_100_no_ssc_rx_ln_vals = {
+	.reg_pairs = ml_pcie_100_no_ssc_rx_ln_regs,
+	.num_regs = ARRAY_SIZE(ml_pcie_100_no_ssc_rx_ln_regs),
+};
+
+/* Multi link PCIe, 100 MHz Ref clk, internal SSC */
+static const struct cdns_reg_pairs ml_pcie_100_int_ssc_cmn_regs[] = {
+	{0x0004, CMN_PLL0_DSM_DIAG_M0},
+	{0x0004, CMN_PLL1_DSM_DIAG_M0},
+	{0x0509, CMN_PDIAG_PLL0_CP_PADJ_M0},
+	{0x0509, CMN_PDIAG_PLL1_CP_PADJ_M0},
+	{0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M0},
+	{0x0F00, CMN_PDIAG_PLL1_CP_IADJ_M0},
+	{0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M0},
+	{0x0F08, CMN_PDIAG_PLL1_FILT_PADJ_M0},
+	{0x0064, CMN_PLL0_INTDIV_M0},
+	{0x0050, CMN_PLL1_INTDIV_M0},
+	{0x0002, CMN_PLL0_FRACDIVH_M0},
+	{0x0002, CMN_PLL1_FRACDIVH_M0},
+	{0x0044, CMN_PLL0_HIGH_THR_M0},
+	{0x0036, CMN_PLL1_HIGH_THR_M0},
+	{0x0002, CMN_PDIAG_PLL0_CTRL_M0},
+	{0x0002, CMN_PDIAG_PLL1_CTRL_M0},
+	{0x0001, CMN_PLL0_SS_CTRL1_M0},
+	{0x0001, CMN_PLL1_SS_CTRL1_M0},
+	{0x011B, CMN_PLL0_SS_CTRL2_M0},
+	{0x011B, CMN_PLL1_SS_CTRL2_M0},
+	{0x006E, CMN_PLL0_SS_CTRL3_M0},
+	{0x0058, CMN_PLL1_SS_CTRL3_M0},
+	{0x000E, CMN_PLL0_SS_CTRL4_M0},
+	{0x0012, CMN_PLL1_SS_CTRL4_M0},
+	{0x0C5E, CMN_PLL0_VCOCAL_REFTIM_START},
+	{0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START},
+	{0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START},
+	{0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START},
+	{0x0003, CMN_PLL0_VCOCAL_TCTRL},
+	{0x0003, CMN_PLL1_VCOCAL_TCTRL},
+	{0x00C7, CMN_PLL0_LOCK_REFCNT_START},
+	{0x00C7, CMN_PLL1_LOCK_REFCNT_START},
+	{0x00C7, CMN_PLL0_LOCK_PLLCNT_START},
+	{0x00C7, CMN_PLL1_LOCK_PLLCNT_START},
+	{0x0005, CMN_PLL0_LOCK_PLLCNT_THR},
+	{0x0005, CMN_PLL1_LOCK_PLLCNT_THR}
+};
+
+static const struct cdns_torrent_vals ml_pcie_100_int_ssc_cmn_vals = {
+	.reg_pairs = ml_pcie_100_int_ssc_cmn_regs,
+	.num_regs = ARRAY_SIZE(ml_pcie_100_int_ssc_cmn_regs),
+};
+
 /* SGMII and QSGMII link configuration */
 static const struct cdns_reg_pairs sgmii_qsgmii_link_cmn_regs[] = {
 	{0x0002, PHY_PLL_CFG}
@@ -4042,6 +4217,8 @@
 	{0x0C02, RX_REE_ATTEN_THR},
 	{0x0330, RX_REE_SMGM_CTRL1},
 	{0x0300, RX_REE_SMGM_CTRL2},
+	{0x0000, RX_REE_PEAK_UTHR},
+	{0x01F5, RX_REE_PEAK_LTHR},
 	{0x0019, RX_REE_TAP1_CLIP},
 	{0x0019, RX_REE_TAP2TON_CLIP},
 	{0x1004, RX_DIAG_SIGDET_TUNE},
@@ -4531,7 +4708,7 @@
 	.num_regs = ARRAY_SIZE(sl_sgmii_xcvr_diag_ln_regs),
 };
 
-/* Multi link PCIe, 100 MHz Ref clk, internal SSC */
+/* For PCIe (with some other protocol), 100 MHz Ref clk, internal SSC */
 static const struct cdns_reg_pairs pcie_100_int_ssc_cmn_regs[] = {
 	{0x0004, CMN_PLL0_DSM_DIAG_M0},
 	{0x0004, CMN_PLL0_DSM_DIAG_M1},
@@ -4670,12 +4847,15 @@
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_DP, TYPE_USB), &usb_dp_link_cmn_vals},
 
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_NONE), NULL},
+	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_PCIE), &ml_pcie_link_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_SGMII), &pcie_sgmii_link_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_QSGMII), &pcie_sgmii_link_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USB), &pcie_usb_link_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_DP), &pcie_dp_link_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USXGMII), &pcie_usxgmii_link_cmn_vals},
 
+	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE_ML, TYPE_USB), &ml_pcie_usb_link_cmn_vals},
+
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_NONE), &sl_sgmii_link_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_PCIE), &pcie_sgmii_link_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_QSGMII), &sgmii_qsgmii_link_cmn_vals},
@@ -4690,6 +4870,7 @@
 
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_NONE), &sl_usb_link_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_PCIE), &pcie_usb_link_cmn_vals},
+	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_PCIE_ML), &ml_pcie_usb_link_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_SGMII), &usb_sgmii_link_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_QSGMII), &usb_sgmii_link_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_DP), &usb_dp_link_cmn_vals},
@@ -4706,12 +4887,15 @@
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_DP, TYPE_USB), &dp_usb_xcvr_diag_ln_vals},
 
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_NONE), NULL},
+	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_PCIE), &ml_pcie_xcvr_diag_ln_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_SGMII), &pcie_sgmii_xcvr_diag_ln_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_QSGMII), &pcie_sgmii_xcvr_diag_ln_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USB), &pcie_usb_xcvr_diag_ln_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_DP), &pcie_dp_xcvr_diag_ln_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USXGMII), &pcie_usxgmii_xcvr_diag_ln_vals},
 
+	{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE_ML, TYPE_USB), &ml_pcie_usb_xcvr_diag_ln_vals},
+
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_NONE), &sl_sgmii_xcvr_diag_ln_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_PCIE), &sgmii_pcie_xcvr_diag_ln_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_QSGMII), &sgmii_qsgmii_xcvr_diag_ln_vals},
@@ -4726,6 +4910,7 @@
 
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_NONE), &sl_usb_xcvr_diag_ln_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_PCIE), &usb_pcie_xcvr_diag_ln_vals},
+	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_PCIE_ML), &usb_ml_pcie_xcvr_diag_ln_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_SGMII), &usb_sgmii_xcvr_diag_ln_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_QSGMII), &usb_sgmii_xcvr_diag_ln_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_DP), &usb_dp_xcvr_diag_ln_vals},
@@ -4739,6 +4924,7 @@
 static const struct cdns_torrent_vals_entry pcs_cmn_vals_entries[] = {
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_NONE), &usb_phy_pcs_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_PCIE), &usb_phy_pcs_cmn_vals},
+	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_PCIE_ML), &usb_phy_pcs_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_SGMII), &usb_phy_pcs_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_QSGMII), &usb_phy_pcs_cmn_vals},
 	{CDNS_TORRENT_KEY_ANYCLK(TYPE_USB, TYPE_DP), &usb_phy_pcs_cmn_vals},
@@ -4756,6 +4942,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), NULL},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), &sl_pcie_100_int_ssc_cmn_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, NO_SSC), &ml_pcie_100_no_ssc_cmn_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, EXTERNAL_SSC), &ml_pcie_100_no_ssc_cmn_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, INTERNAL_SSC), &ml_pcie_100_int_ssc_cmn_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), &pcie_100_no_ssc_cmn_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), &pcie_100_no_ssc_cmn_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), &pcie_100_int_ssc_cmn_vals},
@@ -4770,6 +4960,10 @@
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &ml_pcie_100_no_ssc_cmn_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &ml_pcie_100_no_ssc_cmn_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &ml_pcie_100_int_ssc_cmn_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &sl_sgmii_100_no_ssc_cmn_vals},
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &sgmii_100_no_ssc_cmn_vals},
@@ -4802,6 +4996,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_cmn_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_int_ssc_cmn_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, NO_SSC), &usb_100_no_ssc_cmn_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, EXTERNAL_SSC), &usb_100_no_ssc_cmn_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, INTERNAL_SSC), &usb_100_no_ssc_cmn_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &sl_usb_100_no_ssc_cmn_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &sl_usb_100_no_ssc_cmn_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &sl_usb_100_int_ssc_cmn_vals},
@@ -4838,6 +5036,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), NULL},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), NULL},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, NO_SSC), NULL},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, EXTERNAL_SSC), NULL},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, INTERNAL_SSC), NULL},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), NULL},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), NULL},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), NULL},
@@ -4852,6 +5054,10 @@
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), NULL},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), NULL},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), NULL},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &sgmii_100_no_ssc_tx_ln_vals},
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &sgmii_100_no_ssc_tx_ln_vals},
@@ -4884,6 +5090,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
@@ -4920,6 +5130,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, NO_SSC), &ml_pcie_100_no_ssc_rx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, EXTERNAL_SSC), &ml_pcie_100_no_ssc_rx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, INTERNAL_SSC), &ml_pcie_100_no_ssc_rx_ln_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
@@ -4934,6 +5148,10 @@
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &ml_pcie_100_no_ssc_rx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &ml_pcie_100_no_ssc_rx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &ml_pcie_100_no_ssc_rx_ln_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals},
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals},
@@ -4966,6 +5184,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, NO_SSC), &usb_100_no_ssc_rx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &usb_100_no_ssc_rx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
@@ -5038,6 +5260,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), NULL},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), NULL},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, NO_SSC), NULL},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, EXTERNAL_SSC), NULL},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, INTERNAL_SSC), NULL},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), NULL},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), NULL},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), NULL},
@@ -5052,6 +5278,10 @@
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), NULL},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), NULL},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), NULL},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
@@ -5084,6 +5314,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
@@ -5154,6 +5388,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), NULL},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), &sl_pcie_100_int_ssc_cmn_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, NO_SSC), &ml_pcie_100_no_ssc_cmn_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, EXTERNAL_SSC), &ml_pcie_100_no_ssc_cmn_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, INTERNAL_SSC), &ml_pcie_100_int_ssc_cmn_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), &pcie_100_no_ssc_cmn_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), &pcie_100_no_ssc_cmn_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), &pcie_100_int_ssc_cmn_vals},
@@ -5168,6 +5406,10 @@
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &ml_pcie_100_no_ssc_cmn_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &ml_pcie_100_no_ssc_cmn_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &ml_pcie_100_int_ssc_cmn_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &sl_sgmii_100_no_ssc_cmn_vals},
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &sgmii_100_no_ssc_cmn_vals},
@@ -5200,6 +5442,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_cmn_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_int_ssc_cmn_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, NO_SSC), &usb_100_no_ssc_cmn_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, EXTERNAL_SSC), &usb_100_no_ssc_cmn_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, INTERNAL_SSC), &usb_100_no_ssc_cmn_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &sl_usb_100_no_ssc_cmn_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &sl_usb_100_no_ssc_cmn_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &sl_usb_100_int_ssc_cmn_vals},
@@ -5236,6 +5482,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), NULL},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), NULL},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, NO_SSC), NULL},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, EXTERNAL_SSC), NULL},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, INTERNAL_SSC), NULL},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), NULL},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), NULL},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), NULL},
@@ -5250,6 +5500,10 @@
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), NULL},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), NULL},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), NULL},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
@@ -5282,6 +5536,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals},
@@ -5318,6 +5576,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_NONE, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_PCIE, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_SGMII, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
@@ -5332,6 +5594,10 @@
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_NONE, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals},
 
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals},
@@ -5364,6 +5630,10 @@
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
 
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, NO_SSC), &usb_100_no_ssc_rx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
+	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_PCIE_ML, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
+
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, NO_SSC), &usb_100_no_ssc_rx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, EXTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
 	{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_SGMII, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals},
diff -Naur --no-dereference a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c
--- a/drivers/phy/ti/phy-gmii-sel.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/phy/ti/phy-gmii-sel.c	2025-10-23 09:30:40.286462238 -0400
@@ -230,7 +230,8 @@
 struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
 	.use_of_data = true,
 	.regfields = phy_gmii_sel_fields_am654,
-	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII),
+	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
+		       BIT(PHY_INTERFACE_MODE_USXGMII),
 	.num_ports = 4,
 	.num_qsgmii_main_ports = 1,
 };
diff -Naur --no-dereference a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c
--- a/drivers/pmdomain/ti/ti_sci_pm_domains.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c	2025-10-23 09:30:40.286462238 -0400
@@ -2,7 +2,7 @@
 /*
  * TI SCI Generic Power Domain Driver
  *
- * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2015-2025 Texas Instruments Incorporated - http://www.ti.com/
  *	J Keerthy <j-keerthy@ti.com>
  *	Dave Gerlach <d-gerlach@ti.com>
  */
@@ -12,8 +12,11 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
+#include <linux/pm_qos.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
+#include <linux/pinctrl/consumer.h>
 #include <dt-bindings/soc/ti,sci_pm_domain.h>
 
 /**
@@ -51,6 +54,71 @@
 
 #define genpd_to_ti_sci_pd(gpd) container_of(gpd, struct ti_sci_pm_domain, pd)
 
+static inline bool ti_sci_pd_is_valid_constraint(s32 val)
+{
+	return val != PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static void ti_sci_pd_set_lat_constraint(struct device *dev, s32 val)
+{
+	struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain);
+	struct ti_sci_pm_domain *pd = genpd_to_ti_sci_pd(genpd);
+	const struct ti_sci_handle *ti_sci = pd->parent->ti_sci;
+	u16 val_ms;
+	int ret;
+
+	/* PM QoS latency unit is usecs, TI SCI uses msecs */
+	val_ms = val / USEC_PER_MSEC;
+	ret = ti_sci->ops.pm_ops.set_latency_constraint(ti_sci, val_ms, TISCI_MSG_CONSTRAINT_SET);
+	if (ret)
+		dev_err(dev, "ti_sci_pd: set latency constraint failed: ret=%d\n",
+			ret);
+	else
+		dev_dbg(dev, "ti_sci_pd: ID:%d set latency constraint %d\n",
+			pd->idx, val);
+}
+#endif
+
+static inline void ti_sci_pd_set_wkup_constraint(struct device *dev)
+{
+	struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain);
+	struct ti_sci_pm_domain *pd = genpd_to_ti_sci_pd(genpd);
+	const struct ti_sci_handle *ti_sci = pd->parent->ti_sci;
+	struct pinctrl *pinctrl = devm_pinctrl_get(dev);
+	struct pinctrl_state *pinctrl_state_wakeup;
+	int ret;
+
+	if (device_may_wakeup(dev)) {
+		/*
+		 * If device can wakeup using pinctrl wakeup state,
+		 * we do not want to set a constraint
+		 */
+		if (!IS_ERR_OR_NULL(pinctrl)) {
+			pinctrl_state_wakeup = pinctrl_lookup_state(pinctrl, "wakeup");
+			if (!IS_ERR_OR_NULL(pinctrl_state_wakeup)) {
+				dev_dbg(dev, "%s: has wake pinctrl wakeup state, not setting " \
+						"constraints\n", __func__);
+				return;
+			}
+		}
+
+		/*
+		 * If device can wakeup using IO daisy chain wakeups,
+		 * we do not want to set a constraint.
+		 */
+		if (dev->power.wakeirq) {
+			dev_dbg(dev, "%s: has wake IRQ, not setting constraints\n", __func__);
+			return;
+		}
+
+		ret = ti_sci->ops.pm_ops.set_device_constraint(ti_sci, pd->idx,
+							       TISCI_MSG_CONSTRAINT_SET);
+		if (!ret)
+			dev_dbg(dev, "ti_sci_pd: ID:%d set device constraint.\n", pd->idx);
+	}
+}
+
 /*
  * ti_sci_pd_power_off(): genpd power down hook
  * @domain: pointer to the powerdomain to power off
@@ -79,6 +147,67 @@
 		return ti_sci->ops.dev_ops.get_device(ti_sci, pd->idx);
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int ti_sci_pd_suspend(struct device *dev)
+{
+	int ret;
+	s32 val;
+
+	ret = pm_generic_suspend(dev);
+	if (ret)
+		return ret;
+
+	val = dev_pm_qos_read_value(dev, DEV_PM_QOS_RESUME_LATENCY);
+	if (ti_sci_pd_is_valid_constraint(val))
+		ti_sci_pd_set_lat_constraint(dev, val);
+
+	ti_sci_pd_set_wkup_constraint(dev);
+
+	return 0;
+}
+
+static int ti_sci_pd_suspend_late(struct device *dev)
+{
+	struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain);
+	struct ti_sci_pm_domain *pd = genpd_to_ti_sci_pd(genpd);
+	const struct ti_sci_handle *ti_sci = pd->parent->ti_sci;
+	int ret;
+
+	ret = pm_generic_suspend_late(dev);
+	if (ret) {
+		dev_err(dev, "%s: Failed to suspend. Abort entering low power mode.\n", __func__);
+		if (ti_sci->ops.pm_ops.lpm_abort(ti_sci))
+			dev_err(dev, "%s: Failed to abort.\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ti_sci_pd_suspend_noirq(struct device *dev)
+{
+	struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain);
+	struct ti_sci_pm_domain *pd = genpd_to_ti_sci_pd(genpd);
+	const struct ti_sci_handle *ti_sci = pd->parent->ti_sci;
+	int ret;
+
+	ret = pm_generic_suspend_noirq(dev);
+	if (ret) {
+		dev_err(dev, "%s: Failed to suspend. Abort entering low power mode.\n", __func__);
+		if (ti_sci->ops.pm_ops.lpm_abort(ti_sci))
+			dev_err(dev, "%s: Failed to abort.\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+#else
+#define ti_sci_pd_suspend		NULL
+#define ti_sci_pd_suspend_late		NULL
+#define ti_sci_pd_suspend_noirq		NULL
+#endif
+
 /*
  * ti_sci_pd_xlate(): translation service for TI SCI genpds
  * @genpdspec: DT identification data for the genpd
@@ -189,6 +318,18 @@
 				pd->pd.power_on = ti_sci_pd_power_on;
 				pd->idx = args.args[0];
 				pd->parent = pd_provider;
+				/*
+				 * If SCI constraint functions are present, then firmware
+				 * supports the constraints API.
+				 */
+				if (pd_provider->ti_sci->ops.pm_ops.set_device_constraint &&
+				    pd_provider->ti_sci->ops.pm_ops.set_latency_constraint)
+					pd->pd.domain.ops.suspend = ti_sci_pd_suspend;
+
+				if (pd_provider->ti_sci->ops.pm_ops.lpm_abort) {
+					pd->pd.domain.ops.suspend_late = ti_sci_pd_suspend_late;
+					pd->pd.domain.ops.suspend_noirq = ti_sci_pd_suspend_noirq;
+				}
 
 				pm_genpd_init(&pd->pd, NULL, true);
 
diff -Naur --no-dereference a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
--- a/drivers/regulator/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/regulator/Kconfig	2025-10-23 09:30:40.286462238 -0400
@@ -1579,10 +1579,16 @@
 	tristate "TI TPS65219 Power regulators"
 	depends on MFD_TPS65219 && OF
 	help
-	  This driver supports TPS65219 voltage regulator chips.
+	  This driver supports TPS65219, TPS65215, and TPS65214 voltage
+	  regulator chips.
 	  TPS65219 series of PMICs have 3 single phase BUCKs & 4 LDOs
-	  voltage regulators. It supports software based voltage control
-	  for different voltage domains.
+	  voltage regulators.
+	  TPS65215 PMIC has 3 single phase BUCKs & 2 LDOs.
+	  TPS65214 PMIC has 3 synchronous stepdown DC-DC converters & 2
+	  LDOs. One LDO supports a maximum output current of 300 mA and the
+	  other a maximum of 500 mA
+	  All 3 PMICs support software based voltage control for different
+	  voltage domains.
 
 config REGULATOR_TPS6594
 	tristate "TI TPS6594 Power regulators"
diff -Naur --no-dereference a/drivers/regulator/tps65219-regulator.c b/drivers/regulator/tps65219-regulator.c
--- a/drivers/regulator/tps65219-regulator.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/regulator/tps65219-regulator.c	2025-10-23 09:30:40.286462238 -0400
@@ -1,10 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
 //
-// tps65219-regulator.c
-//
-// Regulator driver for TPS65219 PMIC
+// TPS65214/TPS65215/TPS65219 PMIC Regulator Driver
 //
 // Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+// Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
 //
 // This implementation derived from tps65218 authored by
 // "J Keerthy <j-keerthy@ti.com>"
@@ -30,6 +29,11 @@
 	unsigned long event;
 };
 
+static struct tps65219_regulator_irq_type tps65215_regulator_irq_types[] = {
+	{ "SENSOR_3_WARM", "SENSOR3", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN},
+	{ "SENSOR_3_HOT", "SENSOR3", "hot temperature", REGULATOR_EVENT_OVER_TEMP},
+};
+
 static struct tps65219_regulator_irq_type tps65219_regulator_irq_types[] = {
 	{ "LDO3_SCG", "LDO3", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
 	{ "LDO3_OC", "LDO3", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
@@ -37,6 +41,16 @@
 	{ "LDO4_SCG", "LDO4", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
 	{ "LDO4_OC", "LDO4", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
 	{ "LDO4_UV", "LDO4", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
+	{ "LDO3_RV", "LDO3", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO4_RV", "LDO4", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO3_RV_SD", "LDO3", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "LDO4_RV_SD", "LDO4", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ "SENSOR_3_WARM", "SENSOR3", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN},
+	{ "SENSOR_3_HOT", "SENSOR3", "hot temperature", REGULATOR_EVENT_OVER_TEMP},
+};
+
+/*  All of TPS65214's irq types are the same as common_regulator_irq_types */
+static struct tps65219_regulator_irq_type common_regulator_irq_types[] = {
 	{ "LDO1_SCG", "LDO1", "short circuit to ground", REGULATOR_EVENT_REGULATION_OUT },
 	{ "LDO1_OC", "LDO1", "overcurrent", REGULATOR_EVENT_OVER_CURRENT },
 	{ "LDO1_UV", "LDO1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
@@ -60,8 +74,6 @@
 	{ "BUCK3_RV", "BUCK3", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
 	{ "LDO1_RV", "LDO1", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
 	{ "LDO2_RV", "LDO2", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
-	{ "LDO3_RV", "LDO3", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
-	{ "LDO4_RV", "LDO4", "residual voltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
 	{ "BUCK1_RV_SD", "BUCK1", "residual voltage on shutdown",
 	 REGULATOR_EVENT_OVER_VOLTAGE_WARN },
 	{ "BUCK2_RV_SD", "BUCK2", "residual voltage on shutdown",
@@ -70,13 +82,9 @@
 	 REGULATOR_EVENT_OVER_VOLTAGE_WARN },
 	{ "LDO1_RV_SD", "LDO1", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
 	{ "LDO2_RV_SD", "LDO2", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
-	{ "LDO3_RV_SD", "LDO3", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
-	{ "LDO4_RV_SD", "LDO4", "residual voltage on shutdown", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
-	{ "SENSOR_3_WARM", "SENSOR3", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN},
 	{ "SENSOR_2_WARM", "SENSOR2", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN },
 	{ "SENSOR_1_WARM", "SENSOR1", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN },
 	{ "SENSOR_0_WARM", "SENSOR0", "warm temperature", REGULATOR_EVENT_OVER_TEMP_WARN },
-	{ "SENSOR_3_HOT", "SENSOR3", "hot temperature", REGULATOR_EVENT_OVER_TEMP},
 	{ "SENSOR_2_HOT", "SENSOR2", "hot temperature", REGULATOR_EVENT_OVER_TEMP },
 	{ "SENSOR_1_HOT", "SENSOR1", "hot temperature", REGULATOR_EVENT_OVER_TEMP },
 	{ "SENSOR_0_HOT", "SENSOR0", "hot temperature", REGULATOR_EVENT_OVER_TEMP },
@@ -125,12 +133,28 @@
 	REGULATOR_LINEAR_RANGE(3400000, 0x34, 0x3f, 0),
 };
 
-static const struct linear_range ldos_1_2_ranges[] = {
+static const struct linear_range ldo_1_range[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x37, 50000),
+	REGULATOR_LINEAR_RANGE(3400000, 0x38, 0x3f, 0),
+};
+
+static const struct linear_range tps65214_ldo_1_2_range[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2, 0),
+	REGULATOR_LINEAR_RANGE(650000, 0x3, 0x37, 50000),
+	REGULATOR_LINEAR_RANGE(3300000, 0x38, 0x3F, 0),
+};
+
+static const struct linear_range tps65215_ldo_2_range[] = {
+	REGULATOR_LINEAR_RANGE(1200000, 0x0, 0xC, 50000),
+	REGULATOR_LINEAR_RANGE(3300000, 0x36, 0x3F, 0),
+};
+
+static const struct linear_range tps65219_ldo_2_range[] = {
 	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x37, 50000),
 	REGULATOR_LINEAR_RANGE(3400000, 0x38, 0x3f, 0),
 };
 
-static const struct linear_range ldos_3_4_ranges[] = {
+static const struct linear_range tps65219_ldos_3_4_range[] = {
 	REGULATOR_LINEAR_RANGE(1200000, 0x0, 0xC, 0),
 	REGULATOR_LINEAR_RANGE(1250000, 0xD, 0x35, 50000),
 	REGULATOR_LINEAR_RANGE(3300000, 0x36, 0x3F, 0),
@@ -174,7 +198,7 @@
 }
 
 /* Operations permitted on BUCK1/2/3 */
-static const struct regulator_ops tps65219_bucks_ops = {
+static const struct regulator_ops bucks_ops = {
 	.is_enabled		= regulator_is_enabled_regmap,
 	.enable			= regulator_enable_regmap,
 	.disable		= regulator_disable_regmap,
@@ -189,7 +213,7 @@
 };
 
 /* Operations permitted on LDO1/2 */
-static const struct regulator_ops tps65219_ldos_1_2_ops = {
+static const struct regulator_ops ldos_1_2_ops = {
 	.is_enabled		= regulator_is_enabled_regmap,
 	.enable			= regulator_enable_regmap,
 	.disable		= regulator_disable_regmap,
@@ -204,7 +228,7 @@
 };
 
 /* Operations permitted on LDO3/4 */
-static const struct regulator_ops tps65219_ldos_3_4_ops = {
+static const struct regulator_ops ldos_3_4_ops = {
 	.is_enabled		= regulator_is_enabled_regmap,
 	.enable			= regulator_enable_regmap,
 	.disable		= regulator_disable_regmap,
@@ -216,55 +240,98 @@
 	.map_voltage		= regulator_map_voltage_linear_range,
 };
 
-static const struct regulator_desc regulators[] = {
+static const struct regulator_desc common_regs[] = {
 	TPS65219_REGULATOR("BUCK1", "buck1", TPS65219_BUCK_1,
-			   REGULATOR_VOLTAGE, tps65219_bucks_ops, 64,
+			   REGULATOR_VOLTAGE, bucks_ops, 64,
 			   TPS65219_REG_BUCK1_VOUT,
 			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
 			   TPS65219_REG_ENABLE_CTRL,
 			   TPS65219_ENABLE_BUCK1_EN_MASK, 0, 0, bucks_ranges,
 			   3, 4000, 0, NULL, 0, 0),
 	TPS65219_REGULATOR("BUCK2", "buck2", TPS65219_BUCK_2,
-			   REGULATOR_VOLTAGE, tps65219_bucks_ops, 64,
+			   REGULATOR_VOLTAGE, bucks_ops, 64,
 			   TPS65219_REG_BUCK2_VOUT,
 			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
 			   TPS65219_REG_ENABLE_CTRL,
 			   TPS65219_ENABLE_BUCK2_EN_MASK, 0, 0, bucks_ranges,
 			   3, 4000, 0, NULL, 0, 0),
 	TPS65219_REGULATOR("BUCK3", "buck3", TPS65219_BUCK_3,
-			   REGULATOR_VOLTAGE, tps65219_bucks_ops, 64,
+			   REGULATOR_VOLTAGE, bucks_ops, 64,
 			   TPS65219_REG_BUCK3_VOUT,
 			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
 			   TPS65219_REG_ENABLE_CTRL,
 			   TPS65219_ENABLE_BUCK3_EN_MASK, 0, 0, bucks_ranges,
 			   3, 0, 0, NULL, 0, 0),
+};
+
+static const struct regulator_desc tps65214_regs[] = {
+	// TPS65214's LDO3 pin maps to TPS65219's LDO3 pin
+	TPS65219_REGULATOR("LDO1", "ldo1", TPS65214_LDO_1,
+			   REGULATOR_VOLTAGE, ldos_3_4_ops, 64,
+			   TPS65214_REG_LDO1_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_LDO3_EN_MASK, 0, 0, tps65214_ldo_1_2_range,
+			   3, 0, 0, NULL, 0, 0),
+	TPS65219_REGULATOR("LDO2", "ldo2", TPS65214_LDO_2,
+			   REGULATOR_VOLTAGE, ldos_3_4_ops, 64,
+			   TPS65214_REG_LDO2_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_LDO2_EN_MASK, 0, 0, tps65214_ldo_1_2_range,
+			   3, 0, 0, NULL, 0, 0),
+};
+
+static const struct regulator_desc tps65215_regs[] = {
+	/*
+	 *  TPS65215's LDO1 is the same as TPS65219's LDO1. LDO1 is
+	 *  configurable as load switch and bypass-mode.
+	 *  TPS65215's LDO2 is the same as TPS65219's LDO3
+	 */
+	TPS65219_REGULATOR("LDO1", "ldo1", TPS65219_LDO_1,
+			   REGULATOR_VOLTAGE, ldos_1_2_ops, 64,
+			   TPS65219_REG_LDO1_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65219_ENABLE_LDO1_EN_MASK, 0, 0, ldo_1_range,
+			   2, 0, 0, NULL, 0, TPS65219_LDOS_BYP_CONFIG_MASK),
+	TPS65219_REGULATOR("LDO2", "ldo2", TPS65215_LDO_2,
+			   REGULATOR_VOLTAGE, ldos_3_4_ops, 64,
+			   TPS65215_REG_LDO2_VOUT,
+			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
+			   TPS65219_REG_ENABLE_CTRL,
+			   TPS65215_ENABLE_LDO2_EN_MASK, 0, 0, tps65215_ldo_2_range,
+			   2, 0, 0, NULL, 0, 0),
+};
+
+static const struct regulator_desc tps65219_regs[] = {
 	TPS65219_REGULATOR("LDO1", "ldo1", TPS65219_LDO_1,
-			   REGULATOR_VOLTAGE, tps65219_ldos_1_2_ops, 64,
+			   REGULATOR_VOLTAGE, ldos_1_2_ops, 64,
 			   TPS65219_REG_LDO1_VOUT,
 			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
 			   TPS65219_REG_ENABLE_CTRL,
-			   TPS65219_ENABLE_LDO1_EN_MASK, 0, 0, ldos_1_2_ranges,
+			   TPS65219_ENABLE_LDO1_EN_MASK, 0, 0, ldo_1_range,
 			   2, 0, 0, NULL, 0, TPS65219_LDOS_BYP_CONFIG_MASK),
 	TPS65219_REGULATOR("LDO2", "ldo2", TPS65219_LDO_2,
-			   REGULATOR_VOLTAGE, tps65219_ldos_1_2_ops, 64,
+			   REGULATOR_VOLTAGE, ldos_1_2_ops, 64,
 			   TPS65219_REG_LDO2_VOUT,
 			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
 			   TPS65219_REG_ENABLE_CTRL,
-			   TPS65219_ENABLE_LDO2_EN_MASK, 0, 0, ldos_1_2_ranges,
+			   TPS65219_ENABLE_LDO2_EN_MASK, 0, 0, tps65219_ldo_2_range,
 			   2, 0, 0, NULL, 0, TPS65219_LDOS_BYP_CONFIG_MASK),
 	TPS65219_REGULATOR("LDO3", "ldo3", TPS65219_LDO_3,
-			   REGULATOR_VOLTAGE, tps65219_ldos_3_4_ops, 64,
+			   REGULATOR_VOLTAGE, ldos_3_4_ops, 64,
 			   TPS65219_REG_LDO3_VOUT,
 			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
 			   TPS65219_REG_ENABLE_CTRL,
-			   TPS65219_ENABLE_LDO3_EN_MASK, 0, 0, ldos_3_4_ranges,
+			   TPS65219_ENABLE_LDO3_EN_MASK, 0, 0, tps65219_ldos_3_4_range,
 			   3, 0, 0, NULL, 0, 0),
 	TPS65219_REGULATOR("LDO4", "ldo4", TPS65219_LDO_4,
-			   REGULATOR_VOLTAGE, tps65219_ldos_3_4_ops, 64,
+			   REGULATOR_VOLTAGE, ldos_3_4_ops, 64,
 			   TPS65219_REG_LDO4_VOUT,
 			   TPS65219_BUCKS_LDOS_VOUT_VSET_MASK,
 			   TPS65219_REG_ENABLE_CTRL,
-			   TPS65219_ENABLE_LDO4_EN_MASK, 0, 0, ldos_3_4_ranges,
+			   TPS65219_ENABLE_LDO4_EN_MASK, 0, 0, tps65219_ldos_3_4_range,
 			   3, 0, 0, NULL, 0, 0),
 };
 
@@ -287,99 +354,148 @@
 	return IRQ_HANDLED;
 }
 
-static int tps65219_get_rdev_by_name(const char *regulator_name,
-				     struct regulator_dev *rdevtbl[7],
-				     struct regulator_dev **dev)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
-		if (strcmp(regulator_name, regulators[i].name) == 0) {
-			*dev = rdevtbl[i];
-			return 0;
-		}
-	}
-	return -EINVAL;
-}
+struct tps65219_chip_data {
+	size_t rdesc_size;
+	size_t common_rdesc_size;
+	size_t dev_irq_size;
+	size_t common_irq_size;
+	const struct regulator_desc *rdesc;
+	const struct regulator_desc *common_rdesc;
+	struct tps65219_regulator_irq_type *irq_types;
+	struct tps65219_regulator_irq_type *common_irq_types;
+};
+
+static struct tps65219_chip_data chip_info_table[] = {
+	[TPS65214] = {
+		.rdesc = tps65214_regs,
+		.rdesc_size = ARRAY_SIZE(tps65214_regs),
+		.common_rdesc = common_regs,
+		.common_rdesc_size = ARRAY_SIZE(common_regs),
+		.irq_types = NULL,
+		.dev_irq_size = 0,
+		.common_irq_types = common_regulator_irq_types,
+		.common_irq_size = ARRAY_SIZE(common_regulator_irq_types),
+	},
+	[TPS65215] = {
+		.rdesc = tps65215_regs,
+		.rdesc_size = ARRAY_SIZE(tps65215_regs),
+		.common_rdesc = common_regs,
+		.common_rdesc_size = ARRAY_SIZE(common_regs),
+		.irq_types = tps65215_regulator_irq_types,
+		.dev_irq_size = ARRAY_SIZE(tps65215_regulator_irq_types),
+		.common_irq_types = common_regulator_irq_types,
+		.common_irq_size = ARRAY_SIZE(common_regulator_irq_types),
+	},
+	[TPS65219] = {
+		.rdesc = tps65219_regs,
+		.rdesc_size = ARRAY_SIZE(tps65219_regs),
+		.common_rdesc = common_regs,
+		.common_rdesc_size = ARRAY_SIZE(common_regs),
+		.irq_types = tps65219_regulator_irq_types,
+		.dev_irq_size = ARRAY_SIZE(tps65219_regulator_irq_types),
+		.common_irq_types = common_regulator_irq_types,
+		.common_irq_size = ARRAY_SIZE(common_regulator_irq_types),
+	},
+};
 
 static int tps65219_regulator_probe(struct platform_device *pdev)
 {
-	struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
+	struct tps65219_regulator_irq_data *irq_data;
+	struct tps65219_regulator_irq_type *irq_type;
+	struct tps65219_chip_data *pmic;
 	struct regulator_dev *rdev;
-	struct regulator_config config = { };
-	int i;
 	int error;
 	int irq;
-	struct tps65219_regulator_irq_data *irq_data;
-	struct tps65219_regulator_irq_type *irq_type;
-	struct regulator_dev *rdevtbl[7];
+	int i;
+
+	struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
+	struct regulator_config config = { };
+	enum pmic_id chip = platform_get_device_id(pdev)->driver_data;
+
+	pmic = &chip_info_table[chip];
 
 	config.dev = tps->dev;
 	config.driver_data = tps;
 	config.regmap = tps->regmap;
 
-	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
-		dev_dbg(tps->dev, "%s regul i= %d START", __func__, i);
-		rdev = devm_regulator_register(&pdev->dev, &regulators[i],
+	for (i = 0; i <  pmic->common_rdesc_size; i++) {
+		rdev = devm_regulator_register(&pdev->dev, &pmic->common_rdesc[i],
 					       &config);
-		if (IS_ERR(rdev)) {
-			dev_err(tps->dev, "failed to register %s regulator\n",
-				regulators[i].name);
-			return PTR_ERR(rdev);
-		}
-		rdevtbl[i] = rdev;
-		dev_dbg(tps->dev, "%s regul i= %d COMPLETED", __func__, i);
+		if (IS_ERR(rdev))
+			return dev_err_probe(tps->dev, PTR_ERR(rdev),
+					      "Failed to register %s regulator\n",
+					      pmic->common_rdesc[i].name);
 	}
 
-	irq_data = devm_kmalloc(tps->dev,
-				ARRAY_SIZE(tps65219_regulator_irq_types) *
-				sizeof(struct tps65219_regulator_irq_data),
-				GFP_KERNEL);
-	if (!irq_data)
-		return -ENOMEM;
-
-	for (i = 0; i < ARRAY_SIZE(tps65219_regulator_irq_types); ++i) {
-		irq_type = &tps65219_regulator_irq_types[i];
+	for (i = 0; i <  pmic->rdesc_size; i++) {
+		rdev = devm_regulator_register(&pdev->dev, &pmic->rdesc[i],
+					       &config);
+		if (IS_ERR(rdev))
+			return dev_err_probe(tps->dev, PTR_ERR(rdev),
+					     "Failed to register %s regulator\n",
+					     pmic->rdesc[i].name);
+	}
 
+	for (i = 0; i < pmic->common_irq_size; ++i) {
+		irq_type = &pmic->common_irq_types[i];
 		irq = platform_get_irq_byname(pdev, irq_type->irq_name);
 		if (irq < 0)
 			return -EINVAL;
 
-		irq_data[i].dev = tps->dev;
-		irq_data[i].type = irq_type;
+		irq_data = devm_kmalloc(tps->dev, sizeof(*irq_data), GFP_KERNEL);
+		if (!irq_data)
+			return -ENOMEM;
+
+		irq_data->dev = tps->dev;
+		irq_data->type = irq_type;
+		error = devm_request_threaded_irq(tps->dev, irq, NULL,
+						  tps65219_regulator_irq_handler,
+						  IRQF_ONESHOT,
+						  irq_type->irq_name,
+						  irq_data);
+		if (error)
+			return dev_err_probe(tps->dev, PTR_ERR(rdev),
+					     "Failed to request %s IRQ %d: %d\n",
+					     irq_type->irq_name, irq, error);
+	}
 
-		tps65219_get_rdev_by_name(irq_type->regulator_name, rdevtbl, &rdev);
-		if (IS_ERR(rdev)) {
-			dev_err(tps->dev, "Failed to get rdev for %s\n",
-				irq_type->regulator_name);
+	for (i = 0; i < pmic->dev_irq_size; ++i) {
+		irq_type = &pmic->irq_types[i];
+		irq = platform_get_irq_byname(pdev, irq_type->irq_name);
+		if (irq < 0)
 			return -EINVAL;
-		}
-		irq_data[i].rdev = rdev;
 
+		irq_data = devm_kmalloc(tps->dev, sizeof(*irq_data), GFP_KERNEL);
+		if (!irq_data)
+			return -ENOMEM;
+
+		irq_data->dev = tps->dev;
+		irq_data->type = irq_type;
 		error = devm_request_threaded_irq(tps->dev, irq, NULL,
 						  tps65219_regulator_irq_handler,
 						  IRQF_ONESHOT,
 						  irq_type->irq_name,
-						  &irq_data[i]);
-		if (error) {
-			dev_err(tps->dev, "failed to request %s IRQ %d: %d\n",
-				irq_type->irq_name, irq, error);
-			return error;
-		}
+						  irq_data);
+		if (error)
+			return dev_err_probe(tps->dev, PTR_ERR(rdev),
+					     "Failed to request %s IRQ %d: %d\n",
+					     irq_type->irq_name, irq, error);
 	}
 
 	return 0;
 }
 
 static const struct platform_device_id tps65219_regulator_id_table[] = {
-	{ "tps65219-regulator", },
+	{ "tps65214-regulator", TPS65214 },
+	{ "tps65215-regulator", TPS65215 },
+	{ "tps65219-regulator", TPS65219 },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(platform, tps65219_regulator_id_table);
 
 static struct platform_driver tps65219_regulator_driver = {
 	.driver = {
-		.name = "tps65219-pmic",
+		.name = "tps65219-regulator",
 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
 	},
 	.probe = tps65219_regulator_probe,
@@ -389,6 +505,5 @@
 module_platform_driver(tps65219_regulator_driver);
 
 MODULE_AUTHOR("Jerome Neanne <j-neanne@baylibre.com>");
-MODULE_DESCRIPTION("TPS65219 voltage regulator driver");
-MODULE_ALIAS("platform:tps65219-pmic");
+MODULE_DESCRIPTION("TPS65214/TPS65215/TPS65219 Regulator driver");
 MODULE_LICENSE("GPL");
diff -Naur --no-dereference a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
--- a/drivers/remoteproc/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/remoteproc/Kconfig	2025-10-23 09:30:40.286462238 -0400
@@ -8,6 +8,7 @@
 	select FW_LOADER
 	select VIRTIO
 	select WANT_DEV_COREDUMP
+	select DMA_SHARED_BUFFER
 	help
 	  Support for remote processors (such as DSP coprocessors). These
 	  are mainly used on embedded systems.
diff -Naur --no-dereference a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
--- a/drivers/remoteproc/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/remoteproc/Makefile	2025-10-23 09:30:40.286462238 -0400
@@ -36,7 +36,7 @@
 obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
 obj-$(CONFIG_ST_SLIM_REMOTEPROC)	+= st_slim_rproc.o
 obj-$(CONFIG_STM32_RPROC)		+= stm32_rproc.o
-obj-$(CONFIG_TI_K3_DSP_REMOTEPROC)	+= ti_k3_dsp_remoteproc.o
-obj-$(CONFIG_TI_K3_M4_REMOTEPROC)	+= ti_k3_m4_remoteproc.o
+obj-$(CONFIG_TI_K3_DSP_REMOTEPROC)	+= ti_k3_dsp_remoteproc.o ti_k3_common.o
+obj-$(CONFIG_TI_K3_M4_REMOTEPROC)	+= ti_k3_m4_remoteproc.o ti_k3_common.o
 obj-$(CONFIG_TI_K3_R5_REMOTEPROC)	+= ti_k3_r5_remoteproc.o
 obj-$(CONFIG_XLNX_R5_REMOTEPROC)	+= xlnx_r5_remoteproc.o
diff -Naur --no-dereference a/drivers/remoteproc/omap_remoteproc.h b/drivers/remoteproc/omap_remoteproc.h
--- a/drivers/remoteproc/omap_remoteproc.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/remoteproc/omap_remoteproc.h	2025-10-23 09:30:40.286462238 -0400
@@ -59,7 +59,9 @@
 	RP_MBOX_SUSPEND_SYSTEM	= 0xFFFFFF11,
 	RP_MBOX_SUSPEND_ACK	= 0xFFFFFF12,
 	RP_MBOX_SUSPEND_CANCEL	= 0xFFFFFF13,
-	RP_MBOX_END_MSG		= 0xFFFFFF14,
+	RP_MBOX_SHUTDOWN        = 0xFFFFFF14,
+	RP_MBOX_SHUTDOWN_ACK    = 0xFFFFFF15,
+	RP_MBOX_END_MSG		= 0xFFFFFF16,
 };
 
 #endif /* _OMAP_RPMSG_H */
diff -Naur --no-dereference a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
--- a/drivers/remoteproc/pru_rproc.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/remoteproc/pru_rproc.c	2025-10-23 09:30:40.286462238 -0400
@@ -14,6 +14,7 @@
 
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
+#include <linux/interrupt.h>
 #include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -67,6 +68,8 @@
 
 #define MAX_PRU_SYS_EVENTS 160
 
+static const char *pru_names[PRU_TYPE_MAX] = { "PRU", "RTU", "Tx_PRU" };
+
 /**
  * enum pru_iomem - PRU core memory/register range identifiers
  *
@@ -107,6 +110,7 @@
  * @pru_interrupt_map: pointer to interrupt mapping description (firmware)
  * @pru_interrupt_map_sz: pru_interrupt_map size
  * @rmw_lock: lock for read, modify, write operations on registers
+ * @irq_vring: IRQ number to use for processing vring buffers
  * @dbg_single_step: debug state variable to set PRU into single step mode
  * @dbg_continuous: debug state variable to restore PRU execution mode
  * @evt_count: number of mapped events
@@ -125,7 +129,8 @@
 	unsigned int *mapped_irq;
 	struct pru_irq_rsc *pru_interrupt_map;
 	size_t pru_interrupt_map_sz;
-	spinlock_t rmw_lock;
+	spinlock_t rmw_lock; /* register access lock */
+	int irq_vring;
 	u32 dbg_single_step;
 	u32 dbg_continuous;
 	u8 evt_count;
@@ -503,6 +508,76 @@
 }
 
 /*
+ * pru_rproc_vring_interrupt() - interrupt handler for processing vrings
+ * @irq: irq number associated with the PRU event MPU is listening on
+ * @data: interrupt handler data, will be a PRU rproc structure
+ *
+ * This handler is used by the PRU remoteproc driver when using PRU system
+ * events for processing the virtqueues. Unlike the mailbox IP, there is
+ * no payload associated with an interrupt, so either a unique event is
+ * used for each virtqueue kick, or both virtqueues are processed on a
+ * single event. The latter is chosen to conserve the usable PRU system
+ * events.
+ */
+static irqreturn_t pru_rproc_vring_interrupt(int irq, void *data)
+{
+	struct pru_rproc *pru = data;
+
+	dev_dbg(&pru->rproc->dev, "got vring irq\n");
+
+	/* process incoming buffers on both the Rx and Tx vrings */
+	rproc_vq_interrupt(pru->rproc, 0);
+	rproc_vq_interrupt(pru->rproc, 1);
+
+	return IRQ_HANDLED;
+}
+
+/* Kick a virtqueue. */
+static void pru_rproc_kick(struct rproc *rproc, int vq_id)
+{
+	struct device *dev = &rproc->dev;
+	struct pru_rproc *pru = rproc->priv;
+	int ret;
+
+	if (list_empty(&pru->rproc->rvdevs))
+		return;
+
+	dev_dbg(dev, "kicking vqid %d on %s%d\n", vq_id,
+		pru_names[pru->data->type], pru->id);
+
+	ret = irq_set_irqchip_state(pru->mapped_irq[0], IRQCHIP_STATE_PENDING, true);
+	if (ret < 0)
+		dev_err(dev, "pruss_intc_trigger failed: %d\n", ret);
+}
+
+/* Register vring irq handler if needed. */
+static int pru_vring_interrupt_setup(struct rproc *rproc)
+{
+	struct device *dev = &rproc->dev;
+	struct pru_rproc *pru = rproc->priv;
+	struct platform_device *pdev = to_platform_device(pru->dev);
+	int ret;
+
+	if (list_empty(&pru->rproc->rvdevs))
+		return 0;
+
+	/* get vring interrupts for supporting virtio rpmsg */
+	pru->irq_vring = platform_get_irq_byname(pdev, "vring");
+	if (pru->irq_vring <= 0)
+		return dev_err_probe(dev, pru->irq_vring, "unable to get vring interrupt\n");
+
+	ret = request_threaded_irq(pru->irq_vring, NULL,
+				   pru_rproc_vring_interrupt, IRQF_ONESHOT,
+				   dev_name(dev), pru);
+	if (ret) {
+		dev_err(dev, "failed to register vring irq handler: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
  * Parse the custom PRU interrupt map resource and configure the INTC
  * appropriately.
  */
@@ -597,12 +672,11 @@
 {
 	struct device *dev = &rproc->dev;
 	struct pru_rproc *pru = rproc->priv;
-	const char *names[PRU_TYPE_MAX] = { "PRU", "RTU", "Tx_PRU" };
 	u32 val;
 	int ret;
 
 	dev_dbg(dev, "starting %s%d: entry-point = 0x%llx\n",
-		names[pru->data->type], pru->id, (rproc->bootaddr >> 2));
+		pru_names[pru->data->type], pru->id, (rproc->bootaddr >> 2));
 
 	ret = pru_handle_intrmap(rproc);
 	/*
@@ -614,28 +688,45 @@
 	if (ret)
 		return ret;
 
+	ret = pru_vring_interrupt_setup(rproc);
+	if (ret)
+		goto fail;
+
 	val = CTRL_CTRL_EN | ((rproc->bootaddr >> 2) << 16);
 	pru_control_write_reg(pru, PRU_CTRL_CTRL, val);
 
 	return 0;
+
+fail:
+	/* dispose irq mapping - new firmware can provide new mapping */
+	if (pru->mapped_irq)
+		pru_dispose_irq_mapping(pru);
+
+	return ret;
 }
 
 static int pru_rproc_stop(struct rproc *rproc)
 {
 	struct device *dev = &rproc->dev;
 	struct pru_rproc *pru = rproc->priv;
-	const char *names[PRU_TYPE_MAX] = { "PRU", "RTU", "Tx_PRU" };
 	u32 val;
 
-	dev_dbg(dev, "stopping %s%d\n", names[pru->data->type], pru->id);
+	dev_dbg(dev, "stopping %s%d\n", pru_names[pru->data->type], pru->id);
 
 	val = pru_control_read_reg(pru, PRU_CTRL_CTRL);
 	val &= ~CTRL_CTRL_EN;
 	pru_control_write_reg(pru, PRU_CTRL_CTRL, val);
 
+	if (!list_empty(&pru->rproc->rvdevs) && pru->irq_vring > 0)
+		free_irq(pru->irq_vring, pru);
+
 	/* dispose irq mapping - new firmware can provide new mapping */
 	pru_dispose_irq_mapping(pru);
 
+	/* dispose vring mapping as well */
+	if (pru->irq_vring > 0)
+		irq_dispose_mapping(pru->irq_vring);
+
 	return 0;
 }
 
@@ -752,6 +843,7 @@
 static struct rproc_ops pru_rproc_ops = {
 	.start		= pru_rproc_start,
 	.stop		= pru_rproc_stop,
+	.kick		= pru_rproc_kick,
 	.da_to_va	= pru_rproc_da_to_va,
 };
 
diff -Naur --no-dereference a/drivers/remoteproc/remoteproc_cdev.c b/drivers/remoteproc/remoteproc_cdev.c
--- a/drivers/remoteproc/remoteproc_cdev.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/remoteproc/remoteproc_cdev.c	2025-10-23 09:30:40.286462238 -0400
@@ -18,9 +18,23 @@
 #define NUM_RPROC_DEVICES	64
 static dev_t rproc_major;
 
+struct rproc_cdev {
+	struct rproc *rproc;
+	bool cdev_put_on_release;
+	/* Protects the attachments lists */
+	struct mutex mutex;
+	struct list_head attachments;
+};
+
+struct rproc_cdev_attach {
+	struct dma_buf *dmabuf;
+	struct list_head node;
+};
+
 static ssize_t rproc_cdev_write(struct file *filp, const char __user *buf, size_t len, loff_t *pos)
 {
-	struct rproc *rproc = container_of(filp->f_inode->i_cdev, struct rproc, cdev);
+	struct rproc_cdev *rproc_cdev = filp->private_data;
+	struct rproc *rproc = rproc_cdev->rproc;
 	int ret = 0;
 	char cmd[10];
 
@@ -47,7 +61,8 @@
 
 static long rproc_device_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
 {
-	struct rproc *rproc = container_of(filp->f_inode->i_cdev, struct rproc, cdev);
+	struct rproc_cdev *rproc_cdev = filp->private_data;
+	struct rproc *rproc = rproc_cdev->rproc;
 	void __user *argp = (void __user *)arg;
 	s32 param;
 
@@ -56,14 +71,57 @@
 		if (copy_from_user(&param, argp, sizeof(s32)))
 			return -EFAULT;
 
-		rproc->cdev_put_on_release = !!param;
+		rproc_cdev->cdev_put_on_release = !!param;
 		break;
 	case RPROC_GET_SHUTDOWN_ON_RELEASE:
-		param = (s32)rproc->cdev_put_on_release;
+		param = (s32)rproc_cdev->cdev_put_on_release;
 		if (copy_to_user(argp, &param, sizeof(s32)))
 			return -EFAULT;
 
 		break;
+	case RPROC_IOC_DMA_BUF_ATTACH:
+		{
+			struct rproc_dma_buf_attach_data data;
+			struct rproc_cdev_attach *attach;
+			struct dma_buf *dmabuf;
+			dma_addr_t da;
+			int ret;
+
+			if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(ioctl)))
+				return -EFAULT;
+
+			dmabuf = dma_buf_get(data.fd);
+			if (IS_ERR(dmabuf))
+				return PTR_ERR(dmabuf);
+
+			ret = rproc_attach_dmabuf(rproc, dmabuf);
+			if (ret) {
+				dma_buf_put(dmabuf);
+				return ret;
+			}
+
+			ret = rproc_dmabuf_get_da(rproc, dmabuf, &da);
+			if (ret) {
+				rproc_detach_dmabuf(rproc, dmabuf);
+				dma_buf_put(dmabuf);
+				return ret;
+			}
+			data.da = da;
+
+			/* Save for later removal */
+			attach = kzalloc(sizeof(*attach), GFP_KERNEL);
+			if (!attach) {
+				rproc_detach_dmabuf(rproc, dmabuf);
+				dma_buf_put(dmabuf);
+				return -ENOMEM;
+			}
+			attach->dmabuf = dmabuf;
+			list_add_tail(&attach->node, &rproc_cdev->attachments);
+
+			if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(ioctl)))
+				return -EFAULT;
+		}
+		break;
 	default:
 		dev_err(&rproc->dev, "Unsupported ioctl\n");
 		return -EINVAL;
@@ -72,18 +130,46 @@
 	return 0;
 }
 
-static int rproc_cdev_release(struct inode *inode, struct file *filp)
+static int rproc_cdev_open(struct inode *inode, struct file *file)
 {
 	struct rproc *rproc = container_of(inode->i_cdev, struct rproc, cdev);
+	struct rproc_cdev *rproc_cdev;
+
+	rproc_cdev = kzalloc(sizeof(*rproc_cdev), GFP_KERNEL);
+	if (!rproc_cdev)
+		return -ENOMEM;
+
+	rproc_cdev->rproc = rproc;
+	mutex_init(&rproc_cdev->mutex);
+	INIT_LIST_HEAD(&rproc_cdev->attachments);
+
+	file->private_data = rproc_cdev;
+
+	return 0;
+}
+
+static int rproc_cdev_release(struct inode *inode, struct file *filp)
+{
+	struct rproc_cdev *rproc_cdev = filp->private_data;
+	struct rproc *rproc = rproc_cdev->rproc;
 	int ret = 0;
 
-	if (!rproc->cdev_put_on_release)
-		return 0;
+	if (rproc_cdev->cdev_put_on_release) {
+		if (rproc->state == RPROC_RUNNING)
+			rproc_shutdown(rproc);
+		else if (rproc->state == RPROC_ATTACHED)
+			ret = rproc_detach(rproc);
+	}
 
-	if (rproc->state == RPROC_RUNNING)
-		rproc_shutdown(rproc);
-	else if (rproc->state == RPROC_ATTACHED)
-		ret = rproc_detach(rproc);
+	/* Release all buffers attached with this file */
+	struct rproc_cdev_attach *attach, *atmp;
+	list_for_each_entry_safe(attach, atmp, &rproc_cdev->attachments, node) {
+		rproc_detach_dmabuf(rproc, attach->dmabuf);
+		dma_buf_put(attach->dmabuf);
+		kfree(attach);
+	}
+	mutex_destroy(&rproc_cdev->mutex);
+	kfree(rproc_cdev);
 
 	return ret;
 }
@@ -92,6 +178,7 @@
 	.write = rproc_cdev_write,
 	.unlocked_ioctl = rproc_device_ioctl,
 	.compat_ioctl = compat_ptr_ioctl,
+	.open = rproc_cdev_open,
 	.release = rproc_cdev_release,
 };
 
diff -Naur --no-dereference a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
--- a/drivers/remoteproc/remoteproc_core.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/remoteproc/remoteproc_core.c	2025-10-23 09:30:40.286462238 -0400
@@ -20,6 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/dma-map-ops.h>
 #include <linux/panic_notifier.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
@@ -895,6 +896,129 @@
 }
 EXPORT_SYMBOL(rproc_add_carveout);
 
+static struct rproc_dmabuf_entry *rproc_find_entry_for_dmabuf(struct rproc *rproc,
+							      struct dma_buf *dmabuf)
+{
+	struct rproc_dmabuf_entry *dmabuf_entry;
+
+	list_for_each_entry(dmabuf_entry, &rproc->dmabufs, node) {
+		if (dmabuf_entry->dmabuf == dmabuf)
+			return dmabuf_entry;
+	}
+
+	return NULL;
+}
+
+/* TODO: Should we map here? */
+int rproc_dmabuf_get_da(struct rproc *rproc, struct dma_buf *dmabuf, dma_addr_t *dma)
+{
+	struct rproc_dmabuf_entry *dmabuf_entry;
+
+	guard(mutex)(&rproc->lock);
+
+	dmabuf_entry = rproc_find_entry_for_dmabuf(rproc, dmabuf);
+	if (!dmabuf_entry)
+		return -EINVAL;
+
+	/* TODO: Should this be ->da? */
+	*dma = dmabuf_entry->dma;
+
+	return 0;
+}
+
+/**
+ * rproc_attach_dmabuf() - attach a DMA-BUF to rproc device
+ * @rproc: rproc handle
+ * @dmabuf: dmabuf entry to register
+ *
+ * This function attaches and maps specified DMUBUF to this rproc.
+ */
+int rproc_attach_dmabuf(struct rproc *rproc, struct dma_buf *dmabuf)
+{
+	struct rproc_dmabuf_entry *dmabuf_entry;
+	struct device *dev = &rproc->dev;
+	struct dma_buf_attachment *attachment;
+	struct sg_table *sgt;
+	int ret;
+
+	/* Prevent multiple entries in list for same dmabuf */
+	guard(mutex)(&rproc->lock);
+
+	/* Check if already in list */
+	dmabuf_entry = rproc_find_entry_for_dmabuf(rproc, dmabuf);
+	if (dmabuf_entry) {
+		dmabuf_entry->refcount++;
+		return 0;
+	}
+
+	attachment = dma_buf_attach(dmabuf, dev);
+	if (IS_ERR(attachment))
+		return PTR_ERR(attachment);
+
+	/* TODO: Move mapping to get_da()? */
+	sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL);
+	if (IS_ERR(sgt)) {
+		ret = PTR_ERR(sgt);
+		goto fail_detach;
+	}
+
+	/* FIXME: Only physically contiguous buffers currently supported */
+	if (sgt->orig_nents != 1) {
+		dev_err(dev, "DMA-BUF not contiguous\n");
+		ret =  -EINVAL;
+		goto fail_unmap;
+	}
+
+	dmabuf_entry = kzalloc(sizeof(*dmabuf_entry), GFP_KERNEL);
+	dmabuf_entry->len = sg_dma_len(sgt->sgl);
+	dmabuf_entry->dma = sg_dma_address(sgt->sgl);
+	/* TODO: Check this */
+//	rproc_pa_to_da(rproc, dmabuf_entry->dma, &dmabuf_entry->da);
+	dmabuf_entry->dmabuf = dmabuf;
+	dmabuf_entry->attachment = attachment;
+	dmabuf_entry->sgt = sgt;
+	dmabuf_entry->refcount = 1;
+
+	list_add_tail(&dmabuf_entry->node, &rproc->dmabufs);
+
+	return 0;
+
+fail_unmap:
+	dma_buf_unmap_attachment(attachment, sgt, DMA_BIDIRECTIONAL);
+fail_detach:
+	dma_buf_detach(dmabuf, attachment);
+	return ret;
+}
+EXPORT_SYMBOL(rproc_attach_dmabuf);
+
+static void rproc_release_dmabuf(struct rproc *rproc, struct rproc_dmabuf_entry *dmabuf_entry)
+{
+	if (dmabuf_entry->attachment && dmabuf_entry->sgt)
+		dma_buf_unmap_attachment(dmabuf_entry->attachment, dmabuf_entry->sgt, DMA_BIDIRECTIONAL);
+	if (dmabuf_entry->dmabuf && dmabuf_entry->attachment)
+		dma_buf_detach(dmabuf_entry->dmabuf, dmabuf_entry->attachment);
+	list_del(&dmabuf_entry->node);
+	kfree(dmabuf_entry);
+}
+
+int rproc_detach_dmabuf(struct rproc *rproc, struct dma_buf *dmabuf)
+{
+	struct rproc_dmabuf_entry *dmabuf_entry;
+
+	guard(mutex)(&rproc->lock);
+
+	dmabuf_entry = rproc_find_entry_for_dmabuf(rproc, dmabuf);
+	if (!dmabuf_entry)
+		return -EINVAL;
+
+	dmabuf_entry->refcount--;
+	if (dmabuf_entry->refcount < 1)
+		rproc_release_dmabuf(rproc, dmabuf_entry);
+
+	return 0;
+}
+EXPORT_SYMBOL(rproc_detach_dmabuf);
+
 /**
  * rproc_mem_entry_init() - allocate and initialize rproc_mem_entry struct
  * @dev: pointer on device struct
@@ -1221,6 +1345,7 @@
 void rproc_resource_cleanup(struct rproc *rproc)
 {
 	struct rproc_mem_entry *entry, *tmp;
+	struct rproc_dmabuf_entry *dmabuf, *dtmp;
 	struct rproc_debug_trace *trace, *ttmp;
 	struct rproc_vdev *rvdev, *rvtmp;
 	struct device *dev = &rproc->dev;
@@ -1256,6 +1381,10 @@
 		kfree(entry);
 	}
 
+	/* clean up dmabufs */
+	list_for_each_entry_safe(dmabuf, dtmp, &rproc->dmabufs, node)
+		rproc_release_dmabuf(rproc, dmabuf);
+
 	/* clean up remote vdev entries */
 	list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node)
 		platform_device_unregister(rvdev->pdev);
@@ -2494,6 +2623,18 @@
 		goto put_device;
 	}
 
+	/* Make device dma capable by inheriting from parent's capabilities */
+	set_dma_ops(&rproc->dev, get_dma_ops(rproc->dev.parent));
+	if (dma_coerce_mask_and_coherent(&rproc->dev, dma_get_mask(rproc->dev.parent)))
+		dev_warn(&rproc->dev, "Failed to set DMA mask. Trying to continue...\n");
+	rproc->dev.dma_parms = &rproc->dma_parms;
+	/*
+	 * We could use dma_get_max_seg_size(rproc->dev.parent) here but the
+	 * parent is not usually setup correctly either, use full 32bit mask
+	 * for now.
+	 */
+	dma_set_max_seg_size(&rproc->dev, DMA_BIT_MASK(32));
+
 	rproc->name = kstrdup_const(name, GFP_KERNEL);
 	if (!rproc->name)
 		goto put_device;
@@ -2511,6 +2652,7 @@
 	mutex_init(&rproc->lock);
 
 	INIT_LIST_HEAD(&rproc->carveouts);
+	INIT_LIST_HEAD(&rproc->dmabufs);
 	INIT_LIST_HEAD(&rproc->mappings);
 	INIT_LIST_HEAD(&rproc->traces);
 	INIT_LIST_HEAD(&rproc->rvdevs);
diff -Naur --no-dereference a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
--- a/drivers/remoteproc/remoteproc_internal.h	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/remoteproc/remoteproc_internal.h	2025-10-23 09:30:40.286462238 -0400
@@ -39,6 +39,26 @@
 	struct fw_rsc_vdev *rsc;
 };
 
+/**
+ * struct rproc_dmabuf_entry - dmabuf entry descriptor
+ * @va:	virtual address
+ * @dma: dma address
+ * @len: length, in bytes
+ * @da: device address
+ *
+ * @node: list node
+ */
+struct rproc_dmabuf_entry {
+	size_t len;
+	dma_addr_t dma;
+	u32 da;
+	struct dma_buf *dmabuf;
+	struct dma_buf_attachment *attachment;
+	struct sg_table *sgt;
+	size_t refcount;
+	struct list_head node;
+};
+
 static inline bool rproc_has_feature(struct rproc *rproc, unsigned int feature)
 {
 	return test_bit(feature, rproc->features);
diff -Naur --no-dereference a/drivers/remoteproc/ti_k3_common.c b/drivers/remoteproc/ti_k3_common.c
--- a/drivers/remoteproc/ti_k3_common.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/remoteproc/ti_k3_common.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,771 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 Remote Processor(s) driver common code
+ *
+ * Refactored out of ti_k3_dsp_remoteproc.c and ti_k3_m4_remoteproc.c.
+ *
+ * ti_k3_dsp_remoteproc.c:
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
+ *	Suman Anna <s-anna@ti.com>
+ *
+ * ti_k3_m4_remoteproc.c:
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
+ *	Hari Nagalla <hnagalla@ti.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/omap-mailbox.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+#include <linux/remoteproc.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+#include "ti_sci_proc.h"
+#include "ti_k3_common.h"
+
+/**
+ * is_core_in_wfi - local utility function to check core status
+ * @kproc: remote core pointer used for checking core status
+ *
+ * This utility function is invoked by the shutdown sequence to ensure
+ * the remote core is in wfi, before asserting a reset.
+ */
+static int is_core_in_wfi(struct k3_rproc *core)
+{
+	int ret;
+	u64 boot_vec;
+	u32 cfg, ctrl, stat;
+
+	ret = ti_sci_proc_get_status(core->tsp, &boot_vec, &cfg, &ctrl, &stat);
+
+	if (ret < 0)
+		return 0;
+
+	return (stat & PROC_BOOT_STATUS_FLAG_CPU_WFI);
+}
+
+/**
+ * get_core_status - local utility function to check core status
+ * @core: remote core pointer used for checking core status
+ * @cstatus: core status
+ *
+ * This utility function is invoked by the resume handler to get remote core
+ * status.
+ */
+static int get_core_status(struct k3_rproc *core, bool *cstatus)
+{
+	const struct ti_sci_handle *ti_sci = core->ti_sci;
+	bool r_state = false, c_state = false;
+	int ret;
+
+	ret = ti_sci->ops.dev_ops.is_on(ti_sci, core->ti_sci_id, &r_state, &c_state);
+	if (ret) {
+		dev_err(core->dev, "ti_sci call to get dev status failed\n");
+		return ret;
+	}
+
+	*cstatus = c_state;
+
+	return 0;
+}
+
+/**
+ * k3_rproc_mbox_callback() - inbound mailbox message handler
+ * @client: mailbox client pointer used for requesting the mailbox channel
+ * @data: mailbox payload
+ *
+ * This handler is invoked by the K3 mailbox driver whenever a mailbox
+ * message is received. Usually, the mailbox payload simply contains
+ * the index of the virtqueue that is kicked by the remote processor,
+ * and we let remoteproc core handle it.
+ *
+ * In addition to virtqueue indices, we also have some out-of-band values
+ * that indicate different events. Those values are deliberately very
+ * large so they don't coincide with virtqueue indices.
+ */
+void k3_rproc_mbox_callback(struct mbox_client *client, void *data)
+{
+	struct k3_rproc *kproc = container_of(client, struct k3_rproc, client);
+	struct device *dev = kproc->rproc->dev.parent;
+	struct rproc *rproc = kproc->rproc;
+	u32 msg = (u32)(uintptr_t)(data);
+
+	dev_dbg(dev, "mbox msg: 0x%x\n", msg);
+
+	switch (msg) {
+	case RP_MBOX_CRASH:
+		/*
+		 * remoteproc detected an exception, but error recovery is not
+		 * supported. So, just log this for now
+		 */
+		dev_err(dev, "K3 rproc %s crashed\n", rproc->name);
+		break;
+	case RP_MBOX_ECHO_REPLY:
+		dev_info(dev, "received echo reply from %s\n", rproc->name);
+		break;
+	case RP_MBOX_SHUTDOWN_ACK:
+		dev_dbg(dev, "received shutdown_ack from %s\n", rproc->name);
+		complete(&kproc->shut_comp);
+		break;
+	case RP_MBOX_SUSPEND_ACK:
+		dev_dbg(dev, "received suspend_ack from %s\n", rproc->name);
+		kproc->suspend_status = RP_MBOX_SUSPEND_ACK;
+		complete(&kproc->suspend_comp);
+		break;
+	case RP_MBOX_SUSPEND_CANCEL:
+		dev_err(dev, "received suspend_cancel from %s\n", rproc->name);
+		kproc->suspend_status = RP_MBOX_SUSPEND_CANCEL;
+		complete(&kproc->suspend_comp);
+		break;
+	case RP_MBOX_SUSPEND_AUTO:
+		dev_dbg(dev, "received suspend_auto from %s\n", rproc->name);
+		kproc->suspend_status = RP_MBOX_SUSPEND_AUTO;
+		complete(&kproc->suspend_comp);
+		break;
+	default:
+		/* silently handle all other valid messages */
+		if (msg >= RP_MBOX_READY && msg < RP_MBOX_END_MSG)
+			return;
+		if (msg > rproc->max_notifyid) {
+			dev_dbg(dev, "dropping unknown message 0x%x", msg);
+			return;
+		}
+		/* msg contains the index of the triggered vring */
+		if (rproc_vq_interrupt(rproc, msg) == IRQ_NONE)
+			dev_dbg(dev, "no message was found in vqid %d\n", msg);
+	}
+}
+EXPORT_SYMBOL_GPL(k3_rproc_mbox_callback);
+
+/*
+ * Kick the remote processor to notify about pending unprocessed messages.
+ * The vqid usage is not used and is inconsequential, as the kick is performed
+ * through a simulated GPIO (a bit in an IPC interrupt-triggering register),
+ * the remote processor is expected to process both its Tx and Rx virtqueues.
+ */
+void k3_rproc_kick(struct rproc *rproc, int vqid)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	u32 msg = (u32)vqid;
+	int ret;
+
+	/*
+	 * Send the index of the triggered virtqueue in the mailbox payload.
+	 * NOTE: msg is cast to uintptr_t to prevent compiler warnings when
+	 * void* is 64bit. It is safely cast back to u32 in the mailbox driver.
+	 */
+	ret = mbox_send_message(kproc->mbox, (void *)(uintptr_t)msg);
+	if (ret < 0)
+		dev_err(dev, "failed to send mailbox message, status = %d\n",
+			ret);
+}
+EXPORT_SYMBOL_GPL(k3_rproc_kick);
+
+/* Put the remote processor into reset */
+int k3_rproc_reset(struct k3_rproc *kproc)
+{
+	struct device *dev = kproc->dev;
+	int ret;
+
+	if (kproc->data->uses_lreset) {
+		ret = reset_control_assert(kproc->reset);
+		if (ret)
+			dev_err(dev, "local-reset assert failed (%pe)\n", ERR_PTR(ret));
+		return ret;
+	}
+
+	ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,
+						    kproc->ti_sci_id);
+	if (ret) {
+		dev_err(dev, "module-reset assert failed (%pe)\n", ERR_PTR(ret));
+		if (reset_control_deassert(kproc->reset))
+			dev_warn(dev, "local-reset deassert back failed\n");
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_reset);
+
+/* Release the remote processor from reset */
+int k3_rproc_release(struct k3_rproc *kproc)
+{
+	struct device *dev = kproc->dev;
+	int ret;
+
+	if (kproc->data->uses_lreset) {
+		ret = reset_control_deassert(kproc->reset);
+		if (ret) {
+			dev_err(dev, "local-reset deassert failed, (%pe)\n", ERR_PTR(ret));
+			if (kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,
+								  kproc->ti_sci_id))
+				dev_warn(dev, "module-reset assert back failed\n");
+		}
+
+		return ret;
+	}
+
+	ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci,
+						    kproc->ti_sci_id);
+	if (ret)
+		dev_err(dev, "module-reset deassert failed (%pe)\n", ERR_PTR(ret));
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_release);
+
+int k3_rproc_request_mbox(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	struct mbox_client *client = &kproc->client;
+	struct device *dev = kproc->dev;
+	int ret;
+
+	client->dev = dev;
+	client->tx_done = NULL;
+	client->rx_callback = k3_rproc_mbox_callback;
+	client->tx_block = false;
+	client->knows_txdone = false;
+
+	kproc->mbox = mbox_request_channel(client, 0);
+	if (IS_ERR(kproc->mbox))
+		return dev_err_probe(dev, PTR_ERR(kproc->mbox),
+				     "mbox_request_channel failed\n");
+
+	/*
+	 * Ping the remote processor, this is only for sanity-sake for now;
+	 * there is no functional effect whatsoever.
+	 *
+	 * Note that the reply will _not_ arrive immediately: this message
+	 * will wait in the mailbox fifo until the remote processor is booted.
+	 */
+	ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_ECHO_REQUEST);
+	if (ret < 0) {
+		dev_err(dev, "mbox_send_message failed (%pe)\n", ERR_PTR(ret));
+		mbox_free_channel(kproc->mbox);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_request_mbox);
+
+/*
+ * The K3 DSP and M4 cores have a local reset that affects only the CPU, and a
+ * generic module reset that powers on the device and allows the internal
+ * memories to be accessed while the local reset is asserted. This function is
+ * used to release the global reset on remote cores to allow loading into the
+ * internal RAMs. The .prepare() ops is invoked by remoteproc core before any
+ * firmware loading, and is followed by the .start() ops after loading to
+ * actually let the remote cores to run.
+ */
+int k3_rproc_prepare(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	int ret;
+
+	/* If the core is running already no need to deassert the module reset */
+	if (rproc->state == RPROC_DETACHED)
+		return 0;
+
+	/*
+	 * Ensure the local reset is asserted so the core doesn't
+	 * execute bogus code when the module reset is released.
+	 */
+	if (kproc->data->uses_lreset) {
+		ret = k3_rproc_reset(kproc);
+		if (ret)
+			return ret;
+
+		ret = reset_control_status(kproc->reset);
+		if (ret <= 0) {
+			dev_err(dev, "local reset still not asserted\n");
+			return ret;
+		}
+	}
+
+	ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci,
+						    kproc->ti_sci_id);
+	if (ret) {
+		dev_err(dev, "could not deassert module-reset for internal RAM loading\n");
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_prepare);
+
+/*
+ * This function implements the .unprepare() ops and performs the complimentary
+ * operations to that of the .prepare() ops. The function is used to assert the
+ * global reset on applicable K3 DSP and M4 cores. This completes the second
+ * portion of powering down the remote core. The cores themselves are only
+ * halted in the .stop() callback through the local reset, and the .unprepare()
+ * ops is invoked by the remoteproc core after the remoteproc is stopped to
+ * balance the global reset.
+ */
+int k3_rproc_unprepare(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	int ret;
+
+	/* If the core is going to be detached do not assert the module reset */
+	if (rproc->state == RPROC_ATTACHED)
+		return 0;
+
+	ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,
+						    kproc->ti_sci_id);
+	if (ret) {
+		dev_err(dev, "module-reset assert failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_unprepare);
+
+/*
+ * Power up the remote processor.
+ *
+ * This function will be invoked only after the firmware for this rproc
+ * was loaded, parsed successfully, and all of its resource requirements
+ * were met. This callback is invoked only in remoteproc mode.
+ */
+int k3_rproc_start(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+
+	return k3_rproc_release(kproc);
+}
+EXPORT_SYMBOL_GPL(k3_rproc_start);
+
+/*
+ * Stop the remote processor.
+ *
+ * This function puts the remote processor into reset, and finishes processing
+ * of any pending messages. This callback is invoked only in remoteproc mode.
+ */
+int k3_rproc_stop(struct rproc *rproc)
+{
+	unsigned long to = msecs_to_jiffies(3000);
+	struct k3_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	u32 msg = omap_mbox_message(RP_MBOX_SHUTDOWN);
+	u32 stat = 0;
+	int ret;
+
+	reinit_completion(&kproc->shut_comp);
+	ret = mbox_send_message(kproc->mbox, (void *) (uintptr_t) msg);
+	if (ret < 0) {
+		dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = wait_for_completion_timeout(&kproc->shut_comp, to);
+	if (ret == 0) {
+		dev_err(dev, "%s: timedout waiting for rproc completion event\n", __func__);
+		return -EBUSY;
+	};
+
+	ret = readx_poll_timeout(is_core_in_wfi, kproc, stat, stat, 200, 2000);
+	if (ret)
+		return ret;
+
+	return k3_rproc_reset(kproc);
+}
+EXPORT_SYMBOL_GPL(k3_rproc_stop);
+
+/*
+ * Attach to a running remote processor (IPC-only mode)
+ *
+ * This rproc attach callback is a NOP. The remote processor is already
+ * booted, and all required resources have been acquired during probe
+ * routine, so there is no need to issue any TI-SCI commands to boot the
+ * remote core. This callback is invoked only in IPC-only mode and exists
+ * because rproc_validate() checks for its existence.
+ */
+int k3_rproc_attach(struct rproc *rproc) { return 0; }
+EXPORT_SYMBOL_GPL(k3_rproc_attach);
+
+/*
+ * Detach from a running remote processor (IPC-only mode)
+ *
+ * This rproc detach callback is a NOP. The remote core is not stopped
+ * and will be left to continue to run its booted firmware. This callback
+ * is invoked only in IPC-only mode and exists for sanity sake.
+ */
+int k3_rproc_detach(struct rproc *rproc) { return 0; }
+EXPORT_SYMBOL_GPL(k3_rproc_detach);
+
+/*
+ * This function implements the .get_loaded_rsc_table() callback and is used
+ * to provide the resource table for a booted remote processor in IPC-only
+ * mode. The remote processor firmwares follow a design-by-contract approach
+ * and are expected to have the resource table at the base of the DDR region
+ * reserved for firmware usage. This provides flexibility for the remote
+ * processor to be booted by different bootloaders that may or may not have the
+ * ability to publish the resource table address and size through a DT
+ * property.
+ */
+struct resource_table *k3_get_loaded_rsc_table(struct rproc *rproc,
+					       size_t *rsc_table_sz)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+
+	if (!kproc->rmem[0].cpu_addr) {
+		dev_err(dev, "memory-region #1 does not exist, loaded rsc table can't be found");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/*
+	 * NOTE: The resource table size is currently hard-coded to a maximum
+	 * of 256 bytes. The most common resource table usage for K3 firmwares
+	 * is to only have the vdev resource entry and an optional trace entry.
+	 * The exact size could be computed based on resource table address, but
+	 * the hard-coded value suffices to support the IPC-only mode.
+	 */
+	*rsc_table_sz = 256;
+	return (__force struct resource_table *)kproc->rmem[0].cpu_addr;
+}
+EXPORT_SYMBOL_GPL(k3_get_loaded_rsc_table);
+
+/*
+ * Custom function to translate a remote processor device address (internal
+ * RAMs only) to a kernel virtual address.  The remote processors can access
+ * their RAMs at either an internal address visible only from a remote
+ * processor, or at the SoC-level bus address. Both these addresses need to be
+ * looked through for translation. The translated addresses can be used either
+ * by the remoteproc core for loading (when using kernel remoteproc loader), or
+ * by any rpmsg bus drivers.
+ */
+void *k3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	void __iomem *va = NULL;
+	phys_addr_t bus_addr;
+	u32 dev_addr, offset;
+	size_t size;
+	int i;
+
+	if (len == 0)
+		return NULL;
+
+	for (i = 0; i < kproc->num_mems; i++) {
+		bus_addr = kproc->mem[i].bus_addr;
+		dev_addr = kproc->mem[i].dev_addr;
+		size = kproc->mem[i].size;
+
+		if (da < KEYSTONE_RPROC_LOCAL_ADDRESS_MASK) {
+			/* handle rproc-view addresses */
+			if (da >= dev_addr &&
+			    ((da + len) <= (dev_addr + size))) {
+				offset = da - dev_addr;
+				va = kproc->mem[i].cpu_addr + offset;
+				return (__force void *)va;
+			}
+		} else {
+			/* handle SoC-view addresses */
+			if (da >= bus_addr &&
+			    (da + len) <= (bus_addr + size)) {
+				offset = da - bus_addr;
+				va = kproc->mem[i].cpu_addr + offset;
+				return (__force void *)va;
+			}
+		}
+	}
+
+	/* handle static DDR reserved memory regions */
+	for (i = 0; i < kproc->num_rmems; i++) {
+		dev_addr = kproc->rmem[i].dev_addr;
+		size = kproc->rmem[i].size;
+
+		if (da >= dev_addr && ((da + len) <= (dev_addr + size))) {
+			offset = da - dev_addr;
+			va = kproc->rmem[i].cpu_addr + offset;
+			return (__force void *)va;
+		}
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_da_to_va);
+
+int k3_rproc_of_get_memories(struct platform_device *pdev,
+			     struct k3_rproc *kproc)
+{
+	const struct k3_rproc_dev_data *data = kproc->data;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	int num_mems = 0;
+	int i;
+
+	num_mems = kproc->data->num_mems;
+	kproc->mem = devm_kcalloc(kproc->dev, num_mems,
+				  sizeof(*kproc->mem), GFP_KERNEL);
+	if (!kproc->mem)
+		return -ENOMEM;
+
+	for (i = 0; i < num_mems; i++) {
+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						   data->mems[i].name);
+		if (!res) {
+			dev_err(dev, "found no memory resource for %s\n",
+				data->mems[i].name);
+			return -EINVAL;
+		}
+		if (!devm_request_mem_region(dev, res->start,
+					     resource_size(res),
+					     dev_name(dev))) {
+			dev_err(dev, "could not request %s region for resource\n",
+				data->mems[i].name);
+			return -EBUSY;
+		}
+
+		kproc->mem[i].cpu_addr = devm_ioremap_wc(dev, res->start,
+							 resource_size(res));
+		if (!kproc->mem[i].cpu_addr) {
+			dev_err(dev, "failed to map %s memory\n",
+				data->mems[i].name);
+			return -ENOMEM;
+		}
+		kproc->mem[i].bus_addr = res->start;
+		kproc->mem[i].dev_addr = data->mems[i].dev_addr;
+		kproc->mem[i].size = resource_size(res);
+
+		dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %pK da 0x%x\n",
+			data->mems[i].name, &kproc->mem[i].bus_addr,
+			kproc->mem[i].size, kproc->mem[i].cpu_addr,
+			kproc->mem[i].dev_addr);
+	}
+	kproc->num_mems = num_mems;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_of_get_memories);
+
+void k3_mem_release(void *data)
+{
+	struct device *dev = data;
+
+	of_reserved_mem_device_release(dev);
+}
+EXPORT_SYMBOL_GPL(k3_mem_release);
+
+int k3_reserved_mem_init(struct k3_rproc *kproc)
+{
+	struct device *dev = kproc->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *rmem_np;
+	struct reserved_mem *rmem;
+	int num_rmems;
+	int ret, i;
+
+	num_rmems = of_property_count_elems_of_size(np, "memory-region",
+						    sizeof(phandle));
+	if (num_rmems < 0) {
+		dev_err(dev, "device does not reserved memory regions (%d)\n",
+			num_rmems);
+		return -EINVAL;
+	}
+	if (num_rmems < 2) {
+		dev_err(dev, "device needs at least two memory regions to be defined, num = %d\n",
+			num_rmems);
+		return -EINVAL;
+	}
+
+	/* use reserved memory region 0 for vring DMA allocations */
+	ret = of_reserved_mem_device_init_by_idx(dev, np, 0);
+	if (ret) {
+		dev_err(dev, "device cannot initialize DMA pool (%d)\n", ret);
+		return ret;
+	}
+	ret = devm_add_action_or_reset(dev, k3_mem_release, dev);
+	if (ret)
+		return ret;
+
+	num_rmems--;
+	kproc->rmem = devm_kcalloc(dev, num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
+	if (!kproc->rmem)
+		return -ENOMEM;
+
+	/* use remaining reserved memory regions for static carveouts */
+	for (i = 0; i < num_rmems; i++) {
+		rmem_np = of_parse_phandle(np, "memory-region", i + 1);
+		if (!rmem_np)
+			return -EINVAL;
+
+		rmem = of_reserved_mem_lookup(rmem_np);
+		of_node_put(rmem_np);
+		if (!rmem)
+			return -EINVAL;
+
+		kproc->rmem[i].bus_addr = rmem->base;
+		/* 64-bit address regions currently not supported */
+		kproc->rmem[i].dev_addr = (u32)rmem->base;
+		kproc->rmem[i].size = rmem->size;
+		kproc->rmem[i].cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
+		if (!kproc->rmem[i].cpu_addr) {
+			dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n",
+				i + 1, &rmem->base, &rmem->size);
+			return -ENOMEM;
+		}
+
+		dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",
+			i + 1, &kproc->rmem[i].bus_addr,
+			kproc->rmem[i].size, kproc->rmem[i].cpu_addr,
+			kproc->rmem[i].dev_addr);
+	}
+	kproc->num_rmems = num_rmems;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(k3_reserved_mem_init);
+
+void k3_release_tsp(void *data)
+{
+	struct ti_sci_proc *tsp = data;
+
+	ti_sci_proc_release(tsp);
+}
+EXPORT_SYMBOL_GPL(k3_release_tsp);
+
+int k3_rproc_suspend(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	unsigned long msg = RP_MBOX_SUSPEND_SYSTEM;
+	unsigned long to = msecs_to_jiffies(5000);
+	struct dev_pm_qos_request qos_req;
+	struct device *dev = kproc->dev;
+	int ret = 0;
+
+	if (rproc->state != RPROC_RUNNING)
+		return ret;
+
+	kproc->suspend_status = 0;
+	reinit_completion(&kproc->suspend_comp);
+
+	ret = mbox_send_message(kproc->mbox, (void *)msg);
+	if (ret < 0) {
+		dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = wait_for_completion_timeout(&kproc->suspend_comp, to);
+	if (ret == 0) {
+		dev_err(dev, "%s: timedout waiting for rproc completion event\n", __func__);
+		/* Set constraint to keep the device on */
+		dev_pm_qos_add_request(kproc->dev, &qos_req, DEV_PM_QOS_RESUME_LATENCY, 0);
+		return 0;
+	};
+
+	dev_dbg(dev, "%s: suspend ack from remote 0x%x\n", __func__, kproc->suspend_status);
+	if (kproc->suspend_status == RP_MBOX_SUSPEND_ACK) {
+		/* shutdown the remote core */
+		ret = rproc_shutdown(rproc);
+		if (ret) {
+			dev_err(dev, "rproc_shutdown failed, ret = %d\n", ret);
+			return -EBUSY;
+		}
+		kproc->rproc->state = RPROC_SUSPENDED;
+	} else if (kproc->suspend_status == RP_MBOX_SUSPEND_CANCEL) {
+		return -EBUSY;
+	} else if (kproc->suspend_status == RP_MBOX_SUSPEND_AUTO) {
+		kproc->rproc->state = RPROC_SUSPENDED;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_suspend);
+
+int k3_rproc_resume(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	bool cstatus = false;
+	unsigned long msg = RP_MBOX_ECHO_REQUEST;
+	struct device *dev = kproc->dev;
+	int ret = 0;
+
+	if (rproc->state != RPROC_SUSPENDED)
+		return ret;
+
+	ret = get_core_status(kproc, &cstatus);
+	if (ret) {
+		dev_err(dev, "failed to get core status: %d\n", ret);
+		return ret;
+	}
+
+	if (cstatus) {
+		/* Device is ON/ACTIVE */
+		dev_err(dev, "Core is on in resume\n");
+		msg = RP_MBOX_ECHO_REQUEST;
+		ret = mbox_send_message(kproc->mbox, (void *)msg);
+		if (ret < 0) {
+			dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
+			return ret;
+		}
+	} else {
+		dev_info(dev, "Core is off in resume\n");
+		k3_rproc_reset(kproc);
+		rproc_boot(rproc);
+	}
+
+	kproc->rproc->state = RPROC_RUNNING;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_resume);
+
+/**
+ * PM notifier call.
+ * This is a callback function for PM notifications. On a resume completion
+ * i.e after all the resume driver calls are handled on PM_POST_SUSPEND,
+ * on a deep sleep the remote core is rebooted.
+ */
+int k3_rproc_pm_notifier_call(struct notifier_block *bl, unsigned long state, void *unused)
+{
+	struct k3_rproc *kproc = container_of(bl, struct k3_rproc, pm_notifier);
+	struct rproc *rproc = kproc->rproc;
+
+	switch (state) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_RESTORE_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		break;
+	case PM_POST_HIBERNATION:
+	case PM_POST_RESTORE:
+	case PM_POST_SUSPEND:
+		if (rproc->state == RPROC_SUSPENDED)
+			return k3_rproc_resume(rproc);
+		break;
+	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_pm_notifier_call);
+
+int k3_rproc_suspend_late(struct device *dev)
+{
+	struct k3_rproc *kproc = dev_get_drvdata(dev);
+
+	if (!kproc->pm_notifier.notifier_call)
+		return 0;
+
+	return k3_rproc_suspend(kproc->rproc);
+}
+EXPORT_SYMBOL_GPL(k3_rproc_suspend_late);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TI K3 common Remoteproc code");
diff -Naur --no-dereference a/drivers/remoteproc/ti_k3_common.h b/drivers/remoteproc/ti_k3_common.h
--- a/drivers/remoteproc/ti_k3_common.h	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/remoteproc/ti_k3_common.h	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,120 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * TI K3 Remote Processor(s) driver common code
+ *
+ * Refactored out of ti_k3_dsp_remoteproc.c and ti_k3_m4_remoteproc.c.
+ *
+ * ti_k3_dsp_remoteproc.c:
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
+ *	Suman Anna <s-anna@ti.com>
+ *
+ * ti_k3_m4_remoteproc.c:
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
+ *	Hari Nagalla <hnagalla@ti.com>
+ */
+
+#ifndef REMOTEPROC_TI_K3_COMMON_H
+#define REMOTEPROC_TI_K3_COMMON_H
+
+#define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK	(SZ_16M - 1)
+#define PROC_BOOT_STATUS_FLAG_CPU_WFI		0x00000002
+
+/**
+ * struct k3_rproc_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address of the memory region from remote processor view
+ * @size: Size of the memory region
+ */
+struct k3_rproc_mem {
+	void __iomem *cpu_addr;
+	phys_addr_t bus_addr;
+	u32 dev_addr;
+	size_t size;
+};
+
+/**
+ * struct k3_rproc_mem_data - memory definitions for a remote processor
+ * @name: name for this memory entry
+ * @dev_addr: device address for the memory entry
+ */
+struct k3_rproc_mem_data {
+	const char *name;
+	const u32 dev_addr;
+};
+
+/**
+ * struct k3_rproc_dev_data - device data structure for a remote processor
+ * @mems: pointer to memory definitions for a remote processor
+ * @num_mems: number of memory regions in @mems
+ * @boot_align_addr: boot vector address alignment granularity
+ * @uses_lreset: flag to denote the need for local reset management
+ */
+struct k3_rproc_dev_data {
+	const struct k3_rproc_mem_data *mems;
+	u32 num_mems;
+	u32 boot_align_addr;
+	bool uses_lreset;
+};
+
+/**
+ * struct k3_rproc - k3 remote processor driver structure
+ * @dev: cached device pointer
+ * @rproc: remoteproc device handle
+ * @mem: internal memory regions data
+ * @num_mems: number of internal memory regions
+ * @rmem: reserved memory regions data
+ * @num_rmems: number of reserved memory regions
+ * @reset: reset control handle
+ * @data: pointer to DSP-specific device data
+ * @tsp: TI-SCI processor control handle
+ * @ti_sci: TI-SCI handle
+ * @ti_sci_id: TI-SCI device identifier
+ * @mbox: mailbox channel handle
+ * @client: mailbox client to request the mailbox channel
+ */
+struct k3_rproc {
+	struct device *dev;
+	struct rproc *rproc;
+	struct k3_rproc_mem *mem;
+	int num_mems;
+	struct k3_rproc_mem *rmem;
+	int num_rmems;
+	struct reset_control *reset;
+	const struct k3_rproc_dev_data *data;
+	struct ti_sci_proc *tsp;
+	const struct ti_sci_handle *ti_sci;
+	u32 ti_sci_id;
+	struct mbox_chan *mbox;
+	struct mbox_client client;
+	struct completion shut_comp;
+	struct completion suspend_comp;
+	struct notifier_block pm_notifier;
+	u32 suspend_status;
+};
+
+void k3_rproc_mbox_callback(struct mbox_client *client, void *data);
+void k3_rproc_kick(struct rproc *rproc, int vqid);
+int k3_rproc_reset(struct k3_rproc *kproc);
+int k3_rproc_release(struct k3_rproc *kproc);
+int k3_rproc_request_mbox(struct rproc *rproc);
+int k3_rproc_prepare(struct rproc *rproc);
+int k3_rproc_unprepare(struct rproc *rproc);
+int k3_rproc_start(struct rproc *rproc);
+int k3_rproc_stop(struct rproc *rproc);
+int k3_rproc_attach(struct rproc *rproc);
+int k3_rproc_detach(struct rproc *rproc);
+struct resource_table *k3_get_loaded_rsc_table(struct rproc *rproc,
+					       size_t *rsc_table_sz);
+void *k3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len,
+			bool *is_iomem);
+int k3_rproc_of_get_memories(struct platform_device *pdev,
+			     struct k3_rproc *kproc);
+void k3_mem_release(void *data);
+int k3_reserved_mem_init(struct k3_rproc *kproc);
+void k3_release_tsp(void *data);
+int k3_rproc_suspend(struct rproc *rproc);
+int k3_rproc_resume(struct rproc *rproc);
+int k3_rproc_pm_notifier_call(struct notifier_block *bl, unsigned long state, void *unused);
+int k3_rproc_suspend_late(struct device *dev);
+#endif /* REMOTEPROC_TI_K3_COMMON_H */
diff -Naur --no-dereference a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c	2025-10-23 09:30:40.286462238 -0400
@@ -16,287 +16,12 @@
 #include <linux/remoteproc.h>
 #include <linux/reset.h>
 #include <linux/slab.h>
+#include <linux/suspend.h>
 
 #include "omap_remoteproc.h"
 #include "remoteproc_internal.h"
 #include "ti_sci_proc.h"
-
-#define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK	(SZ_16M - 1)
-
-/**
- * struct k3_dsp_mem - internal memory structure
- * @cpu_addr: MPU virtual address of the memory region
- * @bus_addr: Bus address used to access the memory region
- * @dev_addr: Device address of the memory region from DSP view
- * @size: Size of the memory region
- */
-struct k3_dsp_mem {
-	void __iomem *cpu_addr;
-	phys_addr_t bus_addr;
-	u32 dev_addr;
-	size_t size;
-};
-
-/**
- * struct k3_dsp_mem_data - memory definitions for a DSP
- * @name: name for this memory entry
- * @dev_addr: device address for the memory entry
- */
-struct k3_dsp_mem_data {
-	const char *name;
-	const u32 dev_addr;
-};
-
-/**
- * struct k3_dsp_dev_data - device data structure for a DSP
- * @mems: pointer to memory definitions for a DSP
- * @num_mems: number of memory regions in @mems
- * @boot_align_addr: boot vector address alignment granularity
- * @uses_lreset: flag to denote the need for local reset management
- */
-struct k3_dsp_dev_data {
-	const struct k3_dsp_mem_data *mems;
-	u32 num_mems;
-	u32 boot_align_addr;
-	bool uses_lreset;
-};
-
-/**
- * struct k3_dsp_rproc - k3 DSP remote processor driver structure
- * @dev: cached device pointer
- * @rproc: remoteproc device handle
- * @mem: internal memory regions data
- * @num_mems: number of internal memory regions
- * @rmem: reserved memory regions data
- * @num_rmems: number of reserved memory regions
- * @reset: reset control handle
- * @data: pointer to DSP-specific device data
- * @tsp: TI-SCI processor control handle
- * @ti_sci: TI-SCI handle
- * @ti_sci_id: TI-SCI device identifier
- * @mbox: mailbox channel handle
- * @client: mailbox client to request the mailbox channel
- */
-struct k3_dsp_rproc {
-	struct device *dev;
-	struct rproc *rproc;
-	struct k3_dsp_mem *mem;
-	int num_mems;
-	struct k3_dsp_mem *rmem;
-	int num_rmems;
-	struct reset_control *reset;
-	const struct k3_dsp_dev_data *data;
-	struct ti_sci_proc *tsp;
-	const struct ti_sci_handle *ti_sci;
-	u32 ti_sci_id;
-	struct mbox_chan *mbox;
-	struct mbox_client client;
-};
-
-/**
- * k3_dsp_rproc_mbox_callback() - inbound mailbox message handler
- * @client: mailbox client pointer used for requesting the mailbox channel
- * @data: mailbox payload
- *
- * This handler is invoked by the OMAP mailbox driver whenever a mailbox
- * message is received. Usually, the mailbox payload simply contains
- * the index of the virtqueue that is kicked by the remote processor,
- * and we let remoteproc core handle it.
- *
- * In addition to virtqueue indices, we also have some out-of-band values
- * that indicate different events. Those values are deliberately very
- * large so they don't coincide with virtqueue indices.
- */
-static void k3_dsp_rproc_mbox_callback(struct mbox_client *client, void *data)
-{
-	struct k3_dsp_rproc *kproc = container_of(client, struct k3_dsp_rproc,
-						  client);
-	struct device *dev = kproc->rproc->dev.parent;
-	const char *name = kproc->rproc->name;
-	u32 msg = omap_mbox_message(data);
-
-	dev_dbg(dev, "mbox msg: 0x%x\n", msg);
-
-	switch (msg) {
-	case RP_MBOX_CRASH:
-		/*
-		 * remoteproc detected an exception, but error recovery is not
-		 * supported. So, just log this for now
-		 */
-		dev_err(dev, "K3 DSP rproc %s crashed\n", name);
-		break;
-	case RP_MBOX_ECHO_REPLY:
-		dev_info(dev, "received echo reply from %s\n", name);
-		break;
-	default:
-		/* silently handle all other valid messages */
-		if (msg >= RP_MBOX_READY && msg < RP_MBOX_END_MSG)
-			return;
-		if (msg > kproc->rproc->max_notifyid) {
-			dev_dbg(dev, "dropping unknown message 0x%x", msg);
-			return;
-		}
-		/* msg contains the index of the triggered vring */
-		if (rproc_vq_interrupt(kproc->rproc, msg) == IRQ_NONE)
-			dev_dbg(dev, "no message was found in vqid %d\n", msg);
-	}
-}
-
-/*
- * Kick the remote processor to notify about pending unprocessed messages.
- * The vqid usage is not used and is inconsequential, as the kick is performed
- * through a simulated GPIO (a bit in an IPC interrupt-triggering register),
- * the remote processor is expected to process both its Tx and Rx virtqueues.
- */
-static void k3_dsp_rproc_kick(struct rproc *rproc, int vqid)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-	struct device *dev = rproc->dev.parent;
-	mbox_msg_t msg = (mbox_msg_t)vqid;
-	int ret;
-
-	/* send the index of the triggered virtqueue in the mailbox payload */
-	ret = mbox_send_message(kproc->mbox, (void *)msg);
-	if (ret < 0)
-		dev_err(dev, "failed to send mailbox message (%pe)\n",
-			ERR_PTR(ret));
-}
-
-/* Put the DSP processor into reset */
-static int k3_dsp_rproc_reset(struct k3_dsp_rproc *kproc)
-{
-	struct device *dev = kproc->dev;
-	int ret;
-
-	ret = reset_control_assert(kproc->reset);
-	if (ret) {
-		dev_err(dev, "local-reset assert failed (%pe)\n", ERR_PTR(ret));
-		return ret;
-	}
-
-	if (kproc->data->uses_lreset)
-		return ret;
-
-	ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,
-						    kproc->ti_sci_id);
-	if (ret) {
-		dev_err(dev, "module-reset assert failed (%pe)\n", ERR_PTR(ret));
-		if (reset_control_deassert(kproc->reset))
-			dev_warn(dev, "local-reset deassert back failed\n");
-	}
-
-	return ret;
-}
-
-/* Release the DSP processor from reset */
-static int k3_dsp_rproc_release(struct k3_dsp_rproc *kproc)
-{
-	struct device *dev = kproc->dev;
-	int ret;
-
-	if (kproc->data->uses_lreset)
-		goto lreset;
-
-	ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci,
-						    kproc->ti_sci_id);
-	if (ret) {
-		dev_err(dev, "module-reset deassert failed (%pe)\n", ERR_PTR(ret));
-		return ret;
-	}
-
-lreset:
-	ret = reset_control_deassert(kproc->reset);
-	if (ret) {
-		dev_err(dev, "local-reset deassert failed, (%pe)\n", ERR_PTR(ret));
-		if (kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,
-							  kproc->ti_sci_id))
-			dev_warn(dev, "module-reset assert back failed\n");
-	}
-
-	return ret;
-}
-
-static int k3_dsp_rproc_request_mbox(struct rproc *rproc)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-	struct mbox_client *client = &kproc->client;
-	struct device *dev = kproc->dev;
-	int ret;
-
-	client->dev = dev;
-	client->tx_done = NULL;
-	client->rx_callback = k3_dsp_rproc_mbox_callback;
-	client->tx_block = false;
-	client->knows_txdone = false;
-
-	kproc->mbox = mbox_request_channel(client, 0);
-	if (IS_ERR(kproc->mbox))
-		return dev_err_probe(dev, PTR_ERR(kproc->mbox),
-				     "mbox_request_channel failed\n");
-
-	/*
-	 * Ping the remote processor, this is only for sanity-sake for now;
-	 * there is no functional effect whatsoever.
-	 *
-	 * Note that the reply will _not_ arrive immediately: this message
-	 * will wait in the mailbox fifo until the remote processor is booted.
-	 */
-	ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_ECHO_REQUEST);
-	if (ret < 0) {
-		dev_err(dev, "mbox_send_message failed (%pe)\n", ERR_PTR(ret));
-		mbox_free_channel(kproc->mbox);
-		return ret;
-	}
-
-	return 0;
-}
-/*
- * The C66x DSP cores have a local reset that affects only the CPU, and a
- * generic module reset that powers on the device and allows the DSP internal
- * memories to be accessed while the local reset is asserted. This function is
- * used to release the global reset on C66x DSPs to allow loading into the DSP
- * internal RAMs. The .prepare() ops is invoked by remoteproc core before any
- * firmware loading, and is followed by the .start() ops after loading to
- * actually let the C66x DSP cores run. This callback is invoked only in
- * remoteproc mode.
- */
-static int k3_dsp_rproc_prepare(struct rproc *rproc)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-	int ret;
-
-	ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci,
-						    kproc->ti_sci_id);
-	if (ret)
-		dev_err(dev, "module-reset deassert failed, cannot enable internal RAM loading (%pe)\n",
-			ERR_PTR(ret));
-
-	return ret;
-}
-
-/*
- * This function implements the .unprepare() ops and performs the complimentary
- * operations to that of the .prepare() ops. The function is used to assert the
- * global reset on applicable C66x cores. This completes the second portion of
- * powering down the C66x DSP cores. The cores themselves are only halted in the
- * .stop() callback through the local reset, and the .unprepare() ops is invoked
- * by the remoteproc core after the remoteproc is stopped to balance the global
- * reset. This callback is invoked only in remoteproc mode.
- */
-static int k3_dsp_rproc_unprepare(struct rproc *rproc)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-	int ret;
-
-	ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,
-						    kproc->ti_sci_id);
-	if (ret)
-		dev_err(dev, "module-reset assert failed (%pe)\n", ERR_PTR(ret));
-
-	return ret;
-}
+#include "ti_k3_common.h"
 
 /*
  * Power up the DSP remote processor.
@@ -307,7 +32,7 @@
  */
 static int k3_dsp_rproc_start(struct rproc *rproc)
 {
-	struct k3_dsp_rproc *kproc = rproc->priv;
+	struct k3_rproc *kproc = rproc->priv;
 	struct device *dev = kproc->dev;
 	u32 boot_addr;
 	int ret;
@@ -324,290 +49,30 @@
 	if (ret)
 		return ret;
 
-	ret = k3_dsp_rproc_release(kproc);
+	/* Call the K3 common start function after doing DSP specific stuff */
+	ret = k3_rproc_start(rproc);
 	if (ret)
 		return ret;
 
 	return 0;
 }
 
-/*
- * Stop the DSP remote processor.
- *
- * This function puts the DSP processor into reset, and finishes processing
- * of any pending messages. This callback is invoked only in remoteproc mode.
- */
-static int k3_dsp_rproc_stop(struct rproc *rproc)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-
-	k3_dsp_rproc_reset(kproc);
-
-	return 0;
-}
-
-/*
- * Attach to a running DSP remote processor (IPC-only mode)
- *
- * This rproc attach callback is a NOP. The remote processor is already booted,
- * and all required resources have been acquired during probe routine, so there
- * is no need to issue any TI-SCI commands to boot the DSP core. This callback
- * is invoked only in IPC-only mode and exists because rproc_validate() checks
- * for its existence.
- */
-static int k3_dsp_rproc_attach(struct rproc *rproc) { return 0; }
-
-/*
- * Detach from a running DSP remote processor (IPC-only mode)
- *
- * This rproc detach callback is a NOP. The DSP core is not stopped and will be
- * left to continue to run its booted firmware. This callback is invoked only in
- * IPC-only mode and exists for sanity sake.
- */
-static int k3_dsp_rproc_detach(struct rproc *rproc) { return 0; }
-
-/*
- * This function implements the .get_loaded_rsc_table() callback and is used
- * to provide the resource table for a booted DSP in IPC-only mode. The K3 DSP
- * firmwares follow a design-by-contract approach and are expected to have the
- * resource table at the base of the DDR region reserved for firmware usage.
- * This provides flexibility for the remote processor to be booted by different
- * bootloaders that may or may not have the ability to publish the resource table
- * address and size through a DT property. This callback is invoked only in
- * IPC-only mode.
- */
-static struct resource_table *k3_dsp_get_loaded_rsc_table(struct rproc *rproc,
-							  size_t *rsc_table_sz)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-
-	if (!kproc->rmem[0].cpu_addr) {
-		dev_err(dev, "memory-region #1 does not exist, loaded rsc table can't be found");
-		return ERR_PTR(-ENOMEM);
-	}
-
-	/*
-	 * NOTE: The resource table size is currently hard-coded to a maximum
-	 * of 256 bytes. The most common resource table usage for K3 firmwares
-	 * is to only have the vdev resource entry and an optional trace entry.
-	 * The exact size could be computed based on resource table address, but
-	 * the hard-coded value suffices to support the IPC-only mode.
-	 */
-	*rsc_table_sz = 256;
-	return (struct resource_table *)kproc->rmem[0].cpu_addr;
-}
-
-/*
- * Custom function to translate a DSP device address (internal RAMs only) to a
- * kernel virtual address.  The DSPs can access their RAMs at either an internal
- * address visible only from a DSP, or at the SoC-level bus address. Both these
- * addresses need to be looked through for translation. The translated addresses
- * can be used either by the remoteproc core for loading (when using kernel
- * remoteproc loader), or by any rpmsg bus drivers.
- */
-static void *k3_dsp_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-	void __iomem *va = NULL;
-	phys_addr_t bus_addr;
-	u32 dev_addr, offset;
-	size_t size;
-	int i;
-
-	if (len == 0)
-		return NULL;
-
-	for (i = 0; i < kproc->num_mems; i++) {
-		bus_addr = kproc->mem[i].bus_addr;
-		dev_addr = kproc->mem[i].dev_addr;
-		size = kproc->mem[i].size;
-
-		if (da < KEYSTONE_RPROC_LOCAL_ADDRESS_MASK) {
-			/* handle DSP-view addresses */
-			if (da >= dev_addr &&
-			    ((da + len) <= (dev_addr + size))) {
-				offset = da - dev_addr;
-				va = kproc->mem[i].cpu_addr + offset;
-				return (__force void *)va;
-			}
-		} else {
-			/* handle SoC-view addresses */
-			if (da >= bus_addr &&
-			    (da + len) <= (bus_addr + size)) {
-				offset = da - bus_addr;
-				va = kproc->mem[i].cpu_addr + offset;
-				return (__force void *)va;
-			}
-		}
-	}
-
-	/* handle static DDR reserved memory regions */
-	for (i = 0; i < kproc->num_rmems; i++) {
-		dev_addr = kproc->rmem[i].dev_addr;
-		size = kproc->rmem[i].size;
-
-		if (da >= dev_addr && ((da + len) <= (dev_addr + size))) {
-			offset = da - dev_addr;
-			va = kproc->rmem[i].cpu_addr + offset;
-			return (__force void *)va;
-		}
-	}
-
-	return NULL;
-}
-
 static const struct rproc_ops k3_dsp_rproc_ops = {
-	.start		= k3_dsp_rproc_start,
-	.stop		= k3_dsp_rproc_stop,
-	.kick		= k3_dsp_rproc_kick,
-	.da_to_va	= k3_dsp_rproc_da_to_va,
+	.start			=	k3_dsp_rproc_start,
+	.stop			=	k3_rproc_stop,
+	.attach			=	k3_rproc_attach,
+	.detach			=	k3_rproc_detach,
+	.kick			=	k3_rproc_kick,
+	.da_to_va		=	k3_rproc_da_to_va,
+	.get_loaded_rsc_table	=	k3_get_loaded_rsc_table,
 };
 
-static int k3_dsp_rproc_of_get_memories(struct platform_device *pdev,
-					struct k3_dsp_rproc *kproc)
-{
-	const struct k3_dsp_dev_data *data = kproc->data;
-	struct device *dev = &pdev->dev;
-	struct resource *res;
-	int num_mems = 0;
-	int i;
-
-	num_mems = kproc->data->num_mems;
-	kproc->mem = devm_kcalloc(kproc->dev, num_mems,
-				  sizeof(*kproc->mem), GFP_KERNEL);
-	if (!kproc->mem)
-		return -ENOMEM;
-
-	for (i = 0; i < num_mems; i++) {
-		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						   data->mems[i].name);
-		if (!res) {
-			dev_err(dev, "found no memory resource for %s\n",
-				data->mems[i].name);
-			return -EINVAL;
-		}
-		if (!devm_request_mem_region(dev, res->start,
-					     resource_size(res),
-					     dev_name(dev))) {
-			dev_err(dev, "could not request %s region for resource\n",
-				data->mems[i].name);
-			return -EBUSY;
-		}
-
-		kproc->mem[i].cpu_addr = devm_ioremap_wc(dev, res->start,
-							 resource_size(res));
-		if (!kproc->mem[i].cpu_addr) {
-			dev_err(dev, "failed to map %s memory\n",
-				data->mems[i].name);
-			return -ENOMEM;
-		}
-		kproc->mem[i].bus_addr = res->start;
-		kproc->mem[i].dev_addr = data->mems[i].dev_addr;
-		kproc->mem[i].size = resource_size(res);
-
-		dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %pK da 0x%x\n",
-			data->mems[i].name, &kproc->mem[i].bus_addr,
-			kproc->mem[i].size, kproc->mem[i].cpu_addr,
-			kproc->mem[i].dev_addr);
-	}
-	kproc->num_mems = num_mems;
-
-	return 0;
-}
-
-static void k3_dsp_mem_release(void *data)
-{
-	struct device *dev = data;
-
-	of_reserved_mem_device_release(dev);
-}
-
-static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
-{
-	struct device *dev = kproc->dev;
-	struct device_node *np = dev->of_node;
-	struct device_node *rmem_np;
-	struct reserved_mem *rmem;
-	int num_rmems;
-	int ret, i;
-
-	num_rmems = of_property_count_elems_of_size(np, "memory-region",
-						    sizeof(phandle));
-	if (num_rmems < 0) {
-		dev_err(dev, "device does not reserved memory regions (%pe)\n",
-			ERR_PTR(num_rmems));
-		return -EINVAL;
-	}
-	if (num_rmems < 2) {
-		dev_err(dev, "device needs at least two memory regions to be defined, num = %d\n",
-			num_rmems);
-		return -EINVAL;
-	}
-
-	/* use reserved memory region 0 for vring DMA allocations */
-	ret = of_reserved_mem_device_init_by_idx(dev, np, 0);
-	if (ret) {
-		dev_err(dev, "device cannot initialize DMA pool (%pe)\n",
-			ERR_PTR(ret));
-		return ret;
-	}
-	ret = devm_add_action_or_reset(dev, k3_dsp_mem_release, dev);
-	if (ret)
-		return ret;
-
-	num_rmems--;
-	kproc->rmem = devm_kcalloc(dev, num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
-	if (!kproc->rmem)
-		return -ENOMEM;
-
-	/* use remaining reserved memory regions for static carveouts */
-	for (i = 0; i < num_rmems; i++) {
-		rmem_np = of_parse_phandle(np, "memory-region", i + 1);
-		if (!rmem_np)
-			return -EINVAL;
-
-		rmem = of_reserved_mem_lookup(rmem_np);
-		if (!rmem) {
-			of_node_put(rmem_np);
-			return -EINVAL;
-		}
-		of_node_put(rmem_np);
-
-		kproc->rmem[i].bus_addr = rmem->base;
-		/* 64-bit address regions currently not supported */
-		kproc->rmem[i].dev_addr = (u32)rmem->base;
-		kproc->rmem[i].size = rmem->size;
-		kproc->rmem[i].cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
-		if (!kproc->rmem[i].cpu_addr) {
-			dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n",
-				i + 1, &rmem->base, &rmem->size);
-			return -ENOMEM;
-		}
-
-		dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",
-			i + 1, &kproc->rmem[i].bus_addr,
-			kproc->rmem[i].size, kproc->rmem[i].cpu_addr,
-			kproc->rmem[i].dev_addr);
-	}
-	kproc->num_rmems = num_rmems;
-
-	return 0;
-}
-
-static void k3_dsp_release_tsp(void *data)
-{
-	struct ti_sci_proc *tsp = data;
-
-	ti_sci_proc_release(tsp);
-}
-
 static int k3_dsp_rproc_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
-	const struct k3_dsp_dev_data *data;
-	struct k3_dsp_rproc *kproc;
+	const struct k3_rproc_dev_data *data;
+	struct k3_rproc *kproc;
 	struct rproc *rproc;
 	const char *fw_name;
 	bool p_state = false;
@@ -629,15 +94,15 @@
 	rproc->has_iommu = false;
 	rproc->recovery_disabled = true;
 	if (data->uses_lreset) {
-		rproc->ops->prepare = k3_dsp_rproc_prepare;
-		rproc->ops->unprepare = k3_dsp_rproc_unprepare;
+		rproc->ops->prepare = k3_rproc_prepare;
+		rproc->ops->unprepare = k3_rproc_unprepare;
 	}
 	kproc = rproc->priv;
 	kproc->rproc = rproc;
 	kproc->dev = dev;
 	kproc->data = data;
 
-	ret = k3_dsp_rproc_request_mbox(rproc);
+	ret = k3_rproc_request_mbox(rproc);
 	if (ret)
 		return ret;
 
@@ -665,15 +130,15 @@
 		dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
 		return ret;
 	}
-	ret = devm_add_action_or_reset(dev, k3_dsp_release_tsp, kproc->tsp);
+	ret = devm_add_action_or_reset(dev, k3_release_tsp, kproc->tsp);
 	if (ret)
 		return ret;
 
-	ret = k3_dsp_rproc_of_get_memories(pdev, kproc);
+	ret = k3_rproc_of_get_memories(pdev, kproc);
 	if (ret)
 		return ret;
 
-	ret = k3_dsp_reserved_mem_init(kproc);
+	ret = k3_reserved_mem_init(kproc);
 	if (ret)
 		return dev_err_probe(dev, ret, "reserved memory init failed\n");
 
@@ -682,48 +147,39 @@
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n");
 
-	/* configure J721E devices for either remoteproc or IPC-only mode */
+	/* configure devices for either remoteproc or IPC-only mode */
 	if (p_state) {
 		dev_info(dev, "configured DSP for IPC-only mode\n");
 		rproc->state = RPROC_DETACHED;
-		/* override rproc ops with only required IPC-only mode ops */
-		rproc->ops->prepare = NULL;
-		rproc->ops->unprepare = NULL;
-		rproc->ops->start = NULL;
-		rproc->ops->stop = NULL;
-		rproc->ops->attach = k3_dsp_rproc_attach;
-		rproc->ops->detach = k3_dsp_rproc_detach;
-		rproc->ops->get_loaded_rsc_table = k3_dsp_get_loaded_rsc_table;
+		kproc->rproc->ops->prepare = NULL;
+		kproc->rproc->ops->unprepare = NULL;
+		kproc->rproc->ops->start = NULL;
+		kproc->rproc->ops->stop = NULL;
 	} else {
 		dev_info(dev, "configured DSP for remoteproc mode\n");
-		/*
-		 * ensure the DSP local reset is asserted to ensure the DSP
-		 * doesn't execute bogus code in .prepare() when the module
-		 * reset is released.
-		 */
-		if (data->uses_lreset) {
-			ret = reset_control_status(kproc->reset);
-			if (ret < 0) {
-				return dev_err_probe(dev, ret, "failed to get reset status\n");
-			} else if (ret == 0) {
-				dev_warn(dev, "local reset is deasserted for device\n");
-				k3_dsp_rproc_reset(kproc);
-			}
-		}
+		kproc->pm_notifier.notifier_call = k3_rproc_pm_notifier_call;
+		register_pm_notifier(&kproc->pm_notifier);
 	}
 
+	ret = dma_coerce_mask_and_coherent(&rproc->dev, DMA_BIT_MASK(48));
+	if (ret)
+		dev_warn(dev, "Failed to set DMA mask (%d)\n", ret);
+
 	ret = devm_rproc_add(dev, rproc);
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n");
 
 	platform_set_drvdata(pdev, kproc);
 
+	init_completion(&kproc->shut_comp);
+	init_completion(&kproc->suspend_comp);
+
 	return 0;
 }
 
 static void k3_dsp_rproc_remove(struct platform_device *pdev)
 {
-	struct k3_dsp_rproc *kproc = platform_get_drvdata(pdev);
+	struct k3_rproc *kproc = platform_get_drvdata(pdev);
 	struct rproc *rproc = kproc->rproc;
 	struct device *dev = &pdev->dev;
 	int ret;
@@ -737,37 +193,44 @@
 	mbox_free_channel(kproc->mbox);
 }
 
-static const struct k3_dsp_mem_data c66_mems[] = {
+static const struct k3_rproc_mem_data c66_mems[] = {
 	{ .name = "l2sram", .dev_addr = 0x800000 },
 	{ .name = "l1pram", .dev_addr = 0xe00000 },
 	{ .name = "l1dram", .dev_addr = 0xf00000 },
 };
 
 /* C71x cores only have a L1P Cache, there are no L1P SRAMs */
-static const struct k3_dsp_mem_data c71_mems[] = {
+static const struct k3_rproc_mem_data c71_mems[] = {
 	{ .name = "l2sram", .dev_addr = 0x800000 },
 	{ .name = "l1dram", .dev_addr = 0xe00000 },
 };
 
-static const struct k3_dsp_mem_data c7xv_mems[] = {
+static const struct k3_rproc_mem_data c7xv_mems[] = {
 	{ .name = "l2sram", .dev_addr = 0x800000 },
 };
 
-static const struct k3_dsp_dev_data c66_data = {
+static const struct k3_rproc_dev_data c66_data = {
 	.mems = c66_mems,
 	.num_mems = ARRAY_SIZE(c66_mems),
 	.boot_align_addr = SZ_1K,
 	.uses_lreset = true,
 };
 
-static const struct k3_dsp_dev_data c71_data = {
+static const struct k3_rproc_dev_data c71_data = {
 	.mems = c71_mems,
 	.num_mems = ARRAY_SIZE(c71_mems),
 	.boot_align_addr = SZ_2M,
 	.uses_lreset = false,
 };
 
-static const struct k3_dsp_dev_data c7xv_data = {
+static const struct k3_rproc_dev_data c7xv_data = {
+	.mems = c7xv_mems,
+	.num_mems = ARRAY_SIZE(c7xv_mems),
+	.boot_align_addr = SZ_2M,
+	.uses_lreset = true,
+};
+
+static const struct k3_rproc_dev_data j722s_c7xv_data = {
 	.mems = c7xv_mems,
 	.num_mems = ARRAY_SIZE(c7xv_mems),
 	.boot_align_addr = SZ_2M,
@@ -779,15 +242,21 @@
 	{ .compatible = "ti,j721e-c71-dsp", .data = &c71_data, },
 	{ .compatible = "ti,j721s2-c71-dsp", .data = &c71_data, },
 	{ .compatible = "ti,am62a-c7xv-dsp", .data = &c7xv_data, },
+	{ .compatible = "ti,j722s-c7xv-dsp", .data = &j722s_c7xv_data, },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, k3_dsp_of_match);
 
+static const struct dev_pm_ops k3_dsp_pm_ops = {
+	LATE_SYSTEM_SLEEP_PM_OPS(k3_rproc_suspend_late, NULL)
+};
+
 static struct platform_driver k3_dsp_rproc_driver = {
 	.probe	= k3_dsp_rproc_probe,
 	.remove_new = k3_dsp_rproc_remove,
 	.driver	= {
 		.name = "k3-dsp-rproc",
+		.pm = &k3_dsp_pm_ops,
 		.of_match_table = k3_dsp_of_match,
 	},
 };
diff -Naur --no-dereference a/drivers/remoteproc/ti_k3_m4_remoteproc.c b/drivers/remoteproc/ti_k3_m4_remoteproc.c
--- a/drivers/remoteproc/ti_k3_m4_remoteproc.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/remoteproc/ti_k3_m4_remoteproc.c	2025-10-23 09:30:40.286462238 -0400
@@ -15,558 +15,40 @@
 #include <linux/remoteproc.h>
 #include <linux/reset.h>
 #include <linux/slab.h>
+#include <linux/suspend.h>
 
 #include "omap_remoteproc.h"
 #include "remoteproc_internal.h"
 #include "ti_sci_proc.h"
-
-#define K3_M4_IRAM_DEV_ADDR 0x00000
-#define K3_M4_DRAM_DEV_ADDR 0x30000
-
-/**
- * struct k3_m4_rproc_mem - internal memory structure
- * @cpu_addr: MPU virtual address of the memory region
- * @bus_addr: Bus address used to access the memory region
- * @dev_addr: Device address of the memory region from remote processor view
- * @size: Size of the memory region
- */
-struct k3_m4_rproc_mem {
-	void __iomem *cpu_addr;
-	phys_addr_t bus_addr;
-	u32 dev_addr;
-	size_t size;
-};
-
-/**
- * struct k3_m4_rproc_mem_data - memory definitions for a remote processor
- * @name: name for this memory entry
- * @dev_addr: device address for the memory entry
- */
-struct k3_m4_rproc_mem_data {
-	const char *name;
-	const u32 dev_addr;
-};
-
-/**
- * struct k3_m4_rproc - k3 remote processor driver structure
- * @dev: cached device pointer
- * @mem: internal memory regions data
- * @num_mems: number of internal memory regions
- * @rmem: reserved memory regions data
- * @num_rmems: number of reserved memory regions
- * @reset: reset control handle
- * @tsp: TI-SCI processor control handle
- * @ti_sci: TI-SCI handle
- * @ti_sci_id: TI-SCI device identifier
- * @mbox: mailbox channel handle
- * @client: mailbox client to request the mailbox channel
- */
-struct k3_m4_rproc {
-	struct device *dev;
-	struct k3_m4_rproc_mem *mem;
-	int num_mems;
-	struct k3_m4_rproc_mem *rmem;
-	int num_rmems;
-	struct reset_control *reset;
-	struct ti_sci_proc *tsp;
-	const struct ti_sci_handle *ti_sci;
-	u32 ti_sci_id;
-	struct mbox_chan *mbox;
-	struct mbox_client client;
-};
-
-/**
- * k3_m4_rproc_mbox_callback() - inbound mailbox message handler
- * @client: mailbox client pointer used for requesting the mailbox channel
- * @data: mailbox payload
- *
- * This handler is invoked by the K3 mailbox driver whenever a mailbox
- * message is received. Usually, the mailbox payload simply contains
- * the index of the virtqueue that is kicked by the remote processor,
- * and we let remoteproc core handle it.
- *
- * In addition to virtqueue indices, we also have some out-of-band values
- * that indicate different events. Those values are deliberately very
- * large so they don't coincide with virtqueue indices.
- */
-static void k3_m4_rproc_mbox_callback(struct mbox_client *client, void *data)
-{
-	struct device *dev = client->dev;
-	struct rproc *rproc = dev_get_drvdata(dev);
-	u32 msg = (u32)(uintptr_t)(data);
-
-	dev_dbg(dev, "mbox msg: 0x%x\n", msg);
-
-	switch (msg) {
-	case RP_MBOX_CRASH:
-		/*
-		 * remoteproc detected an exception, but error recovery is not
-		 * supported. So, just log this for now
-		 */
-		dev_err(dev, "K3 rproc %s crashed\n", rproc->name);
-		break;
-	case RP_MBOX_ECHO_REPLY:
-		dev_info(dev, "received echo reply from %s\n", rproc->name);
-		break;
-	default:
-		/* silently handle all other valid messages */
-		if (msg >= RP_MBOX_READY && msg < RP_MBOX_END_MSG)
-			return;
-		if (msg > rproc->max_notifyid) {
-			dev_dbg(dev, "dropping unknown message 0x%x", msg);
-			return;
-		}
-		/* msg contains the index of the triggered vring */
-		if (rproc_vq_interrupt(rproc, msg) == IRQ_NONE)
-			dev_dbg(dev, "no message was found in vqid %d\n", msg);
-	}
-}
-
-/*
- * Kick the remote processor to notify about pending unprocessed messages.
- * The vqid usage is not used and is inconsequential, as the kick is performed
- * through a simulated GPIO (a bit in an IPC interrupt-triggering register),
- * the remote processor is expected to process both its Tx and Rx virtqueues.
- */
-static void k3_m4_rproc_kick(struct rproc *rproc, int vqid)
-{
-	struct k3_m4_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-	u32 msg = (u32)vqid;
-	int ret;
-
-	/*
-	 * Send the index of the triggered virtqueue in the mailbox payload.
-	 * NOTE: msg is cast to uintptr_t to prevent compiler warnings when
-	 * void* is 64bit. It is safely cast back to u32 in the mailbox driver.
-	 */
-	ret = mbox_send_message(kproc->mbox, (void *)(uintptr_t)msg);
-	if (ret < 0)
-		dev_err(dev, "failed to send mailbox message, status = %d\n",
-			ret);
-}
-
-static int k3_m4_rproc_ping_mbox(struct k3_m4_rproc *kproc)
-{
-	struct device *dev = kproc->dev;
-	int ret;
-
-	/*
-	 * Ping the remote processor, this is only for sanity-sake for now;
-	 * there is no functional effect whatsoever.
-	 *
-	 * Note that the reply will _not_ arrive immediately: this message
-	 * will wait in the mailbox fifo until the remote processor is booted.
-	 */
-	ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_ECHO_REQUEST);
-	if (ret < 0) {
-		dev_err(dev, "mbox_send_message failed: %d\n", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-/*
- * The M4 cores have a local reset that affects only the CPU, and a
- * generic module reset that powers on the device and allows the internal
- * memories to be accessed while the local reset is asserted. This function is
- * used to release the global reset on remote cores to allow loading into the
- * internal RAMs. The .prepare() ops is invoked by remoteproc core before any
- * firmware loading, and is followed by the .start() ops after loading to
- * actually let the remote cores to run.
- */
-static int k3_m4_rproc_prepare(struct rproc *rproc)
-{
-	struct k3_m4_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-	int ret;
-
-	/* If the core is running already no need to deassert the module reset */
-	if (rproc->state == RPROC_DETACHED)
-		return 0;
-
-	/*
-	 * Ensure the local reset is asserted so the core doesn't
-	 * execute bogus code when the module reset is released.
-	 */
-	ret = reset_control_assert(kproc->reset);
-	if (ret) {
-		dev_err(dev, "could not assert local reset\n");
-		return ret;
-	}
-
-	ret = reset_control_status(kproc->reset);
-	if (ret <= 0) {
-		dev_err(dev, "local reset still not asserted\n");
-		return ret;
-	}
-
-	ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci,
-						    kproc->ti_sci_id);
-	if (ret) {
-		dev_err(dev, "could not deassert module-reset for internal RAM loading\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-/*
- * This function implements the .unprepare() ops and performs the complimentary
- * operations to that of the .prepare() ops. The function is used to assert the
- * global reset on applicable cores. This completes the second portion of
- * powering down the remote core. The cores themselves are only halted in the
- * .stop() callback through the local reset, and the .unprepare() ops is invoked
- * by the remoteproc core after the remoteproc is stopped to balance the global
- * reset.
- */
-static int k3_m4_rproc_unprepare(struct rproc *rproc)
-{
-	struct k3_m4_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-	int ret;
-
-	/* If the core is going to be detached do not assert the module reset */
-	if (rproc->state == RPROC_ATTACHED)
-		return 0;
-
-	ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,
-						    kproc->ti_sci_id);
-	if (ret) {
-		dev_err(dev, "module-reset assert failed\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-/*
- * This function implements the .get_loaded_rsc_table() callback and is used
- * to provide the resource table for a booted remote processor in IPC-only
- * mode. The remote processor firmwares follow a design-by-contract approach
- * and are expected to have the resource table at the base of the DDR region
- * reserved for firmware usage. This provides flexibility for the remote
- * processor to be booted by different bootloaders that may or may not have the
- * ability to publish the resource table address and size through a DT
- * property.
- */
-static struct resource_table *k3_m4_get_loaded_rsc_table(struct rproc *rproc,
-							 size_t *rsc_table_sz)
-{
-	struct k3_m4_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-
-	if (!kproc->rmem[0].cpu_addr) {
-		dev_err(dev, "memory-region #1 does not exist, loaded rsc table can't be found");
-		return ERR_PTR(-ENOMEM);
-	}
-
-	/*
-	 * NOTE: The resource table size is currently hard-coded to a maximum
-	 * of 256 bytes. The most common resource table usage for K3 firmwares
-	 * is to only have the vdev resource entry and an optional trace entry.
-	 * The exact size could be computed based on resource table address, but
-	 * the hard-coded value suffices to support the IPC-only mode.
-	 */
-	*rsc_table_sz = 256;
-	return (__force struct resource_table *)kproc->rmem[0].cpu_addr;
-}
-
-/*
- * Custom function to translate a remote processor device address (internal
- * RAMs only) to a kernel virtual address.  The remote processors can access
- * their RAMs at either an internal address visible only from a remote
- * processor, or at the SoC-level bus address. Both these addresses need to be
- * looked through for translation. The translated addresses can be used either
- * by the remoteproc core for loading (when using kernel remoteproc loader), or
- * by any rpmsg bus drivers.
- */
-static void *k3_m4_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
-{
-	struct k3_m4_rproc *kproc = rproc->priv;
-	void __iomem *va = NULL;
-	phys_addr_t bus_addr;
-	u32 dev_addr, offset;
-	size_t size;
-	int i;
-
-	if (len == 0)
-		return NULL;
-
-	for (i = 0; i < kproc->num_mems; i++) {
-		bus_addr = kproc->mem[i].bus_addr;
-		dev_addr = kproc->mem[i].dev_addr;
-		size = kproc->mem[i].size;
-
-		/* handle M4-view addresses */
-		if (da >= dev_addr && ((da + len) <= (dev_addr + size))) {
-			offset = da - dev_addr;
-			va = kproc->mem[i].cpu_addr + offset;
-			return (__force void *)va;
-		}
-
-		/* handle SoC-view addresses */
-		if (da >= bus_addr && ((da + len) <= (bus_addr + size))) {
-			offset = da - bus_addr;
-			va = kproc->mem[i].cpu_addr + offset;
-			return (__force void *)va;
-		}
-	}
-
-	/* handle static DDR reserved memory regions */
-	for (i = 0; i < kproc->num_rmems; i++) {
-		dev_addr = kproc->rmem[i].dev_addr;
-		size = kproc->rmem[i].size;
-
-		if (da >= dev_addr && ((da + len) <= (dev_addr + size))) {
-			offset = da - dev_addr;
-			va = kproc->rmem[i].cpu_addr + offset;
-			return (__force void *)va;
-		}
-	}
-
-	return NULL;
-}
-
-static int k3_m4_rproc_of_get_memories(struct platform_device *pdev,
-				       struct k3_m4_rproc *kproc)
-{
-	static const char * const mem_names[] = { "iram", "dram" };
-	static const u32 mem_addrs[] = { K3_M4_IRAM_DEV_ADDR, K3_M4_DRAM_DEV_ADDR };
-	struct device *dev = &pdev->dev;
-	struct resource *res;
-	int num_mems;
-	int i;
-
-	num_mems = ARRAY_SIZE(mem_names);
-	kproc->mem = devm_kcalloc(kproc->dev, num_mems,
-				  sizeof(*kproc->mem), GFP_KERNEL);
-	if (!kproc->mem)
-		return -ENOMEM;
-
-	for (i = 0; i < num_mems; i++) {
-		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						   mem_names[i]);
-		if (!res) {
-			dev_err(dev, "found no memory resource for %s\n",
-				mem_names[i]);
-			return -EINVAL;
-		}
-		if (!devm_request_mem_region(dev, res->start,
-					     resource_size(res),
-					     dev_name(dev))) {
-			dev_err(dev, "could not request %s region for resource\n",
-				mem_names[i]);
-			return -EBUSY;
-		}
-
-		kproc->mem[i].cpu_addr = devm_ioremap_wc(dev, res->start,
-							 resource_size(res));
-		if (!kproc->mem[i].cpu_addr) {
-			dev_err(dev, "failed to map %s memory\n",
-				mem_names[i]);
-			return -ENOMEM;
-		}
-		kproc->mem[i].bus_addr = res->start;
-		kproc->mem[i].dev_addr = mem_addrs[i];
-		kproc->mem[i].size = resource_size(res);
-
-		dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %pK da 0x%x\n",
-			mem_names[i], &kproc->mem[i].bus_addr,
-			kproc->mem[i].size, kproc->mem[i].cpu_addr,
-			kproc->mem[i].dev_addr);
-	}
-	kproc->num_mems = num_mems;
-
-	return 0;
-}
-
-static void k3_m4_rproc_dev_mem_release(void *data)
-{
-	struct device *dev = data;
-
-	of_reserved_mem_device_release(dev);
-}
-
-static int k3_m4_reserved_mem_init(struct k3_m4_rproc *kproc)
-{
-	struct device *dev = kproc->dev;
-	struct device_node *np = dev->of_node;
-	struct device_node *rmem_np;
-	struct reserved_mem *rmem;
-	int num_rmems;
-	int ret, i;
-
-	num_rmems = of_property_count_elems_of_size(np, "memory-region",
-						    sizeof(phandle));
-	if (num_rmems < 0) {
-		dev_err(dev, "device does not reserved memory regions (%d)\n",
-			num_rmems);
-		return -EINVAL;
-	}
-	if (num_rmems < 2) {
-		dev_err(dev, "device needs at least two memory regions to be defined, num = %d\n",
-			num_rmems);
-		return -EINVAL;
-	}
-
-	/* use reserved memory region 0 for vring DMA allocations */
-	ret = of_reserved_mem_device_init_by_idx(dev, np, 0);
-	if (ret) {
-		dev_err(dev, "device cannot initialize DMA pool (%d)\n", ret);
-		return ret;
-	}
-	ret = devm_add_action_or_reset(dev, k3_m4_rproc_dev_mem_release, dev);
-	if (ret)
-		return ret;
-
-	num_rmems--;
-	kproc->rmem = devm_kcalloc(dev, num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
-	if (!kproc->rmem)
-		return -ENOMEM;
-
-	/* use remaining reserved memory regions for static carveouts */
-	for (i = 0; i < num_rmems; i++) {
-		rmem_np = of_parse_phandle(np, "memory-region", i + 1);
-		if (!rmem_np)
-			return -EINVAL;
-
-		rmem = of_reserved_mem_lookup(rmem_np);
-		if (!rmem) {
-			of_node_put(rmem_np);
-			return -EINVAL;
-		}
-		of_node_put(rmem_np);
-
-		kproc->rmem[i].bus_addr = rmem->base;
-		/* 64-bit address regions currently not supported */
-		kproc->rmem[i].dev_addr = (u32)rmem->base;
-		kproc->rmem[i].size = rmem->size;
-		kproc->rmem[i].cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
-		if (!kproc->rmem[i].cpu_addr) {
-			dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n",
-				i + 1, &rmem->base, &rmem->size);
-			return -ENOMEM;
-		}
-
-		dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",
-			i + 1, &kproc->rmem[i].bus_addr,
-			kproc->rmem[i].size, kproc->rmem[i].cpu_addr,
-			kproc->rmem[i].dev_addr);
-	}
-	kproc->num_rmems = num_rmems;
-
-	return 0;
-}
-
-static void k3_m4_release_tsp(void *data)
-{
-	struct ti_sci_proc *tsp = data;
-
-	ti_sci_proc_release(tsp);
-}
-
-/*
- * Power up the M4 remote processor.
- *
- * This function will be invoked only after the firmware for this rproc
- * was loaded, parsed successfully, and all of its resource requirements
- * were met. This callback is invoked only in remoteproc mode.
- */
-static int k3_m4_rproc_start(struct rproc *rproc)
-{
-	struct k3_m4_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-	int ret;
-
-	ret = k3_m4_rproc_ping_mbox(kproc);
-	if (ret)
-		return ret;
-
-	ret = reset_control_deassert(kproc->reset);
-	if (ret) {
-		dev_err(dev, "local-reset deassert failed, ret = %d\n", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-/*
- * Stop the M4 remote processor.
- *
- * This function puts the M4 processor into reset, and finishes processing
- * of any pending messages. This callback is invoked only in remoteproc mode.
- */
-static int k3_m4_rproc_stop(struct rproc *rproc)
-{
-	struct k3_m4_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-	int ret;
-
-	ret = reset_control_assert(kproc->reset);
-	if (ret) {
-		dev_err(dev, "local-reset assert failed, ret = %d\n", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-/*
- * Attach to a running M4 remote processor (IPC-only mode)
- *
- * The remote processor is already booted, so there is no need to issue any
- * TI-SCI commands to boot the M4 core. This callback is used only in IPC-only
- * mode.
- */
-static int k3_m4_rproc_attach(struct rproc *rproc)
-{
-	struct k3_m4_rproc *kproc = rproc->priv;
-	int ret;
-
-	ret = k3_m4_rproc_ping_mbox(kproc);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
-/*
- * Detach from a running M4 remote processor (IPC-only mode)
- *
- * This rproc detach callback performs the opposite operation to attach
- * callback, the M4 core is not stopped and will be left to continue to
- * run its booted firmware. This callback is invoked only in IPC-only mode.
- */
-static int k3_m4_rproc_detach(struct rproc *rproc)
-{
-	return 0;
-}
+#include "ti_k3_common.h"
 
 static const struct rproc_ops k3_m4_rproc_ops = {
-	.prepare = k3_m4_rproc_prepare,
-	.unprepare = k3_m4_rproc_unprepare,
-	.start = k3_m4_rproc_start,
-	.stop = k3_m4_rproc_stop,
-	.attach = k3_m4_rproc_attach,
-	.detach = k3_m4_rproc_detach,
-	.kick = k3_m4_rproc_kick,
-	.da_to_va = k3_m4_rproc_da_to_va,
-	.get_loaded_rsc_table = k3_m4_get_loaded_rsc_table,
+	.prepare = k3_rproc_prepare,
+	.unprepare = k3_rproc_unprepare,
+	.start = k3_rproc_start,
+	.stop = k3_rproc_stop,
+	.attach = k3_rproc_attach,
+	.detach = k3_rproc_detach,
+	.kick = k3_rproc_kick,
+	.da_to_va = k3_rproc_da_to_va,
+	.get_loaded_rsc_table = k3_get_loaded_rsc_table,
 };
 
 static int k3_m4_rproc_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct k3_m4_rproc *kproc;
+	const struct k3_rproc_dev_data *data;
+	struct k3_rproc *kproc;
 	struct rproc *rproc;
 	const char *fw_name;
 	bool r_state = false;
 	bool p_state = false;
 	int ret;
 
+	data = of_device_get_match_data(dev);
+	if (!data)
+		return -ENODEV;
+
 	ret = rproc_of_parse_firmware(dev, 0, &fw_name);
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to parse firmware-name property\n");
@@ -580,7 +62,9 @@
 	rproc->recovery_disabled = true;
 	kproc = rproc->priv;
 	kproc->dev = dev;
-	platform_set_drvdata(pdev, rproc);
+	kproc->data = data;
+	kproc->rproc = rproc;
+	platform_set_drvdata(pdev, kproc);
 
 	kproc->ti_sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
 	if (IS_ERR(kproc->ti_sci))
@@ -600,18 +84,20 @@
 		return dev_err_probe(dev, PTR_ERR(kproc->tsp),
 				     "failed to construct ti-sci proc control\n");
 
+	init_completion(&kproc->shut_comp);
+
 	ret = ti_sci_proc_request(kproc->tsp);
 	if (ret < 0)
 		return dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
-	ret = devm_add_action_or_reset(dev, k3_m4_release_tsp, kproc->tsp);
+	ret = devm_add_action_or_reset(dev, k3_release_tsp, kproc->tsp);
 	if (ret)
 		return ret;
 
-	ret = k3_m4_rproc_of_get_memories(pdev, kproc);
+	ret = k3_rproc_of_get_memories(pdev, kproc);
 	if (ret)
 		return ret;
 
-	ret = k3_m4_reserved_mem_init(kproc);
+	ret = k3_reserved_mem_init(kproc);
 	if (ret)
 		return dev_err_probe(dev, ret, "reserved memory init failed\n");
 
@@ -625,38 +111,59 @@
 	if (p_state) {
 		rproc->state = RPROC_DETACHED;
 		dev_info(dev, "configured M4F for IPC-only mode\n");
+		/* override rproc ops with only required IPC-only mode ops */
+		kproc->rproc->ops->prepare = NULL;
+		kproc->rproc->ops->unprepare = NULL;
+		kproc->rproc->ops->start = NULL;
+		kproc->rproc->ops->stop = NULL;
 	} else {
 		dev_info(dev, "configured M4F for remoteproc mode\n");
+		kproc->pm_notifier.notifier_call = k3_rproc_pm_notifier_call;
+		register_pm_notifier(&kproc->pm_notifier);
 	}
 
-	kproc->client.dev = dev;
-	kproc->client.tx_done = NULL;
-	kproc->client.rx_callback = k3_m4_rproc_mbox_callback;
-	kproc->client.tx_block = false;
-	kproc->client.knows_txdone = false;
-	kproc->mbox = mbox_request_channel(&kproc->client, 0);
-	if (IS_ERR(kproc->mbox))
-		return dev_err_probe(dev, PTR_ERR(kproc->mbox),
-				     "mbox_request_channel failed\n");
+	ret = k3_rproc_request_mbox(rproc);
+	if (ret)
+		return ret;
 
 	ret = devm_rproc_add(dev, rproc);
 	if (ret)
 		return dev_err_probe(dev, ret,
 				     "failed to register device with remoteproc core\n");
 
+	init_completion(&kproc->shut_comp);
+	init_completion(&kproc->suspend_comp);
+
 	return 0;
 }
 
+static const struct k3_rproc_mem_data am64_m4_mems[] = {
+	{ .name = "iram", .dev_addr = 0x0 },
+	{ .name = "dram", .dev_addr = 0x30000 },
+};
+
+static const struct k3_rproc_dev_data am64_m4_data = {
+	.mems = am64_m4_mems,
+	.num_mems = ARRAY_SIZE(am64_m4_mems),
+	.boot_align_addr = SZ_1K,
+	.uses_lreset = true,
+};
+
 static const struct of_device_id k3_m4_of_match[] = {
-	{ .compatible = "ti,am64-m4fss", },
+	{ .compatible = "ti,am64-m4fss", .data = &am64_m4_data, },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, k3_m4_of_match);
 
+static const struct dev_pm_ops k3_m4_pm_ops = {
+	LATE_SYSTEM_SLEEP_PM_OPS(k3_rproc_suspend_late, NULL)
+};
+
 static struct platform_driver k3_m4_rproc_driver = {
 	.probe	= k3_m4_rproc_probe,
 	.driver	= {
 		.name = "k3-m4-rproc",
+		.pm = &k3_m4_pm_ops,
 		.of_match_table = k3_m4_of_match,
 	},
 };
diff -Naur --no-dereference a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c	2025-10-23 09:30:40.286462238 -0400
@@ -2,13 +2,15 @@
 /*
  * TI K3 R5F (MCU) Remote Processor driver
  *
- * Copyright (C) 2017-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2017-2025 Texas Instruments Incorporated - https://www.ti.com/
  *	Suman Anna <s-anna@ti.com>
  */
 
+#include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/mailbox_client.h>
 #include <linux/module.h>
@@ -18,10 +20,12 @@
 #include <linux/of_platform.h>
 #include <linux/omap-mailbox.h>
 #include <linux/platform_device.h>
+#include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
 #include <linux/remoteproc.h>
 #include <linux/reset.h>
 #include <linux/slab.h>
+#include <linux/suspend.h>
 
 #include "omap_remoteproc.h"
 #include "remoteproc_internal.h"
@@ -112,6 +116,7 @@
 	struct list_head cores;
 	wait_queue_head_t core_transition;
 	const struct k3_r5_soc_data *soc_data;
+	struct dev_pm_qos_request qos_req;
 };
 
 /**
@@ -147,6 +152,9 @@
 	u32 atcm_enable;
 	u32 btcm_enable;
 	u32 loczrama;
+	u32 set_cfg;
+	u32 clr_cfg;
+	u64 boot_vec;
 	bool released_from_reset;
 };
 
@@ -170,9 +178,68 @@
 	struct k3_r5_core *core;
 	struct k3_r5_mem *rmem;
 	int num_rmems;
+	struct completion shut_comp;
+	struct completion suspend_comp;
+	struct notifier_block pm_notifier;
+	u32 suspend_status;
 };
 
 /**
+ * is_core_in_wfi - local utility function to check core status
+ * @core: remote core pointer used for checking core status
+ *
+ * This utility function is invoked by the shutdown sequence to ensure
+ * the remote core is in wfi, before asserting a reset.
+ */
+static int is_core_in_wfi(struct k3_r5_core *core)
+{
+	int ret;
+	u64 boot_vec = 0;
+	u32 cfg = 0, ctrl = 0, stat = 0;
+
+	ret = ti_sci_proc_get_status(core->tsp, &boot_vec, &cfg, &ctrl, &stat);
+
+	if (ret < 0)
+		return 0;
+
+	return (stat & PROC_BOOT_STATUS_FLAG_R5_WFI);
+}
+
+/**
+ * get_core_status - local utility function to check core status
+ * @core: remote core pointer used for checking core status
+ * @cstatus: core status
+ *
+ * This utility function is invoked by the resume handler to get remote core
+ * status.
+ */
+static int get_core_status(struct k3_r5_core *core, bool *cstatus)
+{
+	int ret;
+	bool r_state = false, c_state = false;
+	u64 boot_vec = 0;
+	u32 ctrl = 0, cfg = 0, stat = 0, halted = 0;
+
+	ret = core->ti_sci->ops.dev_ops.is_on(core->ti_sci, core->ti_sci_id,
+					      &r_state, &c_state);
+	if (ret) {
+		dev_err(core->dev, "ti_sci call to get dev status failed\n");
+		return ret;
+	}
+
+	ret = ti_sci_proc_get_status(core->tsp, &boot_vec, &cfg, &ctrl, &stat);
+	if (ret) {
+		dev_err(core->dev, "ti_sci call to get proc status failed\n");
+		return ret;
+	}
+	halted = ctrl & PROC_BOOT_CTRL_FLAG_R5_CORE_HALT;
+
+	*cstatus = !!(c_state && !halted);
+
+	return 0;
+}
+
+/**
  * k3_r5_rproc_mbox_callback() - inbound mailbox message handler
  * @client: mailbox client pointer used for requesting the mailbox channel
  * @data: mailbox payload
@@ -207,6 +274,25 @@
 	case RP_MBOX_ECHO_REPLY:
 		dev_info(dev, "received echo reply from %s\n", name);
 		break;
+	case RP_MBOX_SHUTDOWN_ACK:
+		dev_dbg(dev, "received shutdown_ack from %s\n", name);
+		complete(&kproc->shut_comp);
+		break;
+	case RP_MBOX_SUSPEND_ACK:
+		dev_dbg(dev, "received suspend_ack from %s\n", name);
+		kproc->suspend_status = RP_MBOX_SUSPEND_ACK;
+		complete(&kproc->suspend_comp);
+		break;
+	case RP_MBOX_SUSPEND_CANCEL:
+		dev_err(dev, "received suspend_cancel from %s\n", name);
+		kproc->suspend_status = RP_MBOX_SUSPEND_CANCEL;
+		complete(&kproc->suspend_comp);
+		break;
+	case RP_MBOX_SUSPEND_AUTO:
+		dev_dbg(dev, "received suspend_auto from %s\n", name);
+		kproc->suspend_status = RP_MBOX_SUSPEND_AUTO;
+		complete(&kproc->suspend_comp);
+		break;
 	default:
 		/* silently handle all other valid messages */
 		if (msg >= RP_MBOX_READY && msg < RP_MBOX_END_MSG)
@@ -239,6 +325,11 @@
 static int k3_r5_split_reset(struct k3_r5_core *core)
 {
 	int ret;
+	struct k3_r5_rproc *kproc;
+	const struct k3_r5_soc_data *soc_data;
+
+	kproc = core->rproc->priv;
+	soc_data = kproc->cluster->soc_data;
 
 	ret = reset_control_assert(core->reset);
 	if (ret) {
@@ -247,6 +338,14 @@
 		return ret;
 	}
 
+	/* On AM64 devices power-down of core1 in r5f cluster, even when core0
+	 * is on randomly gets the lpsc stuck in transition state and makes the core
+	 * un-usable. So as a work around keep the power state on with reset
+	 * asserted.
+	 */
+	if (soc_data->single_cpu_mode)
+		return ret;
+
 	ret = core->ti_sci->ops.dev_ops.put_device(core->ti_sci,
 						   core->ti_sci_id);
 	if (ret) {
@@ -420,6 +519,151 @@
 	return 0;
 }
 
+static int k3_r5_suspend(struct rproc *rproc)
+{
+	struct k3_r5_rproc *kproc = rproc->priv;
+	unsigned long msg = RP_MBOX_SUSPEND_SYSTEM;
+	unsigned long to = msecs_to_jiffies(5000);
+	struct dev_pm_qos_request qos_req;
+	struct device *dev = kproc->dev;
+	int ret = 0;
+
+	if (rproc->state != RPROC_RUNNING) {
+		dev_err(dev, "remoteproc state not suspendable! State=%d\n", rproc->state);
+		return ret;
+	}
+
+	kproc->suspend_status = 0;
+	reinit_completion(&kproc->suspend_comp);
+
+	ret = mbox_send_message(kproc->mbox, (void *)msg);
+	if (ret < 0) {
+		dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = wait_for_completion_timeout(&kproc->suspend_comp, to);
+	if (ret == 0) {
+		dev_err(dev, "%s: timedout waiting for rproc completion event\n", __func__);
+		/* Set constraint to keep the device on */
+		dev_pm_qos_add_request(kproc->dev, &qos_req, DEV_PM_QOS_RESUME_LATENCY, 0);
+		return 0;
+	}
+
+	if (kproc->suspend_status == RP_MBOX_SUSPEND_ACK) {
+		/* shutdown the remote core */
+		ret = rproc_shutdown(rproc);
+		if (ret) {
+			dev_err(dev, "rproc_shutdown failed, ret = %d\n", ret);
+			return -EBUSY;
+		}
+		kproc->rproc->state = RPROC_SUSPENDED;
+	} else if (kproc->suspend_status == RP_MBOX_SUSPEND_CANCEL) {
+		return -EBUSY;
+	} else if (kproc->suspend_status == RP_MBOX_SUSPEND_AUTO) {
+		kproc->rproc->state = RPROC_SUSPENDED;
+	}
+
+	return 0;
+}
+
+static int k3_r5_resume(struct rproc *rproc)
+{
+	struct k3_r5_rproc *kproc = rproc->priv;
+	bool cstatus = false;
+	unsigned long msg = RP_MBOX_ECHO_REQUEST;
+	struct k3_r5_core *core = kproc->core;
+	struct device *dev = kproc->dev;
+	int ret = 0;
+
+	if (rproc->state != RPROC_SUSPENDED)
+		return ret;
+
+	ret = get_core_status(core, &cstatus);
+	if (ret) {
+		dev_err(dev, "failed to get core status: %d\n", ret);
+		return ret;
+	}
+
+	if (cstatus) {
+		dev_err(dev, "Core is on in resume\n");
+		msg = RP_MBOX_ECHO_REQUEST;
+		ret = mbox_send_message(kproc->mbox, (void *)msg);
+		if (ret < 0) {
+			dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
+			return ret;
+		}
+	} else {
+		dev_info(dev, "Core is off in resume\n");
+		/* restore device configuration */
+		ret = ti_sci_proc_set_config(core->tsp, core->boot_vec,
+						     core->set_cfg, core->clr_cfg);
+		if (ret)
+			dev_err(dev, "set config failed: %d\n", ret);
+
+		ret = rproc_boot(rproc);
+		if (ret) {
+			dev_err(dev, "rproc_boot failed: %d\n", ret);
+			return ret;
+		}
+	}
+	kproc->rproc->state = RPROC_RUNNING;
+	return 0;
+}
+
+/* PM notifier call.
+ * This is a callback function for PM notifications. On a resume completion
+ * i.e after all the resume driver calls are handled on PM_POST_SUSPEND,
+ * on a deep sleep the remote core is rebooted.
+ */
+static int r5f_pm_notifier_call(struct notifier_block *bl,
+				unsigned long state, void *unused)
+{
+	struct k3_r5_rproc *kproc = container_of(bl, struct k3_r5_rproc,
+						 pm_notifier);
+	struct rproc *rproc = kproc->rproc;
+
+	switch (state) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_RESTORE_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		break;
+	case PM_POST_HIBERNATION:
+	case PM_POST_RESTORE:
+	case PM_POST_SUSPEND:
+		if (rproc->state == RPROC_SUSPENDED)
+			return k3_r5_resume(rproc);
+		break;
+	}
+	return 0;
+}
+
+static int k3_r5_suspend_late(struct device *dev)
+{
+	struct k3_r5_cluster *cluster = dev_get_drvdata(dev);
+	struct k3_r5_core *core;
+	int ret = 0;
+
+	list_for_each_entry(core, &cluster->cores, elem) {
+		struct k3_r5_rproc *kproc;
+		struct rproc *rproc;
+
+		rproc = core->rproc;
+		kproc = rproc->priv;
+
+		/* Check if pm notifier call is set. if it is, suspend/resume is
+		 * supported
+		 */
+		if (kproc->pm_notifier.notifier_call) {
+			ret = k3_r5_suspend(rproc);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
 /*
  * The R5F cores have controls for both a reset and a halt/run. The code
  * execution from DDR requires the initial boot-strapping code to be run
@@ -440,13 +684,36 @@
 {
 	struct k3_r5_rproc *kproc = rproc->priv;
 	struct k3_r5_cluster *cluster = kproc->cluster;
-	struct k3_r5_core *core = kproc->core;
+	struct k3_r5_core *core = kproc->core, *core0, *core1;
 	struct device *dev = kproc->dev;
 	u32 ctrl = 0, cfg = 0, stat = 0;
 	u64 boot_vec = 0;
 	bool mem_init_dis;
 	int ret;
 
+	/*
+	 * R5 cores require to be powered on sequentially, core0 should be in
+	 * higher power state than core1 in a cluster. So, wait for core0 to
+	 * power up before proceeding to core1 and put timeout of 2sec. This
+	 * waiting mechanism is necessary because rproc_auto_boot_callback() for
+	 * core1 can be called before core0 due to thread execution order.
+	 *
+	 * By placing the wait mechanism here in .prepare() ops, this condition
+	 * is enforced for rproc boot requests from sysfs as well.
+	 */
+	core0 = list_first_entry(&cluster->cores, struct k3_r5_core, elem);
+	core1 = list_last_entry(&cluster->cores, struct k3_r5_core, elem);
+	if (cluster->mode == CLUSTER_MODE_SPLIT && core == core1 &&
+	    !core0->released_from_reset) {
+		ret = wait_event_interruptible_timeout(cluster->core_transition,
+						       core0->released_from_reset,
+						       msecs_to_jiffies(2000));
+		if (ret <= 0) {
+			dev_err(dev, "can not power up core1 before core0");
+			return -EPERM;
+		}
+	}
+
 	ret = ti_sci_proc_get_status(core->tsp, &boot_vec, &cfg, &ctrl, &stat);
 	if (ret < 0)
 		return ret;
@@ -463,6 +730,14 @@
 	}
 
 	/*
+	 * Notify all threads in the wait queue when core0 state has changed so
+	 * that threads waiting for this condition can be executed.
+	 */
+	core->released_from_reset = true;
+	if (core == core0)
+		wake_up_interruptible(&cluster->core_transition);
+
+	/*
 	 * Newer IP revisions like on J7200 SoCs support h/w auto-initialization
 	 * of TCMs, so there is no need to perform the s/w memzero. This bit is
 	 * configurable through System Firmware, the default value does perform
@@ -507,10 +782,30 @@
 {
 	struct k3_r5_rproc *kproc = rproc->priv;
 	struct k3_r5_cluster *cluster = kproc->cluster;
-	struct k3_r5_core *core = kproc->core;
+	struct k3_r5_core *core = kproc->core, *core0, *core1;
 	struct device *dev = kproc->dev;
 	int ret;
 
+	/*
+	 * Ensure power-down of cores is sequential in split mode. Core1 must
+	 * power down before Core0 to maintain the expected state. By placing
+	 * the wait mechanism here in .unprepare() ops, this condition is
+	 * enforced for rproc stop or shutdown requests from sysfs and device
+	 * removal as well.
+	 */
+	core0 = list_first_entry(&cluster->cores, struct k3_r5_core, elem);
+	core1 = list_last_entry(&cluster->cores, struct k3_r5_core, elem);
+	if (cluster->mode == CLUSTER_MODE_SPLIT && core == core0 &&
+	    core1->released_from_reset && !cluster->soc_data->single_cpu_mode) {
+		ret = wait_event_interruptible_timeout(cluster->core_transition,
+						       !core1->released_from_reset,
+						       msecs_to_jiffies(2000));
+		if (ret <= 0) {
+			dev_err(dev, "can not power down core0 before core1");
+			return -EPERM;
+		}
+	}
+
 	/* Re-use LockStep-mode reset logic for Single-CPU mode */
 	ret = (cluster->mode == CLUSTER_MODE_LOCKSTEP ||
 	       cluster->mode == CLUSTER_MODE_SINGLECPU) ?
@@ -518,6 +813,16 @@
 	if (ret)
 		dev_err(dev, "unable to disable cores, ret = %d\n", ret);
 
+	/*
+	 * Notify all threads in the wait queue when core1 state has changed so
+	 * that threads waiting for this condition can be executed.
+	 */
+	if (!cluster->soc_data->single_cpu_mode)
+		core->released_from_reset = false;
+
+	if (core == core1)
+		wake_up_interruptible(&cluster->core_transition);
+
 	return ret;
 }
 
@@ -543,7 +848,7 @@
 	struct k3_r5_rproc *kproc = rproc->priv;
 	struct k3_r5_cluster *cluster = kproc->cluster;
 	struct device *dev = kproc->dev;
-	struct k3_r5_core *core0, *core;
+	struct k3_r5_core *core;
 	u32 boot_addr;
 	int ret;
 
@@ -565,21 +870,9 @@
 				goto unroll_core_run;
 		}
 	} else {
-		/* do not allow core 1 to start before core 0 */
-		core0 = list_first_entry(&cluster->cores, struct k3_r5_core,
-					 elem);
-		if (core != core0 && core0->rproc->state == RPROC_OFFLINE) {
-			dev_err(dev, "%s: can not start core 1 before core 0\n",
-				__func__);
-			return -EPERM;
-		}
-
 		ret = k3_r5_core_run(core);
 		if (ret)
 			return ret;
-
-		core->released_from_reset = true;
-		wake_up_interruptible(&cluster->core_transition);
 	}
 
 	return 0;
@@ -618,11 +911,14 @@
  */
 static int k3_r5_rproc_stop(struct rproc *rproc)
 {
+	unsigned long to  = msecs_to_jiffies(5000);
 	struct k3_r5_rproc *kproc = rproc->priv;
 	struct k3_r5_cluster *cluster = kproc->cluster;
+	struct k3_r5_core *core = kproc->core;
 	struct device *dev = kproc->dev;
-	struct k3_r5_core *core1, *core = kproc->core;
+	unsigned long msg = RP_MBOX_SHUTDOWN;
 	int ret;
+	u32 stat = 0;
 
 	/* halt all applicable cores */
 	if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
@@ -634,16 +930,28 @@
 			}
 		}
 	} else {
-		/* do not allow core 0 to stop before core 1 */
-		core1 = list_last_entry(&cluster->cores, struct k3_r5_core,
-					elem);
-		if (core != core1 && core1->rproc->state != RPROC_OFFLINE) {
-			dev_err(dev, "%s: can not stop core 0 before core 1\n",
-				__func__);
-			ret = -EPERM;
-			goto out;
+		if (kproc->rproc->state == RPROC_SUSPENDED) {
+			dev_err(dev, "We can't stop in suspended state!!!!\n");
+			return 0;
+		}
+
+		reinit_completion(&kproc->shut_comp);
+		ret = mbox_send_message(kproc->mbox, (void *)msg);
+		if (ret < 0) {
+			dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
+			return ret;
+		}
+
+		ret = wait_for_completion_timeout(&kproc->shut_comp, to);
+		if (ret == 0) {
+			dev_err(dev, "%s: timeout waiting for rproc completion event\n", __func__);
+			return -EBUSY;
 		}
 
+		ret = readx_poll_timeout(is_core_in_wfi, core, stat, stat, 200, 2000);
+		if (ret)
+			goto out;
+
 		ret = k3_r5_core_halt(core);
 		if (ret)
 			goto out;
@@ -942,11 +1250,21 @@
 		ret = ti_sci_proc_set_config(core->tsp, boot_vec,
 					     set_cfg, clr_cfg);
 	}
-
+	/* cache set_cfg and clr_cfg */
+	core->boot_vec = boot_vec;
+	core->set_cfg = set_cfg;
+	core->clr_cfg = clr_cfg;
 out:
 	return ret;
 }
 
+static void k3_r5_mem_release(void *data)
+{
+	struct device *dev = data;
+
+	of_reserved_mem_device_release(dev);
+}
+
 static int k3_r5_reserved_mem_init(struct k3_r5_rproc *kproc)
 {
 	struct device *dev = kproc->dev;
@@ -977,28 +1295,25 @@
 		return ret;
 	}
 
+	ret = devm_add_action_or_reset(dev, k3_r5_mem_release, dev);
+	if (ret)
+		return ret;
+
 	num_rmems--;
-	kproc->rmem = kcalloc(num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
-	if (!kproc->rmem) {
-		ret = -ENOMEM;
-		goto release_rmem;
-	}
+	kproc->rmem = devm_kcalloc(dev, num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
+	if (!kproc->rmem)
+		return -ENOMEM;
 
 	/* use remaining reserved memory regions for static carveouts */
 	for (i = 0; i < num_rmems; i++) {
 		rmem_np = of_parse_phandle(np, "memory-region", i + 1);
-		if (!rmem_np) {
-			ret = -EINVAL;
-			goto unmap_rmem;
-		}
+		if (!rmem_np)
+			return -EINVAL;
 
 		rmem = of_reserved_mem_lookup(rmem_np);
-		if (!rmem) {
-			of_node_put(rmem_np);
-			ret = -EINVAL;
-			goto unmap_rmem;
-		}
 		of_node_put(rmem_np);
+		if (!rmem)
+			return -EINVAL;
 
 		kproc->rmem[i].bus_addr = rmem->base;
 		/*
@@ -1013,12 +1328,11 @@
 		 */
 		kproc->rmem[i].dev_addr = (u32)rmem->base;
 		kproc->rmem[i].size = rmem->size;
-		kproc->rmem[i].cpu_addr = ioremap_wc(rmem->base, rmem->size);
+		kproc->rmem[i].cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
 		if (!kproc->rmem[i].cpu_addr) {
 			dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n",
 				i + 1, &rmem->base, &rmem->size);
-			ret = -ENOMEM;
-			goto unmap_rmem;
+			return -ENOMEM;
 		}
 
 		dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",
@@ -1029,25 +1343,6 @@
 	kproc->num_rmems = num_rmems;
 
 	return 0;
-
-unmap_rmem:
-	for (i--; i >= 0; i--)
-		iounmap(kproc->rmem[i].cpu_addr);
-	kfree(kproc->rmem);
-release_rmem:
-	of_reserved_mem_device_release(dev);
-	return ret;
-}
-
-static void k3_r5_reserved_mem_exit(struct k3_r5_rproc *kproc)
-{
-	int i;
-
-	for (i = 0; i < kproc->num_rmems; i++)
-		iounmap(kproc->rmem[i].cpu_addr);
-	kfree(kproc->rmem);
-
-	of_reserved_mem_device_release(kproc->dev);
 }
 
 /*
@@ -1184,6 +1479,9 @@
 						k3_r5_get_loaded_rsc_table;
 	} else if (!c_state) {
 		dev_info(cdev, "configured R5F for remoteproc mode\n");
+		/* add support for suspend/resume */
+		kproc->pm_notifier.notifier_call = r5f_pm_notifier_call;
+		register_pm_notifier(&kproc->pm_notifier);
 		ret = 0;
 	} else {
 		dev_err(cdev, "mismatched mode: local_reset = %s, module_reset = %s, core_state = %s\n",
@@ -1235,6 +1533,10 @@
 			goto out;
 		}
 
+		ret = dma_coerce_mask_and_coherent(&rproc->dev, DMA_BIT_MASK(48));
+		if (ret)
+			dev_warn(dev, "Failed to set DMA mask (%d)\n", ret);
+
 		/* K3 R5s have a Region Address Translator (RAT) but no MMU */
 		rproc->has_iommu = false;
 		/* error recovery is not supported at present */
@@ -1264,6 +1566,7 @@
 			goto out;
 		}
 
+		init_completion(&kproc->shut_comp);
 init_rmem:
 		k3_r5_adjust_tcm_sizes(kproc);
 
@@ -1274,12 +1577,13 @@
 			goto out;
 		}
 
-		ret = rproc_add(rproc);
+		ret = devm_rproc_add(dev, rproc);
 		if (ret) {
-			dev_err(dev, "rproc_add failed, ret = %d\n", ret);
-			goto err_add;
+			dev_err_probe(dev, ret, "rproc_add failed\n");
+			goto out;
 		}
 
+		init_completion(&kproc->suspend_comp);
 		/* create only one rproc in lockstep, single-cpu or
 		 * single core mode
 		 */
@@ -1287,26 +1591,6 @@
 		    cluster->mode == CLUSTER_MODE_SINGLECPU ||
 		    cluster->mode == CLUSTER_MODE_SINGLECORE)
 			break;
-
-		/*
-		 * R5 cores require to be powered on sequentially, core0
-		 * should be in higher power state than core1 in a cluster
-		 * So, wait for current core to power up before proceeding
-		 * to next core and put timeout of 2sec for each core.
-		 *
-		 * This waiting mechanism is necessary because
-		 * rproc_auto_boot_callback() for core1 can be called before
-		 * core0 due to thread execution order.
-		 */
-		ret = wait_event_interruptible_timeout(cluster->core_transition,
-						       core->released_from_reset,
-						       msecs_to_jiffies(2000));
-		if (ret <= 0) {
-			dev_err(dev,
-				"Timed out waiting for %s core to power up!\n",
-				rproc->name);
-			goto err_powerup;
-		}
 	}
 
 	return 0;
@@ -1321,10 +1605,6 @@
 		}
 	}
 
-err_powerup:
-	rproc_del(rproc);
-err_add:
-	k3_r5_reserved_mem_exit(kproc);
 out:
 	/* undo core0 upon any failures on core1 in split-mode */
 	if (cluster->mode == CLUSTER_MODE_SPLIT && core == core1) {
@@ -1367,10 +1647,7 @@
 		}
 
 		mbox_free_channel(kproc->mbox);
-
-		rproc_del(rproc);
-
-		k3_r5_reserved_mem_exit(kproc);
+		unregister_pm_notifier(&kproc->pm_notifier);
 	}
 }
 
@@ -1503,6 +1780,13 @@
 	return 0;
 }
 
+static void k3_r5_release_tsp(void *data)
+{
+	struct ti_sci_proc *tsp = data;
+
+	ti_sci_proc_release(tsp);
+}
+
 static int k3_r5_core_of_init(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1604,6 +1888,10 @@
 		goto err;
 	}
 
+	ret = devm_add_action_or_reset(dev, k3_r5_release_tsp, core->tsp);
+	if (ret)
+		goto err;
+
 	platform_set_drvdata(pdev, core);
 	devres_close_group(dev, k3_r5_core_of_init);
 
@@ -1620,13 +1908,7 @@
  */
 static void k3_r5_core_of_exit(struct platform_device *pdev)
 {
-	struct k3_r5_core *core = platform_get_drvdata(pdev);
 	struct device *dev = &pdev->dev;
-	int ret;
-
-	ret = ti_sci_proc_release(core->tsp);
-	if (ret)
-		dev_err(dev, "failed to release proc, ret = %d\n", ret);
 
 	platform_set_drvdata(pdev, NULL);
 	devres_release_group(dev, k3_r5_core_of_init);
@@ -1781,6 +2063,7 @@
 	if (ret)
 		return ret;
 
+	dev_pm_qos_expose_latency_limit(dev, PM_QOS_RESUME_LATENCY_NO_CONSTRAINT);
 	return 0;
 }
 
@@ -1823,10 +2106,15 @@
 };
 MODULE_DEVICE_TABLE(of, k3_r5_of_match);
 
+static const struct dev_pm_ops k3_r5_pm_ops = {
+	LATE_SYSTEM_SLEEP_PM_OPS(k3_r5_suspend_late, NULL)
+};
+
 static struct platform_driver k3_r5_rproc_driver = {
 	.probe = k3_r5_probe,
 	.driver = {
 		.name = "k3_r5_rproc",
+		.pm = &k3_r5_pm_ops,
 		.of_match_table = k3_r5_of_match,
 	},
 };
diff -Naur --no-dereference a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
--- a/drivers/rpmsg/rpmsg_char.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/rpmsg/rpmsg_char.c	2025-10-23 09:30:40.286462238 -0400
@@ -170,6 +170,9 @@
 
 	ept->flow_cb = rpmsg_ept_flow_cb;
 	eptdev->ept = ept;
+	if (eptdev->chinfo.src == RPMSG_ADDR_ANY)
+		eptdev->chinfo.src = ept->addr;
+
 	filp->private_data = eptdev;
 	mutex_unlock(&eptdev->ept_lock);
 
@@ -522,8 +525,10 @@
 
 static struct rpmsg_device_id rpmsg_chrdev_id_table[] = {
 	{ .name	= "rpmsg-raw" },
+	{ .name	= "rpmsg_chrdev" },
 	{ },
 };
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_chrdev_id_table);
 
 static struct rpmsg_driver rpmsg_chrdev_driver = {
 	.probe = rpmsg_chrdev_probe,
@@ -565,6 +570,5 @@
 }
 module_exit(rpmsg_chrdev_exit);
 
-MODULE_ALIAS("rpmsg:rpmsg_chrdev");
 MODULE_DESCRIPTION("RPMSG device interface");
 MODULE_LICENSE("GPL v2");
diff -Naur --no-dereference a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c
--- a/drivers/soc/ti/k3-ringacc.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/soc/ti/k3-ringacc.c	2025-10-23 09:30:40.286462238 -0400
@@ -45,6 +45,38 @@
 	u32	hwindx;
 };
 
+#define K3_RINGACC_RT_CFG_REGS_OFS	0x40
+#define K3_DMARING_CFG_ADDR_HI_MASK	GENMASK(3, 0)
+#define K3_DMARING_CFG_ASEL_SHIFT	16
+#define K3_DMARING_CFG_SIZE_MASK	GENMASK(15, 0)
+
+/**
+ * struct k3_ring_cfg_regs - The RA Configuration Registers region
+ *
+ * @ba_lo: Ring Base Address Low Register
+ * @ba_hi: Ring Base Address High Register
+ * @size: Ring Size Register
+ */
+struct k3_ring_cfg_regs {
+	u32	ba_lo;
+	u32	ba_hi;
+	u32	size;
+};
+
+#define K3_RINGACC_RT_INT_REGS_OFS		0x140
+#define K3_RINGACC_RT_INT_ENABLE_SET_COMPLETE	BIT(0)
+#define K3_RINGACC_RT_INT_ENABLE_SET_TR			BIT(2)
+
+struct k3_ring_intr_regs {
+	u32	enable_set;
+	u32	resv_4;
+	u32	clr;
+	u32	resv_16;
+	u32	status_set;
+	u32	resv_8;
+	u32	status;
+};
+
 #define K3_RINGACC_RT_REGS_STEP			0x1000
 #define K3_DMARING_RT_REGS_STEP			0x2000
 #define K3_DMARING_RT_REGS_REVERSE_OFS		0x1000
@@ -157,6 +189,8 @@
  */
 struct k3_ring {
 	struct k3_ring_rt_regs __iomem *rt;
+	struct k3_ring_cfg_regs __iomem *cfg;
+	struct k3_ring_intr_regs __iomem *intr;
 	struct k3_ring_fifo_regs __iomem *fifos;
 	struct k3_ringacc_proxy_target_regs  __iomem *proxy;
 	dma_addr_t	ring_mem_dma;
@@ -465,16 +499,30 @@
 	struct ti_sci_msg_rm_ring_cfg ring_cfg = { 0 };
 	struct k3_ringacc *ringacc = ring->parent;
 	int ret;
+	u32 reg;
 
-	ring_cfg.nav_id = ringacc->tisci_dev_id;
-	ring_cfg.index = ring->ring_id;
-	ring_cfg.valid_params = TI_SCI_MSG_VALUE_RM_RING_COUNT_VALID;
-	ring_cfg.count = ring->size;
+	if (!ringacc->tisci) {
+		if (ring->cfg == NULL)
+			return;
+		reg = readl(&ring->cfg->size);
+		reg &= ~K3_DMARING_CFG_SIZE_MASK;
+
+		writel(reg, &ring->cfg->size);
+		wmb();
+		reg |= ring->size;
 
-	ret = ringacc->tisci_ring_ops->set_cfg(ringacc->tisci, &ring_cfg);
-	if (ret)
-		dev_err(ringacc->dev, "TISCI reset ring fail (%d) ring_idx %d\n",
-			ret, ring->ring_id);
+		writel(reg, &ring->cfg->size);
+	} else {
+		ring_cfg.nav_id = ringacc->tisci_dev_id;
+		ring_cfg.index = ring->ring_id;
+		ring_cfg.valid_params = TI_SCI_MSG_VALUE_RM_RING_COUNT_VALID;
+		ring_cfg.count = ring->size;
+
+		ret = ringacc->tisci_ring_ops->set_cfg(ringacc->tisci, &ring_cfg);
+		if (ret)
+			dev_err(ringacc->dev, "TISCI reset ring fail (%d) ring_idx %d\n",
+				ret, ring->ring_id);
+	}
 }
 
 void k3_ringacc_ring_reset(struct k3_ring *ring)
@@ -494,16 +542,30 @@
 	struct ti_sci_msg_rm_ring_cfg ring_cfg = { 0 };
 	struct k3_ringacc *ringacc = ring->parent;
 	int ret;
+	u32 reg;
 
 	ring_cfg.nav_id = ringacc->tisci_dev_id;
 	ring_cfg.index = ring->ring_id;
 	ring_cfg.valid_params = TI_SCI_MSG_VALUE_RM_RING_MODE_VALID;
 	ring_cfg.mode = mode;
 
-	ret = ringacc->tisci_ring_ops->set_cfg(ringacc->tisci, &ring_cfg);
-	if (ret)
-		dev_err(ringacc->dev, "TISCI reconf qmode fail (%d) ring_idx %d\n",
-			ret, ring->ring_id);
+	if (!ringacc->tisci) {
+		writel(ring_cfg.addr_lo, &ring->cfg->ba_lo);
+		writel((ring_cfg.addr_hi & K3_DMARING_CFG_ADDR_HI_MASK) +
+				(ring_cfg.asel << K3_DMARING_CFG_ASEL_SHIFT),
+				&ring->cfg->ba_hi);
+
+		reg = readl(&ring->cfg->size);
+		reg &= ~K3_DMARING_CFG_SIZE_MASK;
+		reg |= ring_cfg.count & K3_DMARING_CFG_SIZE_MASK;
+
+		writel(reg, &ring->cfg->size);
+	} else {
+		ret = ringacc->tisci_ring_ops->set_cfg(ringacc->tisci, &ring_cfg);
+		if (ret)
+			dev_err(ringacc->dev, "TISCI reconf qmode fail (%d) ring_idx %d\n",
+					ret, ring->ring_id);
+	}
 }
 
 void k3_ringacc_ring_reset_dma(struct k3_ring *ring, u32 occ)
@@ -570,15 +632,29 @@
 	struct ti_sci_msg_rm_ring_cfg ring_cfg = { 0 };
 	struct k3_ringacc *ringacc = ring->parent;
 	int ret;
+	u32 reg;
 
 	ring_cfg.nav_id = ringacc->tisci_dev_id;
 	ring_cfg.index = ring->ring_id;
 	ring_cfg.valid_params = TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER;
 
-	ret = ringacc->tisci_ring_ops->set_cfg(ringacc->tisci, &ring_cfg);
-	if (ret)
-		dev_err(ringacc->dev, "TISCI ring free fail (%d) ring_idx %d\n",
-			ret, ring->ring_id);
+	if (!ringacc->tisci) {
+		writel(ring_cfg.addr_lo, &ring->cfg->ba_lo);
+		writel((ring_cfg.addr_hi & K3_DMARING_CFG_ADDR_HI_MASK) +
+				(ring_cfg.asel << K3_DMARING_CFG_ASEL_SHIFT),
+				&ring->cfg->ba_hi);
+
+		reg = readl(&ring->cfg->size);
+		reg &= ~K3_DMARING_CFG_SIZE_MASK;
+		reg |= ring_cfg.count & K3_DMARING_CFG_SIZE_MASK;
+
+		writel(reg, &ring->cfg->size);
+	} else {
+		ret = ringacc->tisci_ring_ops->set_cfg(ringacc->tisci, &ring_cfg);
+		if (ret)
+			dev_err(ringacc->dev, "TISCI ring free fail (%d) ring_idx %d\n",
+					ret, ring->ring_id);
+	}
 }
 
 int k3_ringacc_ring_free(struct k3_ring *ring)
@@ -669,15 +745,31 @@
 }
 EXPORT_SYMBOL_GPL(k3_ringacc_get_ring_irq_num);
 
+u32 k3_ringacc_ring_get_irq_status(struct k3_ring *ring)
+{
+	struct k3_ringacc *ringacc = ring->parent;
+	struct k3_ring *ring2 = &ringacc->rings[ring->ring_id];
+
+	return readl(&ring2->intr->status);
+}
+EXPORT_SYMBOL_GPL(k3_ringacc_ring_get_irq_status);
+
+void k3_ringacc_ring_clear_irq(struct k3_ring *ring)
+{
+	struct k3_ringacc *ringacc = ring->parent;
+	struct k3_ring *ring2 = &ringacc->rings[ring->ring_id];
+
+	writel(0xFF, &ring2->intr->status);
+}
+EXPORT_SYMBOL_GPL(k3_ringacc_ring_clear_irq);
+
 static int k3_ringacc_ring_cfg_sci(struct k3_ring *ring)
 {
 	struct ti_sci_msg_rm_ring_cfg ring_cfg = { 0 };
 	struct k3_ringacc *ringacc = ring->parent;
+	u32 reg;
 	int ret;
 
-	if (!ringacc->tisci)
-		return -EINVAL;
-
 	ring_cfg.nav_id = ringacc->tisci_dev_id;
 	ring_cfg.index = ring->ring_id;
 	ring_cfg.valid_params = TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER;
@@ -688,11 +780,26 @@
 	ring_cfg.size = ring->elm_size;
 	ring_cfg.asel = ring->asel;
 
+	if (!ringacc->tisci) {
+		writel(ring_cfg.addr_lo, &ring->cfg->ba_lo);
+		writel((ring_cfg.addr_hi & K3_DMARING_CFG_ADDR_HI_MASK) +
+				(ring_cfg.asel << K3_DMARING_CFG_ASEL_SHIFT),
+				&ring->cfg->ba_hi);
+
+		reg = readl(&ring->cfg->size);
+		reg &= ~K3_DMARING_CFG_SIZE_MASK;
+		reg |= ring_cfg.count & K3_DMARING_CFG_SIZE_MASK;
+
+		writel(reg, &ring->cfg->size);
+		writel(K3_RINGACC_RT_INT_ENABLE_SET_COMPLETE | K3_RINGACC_RT_INT_ENABLE_SET_TR,
+				&ring->intr->enable_set);
+		return 0;
+	}
+
 	ret = ringacc->tisci_ring_ops->set_cfg(ringacc->tisci, &ring_cfg);
 	if (ret)
 		dev_err(ringacc->dev, "TISCI config ring fail (%d) ring_idx %d\n",
-			ret, ring->ring_id);
-
+				ret, ring->ring_id);
 	return ret;
 }
 
@@ -1480,9 +1587,12 @@
 
 	mutex_init(&ringacc->req_lock);
 
-	base_rt = devm_platform_ioremap_resource_byname(pdev, "ringrt");
-	if (IS_ERR(base_rt))
-		return ERR_CAST(base_rt);
+	base_rt = data->base_rt;
+	if (!base_rt) {
+		base_rt = devm_platform_ioremap_resource_byname(pdev, "ringrt");
+		if (IS_ERR(base_rt))
+			return ERR_CAST(base_rt);
+	}
 
 	ringacc->rings = devm_kzalloc(dev,
 				      sizeof(*ringacc->rings) *
@@ -1498,6 +1608,10 @@
 		struct k3_ring *ring = &ringacc->rings[i];
 
 		ring->rt = base_rt + K3_DMARING_RT_REGS_STEP * i;
+		ring->cfg = base_rt + K3_RINGACC_RT_CFG_REGS_OFS +
+			    K3_DMARING_RT_REGS_STEP * i;
+		ring->intr = base_rt + K3_RINGACC_RT_INT_REGS_OFS +
+			     K3_DMARING_RT_REGS_STEP * i;
 		ring->parent = ringacc;
 		ring->ring_id = i;
 		ring->proxy_id = K3_RINGACC_PROXY_NOT_USED;
diff -Naur --no-dereference a/drivers/soc/ti/k3-socinfo.c b/drivers/soc/ti/k3-socinfo.c
--- a/drivers/soc/ti/k3-socinfo.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/soc/ti/k3-socinfo.c	2025-10-23 09:30:40.286462238 -0400
@@ -43,6 +43,7 @@
 #define JTAG_ID_PARTNO_AM62AX		0xBB8D
 #define JTAG_ID_PARTNO_AM62PX		0xBB9D
 #define JTAG_ID_PARTNO_J722S		0xBBA0
+#define JTAG_ID_PARTNO_AM62LX		0xbba7
 
 static const struct k3_soc_id {
 	unsigned int id;
@@ -58,6 +59,7 @@
 	{ JTAG_ID_PARTNO_AM62AX, "AM62AX" },
 	{ JTAG_ID_PARTNO_AM62PX, "AM62PX" },
 	{ JTAG_ID_PARTNO_J722S, "J722S" },
+	{ JTAG_ID_PARTNO_AM62LX, "AM62LX" },
 };
 
 static const char * const j721e_rev_string_map[] = {
diff -Naur --no-dereference a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
--- a/drivers/spi/spi-cadence-quadspi.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/spi/spi-cadence-quadspi.c	2025-10-23 09:30:40.286462238 -0400
@@ -28,6 +28,7 @@
 #include <linux/sched.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi-mem.h>
+#include <linux/sys_soc.h>
 #include <linux/timer.h>
 
 #define CQSPI_NAME			"cadence-qspi"
@@ -47,6 +48,7 @@
 
 /* Capabilities */
 #define CQSPI_SUPPORTS_OCTAL		BIT(0)
+#define CQSPI_SUPPORTS_QUAD		BIT(1)
 
 #define CQSPI_OP_WIDTH(part) ((part).nbytes ? ilog2((part).buswidth) : 0)
 
@@ -58,15 +60,26 @@
 
 struct cqspi_st;
 
+struct phy_setting {
+	u8	rx;
+	u8	tx;
+	u8	read_delay;
+};
+
 struct cqspi_flash_pdata {
-	struct cqspi_st	*cqspi;
-	u32		clk_rate;
-	u32		read_delay;
-	u32		tshsl_ns;
-	u32		tsd2d_ns;
-	u32		tchsh_ns;
-	u32		tslch_ns;
-	u8		cs;
+	struct cqspi_st		*cqspi;
+	u32			clk_rate;
+	u32			read_delay;
+	u32			tshsl_ns;
+	u32			tsd2d_ns;
+	u32			tchsh_ns;
+	u32			tslch_ns;
+	bool			dtr;
+	u8			cs;
+	bool			use_phy;
+	bool			use_dqs;
+	struct phy_setting	phy_setting;
+	struct spi_mem_op	phy_read_op;
 };
 
 struct cqspi_st {
@@ -93,6 +106,7 @@
 	u32			num_chipselect;
 	bool			rclk_en;
 	u32			trigger_address;
+	u32			phase_detect_selector;
 	u32			wr_delay;
 	bool			use_direct_mode;
 	bool			use_direct_mode_wr;
@@ -123,6 +137,7 @@
 #define CQSPI_TIMEOUT_MS			500
 #define CQSPI_READ_TIMEOUT_MS			10
 #define CQSPI_BUSYWAIT_TIMEOUT_US		500
+#define CQSPI_DLL_TIMEOUT_US			300
 
 /* Runtime_pm autosuspend delay */
 #define CQSPI_AUTOSUSPEND_TIMEOUT		2000
@@ -136,12 +151,14 @@
 /* Register map */
 #define CQSPI_REG_CONFIG			0x00
 #define CQSPI_REG_CONFIG_ENABLE_MASK		BIT(0)
+#define CQSPI_REG_CONFIG_PHY_EN		BIT(3)
 #define CQSPI_REG_CONFIG_ENB_DIR_ACC_CTRL	BIT(7)
 #define CQSPI_REG_CONFIG_DECODE_MASK		BIT(9)
 #define CQSPI_REG_CONFIG_CHIPSELECT_LSB		10
 #define CQSPI_REG_CONFIG_DMA_MASK		BIT(15)
 #define CQSPI_REG_CONFIG_BAUD_LSB		19
 #define CQSPI_REG_CONFIG_DTR_PROTO		BIT(24)
+#define CQSPI_REG_CONFIG_PHY_PIPELINE		BIT(25)
 #define CQSPI_REG_CONFIG_DUAL_OPCODE		BIT(30)
 #define CQSPI_REG_CONFIG_IDLE_LSB		31
 #define CQSPI_REG_CONFIG_CHIPSELECT_MASK	0xF
@@ -178,6 +195,8 @@
 #define CQSPI_REG_READCAPTURE_BYPASS_LSB	0
 #define CQSPI_REG_READCAPTURE_DELAY_LSB		1
 #define CQSPI_REG_READCAPTURE_DELAY_MASK	0xF
+#define CQSPI_REG_READCAPTURE_EDGE_LSB		5
+#define CQSPI_REG_READCAPTURE_DQS_LSB		8
 
 #define CQSPI_REG_SIZE				0x14
 #define CQSPI_REG_SIZE_ADDRESS_LSB		0
@@ -256,6 +275,26 @@
 #define CQSPI_REG_POLLING_STATUS		0xB0
 #define CQSPI_REG_POLLING_STATUS_DUMMY_LSB	16
 
+#define CQSPI_REG_PHY_CONFIG			0xB4
+#define CQSPI_REG_PHY_CONFIG_RX_DEL_LSB		0
+#define CQSPI_REG_PHY_CONFIG_RX_DEL_MASK	0x7F
+#define CQSPI_REG_PHY_CONFIG_TX_DEL_LSB		16
+#define CQSPI_REG_PHY_CONFIG_TX_DEL_MASK	0x7F
+#define CQSPI_REG_PHY_CONFIG_DLL_RESET		BIT(30)
+#define CQSPI_REG_PHY_CONFIG_RESYNC		BIT(31)
+
+#define CQSPI_REG_PHY_DLL_MASTER		0xB8
+#define CQSPI_REG_PHY_DLL_MASTER_INIT_DELAY_LSB	0
+#define CQSPI_REG_PHY_DLL_MASTER_INIT_DELAY_VAL	16
+#define CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_LEN	0x7
+#define CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_LSB	20
+#define CQSPI_REG_PHY_DLL_MASTER_BYPASS		BIT(23)
+#define CQSPI_REG_PHY_DLL_MASTER_CYCLE		BIT(24)
+
+#define CQSPI_REG_DLL_OBS_LOW			0xBC
+#define CQSPI_REG_DLL_OBS_LOW_DLL_LOCK_LSB	0
+#define CQSPI_REG_DLL_OBS_LOW_LOOPBACK_LOCK_LSB	15
+
 #define CQSPI_REG_OP_EXT_LOWER			0xE0
 #define CQSPI_REG_OP_EXT_READ_LSB		24
 #define CQSPI_REG_OP_EXT_WRITE_LSB		16
@@ -301,6 +340,46 @@
 
 #define CQSPI_REG_VERSAL_DMA_VAL		0x602
 
+#define CQSPI_PHY_INIT_RD			1
+#define CQSPI_PHY_MAX_RD			4
+#define CQSPI_PHY_MAX_DELAY			127
+#define CQSPI_PHY_DDR_SEARCH_STEP		4
+#define CQSPI_PHY_MAX_RX			63
+#define CQSPI_PHY_MAX_TX			63
+#define CQSPI_PHY_TX_LOOKUP_LOW_START		28
+#define CQSPI_PHY_TX_LOOKUP_LOW_END		48
+#define CQSPI_PHY_TX_LOOKUP_HIGH_START		60
+#define CQSPI_PHY_TX_LOOKUP_HIGH_END		96
+#define CQSPI_PHY_RX_LOW_SEARCH_START		0
+#define CQSPI_PHY_RX_LOW_SEARCH_END		40
+#define CQSPI_PHY_RX_HIGH_SEARCH_START		24
+#define CQSPI_PHY_RX_HIGH_SEARCH_END		127
+#define CQSPI_PHY_TX_LOW_SEARCH_START		0
+#define CQSPI_PHY_TX_LOW_SEARCH_END		64
+#define CQSPI_PHY_TX_HIGH_SEARCH_START		78
+#define CQSPI_PHY_TX_HIGH_SEARCH_END		127
+#define CQSPI_PHY_SEARCH_OFFSET			8
+
+#define CQSPI_PHY_DEFAULT_TEMP		45
+#define CQSPI_PHY_MIN_TEMP		-45
+#define CQSPI_PHY_MAX_TEMP		130
+#define CQSPI_PHY_MID_TEMP \
+	(CQSPI_PHY_MIN_TEMP + ((CQSPI_PHY_MAX_TEMP - CQSPI_PHY_MIN_TEMP) / 2))
+
+static const u8 phy_tuning_pattern[] = {
+	0xFE, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xFE, 0xFE, 0x01,
+	0x01, 0x01, 0x01, 0x00, 0x00, 0xFE, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0x00, 0x00, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE,
+	0xFE, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0x00, 0xFE, 0xFE, 0x01,
+	0x01, 0x01, 0x01, 0xFE, 0x00, 0xFE, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFE, 0x00, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFE,
+	0xFE, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0xFE, 0xFE, 0xFE, 0x01,
+	0x01, 0x01, 0x01, 0x00, 0xFE, 0xFE, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0x00, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFE, 0xFE,
+	0xFE, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFE, 0x01,
+	0x01, 0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFE, 0x01,
+};
+
 static int cqspi_wait_for_bit(const struct cqspi_driver_platdata *ddata,
 			      void __iomem *reg, const u32 mask, bool clr,
 			      bool busywait)
@@ -439,6 +518,1346 @@
 	}
 }
 
+static void cqspi_set_tx_dll(void __iomem *reg_base, u8 dll)
+{
+	unsigned int reg;
+
+	reg = readl(reg_base + CQSPI_REG_PHY_CONFIG);
+	reg &= ~(CQSPI_REG_PHY_CONFIG_TX_DEL_MASK <<
+		CQSPI_REG_PHY_CONFIG_TX_DEL_LSB);
+	reg |= (dll & CQSPI_REG_PHY_CONFIG_TX_DEL_MASK) <<
+		CQSPI_REG_PHY_CONFIG_TX_DEL_LSB;
+	reg |= CQSPI_REG_PHY_CONFIG_RESYNC;
+	writel(reg, reg_base + CQSPI_REG_PHY_CONFIG);
+}
+
+static void cqspi_set_rx_dll(void __iomem *reg_base, u8 dll)
+{
+	unsigned int reg;
+
+	reg = readl(reg_base + CQSPI_REG_PHY_CONFIG);
+	reg &= ~(CQSPI_REG_PHY_CONFIG_RX_DEL_MASK <<
+		CQSPI_REG_PHY_CONFIG_RX_DEL_LSB);
+	reg |= (dll & CQSPI_REG_PHY_CONFIG_RX_DEL_MASK) <<
+		CQSPI_REG_PHY_CONFIG_RX_DEL_LSB;
+	reg |= CQSPI_REG_PHY_CONFIG_RESYNC;
+	writel(reg, reg_base + CQSPI_REG_PHY_CONFIG);
+}
+
+static int cqspi_resync_dll(struct cqspi_st *cqspi)
+{
+	void __iomem *reg_base = cqspi->iobase;
+	unsigned int reg;
+	int ret;
+
+	ret = cqspi_wait_idle(cqspi);
+
+	if (!ret) {
+		reg = readl(reg_base + CQSPI_REG_CONFIG);
+		reg &= ~(CQSPI_REG_CONFIG_ENABLE_MASK);
+		writel(reg, reg_base + CQSPI_REG_CONFIG);
+
+		reg = readl(reg_base + CQSPI_REG_PHY_CONFIG);
+		reg &= ~(CQSPI_REG_PHY_CONFIG_DLL_RESET |
+			 CQSPI_REG_PHY_CONFIG_RESYNC);
+		writel(reg, reg_base + CQSPI_REG_PHY_CONFIG);
+
+		reg = readl(reg_base + CQSPI_REG_PHY_DLL_MASTER);
+		reg |= (CQSPI_REG_PHY_DLL_MASTER_INIT_DELAY_VAL
+			<< CQSPI_REG_PHY_DLL_MASTER_INIT_DELAY_LSB);
+		writel(reg, reg_base + CQSPI_REG_PHY_DLL_MASTER);
+
+		reg = readl(reg_base + CQSPI_REG_PHY_CONFIG);
+		reg |= CQSPI_REG_PHY_CONFIG_DLL_RESET;
+		writel(reg, reg_base + CQSPI_REG_PHY_CONFIG);
+
+		readl_poll_timeout(reg_base + CQSPI_REG_DLL_OBS_LOW, reg,
+				   !(reg &= (1 << CQSPI_REG_DLL_OBS_LOW_DLL_LOCK_LSB)),
+				   0, CQSPI_DLL_TIMEOUT_US);
+
+		readl_poll_timeout(reg_base + CQSPI_REG_DLL_OBS_LOW, reg,
+				   !(reg &= (1 << CQSPI_REG_DLL_OBS_LOW_LOOPBACK_LOCK_LSB)),
+				   0, CQSPI_DLL_TIMEOUT_US);
+
+		reg = readl(reg_base + CQSPI_REG_PHY_CONFIG);
+		reg |= CQSPI_REG_PHY_CONFIG_RESYNC;
+		writel(reg, reg_base + CQSPI_REG_PHY_CONFIG);
+
+		reg = readl(reg_base + CQSPI_REG_CONFIG);
+		reg |= CQSPI_REG_CONFIG_ENABLE_MASK;
+		writel(reg, reg_base + CQSPI_REG_CONFIG);
+	}
+
+	return ret;
+}
+
+/* TODO: Figure out how to get the temperature here. */
+static int cqspi_get_temp(int *temp)
+{
+	return -EOPNOTSUPP;
+}
+
+static int cqspi_phy_apply_setting(struct cqspi_flash_pdata *f_pdata,
+				   struct phy_setting *phy)
+{
+	struct cqspi_st *cqspi = f_pdata->cqspi;
+	unsigned int reg;
+
+	reg = readl(cqspi->iobase + CQSPI_REG_READCAPTURE);
+	reg |= (1 << CQSPI_REG_READCAPTURE_EDGE_LSB);
+	writel(reg, cqspi->iobase + CQSPI_REG_READCAPTURE);
+
+	cqspi_set_rx_dll(cqspi->iobase, phy->rx);
+	cqspi_set_tx_dll(cqspi->iobase, phy->tx);
+	f_pdata->phy_setting.read_delay = phy->read_delay;
+
+	return cqspi_resync_dll(cqspi);
+}
+
+static int cqspi_phy_check_pattern(struct cqspi_flash_pdata *f_pdata,
+				   struct spi_mem *mem)
+{
+	struct spi_mem_op op = f_pdata->phy_read_op;
+	u8 *read_data;
+	unsigned int size = sizeof(phy_tuning_pattern);
+	int ret;
+
+	read_data = kmalloc(size, GFP_KERNEL);
+	if (!read_data)
+		return -ENOMEM;
+
+	op.data.buf.in = read_data;
+	op.data.nbytes = size;
+
+	ret = spi_mem_exec_op(mem, &op);
+	if (ret)
+		goto out;
+
+	if (memcmp(read_data, phy_tuning_pattern,
+		   ARRAY_SIZE(phy_tuning_pattern))) {
+		ret = -EAGAIN;
+		goto out;
+	}
+
+	ret = 0;
+
+out:
+	kfree(read_data);
+	return ret;
+}
+
+static int cqspi_find_rx_low(struct cqspi_flash_pdata *f_pdata,
+			     struct spi_mem *mem, struct phy_setting *phy)
+{
+	struct device *dev = &f_pdata->cqspi->pdev->dev;
+	int ret;
+
+	do {
+		phy->rx = CQSPI_PHY_RX_LOW_SEARCH_START;
+		do {
+			ret = cqspi_phy_apply_setting(f_pdata, phy);
+			if (!ret) {
+				ret = cqspi_phy_check_pattern(f_pdata, mem);
+				if (!ret)
+					return 0;
+			}
+
+			phy->rx += CQSPI_PHY_DDR_SEARCH_STEP;
+		} while (phy->rx <= CQSPI_PHY_RX_LOW_SEARCH_END);
+
+		phy->read_delay++;
+	} while (phy->read_delay <= CQSPI_PHY_MAX_RD);
+
+	dev_dbg(dev, "Unable to find RX low\n");
+	return -ENOENT;
+}
+
+static int cqspi_find_rx_low_sdr(struct cqspi_flash_pdata *f_pdata,
+				 struct spi_mem *mem, struct phy_setting *phy)
+{
+	struct device *dev = &f_pdata->cqspi->pdev->dev;
+	int ret;
+
+	phy->rx = 0;
+	do {
+		ret = cqspi_phy_apply_setting(f_pdata, phy);
+		if (!ret) {
+			ret = cqspi_phy_check_pattern(f_pdata, mem);
+			if (!ret)
+				return 0;
+		}
+		phy->rx++;
+	} while (phy->rx < CQSPI_PHY_MAX_DELAY - 1);
+
+	dev_dbg(dev, "Unable to find RX low\n");
+	return -ENOENT;
+}
+
+static int cqspi_find_rx_high(struct cqspi_flash_pdata *f_pdata,
+			      struct spi_mem *mem, struct phy_setting *phy)
+{
+	struct device *dev = &f_pdata->cqspi->pdev->dev;
+	int ret;
+
+	do {
+		phy->rx = CQSPI_PHY_RX_HIGH_SEARCH_END;
+		do {
+			ret = cqspi_phy_apply_setting(f_pdata, phy);
+			if (!ret) {
+				ret = cqspi_phy_check_pattern(f_pdata, mem);
+				if (!ret)
+					return 0;
+			}
+
+			phy->rx -= CQSPI_PHY_DDR_SEARCH_STEP;
+		} while (phy->rx >= CQSPI_PHY_RX_HIGH_SEARCH_START);
+
+		phy->read_delay--;
+	} while (phy->read_delay >= CQSPI_PHY_INIT_RD);
+
+	dev_dbg(dev, "Unable to find RX high\n");
+	return -ENOENT;
+}
+
+static int cqspi_find_rx_high_sdr(struct cqspi_flash_pdata *f_pdata,
+				  struct spi_mem *mem, struct phy_setting *phy,
+				  u8 lowerbound)
+{
+	struct device *dev = &f_pdata->cqspi->pdev->dev;
+	int ret;
+
+	phy->rx = CQSPI_PHY_MAX_DELAY;
+	do {
+		ret = cqspi_phy_apply_setting(f_pdata, phy);
+		if (!ret) {
+			ret = cqspi_phy_check_pattern(f_pdata, mem);
+			if (!ret)
+				return 0;
+		}
+		phy->rx--;
+	} while (phy->rx > lowerbound);
+
+	dev_dbg(dev, "Unable to find RX high\n");
+	return -ENOENT;
+}
+
+static int cqspi_find_tx_low(struct cqspi_flash_pdata *f_pdata,
+			     struct spi_mem *mem, struct phy_setting *phy)
+{
+	struct device *dev = &f_pdata->cqspi->pdev->dev;
+	int ret;
+
+	do {
+		phy->tx = CQSPI_PHY_TX_LOW_SEARCH_START;
+		do {
+			ret = cqspi_phy_apply_setting(f_pdata, phy);
+			if (!ret) {
+				ret = cqspi_phy_check_pattern(f_pdata, mem);
+				if (!ret)
+					return 0;
+			}
+
+			phy->tx += CQSPI_PHY_DDR_SEARCH_STEP;
+		} while (phy->tx <= CQSPI_PHY_TX_LOW_SEARCH_END);
+
+		phy->read_delay++;
+	} while (phy->read_delay <= CQSPI_PHY_MAX_RD);
+
+	dev_dbg(dev, "Unable to find TX low\n");
+	return -ENOENT;
+}
+
+static int cqspi_find_tx_high(struct cqspi_flash_pdata *f_pdata,
+			      struct spi_mem *mem, struct phy_setting *phy)
+{
+	struct device *dev = &f_pdata->cqspi->pdev->dev;
+	int ret;
+
+	do {
+		phy->tx = CQSPI_PHY_TX_HIGH_SEARCH_END;
+		do {
+			ret = cqspi_phy_apply_setting(f_pdata, phy);
+			if (!ret) {
+				ret = cqspi_phy_check_pattern(f_pdata, mem);
+				if (!ret)
+					return 0;
+			}
+
+			phy->tx -= CQSPI_PHY_DDR_SEARCH_STEP;
+		} while (phy->tx >= CQSPI_PHY_TX_HIGH_SEARCH_START);
+
+		phy->read_delay--;
+	} while (phy->read_delay >= CQSPI_PHY_INIT_RD);
+
+	dev_dbg(dev, "Unable to find TX high\n");
+	return -ENOENT;
+}
+
+static int cqspi_phy_find_gaplow(struct cqspi_flash_pdata *f_pdata,
+				 struct spi_mem *mem,
+				 struct phy_setting *bottomleft,
+				 struct phy_setting *topright,
+				 struct phy_setting *gaplow)
+{
+	struct phy_setting left, right, mid;
+	int ret;
+
+	left = *bottomleft;
+	right = *topright;
+
+	mid.tx = left.tx + ((right.tx - left.tx) / 2);
+	mid.rx = left.rx + ((right.rx - left.rx) / 2);
+	mid.read_delay = left.read_delay;
+
+	do {
+		ret = cqspi_phy_apply_setting(f_pdata, &mid);
+		if (!ret)
+			ret = cqspi_phy_check_pattern(f_pdata, mem);
+
+		if (ret) {
+			/* The pattern was not found. Go to the lower half. */
+			right.tx = mid.tx;
+			right.rx = mid.rx;
+
+			mid.tx = left.tx + ((mid.tx - left.tx) / 2);
+			mid.rx = left.rx + ((mid.rx - left.rx) / 2);
+		} else {
+			/* The pattern was found. Go to the upper half. */
+			left.tx = mid.tx;
+			left.rx = mid.rx;
+
+			mid.tx = mid.tx + ((right.tx - mid.tx) / 2);
+			mid.rx = mid.rx + ((right.rx - mid.rx) / 2);
+		}
+
+	/* Break the loop if the window has closed. */
+	} while ((right.tx - left.tx >= 2) && (right.rx - left.rx >= 2));
+
+	*gaplow = mid;
+	return 0;
+}
+
+static int cqspi_phy_find_gaphigh(struct cqspi_flash_pdata *f_pdata,
+				  struct spi_mem *mem,
+				  struct phy_setting *bottomleft,
+				  struct phy_setting *topright,
+				  struct phy_setting *gaphigh)
+{
+	struct phy_setting left, right, mid;
+	int ret;
+
+	left = *bottomleft;
+	right = *topright;
+
+	mid.tx = left.tx + ((right.tx - left.tx) / 2);
+	mid.rx = left.rx + ((right.rx - left.rx) / 2);
+	mid.read_delay = right.read_delay;
+
+	do {
+		ret = cqspi_phy_apply_setting(f_pdata, &mid);
+		if (!ret)
+			ret = cqspi_phy_check_pattern(f_pdata, mem);
+
+		if (ret) {
+			/* The pattern was not found. Go to the upper half. */
+			left.tx = mid.tx;
+			left.rx = mid.rx;
+
+			mid.tx = mid.tx + ((right.tx - mid.tx) / 2);
+			mid.rx = mid.rx + ((right.rx - mid.rx) / 2);
+		} else {
+			/* The pattern was found. Go to the lower half. */
+			right.tx = mid.tx;
+			right.rx = mid.rx;
+
+			mid.tx = left.tx + ((mid.tx - left.tx) / 2);
+			mid.rx = left.rx + ((mid.rx - left.rx) / 2);
+		}
+
+	/* Break the loop if the window has closed. */
+	} while ((right.tx - left.tx >= 2) && (right.rx - left.rx >= 2));
+
+	*gaphigh = mid;
+	return 0;
+}
+
+static int cqspi_phy_calibrate_ddr(struct cqspi_flash_pdata *f_pdata,
+				   struct spi_mem *mem)
+{
+	struct cqspi_st *cqspi = f_pdata->cqspi;
+	struct device *dev = &cqspi->pdev->dev;
+	struct phy_setting rxlow, rxhigh, txlow, txhigh;
+	struct phy_setting srxlow, srxhigh;
+	struct phy_setting bottomleft, topright, searchpoint;
+	struct phy_setting gaplow, gaphigh;
+	struct phy_setting backuppoint, backupcornerpoint;
+	int ret, tmp;
+	bool primary = 1, secondary = 1;
+
+	f_pdata->use_phy = true;
+
+	/*
+	 * Finding rx fails at some of the tx values based on the H/W platform.
+	 * A window of tx values is used to find the rx without errors. This
+	 * can increase the number of CPU cycles taken for the PHY tuning in
+	 * the cases where more tx values need to be parsed to find a stable
+	 * rx.
+	 */
+
+	/* ***********************Golden rxlow search*********************** */
+
+	/*
+	 *
+	 *		rx
+	 *	    127	^
+	 *		|
+	 *		|	xxxxx     ++++++++++++++++++++
+	 *		|	xxxxxx     +++++++++++++++++++
+	 *		|	xxxxxxx     ++++++++++++++++++
+	 *		|	xxxxxxxx     +++++++++++++++++
+	 *		|	xxxxxxxxx     ++++++++++++++++
+	 *		|	xxxxxxxxxx     +++++++++++++++
+	 *		|	xxxxxxxxxxx     ++++++++++++++
+	 *		|	|xxxxx|xxxxx     +++++++++++++
+	 *		|	|xxxxx|xxxxxx     ++++++++++++
+	 *	search	|	|xxxxx|xxxxxxx     +++++++++++
+	 *	rxlow --------->|xxxxx|xxxxxxxx     ++++++++++
+	 *		|	|xxxxx|xxxxxxxxx     +++++++++
+	 *		|	|xxxxx|xxxxxxxxxx     ++++++++
+	 *		|	|xxxxx|xxxxxxxxxxx     +++++++
+	 *		|	|     |
+	 *		--------|-----|----------------------------> tx
+	 *		0	|     |				 127
+	 *		    txlow     txlow
+	 *		    start     end
+	 *
+	 */
+
+	/*
+	 *	|----------------------------------------------------------|
+	 *	| Primary | Secondary | Final                              |
+	 *	| Search  | Search    | Point                              |
+	 *	|---------|-----------|------------------------------------|
+	 *	| Fail    | Fail      | Return Fail                        |
+	 *	|---------|-----------|------------------------------------|
+	 *	| Fail    | Pass      | Return Fail                        |
+	 *	|---------|-----------|------------------------------------|
+	 *	| Pass    | Fail      | Return Fail                        |
+	 *	|---------|-----------|------------------------------------|
+	 *	| Pass    | Pass      | rx = min(primary.rx, secondary.rx) |
+	 *	|         |           | tx = primary.tx                    |
+	 *	|         |           | read_delay =                       |
+	 *	|	  |	      |		min(primary.read_delay,    |
+	 *	|	  |	      |		    secondary.read_delay)  |
+	 *	|----------------------------------------------------------|
+	 */
+
+	/* *******************Golden Primary rxlow search******************* */
+	/*
+	 * To find the rx boundaries, we fix a valid tx and search through rx
+	 * range, read_delay values. As we are not sure of a valid tx we use a
+	 * window of tx values to find the rx boundaries.
+	 */
+
+	rxlow.tx = CQSPI_PHY_TX_LOOKUP_LOW_START;
+	do {
+		dev_dbg(dev, "Searching for Golden Primary rxlow on TX = %d\n",
+			rxlow.tx);
+		rxlow.read_delay = CQSPI_PHY_INIT_RD;
+		ret = cqspi_find_rx_low(f_pdata, mem, &rxlow);
+		rxlow.tx += CQSPI_PHY_DDR_SEARCH_STEP;
+	} while (ret && rxlow.tx <= CQSPI_PHY_TX_LOOKUP_LOW_END);
+	if (ret)
+		goto out;
+	dev_dbg(dev, "Golden Primary rxlow: RX: %d TX: %d RD: %d\n", rxlow.rx,
+		rxlow.tx, rxlow.read_delay);
+
+	/* ******************Golden Secondary rxlow search****************** */
+	/* Search for one more rxlow at different tx */
+
+	if (rxlow.tx <= (CQSPI_PHY_TX_LOOKUP_LOW_END -
+			 CQSPI_PHY_SEARCH_OFFSET))
+		srxlow.tx = rxlow.tx + CQSPI_PHY_SEARCH_OFFSET;
+	else
+		srxlow.tx = CQSPI_PHY_TX_LOOKUP_LOW_END;
+	dev_dbg(dev, "Searching for Golden Secondary rxlow on TX = %d\n",
+		srxlow.tx);
+	srxlow.read_delay = CQSPI_PHY_INIT_RD;
+	ret = cqspi_find_rx_low(f_pdata, mem, &srxlow);
+	if (ret)
+		goto out;
+	dev_dbg(dev, "Golden Secondary rxlow: RX: %d TX: %d RD: %d\n",
+		srxlow.rx, srxlow.tx, srxlow.read_delay);
+
+	rxlow.rx = min(rxlow.rx, srxlow.rx);
+	rxlow.read_delay = min(rxlow.read_delay, srxlow.read_delay);
+	dev_dbg(dev, "Golden Final rxlow: RX: %d TX: %d RD: %d\n", rxlow.rx,
+		rxlow.tx, rxlow.read_delay);
+
+	/* **********************Golden rxhigh search********************** */
+
+	/*
+	 *
+	 *		rx
+	 *	    127	^
+	 *		|
+	 *		|	|xxxx     ++++++++++++++++++++
+	 *		|	|xxxxx     +++++++++++++++++++
+	 *    search	|	|xxxxxx     ++++++++++++++++++
+	 *    rxhigh  --------->|xxxxxxx     +++++++++++++++++
+	 *    on fixed  |	|xxxxxxxx     ++++++++++++++++
+	 *    tx	|	|xxxxxxxxx     +++++++++++++++
+	 *		|	|xxxxxxxxxx     ++++++++++++++
+	 *		|	xxxxxxxxxxxx     +++++++++++++
+	 *		|	xxxxxxxxxxxxx     ++++++++++++
+	 *		|	xxxxxxxxxxxxxx     +++++++++++
+	 *		|	xxxxxxxxxxxxxxx     ++++++++++
+	 *		|	xxxxxxxxxxxxxxxx     +++++++++
+	 *		|	xxxxxxxxxxxxxxxxx     ++++++++
+	 *		|	xxxxxxxxxxxxxxxxxx     +++++++
+	 *		|
+	 *		-------------------------------------------> tx
+	 *		0					 127
+	 *
+	 */
+
+	/*
+	 *	|----------------------------------------------------------|
+	 *	| Primary | Secondary | Final                              |
+	 *	| Search  | Search    | Point                              |
+	 *	|---------|-----------|------------------------------------|
+	 *	| Fail    | Fail      | Return Fail                        |
+	 *	|---------|-----------|------------------------------------|
+	 *	| Fail    | Pass      | Choose Secondary                   |
+	 *	|---------|-----------|------------------------------------|
+	 *	| Pass    | Fail      | Choose Primary                     |
+	 *	|---------|-----------|------------------------------------|
+	 *	| Pass    | Pass      | if (secondary.rx > primary.rx)     |
+	 *	|         |           |		Choose Secondary           |
+	 *	|         |           | else                               |
+	 *	|	  |	      |		Choose Primary             |
+	 *	|----------------------------------------------------------|
+	 */
+
+	/* ******************Golden Primary rxhigh search****************** */
+	/*
+	 * To find rxhigh we use the tx values of rxlow. Start the read_delay
+	 * from maximum and decrement it. As these are valid values and rxhigh
+	 * read_delay is always greater than or equal to rxlow read_delay.
+	 */
+
+	rxhigh.tx = rxlow.tx;
+	dev_dbg(dev, "Searching for Golden Primary rxhigh on TX = %d\n",
+		rxhigh.tx);
+	rxhigh.read_delay = CQSPI_PHY_MAX_RD;
+	ret = cqspi_find_rx_high(f_pdata, mem, &rxhigh);
+	if (ret)
+		primary = 0;
+	dev_dbg(dev, "Golden Primary rxhigh: RX: %d TX: %d RD: %d\n",
+		rxhigh.rx, rxhigh.tx, rxhigh.read_delay);
+
+	/* *****************Golden Secondary rxhigh search***************** */
+	/* Search for one more rxhigh at different tx */
+
+	if (rxhigh.tx <=
+	    (CQSPI_PHY_TX_LOOKUP_LOW_END - CQSPI_PHY_SEARCH_OFFSET))
+		srxhigh.tx = rxhigh.tx + CQSPI_PHY_SEARCH_OFFSET;
+	else
+		srxhigh.tx = CQSPI_PHY_TX_LOOKUP_LOW_END;
+	dev_dbg(dev, "Searching for Golden Secondary rxhigh on TX = %d\n",
+		srxhigh.tx);
+	srxhigh.read_delay = CQSPI_PHY_MAX_RD;
+	ret = cqspi_find_rx_high(f_pdata, mem, &srxhigh);
+	if (ret)
+		secondary = 0;
+	dev_dbg(dev, "Golden Secondary rxhigh: RX: %d TX: %d RD: %d\n",
+		srxhigh.rx, srxhigh.tx, srxhigh.read_delay);
+
+	if (primary || secondary) {
+		if (srxhigh.rx > rxhigh.rx)
+			rxhigh = srxhigh;
+	} else {
+		goto out;
+	}
+	dev_dbg(dev, "Golden Final rxhigh: RX: %d TX: %d RD: %d\n", rxhigh.rx,
+		rxhigh.tx, rxhigh.read_delay);
+
+	primary = 1;
+	secondary = 1;
+
+	/*
+	 * Check a different point if rxlow and rxhigh are on the same read
+	 * delay. This avoids mistaking the failing region for an RX boundary.
+	 */
+
+	if (rxlow.read_delay == rxhigh.read_delay) {
+		dev_dbg(dev, "rxlow and rxhigh at the same read delay.\n");
+
+		/* *******************Backup rxlow search******************* */
+
+		/* Look for RX boundaries at upper TX range. */
+
+		/*
+		 *
+		 *		rx
+		 *	    127	^
+		 *		|
+		 *		|	xxxxx     ++++++++++++++++++++
+		 *		|	xxxxxx     +++++++++++++++++++
+		 *		|	xxxxxxx     ++++++++++++++++++
+		 *		|	xxxxxxxx     +++++++++++++++++
+		 *		|	xxxxxxxxx     ++++++++++++++++
+		 *		|	xxxxxxxxxx     +++++++++++++++
+		 *		|	xxxxxxxxxxx     ++++++++++++++
+		 *		|	xxxxxxxxxxxx     +++++++|++++|
+		 *		|	xxxxxxxxxxxxx     ++++++|++++|
+		 *	search	|	xxxxxxxxxxxxxx     +++++|++++|
+		 *	rxlow --------------------------------->|++++|
+		 *		|	xxxxxxxxxxxxxxxx     +++|++++|
+		 *		|	xxxxxxxxxxxxxxxxx     ++|++++|
+		 *		|	xxxxxxxxxxxxxxxxxx     +|++++|
+		 *		|				|    |
+		 *		--------------------------------|----|-----> tx
+		 *		0				|    |	 127
+		 *`					   txhigh    txhigh
+		 *					    start    end
+		 *
+		 */
+
+		/*
+		 *	|-----------------------------------------------------|
+		 *	| Primary | Secondary | Final                         |
+		 *	| Search  | Search    | Point                         |
+		 *	|---------|-----------|-------------------------------|
+		 *	| Fail    | Fail      | Return Fail                   |
+		 *	|---------|-----------|-------------------------------|
+		 *	| Fail    | Pass      | Return Fail                   |
+		 *	|---------|-----------|-------------------------------|
+		 *	| Pass    | Fail      | Return Fail                   |
+		 *	|---------|-----------|-------------------------------|
+		 *	| Pass    | Pass      | rx =			      |
+		 *	|	  |	      |	 min(primary.rx, secondary.rx)|
+		 *	|         |           | tx = primary.tx               |
+		 *	|         |           | read_delay =                  |
+		 *	|	  |	      |	 min(primary.read_delay,      |
+		 *	|	  |	      |	     secondary.read_delay)    |
+		 *	|-----------------------------------------------------|
+		 */
+
+		/* ***************Backup Primary rxlow search*************** */
+		/*
+		 * Find the rx boundaries using the tx window at the higher
+		 * end. We start at the window end and decrement the tx value
+		 * until we find the valid point.
+		 */
+
+		backuppoint.tx = CQSPI_PHY_TX_LOOKUP_HIGH_END;
+		do {
+			dev_dbg(dev, "Searching for Backup Primary rxlow on TX = %d\n",
+				backuppoint.tx);
+			backuppoint.read_delay = CQSPI_PHY_INIT_RD;
+			ret = cqspi_find_rx_low(f_pdata, mem, &backuppoint);
+			backuppoint.tx -= CQSPI_PHY_DDR_SEARCH_STEP;
+		} while (ret &&
+			 backuppoint.tx >= CQSPI_PHY_TX_LOOKUP_HIGH_START);
+		if (ret)
+			goto out;
+		dev_dbg(dev, "Backup Primary rxlow: RX: %d TX: %d RD: %d\n",
+			backuppoint.rx, backuppoint.tx,
+			backuppoint.read_delay);
+
+		/* **************Backup Secondary rxlow search************** */
+		/* Search for one more rxlow at different tx */
+
+		if (backuppoint.tx >=
+		    (CQSPI_PHY_TX_LOOKUP_HIGH_START + CQSPI_PHY_SEARCH_OFFSET))
+			srxlow.tx = backuppoint.tx - CQSPI_PHY_SEARCH_OFFSET;
+		else
+			srxlow.tx = CQSPI_PHY_TX_LOOKUP_HIGH_START;
+		dev_dbg(dev,
+			"Searching for Backup Secondary rxlow on TX = %d\n",
+			srxlow.tx);
+		srxlow.read_delay = CQSPI_PHY_INIT_RD;
+		ret = cqspi_find_rx_low(f_pdata, mem, &srxlow);
+		if (ret)
+			goto out;
+		dev_dbg(dev, "Backup Secondary rxlow: RX: %d TX: %d RD: %d\n",
+			srxlow.rx, srxlow.tx, srxlow.read_delay);
+
+		backuppoint.rx = min(backuppoint.rx, srxlow.rx);
+		backuppoint.read_delay =
+			min(backuppoint.read_delay, srxlow.read_delay);
+		dev_dbg(dev, "Backup Final rxlow: RX: %d TX: %d RD: %d\n",
+			backuppoint.rx, backuppoint.tx,
+			backuppoint.read_delay);
+
+		if (backuppoint.rx < rxlow.rx) {
+			rxlow = backuppoint;
+			dev_dbg(dev, "Updating rxlow to the one at TX = %d\n",
+				backuppoint.tx);
+		}
+		dev_dbg(dev, "Final rxlow: RX: %d TX: %d RD: %d\n", rxlow.rx,
+			rxlow.tx, rxlow.read_delay);
+
+		/* ******************Backup rxhigh search****************** */
+
+		/*
+		 *
+		 *		rx
+		 *	    127	^
+		 *		|
+		 *		|	xxxxx     +++++++++++++++++++|
+		 *		|	xxxxxx     ++++++++++++++++++|
+		 *    search	|	xxxxxxx     +++++++++++++++++|
+		 *    rxhigh  -------------------------------------->|
+		 *    on fixed	|	xxxxxxxxx     +++++++++++++++|
+		 *    tx	|	xxxxxxxxxx     ++++++++++++++|
+		 *		|	xxxxxxxxxxx     +++++++++++++|
+		 *		|	xxxxxxxxxxxx     +++++++++++++
+		 *		|	xxxxxxxxxxxxx     ++++++++++++
+		 *		|	xxxxxxxxxxxxxx     +++++++++++
+		 *		|	xxxxxxxxxxxxxxx     ++++++++++
+		 *		|	xxxxxxxxxxxxxxxx     +++++++++
+		 *		|	xxxxxxxxxxxxxxxxx     ++++++++
+		 *		|	xxxxxxxxxxxxxxxxxx     +++++++
+		 *		|
+		 *		-------------------------------------------> tx
+		 *		0					 127
+		 *
+		 */
+
+		/*
+		 *	|-----------------------------------------------------|
+		 *	| Primary | Secondary | Final                         |
+		 *	| Search  | Search    | Point                         |
+		 *	|---------|-----------|-------------------------------|
+		 *	| Fail    | Fail      | Return Fail                   |
+		 *	|---------|-----------|-------------------------------|
+		 *	| Fail    | Pass      | Choose Secondary              |
+		 *	|---------|-----------|-------------------------------|
+		 *	| Pass    | Fail      | Choose Primary                |
+		 *	|---------|-----------|-------------------------------|
+		 *	| Pass    | Pass      | if (secondary.rx > primary.rx)|
+		 *	|         |           |		Choose Secondary      |
+		 *	|         |           | else                          |
+		 *	|	  |	      |		Choose Primary        |
+		 *	|-----------------------------------------------------|
+		 */
+
+		/* **************Backup Primary rxhigh search************** */
+		/*
+		 * To find rxhigh we use the tx values of backuppoint. Start
+		 * the read_delay from maximum and decrement it. As these are
+		 * valid values and rxhigh read_delay is always greater than or
+		 * equal to rxlow read_delay.
+		 */
+
+		dev_dbg(dev, "Searching for Backup Primary rxhigh on TX = %d\n",
+			backuppoint.tx);
+		backuppoint.read_delay = CQSPI_PHY_MAX_RD;
+		ret = cqspi_find_rx_high(f_pdata, mem, &backuppoint);
+		if (ret)
+			primary = 0;
+		dev_dbg(dev, "Backup Primary rxhigh: RX: %d TX: %d RD: %d\n",
+			backuppoint.rx, backuppoint.tx,
+			backuppoint.read_delay);
+
+		/* *************Backup Secondary rxhigh search************* */
+		/* Search for one more rxhigh at different tx */
+
+		if (backuppoint.tx >=
+		    (CQSPI_PHY_TX_LOOKUP_HIGH_START + CQSPI_PHY_SEARCH_OFFSET))
+			srxhigh.tx = backuppoint.tx - CQSPI_PHY_SEARCH_OFFSET;
+		else
+			srxhigh.tx = CQSPI_PHY_TX_LOOKUP_HIGH_START;
+		dev_dbg(dev,
+			"Searching for Backup Secondary rxhigh on TX = %d\n",
+			srxhigh.tx);
+		srxhigh.read_delay = CQSPI_PHY_MAX_RD;
+		ret = cqspi_find_rx_high(f_pdata, mem, &srxhigh);
+		if (ret)
+			secondary = 0;
+		dev_dbg(dev, "Backup Secondary rxhigh: RX: %d TX: %d RD: %d\n",
+			srxhigh.rx, srxhigh.tx, srxhigh.read_delay);
+
+		if (primary || secondary) {
+			if (srxhigh.rx > backuppoint.rx)
+				backuppoint = srxhigh;
+		} else {
+			goto out;
+		}
+		dev_dbg(dev, "Backup Final rxhigh: RX: %d TX: %d RD: %d\n",
+			backuppoint.rx, backuppoint.tx,
+			backuppoint.read_delay);
+
+		if (backuppoint.rx > rxhigh.rx) {
+			rxhigh = backuppoint;
+			dev_dbg(dev, "Updating rxhigh to the one at TX = %d\n",
+				backuppoint.tx);
+		}
+		dev_dbg(dev, "Final rxhigh: RX: %d TX: %d RD: %d\n", rxhigh.rx,
+			rxhigh.tx, rxhigh.read_delay);
+	}
+
+	/* ***********************Golden txlow search*********************** */
+	/* Look for TX boundaries at 1/4 of RX window. */
+
+	/*
+	 *
+	 *		rx
+	 *	    127	^
+	 *		|
+	 *     rxhigh --------->xxxxx     ++++++++++++++++++++
+	 *		|	xxxxxx     +++++++++++++++++++
+	 *		|	xxxxxxx     ++++++++++++++++++
+	 *		|	xxxxxxxx     +++++++++++++++++
+	 *		|	xxxxxxxxx     ++++++++++++++++
+	 *		|	xxxxxxxxxx     +++++++++++++++
+	 *		|	xxxxxxxxxxx     ++++++++++++++
+	 *		|	xxxxxxxxxxxx     +++++++++++++
+	 *    fix rx	|	xxxxxxxxxxxxx     ++++++++++++
+	 *    1/4 b/w ---------><------->xxxxx     +++++++++++
+	 *    rxlow and	|	xxxx|xxxxxxxxxx     ++++++++++
+	 *    rxhigh	|	xxxx|xxxxxxxxxxx     +++++++++
+	 *		|	xxxx|xxxxxxxxxxxx     ++++++++
+	 *	rxlow --------->xxxx|xxxxxxxxxxxxx     +++++++
+	 *		|	    |
+	 *		------------|------------------------------> tx
+	 *		0	    |				 127
+	 *		       search
+	 *			txlow
+	 *
+	 */
+
+	txlow.rx = rxlow.rx + ((rxhigh.rx - rxlow.rx) / 4);
+	dev_dbg(dev, "Searching for Golden txlow on RX = %d\n", txlow.rx);
+	txlow.read_delay = CQSPI_PHY_INIT_RD;
+	ret = cqspi_find_tx_low(f_pdata, mem, &txlow);
+	if (ret)
+		goto out;
+	dev_dbg(dev, "Golden txlow: RX: %d TX: %d RD: %d\n", txlow.rx,
+		txlow.tx, txlow.read_delay);
+
+	/* **********************Golden txhigh search********************** */
+	/* Start from maximum read_delay and decrememt it */
+
+	/*
+	 *
+	 *		rx
+	 *	    127	^
+	 *		|
+	 *     rxhigh --------->xxxxx     ++++++++++++++++++++
+	 *		|	xxxxxx     +++++++++++++++++++
+	 *		|	xxxxxxx     ++++++++++++++++++
+	 *		|	xxxxxxxx     +++++++++++++++++
+	 *		|	xxxxxxxxx     ++++++++++++++++
+	 *		|	xxxxxxxxxx     +++++++++++++++
+	 *		|	xxxxxxxxxxx     ++++++++++++++
+	 *		|	xxxxxxxxxxxx     +++++++++++++
+	 *    fix rx	|	xxxxxxxxxxxxx     ++++++++++++
+	 *    1/4 b/w --------------------------------><----->
+	 *    rxlow and	|	xxxxxxxxxxxxxxx     ++++++|+++
+	 *    rxhigh	|	xxxxxxxxxxxxxxxx     +++++|+++
+	 *		|	xxxxxxxxxxxxxxxxx     ++++|+++
+	 *	rxlow --------->xxxxxxxxxxxxxxxxxx     +++|+++
+	 *		|				  |
+	 *		----------------------------------|--------> tx
+	 *		0				  |	 127
+	 *					     search
+	 *					     txhigh
+	 *
+	 */
+
+	txhigh.rx = txlow.rx;
+	dev_dbg(dev, "Searching for Golden txhigh on RX = %d\n", txhigh.rx);
+	txhigh.read_delay = CQSPI_PHY_MAX_RD;
+	ret = cqspi_find_tx_high(f_pdata, mem, &txhigh);
+	if (ret)
+		goto out;
+	dev_dbg(dev, "Golden txhigh: RX: %d TX: %d RD: %d\n", txhigh.rx,
+		txhigh.tx, txhigh.read_delay);
+
+	/*
+	 * Check a different point if txlow and txhigh are on the same read
+	 * delay. This avoids mistaking the failing region for an TX boundary.
+	 */
+
+	if (txlow.read_delay == txhigh.read_delay) {
+		/* *******************Backup txlow search******************* */
+		/* Look for TX boundaries at 3/4 of RX window. */
+
+		/*
+		 *
+		 *		rx
+		 *	    127	^
+		 *		|
+		 *     rxhigh --------->xxxxx     ++++++++++++++++++++
+		 *		|	xxxxxx     +++++++++++++++++++
+		 *    fix rx	|	xxxxxxx     ++++++++++++++++++
+		 *    3/4 b/w ---------><----->x     +++++++++++++++++
+		 *    rxlow and	|	xxxx|xxxx     ++++++++++++++++
+		 *    rxhigh	|	xxxx|xxxxx     +++++++++++++++
+		 *		|	xxxx|xxxxxx     ++++++++++++++
+		 *		|	xxxx|xxxxxxx     +++++++++++++
+		 *		|	xxxx|xxxxxxxx     ++++++++++++
+		 *		|	xxxx|xxxxxxxxx     +++++++++++
+		 *		|	xxxx|xxxxxxxxxx     ++++++++++
+		 *		|	xxxx|xxxxxxxxxxx     +++++++++
+		 *		|	xxxx|xxxxxxxxxxxx     ++++++++
+		 *	rxlow --------->xxxx|xxxxxxxxxxxxx     +++++++
+		 *		|	    |
+		 *		------------|------------------------------> tx
+		 *		0	    |				 127
+		 *		       search
+		 *			txlow
+		 *
+		 */
+
+		dev_dbg(dev, "txlow and txhigh at the same read delay.\n");
+		backuppoint.rx = rxlow.rx + (3 * (rxhigh.rx - rxlow.rx) / 4);
+		dev_dbg(dev, "Searching for Backup txlow on RX = %d\n",
+			backuppoint.rx);
+		backuppoint.read_delay = CQSPI_PHY_INIT_RD;
+		ret = cqspi_find_tx_low(f_pdata, mem, &backuppoint);
+		if (ret)
+			goto out;
+		dev_dbg(dev, "Backup txlow: RX: %d TX: %d RD: %d\n",
+			backuppoint.rx, backuppoint.tx,
+			backuppoint.read_delay);
+
+		if (backuppoint.tx < txlow.tx) {
+			txlow = backuppoint;
+			dev_dbg(dev, "Updating txlow with the one at RX = %d\n",
+				backuppoint.rx);
+		}
+		dev_dbg(dev, "Final txlow: RX: %d TX: %d RD: %d\n", txlow.rx,
+			txlow.tx, txlow.read_delay);
+
+		/* ******************Backup txhigh search****************** */
+		/* Start from maximum read_delay and decrememt it */
+
+		/*
+		 *
+		 *		rx
+		 *	    127	^
+		 *		|
+		 *     rxhigh --------->xxxxx     ++++++++++++++++++++
+		 *		|	xxxxxx     +++++++++++++++++++
+		 *    fix rx	|	xxxxxxx     ++++++++++++++++++
+		 *    3/4 b/w ------------------------------><------->
+		 *    rxlow and	|	xxxxxxxxx     +++++++++++|++++
+		 *    rxhigh	|	xxxxxxxxxx     ++++++++++|++++
+		 *		|	xxxxxxxxxxx     +++++++++|++++
+		 *		|	xxxxxxxxxxxx     ++++++++|++++
+		 *		|	xxxxxxxxxxxxx     +++++++|++++
+		 *		|	xxxxxxxxxxxxxx     ++++++|++++
+		 *		|	xxxxxxxxxxxxxxx     +++++|++++
+		 *		|	xxxxxxxxxxxxxxxx     ++++|++++
+		 *		|	xxxxxxxxxxxxxxxxx     +++|++++
+		 *	rxlow --------->xxxxxxxxxxxxxxxxxx     ++|++++
+		 *		|				 |
+		 *		---------------------------------|---------> tx
+		 *		0				 |	 127
+		 *						 search
+		 *						 txhigh
+		 *
+		 */
+
+		dev_dbg(dev, "Searching for Backup txhigh on RX = %d\n",
+			backuppoint.rx);
+		backuppoint.read_delay = CQSPI_PHY_MAX_RD;
+		ret = cqspi_find_tx_high(f_pdata, mem, &backuppoint);
+		if (ret)
+			goto out;
+		dev_dbg(dev, "Backup txhigh: RX: %d TX: %d RD: %d\n",
+			backuppoint.rx, backuppoint.tx,
+			backuppoint.read_delay);
+
+		if (backuppoint.tx > txhigh.tx) {
+			txhigh = backuppoint;
+			dev_dbg(dev,
+				"Updating txhigh with the one at RX = %d\n",
+				backuppoint.rx);
+		}
+		dev_dbg(dev, "Final txhigh: RX: %d TX: %d RD: %d\n", txhigh.rx,
+			txhigh.tx, txhigh.read_delay);
+	}
+
+	/*
+	 * Set bottom left and top right corners. These are theoretical
+	 * corners. They may not actually be "good" points. But the longest
+	 * diagonal will be between these corners.
+	 */
+
+	bottomleft.tx = txlow.tx;
+	bottomleft.rx = rxlow.rx;
+	if (txlow.read_delay <= rxlow.read_delay)
+		bottomleft.read_delay = txlow.read_delay;
+	else
+		bottomleft.read_delay = rxlow.read_delay;
+
+	backupcornerpoint = bottomleft;
+	backupcornerpoint.tx += 4;
+	backupcornerpoint.rx += 4;
+	ret = cqspi_phy_apply_setting(f_pdata, &backupcornerpoint);
+	if (!ret)
+		ret = cqspi_phy_check_pattern(f_pdata, mem);
+
+	if (ret) {
+		backupcornerpoint.read_delay--;
+		ret = cqspi_phy_apply_setting(f_pdata, &backupcornerpoint);
+		if (!ret)
+			ret = cqspi_phy_check_pattern(f_pdata, mem);
+	}
+
+	/* TODO: if (ret) */
+
+	if (!ret)
+		bottomleft.read_delay = backupcornerpoint.read_delay;
+
+	topright.tx = txhigh.tx;
+	topright.rx = rxhigh.rx;
+	if (txhigh.read_delay >= rxhigh.read_delay)
+		topright.read_delay = txhigh.read_delay;
+	else
+		topright.read_delay = rxhigh.read_delay;
+
+	backupcornerpoint = topright;
+	backupcornerpoint.tx -= 4;
+	backupcornerpoint.rx -= 4;
+	ret = cqspi_phy_apply_setting(f_pdata, &backupcornerpoint);
+	if (!ret)
+		ret = cqspi_phy_check_pattern(f_pdata, mem);
+
+	if (ret) {
+		backupcornerpoint.read_delay++;
+		ret = cqspi_phy_apply_setting(f_pdata, &backupcornerpoint);
+		if (!ret)
+			ret = cqspi_phy_check_pattern(f_pdata, mem);
+	}
+
+	/* TODO: if (ret) */
+
+	if (!ret)
+		topright.read_delay = backupcornerpoint.read_delay;
+
+	dev_dbg(dev, "topright: RX: %d TX: %d RD: %d\n", topright.rx,
+		topright.tx, topright.read_delay);
+	dev_dbg(dev, "bottomleft: RX: %d TX: %d RD: %d\n", bottomleft.rx,
+		bottomleft.tx, bottomleft.read_delay);
+
+	ret = cqspi_phy_find_gaplow(f_pdata, mem, &bottomleft, &topright,
+				    &gaplow);
+	if (ret)
+		goto out;
+	dev_dbg(dev, "gaplow: RX: %d TX: %d RD: %d\n", gaplow.rx, gaplow.tx,
+		gaplow.read_delay);
+
+	if (bottomleft.read_delay == topright.read_delay) {
+		/*
+		 * If there is only one passing region, it means that the
+		 * "true" topright is too small to find, so the start of the
+		 * failing region is a good approximation. Put the tuning point
+		 * in the middle and adjust for temperature.
+		 */
+
+		dev_dbg(dev,
+			"bottomleft and topright at the same read delay.\n");
+
+		topright = gaplow;
+		searchpoint.read_delay = bottomleft.read_delay;
+		searchpoint.tx =
+			bottomleft.tx + ((topright.tx - bottomleft.tx) / 2);
+		searchpoint.rx =
+			bottomleft.rx + ((topright.rx - bottomleft.rx) / 2);
+
+		ret = cqspi_get_temp(&tmp);
+		if (ret) {
+			/*
+			 * Assume room temperature if it couldn't be obtained
+			 * from the thermal sensor.
+			 *
+			 * TODO: Change it to dev_warn once support for finding
+			 * out the temperature is added.
+			 */
+
+			dev_dbg(dev, "Unable to get temperature. Assuming room temperature\n");
+			tmp = CQSPI_PHY_DEFAULT_TEMP;
+		}
+
+		if (tmp < CQSPI_PHY_MIN_TEMP || tmp > CQSPI_PHY_MAX_TEMP) {
+			dev_err(dev,
+				"Temperature outside operating range: %dC\n",
+				tmp);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/* Avoid a divide-by-zero. */
+
+		if (tmp == CQSPI_PHY_MID_TEMP)
+			tmp++;
+		dev_dbg(dev, "Temperature: %dC\n", tmp);
+
+		searchpoint.tx += (topright.tx - bottomleft.tx) /
+				  (330 / (tmp - CQSPI_PHY_MID_TEMP));
+		searchpoint.rx += (topright.rx - bottomleft.rx) /
+				  (330 / (tmp - CQSPI_PHY_MID_TEMP));
+	} else {
+		/*
+		 * If there are two passing regions, find the start and end of
+		 * the second one.
+		 */
+
+		ret = cqspi_phy_find_gaphigh(f_pdata, mem, &bottomleft,
+					     &topright, &gaphigh);
+		if (ret)
+			goto out;
+		dev_dbg(dev, "gaphigh: RX: %d TX: %d RD: %d\n", gaphigh.rx,
+			gaphigh.tx, gaphigh.read_delay);
+
+		/*
+		 * Place the final tuning point in the corner furthest from the
+		 * failing region but leave some margin for temperature
+		 * changes.
+		 */
+
+		if ((abs(gaplow.tx - bottomleft.tx) +
+		     abs(gaplow.rx - bottomleft.rx)) <
+		    (abs(gaphigh.tx - topright.tx) +
+		     abs(gaphigh.rx - topright.rx))) {
+			searchpoint = topright;
+			searchpoint.tx -= 16;
+			searchpoint.rx -= (16 * (topright.rx - bottomleft.rx))
+					  / (topright.tx - bottomleft.tx);
+		} else {
+			searchpoint = bottomleft;
+			searchpoint.tx += 16;
+			searchpoint.rx += (16 * (topright.rx - bottomleft.rx))
+					  / (topright.tx - bottomleft.tx);
+		}
+	}
+
+	/* Set the final PHY settings and check if they are working. */
+
+	dev_dbg(dev, "Final tuning point: RX: %d TX: %d RD: %d\n",
+		searchpoint.rx, searchpoint.tx, searchpoint.read_delay);
+	ret = cqspi_phy_apply_setting(f_pdata, &searchpoint);
+	if (!ret)
+		ret = cqspi_phy_check_pattern(f_pdata, mem);
+
+	if (ret) {
+		dev_err(dev,
+			"Failed to find pattern at final calibration point\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = 0;
+	f_pdata->phy_setting.read_delay = searchpoint.read_delay;
+	f_pdata->phy_setting.rx = searchpoint.rx;
+	f_pdata->phy_setting.tx = searchpoint.tx;
+out:
+	if (ret)
+		f_pdata->use_phy = false;
+	return ret;
+}
+
+static void cqspi_phy_reset_setting(struct phy_setting *phy)
+{
+	phy->rx = 0;
+	phy->tx = 127;
+	phy->read_delay = 0;
+}
+
+static int cqspi_phy_calibrate_sdr(struct cqspi_flash_pdata *f_pdata,
+				   struct spi_mem *mem)
+{
+	struct cqspi_st *cqspi = f_pdata->cqspi;
+	struct device *dev = &cqspi->pdev->dev;
+	struct phy_setting rxlow, rxhigh, first, second, final;
+	char window1 = 0;
+	char window2 = 0;
+	int ret;
+
+	f_pdata->use_phy = true;
+	cqspi_phy_reset_setting(&rxlow);
+	cqspi_phy_reset_setting(&rxhigh);
+	cqspi_phy_reset_setting(&first);
+
+	do {
+		ret = cqspi_find_rx_low_sdr(f_pdata, mem, &rxlow);
+
+		if (ret)
+			rxlow.read_delay++;
+	} while (ret && rxlow.read_delay <= CQSPI_PHY_MAX_RD);
+
+	rxhigh.read_delay = rxlow.read_delay;
+	ret = cqspi_find_rx_high_sdr(f_pdata, mem, &rxhigh, rxlow.rx);
+	if (ret)
+		goto out;
+
+	first.read_delay = rxlow.read_delay;
+	window1 = rxhigh.rx - rxlow.rx;
+	first.rx = rxlow.rx + (window1 / 2);
+
+	dev_dbg(dev, "First tuning point: RX: %d TX: %d RD: %d\n", first.rx,
+		first.tx, first.read_delay);
+	ret = cqspi_phy_apply_setting(f_pdata, &first);
+	if (!ret)
+		ret = cqspi_phy_check_pattern(f_pdata, mem);
+
+	if (ret || first.read_delay > CQSPI_PHY_MAX_RD)
+		goto out;
+
+	cqspi_phy_reset_setting(&rxlow);
+	cqspi_phy_reset_setting(&rxhigh);
+	cqspi_phy_reset_setting(&second);
+
+	rxlow.read_delay = first.read_delay + 1;
+	if (rxlow.read_delay > CQSPI_PHY_MAX_RD)
+		goto compare;
+
+	ret = cqspi_find_rx_low_sdr(f_pdata, mem, &rxlow);
+	if (ret)
+		goto compare;
+
+	rxhigh.read_delay = rxlow.read_delay;
+	ret = cqspi_find_rx_high_sdr(f_pdata, mem, &rxhigh, rxlow.rx);
+	if (ret)
+		goto compare;
+
+	window2 = rxhigh.rx - rxlow.rx;
+	second.rx = rxlow.rx + (window2 / 2);
+	second.read_delay = rxlow.read_delay;
+
+	dev_dbg(dev, "Second tuning point: RX: %d TX: %d RD: %d\n", second.rx,
+		second.tx, second.read_delay);
+	ret = cqspi_phy_apply_setting(f_pdata, &second);
+	if (!ret)
+		ret = cqspi_phy_check_pattern(f_pdata, mem);
+
+	if (ret || second.read_delay > CQSPI_PHY_MAX_RD)
+		window2 = 0;
+
+compare:
+	cqspi_phy_reset_setting(&final);
+	if (window2 > window1) {
+		final.rx = second.rx;
+		final.read_delay = second.read_delay;
+	} else {
+		final.rx = first.rx;
+		final.read_delay = first.read_delay;
+	}
+
+	dev_dbg(dev, "Final tuning point: RX: %d TX: %d RD: %d\n", final.rx,
+		final.tx, final.read_delay);
+	ret = cqspi_phy_apply_setting(f_pdata, &final);
+	if (!ret)
+		ret = cqspi_phy_check_pattern(f_pdata, mem);
+
+	if (ret) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	f_pdata->phy_setting.read_delay = final.read_delay;
+	f_pdata->phy_setting.rx = final.rx;
+	f_pdata->phy_setting.tx = final.tx;
+
+out:
+	if (ret)
+		f_pdata->use_phy = false;
+
+	return ret;
+}
+
+static void cqspi_readdata_capture(struct cqspi_st *cqspi,
+				   const bool bypass,
+				   const bool dqs,
+				   const unsigned int delay)
+{
+	void __iomem *reg_base = cqspi->iobase;
+	unsigned int reg;
+
+	reg = readl(reg_base + CQSPI_REG_READCAPTURE);
+
+	if (bypass)
+		reg |= (1 << CQSPI_REG_READCAPTURE_BYPASS_LSB);
+	else
+		reg &= ~(1 << CQSPI_REG_READCAPTURE_BYPASS_LSB);
+
+	reg &= ~(CQSPI_REG_READCAPTURE_DELAY_MASK
+		 << CQSPI_REG_READCAPTURE_DELAY_LSB);
+
+	reg |= (delay & CQSPI_REG_READCAPTURE_DELAY_MASK)
+		<< CQSPI_REG_READCAPTURE_DELAY_LSB;
+
+	if (dqs)
+		reg |= (1 << CQSPI_REG_READCAPTURE_DQS_LSB);
+	else
+		reg &= ~(1 << CQSPI_REG_READCAPTURE_DQS_LSB);
+
+	writel(reg, reg_base + CQSPI_REG_READCAPTURE);
+}
+
+static void cqspi_phy_enable(struct cqspi_flash_pdata *f_pdata, bool enable)
+{
+	struct cqspi_st *cqspi = f_pdata->cqspi;
+	void __iomem *reg_base = cqspi->iobase;
+	u32 reg;
+	u8 dummy;
+
+	if (enable) {
+		cqspi_readdata_capture(cqspi, 1, f_pdata->use_dqs,
+				       f_pdata->phy_setting.read_delay);
+
+		reg = readl(reg_base + CQSPI_REG_CONFIG);
+		reg |= CQSPI_REG_CONFIG_PHY_EN | CQSPI_REG_CONFIG_PHY_PIPELINE;
+		writel(reg, reg_base + CQSPI_REG_CONFIG);
+
+		/*
+		 * Reduce dummy cycle by 1. This is a requirement of PHY mode
+		 * operation for correctly reading the data.
+		 */
+		reg = readl(reg_base + CQSPI_REG_RD_INSTR);
+		dummy = (reg >> CQSPI_REG_RD_INSTR_DUMMY_LSB) &
+			CQSPI_REG_RD_INSTR_DUMMY_MASK;
+		dummy--;
+		reg &= ~(CQSPI_REG_RD_INSTR_DUMMY_MASK
+			 << CQSPI_REG_RD_INSTR_DUMMY_LSB);
+
+		reg |= (dummy & CQSPI_REG_RD_INSTR_DUMMY_MASK)
+		       << CQSPI_REG_RD_INSTR_DUMMY_LSB;
+		writel(reg, reg_base + CQSPI_REG_RD_INSTR);
+	} else {
+		cqspi_readdata_capture(cqspi, !cqspi->rclk_en, false,
+				       f_pdata->read_delay);
+
+		reg = readl(reg_base + CQSPI_REG_CONFIG);
+		reg &= ~(CQSPI_REG_CONFIG_PHY_EN |
+			 CQSPI_REG_CONFIG_PHY_PIPELINE);
+		writel(reg, reg_base + CQSPI_REG_CONFIG);
+
+		/*
+		 * Dummy cycles were decremented when enabling PHY. Increment
+		 * dummy cycle by 1 to restore the original value.
+		 */
+		reg = readl(reg_base + CQSPI_REG_RD_INSTR);
+		dummy = (reg >> CQSPI_REG_RD_INSTR_DUMMY_LSB) &
+			CQSPI_REG_RD_INSTR_DUMMY_MASK;
+		dummy++;
+		reg &= ~(CQSPI_REG_RD_INSTR_DUMMY_MASK
+			 << CQSPI_REG_RD_INSTR_DUMMY_LSB);
+
+		reg |= (dummy & CQSPI_REG_RD_INSTR_DUMMY_MASK)
+		       << CQSPI_REG_RD_INSTR_DUMMY_LSB;
+		writel(reg, reg_base + CQSPI_REG_RD_INSTR);
+	}
+
+	cqspi_wait_idle(cqspi);
+}
+
 static int cqspi_exec_flash_cmd(struct cqspi_st *cqspi, unsigned int reg)
 {
 	void __iomem *reg_base = cqspi->iobase;
@@ -712,6 +2131,7 @@
 	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
 	reg |= (op->addr.nbytes - 1);
 	writel(reg, reg_base + CQSPI_REG_SIZE);
+	readl(reg_base + CQSPI_REG_SIZE); /* Flush posted write. */
 	return 0;
 }
 
@@ -754,6 +2174,7 @@
 	reinit_completion(&cqspi->transfer_complete);
 	writel(CQSPI_REG_INDIRECTRD_START_MASK,
 	       reg_base + CQSPI_REG_INDIRECTRD);
+	readl(reg_base + CQSPI_REG_INDIRECTRD); /* Flush posted write. */
 
 	while (remaining > 0) {
 		if (use_irq &&
@@ -1033,6 +2454,7 @@
 	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
 	reg |= (op->addr.nbytes - 1);
 	writel(reg, reg_base + CQSPI_REG_SIZE);
+	readl(reg_base + CQSPI_REG_SIZE); /* Flush posted write. */
 	return 0;
 }
 
@@ -1058,6 +2480,8 @@
 	reinit_completion(&cqspi->transfer_complete);
 	writel(CQSPI_REG_INDIRECTWR_START_MASK,
 	       reg_base + CQSPI_REG_INDIRECTWR);
+	readl(reg_base + CQSPI_REG_INDIRECTWR); /* Flush posted write. */
+
 	/*
 	 * As per 66AK2G02 TRM SPRUHY8F section 11.15.5.3 Indirect Access
 	 * Controller programming sequence, couple of cycles of
@@ -1075,6 +2499,9 @@
 	if (cqspi->apb_ahb_hazard)
 		readl(reg_base + CQSPI_REG_INDIRECTWR);
 
+	if (n_tx >= SZ_1K && f_pdata->use_phy)
+		cqspi_phy_enable(f_pdata, true);
+
 	while (remaining > 0) {
 		size_t write_words, mod_bytes;
 
@@ -1115,6 +2542,9 @@
 		goto failwr;
 	}
 
+	if (n_tx >= SZ_1K && f_pdata->use_phy)
+		cqspi_phy_enable(f_pdata, false);
+
 	/* Disable interrupt. */
 	writel(0, reg_base + CQSPI_REG_IRQMASK);
 
@@ -1126,6 +2556,9 @@
 	return 0;
 
 failwr:
+	if (n_tx >= SZ_1K && f_pdata->use_phy)
+		cqspi_phy_enable(f_pdata, false);
+
 	/* Disable interrupt. */
 	writel(0, reg_base + CQSPI_REG_IRQMASK);
 
@@ -1230,35 +2663,92 @@
 	writel(reg, reg_base + CQSPI_REG_CONFIG);
 }
 
-static void cqspi_readdata_capture(struct cqspi_st *cqspi,
-				   const bool bypass,
-				   const unsigned int delay)
+static void cqspi_phy_set_dll_master(struct cqspi_st *cqspi)
 {
 	void __iomem *reg_base = cqspi->iobase;
 	unsigned int reg;
 
-	reg = readl(reg_base + CQSPI_REG_READCAPTURE);
+	reg = readl(reg_base + CQSPI_REG_PHY_DLL_MASTER);
+	reg &= ~((CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_LEN
+		  << CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_LSB) |
+		 CQSPI_REG_PHY_DLL_MASTER_BYPASS |
+		 CQSPI_REG_PHY_DLL_MASTER_CYCLE);
+	reg |= ((cqspi->phase_detect_selector
+		 << CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_LSB) |
+		CQSPI_REG_PHY_DLL_MASTER_CYCLE);
+
+	writel(reg, reg_base + CQSPI_REG_PHY_DLL_MASTER);
+}
 
-	if (bypass)
-		reg |= (1 << CQSPI_REG_READCAPTURE_BYPASS_LSB);
-	else
-		reg &= ~(1 << CQSPI_REG_READCAPTURE_BYPASS_LSB);
+static void cqspi_phy_pre_config(struct cqspi_st *cqspi, const bool bypass,
+				 const bool dqs,
+				 struct cqspi_flash_pdata *f_pdata)
+{
+	void __iomem *reg_base = cqspi->iobase;
+	unsigned int reg;
+	u8 dummy;
+
+	cqspi_readdata_capture(cqspi, bypass, dqs,
+			       f_pdata->phy_setting.read_delay);
+
+	reg = readl(reg_base + CQSPI_REG_CONFIG);
+	reg &= ~(CQSPI_REG_CONFIG_PHY_EN | CQSPI_REG_CONFIG_PHY_PIPELINE);
+	reg |= CQSPI_REG_CONFIG_PHY_EN;
+	writel(reg, reg_base + CQSPI_REG_CONFIG);
+
+	reg = readl(reg_base + CQSPI_REG_RD_INSTR);
+	dummy = (reg >> CQSPI_REG_RD_INSTR_DUMMY_LSB) &
+		CQSPI_REG_RD_INSTR_DUMMY_MASK;
+	dummy--;
+	reg &= ~(CQSPI_REG_RD_INSTR_DUMMY_MASK << CQSPI_REG_RD_INSTR_DUMMY_LSB);
+
+	reg |= (dummy & CQSPI_REG_RD_INSTR_DUMMY_MASK)
+	       << CQSPI_REG_RD_INSTR_DUMMY_LSB;
+	writel(reg, reg_base + CQSPI_REG_RD_INSTR);
 
+	cqspi_phy_set_dll_master(cqspi);
+}
+
+static void cqspi_phy_post_config(struct cqspi_st *cqspi,
+				  const unsigned int delay)
+{
+	void __iomem *reg_base = cqspi->iobase;
+	unsigned int reg;
+	u8 dummy;
+
+	reg = readl(reg_base + CQSPI_REG_READCAPTURE);
 	reg &= ~(CQSPI_REG_READCAPTURE_DELAY_MASK
 		 << CQSPI_REG_READCAPTURE_DELAY_LSB);
 
 	reg |= (delay & CQSPI_REG_READCAPTURE_DELAY_MASK)
-		<< CQSPI_REG_READCAPTURE_DELAY_LSB;
-
+	       << CQSPI_REG_READCAPTURE_DELAY_LSB;
 	writel(reg, reg_base + CQSPI_REG_READCAPTURE);
+
+	reg = readl(reg_base + CQSPI_REG_CONFIG);
+	reg &= ~(CQSPI_REG_CONFIG_PHY_EN | CQSPI_REG_CONFIG_PHY_PIPELINE);
+	reg &= ~(CQSPI_REG_CONFIG_PHY_EN);
+	writel(reg, reg_base + CQSPI_REG_CONFIG);
+
+	reg = readl(reg_base + CQSPI_REG_RD_INSTR);
+	dummy = (reg >> CQSPI_REG_RD_INSTR_DUMMY_LSB) &
+		CQSPI_REG_RD_INSTR_DUMMY_MASK;
+	dummy++;
+	reg &= ~(CQSPI_REG_RD_INSTR_DUMMY_MASK << CQSPI_REG_RD_INSTR_DUMMY_LSB);
+
+	reg |= (dummy & CQSPI_REG_RD_INSTR_DUMMY_MASK)
+	       << CQSPI_REG_RD_INSTR_DUMMY_LSB;
+	writel(reg, reg_base + CQSPI_REG_RD_INSTR);
 }
 
 static void cqspi_configure(struct cqspi_flash_pdata *f_pdata,
 			    unsigned long sclk)
 {
 	struct cqspi_st *cqspi = f_pdata->cqspi;
+	void __iomem *reg_base = cqspi->iobase;
 	int switch_cs = (cqspi->current_cs != f_pdata->cs);
 	int switch_ck = (cqspi->sclk != sclk);
+	unsigned int reg;
+	int ret;
 
 	if (switch_cs || switch_ck)
 		cqspi_controller_enable(cqspi, 0);
@@ -1267,6 +2757,27 @@
 	if (switch_cs) {
 		cqspi->current_cs = f_pdata->cs;
 		cqspi_chipselect(f_pdata);
+
+		if (f_pdata->use_dqs) {
+			reg = readl(reg_base + CQSPI_REG_CONFIG);
+			reg |= (CQSPI_REG_CONFIG_DTR_PROTO |
+				CQSPI_REG_CONFIG_DUAL_OPCODE);
+			writel(reg, reg_base + CQSPI_REG_CONFIG);
+		} else {
+			reg = readl(reg_base + CQSPI_REG_CONFIG);
+			reg &= ~(CQSPI_REG_CONFIG_DTR_PROTO |
+				 CQSPI_REG_CONFIG_DUAL_OPCODE);
+			writel(reg, reg_base + CQSPI_REG_CONFIG);
+		}
+
+		if (f_pdata->use_phy) {
+			ret = cqspi_phy_apply_setting(f_pdata,
+						      &f_pdata->phy_setting);
+
+			if (ret)
+				dev_err(&cqspi->pdev->dev,
+					"Applying phy_setting failed during switching chip select\n");
+		}
 	}
 
 	/* Setup baudrate divisor and delays */
@@ -1274,7 +2785,7 @@
 		cqspi->sclk = sclk;
 		cqspi_config_baudrate_div(cqspi);
 		cqspi_delay(f_pdata);
-		cqspi_readdata_capture(cqspi, !cqspi->rclk_en,
+		cqspi_readdata_capture(cqspi, !cqspi->rclk_en, false,
 				       f_pdata->read_delay);
 	}
 
@@ -1312,6 +2823,56 @@
 	return cqspi_indirect_write_execute(f_pdata, to, buf, len);
 }
 
+/*
+ * Check if PHY mode can be used on the given op. This is assuming it will be a
+ * DAC mode read, since PHY won't work on any other type of operation anyway.
+ */
+static bool cqspi_phy_op_eligible_ddr(const struct spi_mem_op *op)
+{
+	/* PHY is only tuned for 8D-8D-8D. */
+	if (!(op->cmd.dtr && op->addr.dtr && op->dummy.dtr && op->data.dtr))
+		return false;
+	if (op->cmd.buswidth != 8)
+		return false;
+	if (!(op->addr.nbytes) || op->addr.buswidth != 8)
+		return false;
+	if (!(op->dummy.nbytes) || op->dummy.buswidth != 8)
+		return false;
+	if (!(op->data.nbytes) || op->data.buswidth != 8)
+		return false;
+
+	return true;
+}
+
+static bool cqspi_phy_op_eligible_sdr(const struct spi_mem_op *op)
+{
+	if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr)
+		return false;
+	if (!(op->addr.nbytes) || op->addr.buswidth < 1)
+		return false;
+	if (!(op->dummy.nbytes) || op->dummy.buswidth < 1)
+		return false;
+	if (!(op->data.nbytes) || op->data.buswidth < 1)
+		return false;
+
+	return true;
+}
+
+static bool cqspi_use_phy(struct cqspi_flash_pdata *f_pdata,
+			  const struct spi_mem_op *op)
+{
+	if (!f_pdata->use_phy)
+		return false;
+
+	if (op->data.nbytes < 16)
+		return false;
+
+	if (f_pdata->use_dqs)
+		return cqspi_phy_op_eligible_ddr(op);
+	else
+		return cqspi_phy_op_eligible_sdr(op);
+}
+
 static void cqspi_rx_dma_callback(void *param)
 {
 	struct cqspi_st *cqspi = param;
@@ -1319,8 +2880,8 @@
 	complete(&cqspi->rx_dma_complete);
 }
 
-static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
-				     u_char *buf, loff_t from, size_t len)
+static int cqspi_direct_read_dma(struct cqspi_flash_pdata *f_pdata,
+				 u_char *buf, loff_t from, size_t len)
 {
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	struct device *dev = &cqspi->pdev->dev;
@@ -1332,11 +2893,6 @@
 	dma_addr_t dma_dst;
 	struct device *ddev;
 
-	if (!cqspi->rx_chan || !virt_addr_valid(buf)) {
-		memcpy_fromio(buf, cqspi->ahb_base + from, len);
-		return 0;
-	}
-
 	ddev = cqspi->rx_chan->device->dev;
 	dma_dst = dma_map_single(ddev, buf, len, DMA_FROM_DEVICE);
 	if (dma_mapping_error(ddev, dma_dst)) {
@@ -1378,6 +2934,104 @@
 	return ret;
 }
 
+static void cqspi_memcpy_fromio(const struct spi_mem_op *op, void *to,
+				const void __iomem *from, size_t count)
+{
+	if (op->data.buswidth == 8 && op->data.dtr) {
+		/*
+		 * 8D-8D-8D ops with odd length should be rejected by
+		 * supports_op() so no need to worry about that.
+		 */
+		while (count && !IS_ALIGNED((unsigned long)from, 4)) {
+			*(u16 *)to = __raw_readw(from);
+			from += 2;
+			to += 2;
+			count -= 2;
+		}
+
+		/*
+		 * The controller can work with both 32-bit and 64-bit
+		 * platforms. 32-bit platforms won't have a readq. So use a
+		 * readl instead.
+		 */
+		while (count >= 4) {
+			*(u32 *)to = __raw_readl(from);
+			from += 4;
+			to += 4;
+			count -= 4;
+		}
+
+		while (count) {
+			*(u16 *)to = __raw_readw(from);
+			from += 2;
+			to += 2;
+			count -= 2;
+		}
+
+		return;
+	}
+
+	memcpy_fromio(to, from, count);
+}
+
+static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
+				     const struct spi_mem_op *op)
+{
+	struct cqspi_st *cqspi = f_pdata->cqspi;
+	loff_t from = op->addr.val;
+	loff_t from_aligned, to_aligned;
+	size_t len = op->data.nbytes;
+	size_t len_aligned;
+	u_char *buf = op->data.buf.in;
+	int ret;
+
+	if (!cqspi->rx_chan || !virt_addr_valid(buf) || len <= 16) {
+		cqspi_memcpy_fromio(op, buf, cqspi->ahb_base + from, len);
+		return 0;
+	}
+
+	if (!cqspi_use_phy(f_pdata, op))
+		return cqspi_direct_read_dma(f_pdata, buf, from, len);
+
+	/*
+	 * PHY reads must be 16-byte aligned, and they must be a multiple of 16
+	 * bytes.
+	 */
+	from_aligned = (from + 0xF) & ~0xF;
+	to_aligned = (from + len) & ~0xF;
+	len_aligned = to_aligned - from_aligned;
+
+	/* Read the unaligned part at the start. */
+	if (from != from_aligned) {
+		ret = cqspi_direct_read_dma(f_pdata, buf, from,
+					    from_aligned - from);
+		if (ret)
+			return ret;
+		buf += from_aligned - from;
+	}
+
+	if (len_aligned) {
+		cqspi_phy_enable(f_pdata, true);
+		ret = cqspi_direct_read_dma(f_pdata, buf, from_aligned,
+					    len_aligned);
+		cqspi_phy_enable(f_pdata, false);
+		if (ret)
+			return ret;
+		buf += len_aligned;
+	}
+
+	/* Now read the remaining part, if any. */
+	if (to_aligned != (from + len)) {
+		ret = cqspi_direct_read_dma(f_pdata, buf, to_aligned,
+					    (from + len) - to_aligned);
+		if (ret)
+			return ret;
+		buf += (from + len) - to_aligned;
+	}
+
+	return 0;
+}
+
 static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata,
 			  const struct spi_mem_op *op)
 {
@@ -1394,7 +3048,7 @@
 		return ret;
 
 	if (cqspi->use_direct_mode && ((from + len) <= cqspi->ahb_size))
-		return cqspi_direct_read_execute(f_pdata, buf, from, len);
+		return cqspi_direct_read_execute(f_pdata, op);
 
 	if (cqspi->use_dma_read && ddata && ddata->indirect_read_dma &&
 	    virt_addr_valid(buf) && ((dma_align & CQSPI_DMA_UNALIGN) == 0))
@@ -1487,6 +3141,55 @@
 	return spi_mem_default_supports_op(mem, op);
 }
 
+static void cqspi_mem_do_calibration(struct spi_mem *mem,
+				     const struct spi_mem_op *op)
+{
+	struct cqspi_st *cqspi = spi_controller_get_devdata(mem->spi->controller);
+	struct cqspi_flash_pdata *f_pdata;
+	struct device *dev = &cqspi->pdev->dev;
+	int ret;
+
+	f_pdata = &cqspi->f_pdata[spi_get_chipselect(mem->spi, 0)];
+	f_pdata->phy_read_op = *op;
+
+	if (cqspi->phase_detect_selector >
+	    CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_LEN) {
+		dev_warn(dev,
+			 "Phase Detect Selector should be in between [0, 7]. Skipping Calibration\n");
+		return;
+	}
+
+	ret = cqspi_phy_check_pattern(f_pdata, mem);
+	if (ret) {
+		dev_warn(dev, "Pattern not found. Skipping calibration.\n");
+		return;
+	}
+
+	if (cqspi_phy_op_eligible_ddr(op)) {
+		f_pdata->use_dqs = true;
+
+		cqspi_phy_pre_config(cqspi, 0, 1, f_pdata);
+		ret = cqspi_phy_calibrate_ddr(f_pdata, mem);
+
+	} else if (cqspi_phy_op_eligible_sdr(op)) {
+		f_pdata->use_dqs = false;
+
+		cqspi_phy_pre_config(cqspi, 1, 0, f_pdata);
+		ret = cqspi_phy_calibrate_sdr(f_pdata, mem);
+
+	} else {
+		dev_warn(dev,
+			 "Given read_op not eligible. Skipping Calibration.\n");
+		return;
+	}
+
+	if (ret)
+		dev_info(&cqspi->pdev->dev, "PHY calibration failed: %d\n",
+			 ret);
+
+	cqspi_phy_post_config(cqspi, f_pdata->read_delay);
+}
+
 static int cqspi_of_get_flash_pdata(struct platform_device *pdev,
 				    struct cqspi_flash_pdata *f_pdata,
 				    struct device_node *np)
@@ -1548,6 +3251,13 @@
 		return -ENXIO;
 	}
 
+	if (of_property_read_u32(np, "cdns,phase-detect-selector",
+				 &cqspi->phase_detect_selector)) {
+		dev_warn(dev, "couldn't determine phase-detect-selector\n");
+		cqspi->phase_detect_selector =
+			CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_LEN + 1;
+	}
+
 	if (of_property_read_u32(np, "num-cs", &cqspi->num_chipselect))
 		cqspi->num_chipselect = CQSPI_MAX_CHIPSELECT;
 
@@ -1631,7 +3341,7 @@
 
 	cqspi->rx_chan = dma_request_chan_by_mask(&mask);
 	if (IS_ERR(cqspi->rx_chan)) {
-		int ret = PTR_ERR(cqspi->rx_chan);
+		int ret = (-EPROBE_DEFER);
 
 		cqspi->rx_chan = NULL;
 		if (ret == -ENODEV) {
@@ -1660,6 +3370,7 @@
 	.exec_op = cqspi_exec_mem_op,
 	.get_name = cqspi_get_name,
 	.supports_op = cqspi_supports_mem_op,
+	.do_calibration = cqspi_mem_do_calibration,
 };
 
 static const struct spi_controller_mem_caps cqspi_mem_caps = {
@@ -1668,7 +3379,7 @@
 
 static int cqspi_setup_flash(struct cqspi_st *cqspi)
 {
-	unsigned int max_cs = cqspi->num_chipselect - 1;
+	unsigned int max_cs = 0;
 	struct platform_device *pdev = cqspi->pdev;
 	struct device *dev = &pdev->dev;
 	struct cqspi_flash_pdata *f_pdata;
@@ -1686,7 +3397,7 @@
 		if (cs >= cqspi->num_chipselect) {
 			dev_err(dev, "Chip select %d out of range.\n", cs);
 			return -EINVAL;
-		} else if (cs < max_cs) {
+		} else if (cs > max_cs) {
 			max_cs = cs;
 		}
 
@@ -1748,6 +3459,11 @@
 	clk_disable_unprepare(cqspi->clks[CLK_QSPI_AHB]);
 	clk_disable_unprepare(cqspi->clks[CLK_QSPI_APB]);
 }
+static const struct soc_device_attribute k3_soc_devices[] = {
+	{ .family = "AM64X", .revision = "SR1.0" },
+	{ /* sentinel */ }
+};
+
 static int cqspi_probe(struct platform_device *pdev)
 {
 	const struct cqspi_driver_platdata *ddata;
@@ -1871,6 +3587,8 @@
 						cqspi->master_ref_clk_hz);
 		if (ddata->hwcaps_mask & CQSPI_SUPPORTS_OCTAL)
 			host->mode_bits |= SPI_RX_OCTAL | SPI_TX_OCTAL;
+		if (ddata->hwcaps_mask & CQSPI_SUPPORTS_QUAD)
+			host->mode_bits |= SPI_TX_QUAD;
 		if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) {
 			cqspi->use_direct_mode = true;
 			cqspi->use_direct_mode_wr = true;
@@ -1923,7 +3641,7 @@
 
 	host->num_chipselect = cqspi->num_chipselect;
 
-	if (cqspi->use_direct_mode) {
+	if (cqspi->use_direct_mode && !soc_device_match(k3_soc_devices)) {
 		ret = cqspi_request_mmap_dma(cqspi);
 		if (ret == -EPROBE_DEFER)
 			goto probe_setup_failed;
@@ -1979,6 +3697,20 @@
 	pm_runtime_disable(&pdev->dev);
 }
 
+static void __maybe_unused cqspi_restore_context(struct cqspi_st *cqspi)
+{
+	struct device *dev = &cqspi->pdev->dev;
+	int ret;
+
+	cqspi_phy_set_dll_master(cqspi);
+
+	ret = cqspi_phy_apply_setting(cqspi->f_pdata,
+				      &cqspi->f_pdata->phy_setting);
+
+	if (ret)
+		dev_err(dev, "Applying phy_setting failed during restore\n");
+}
+
 static int cqspi_runtime_suspend(struct device *dev)
 {
 	struct cqspi_st *cqspi = dev_get_drvdata(dev);
@@ -1998,6 +3730,12 @@
 	cqspi_controller_init(cqspi);
 	cqspi_controller_enable(cqspi, 1);
 
+	/*
+	 * Only restore context if PHY is enabled, or else skip this step
+	 */
+	if ((cqspi->f_pdata->use_phy) == true)
+		cqspi_restore_context(cqspi);
+
 	cqspi->current_cs = -1;
 	cqspi->sclk = 0;
 	return 0;
@@ -2043,7 +3781,7 @@
 };
 
 static const struct cqspi_driver_platdata am654_ospi = {
-	.hwcaps_mask = CQSPI_SUPPORTS_OCTAL,
+	.hwcaps_mask = CQSPI_SUPPORTS_OCTAL | CQSPI_SUPPORTS_QUAD,
 	.quirks = CQSPI_NEEDS_WR_DELAY,
 };
 
diff -Naur --no-dereference a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
--- a/drivers/spi/spi-mem.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/spi/spi-mem.c	2025-10-23 09:30:40.286462238 -0400
@@ -525,6 +525,18 @@
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
 
+int spi_mem_do_calibration(struct spi_mem *mem, const struct spi_mem_op *op)
+{
+	struct spi_controller *ctlr = mem->spi->controller;
+
+	if (!ctlr->mem_ops || !ctlr->mem_ops->do_calibration)
+		return -EOPNOTSUPP;
+
+	ctlr->mem_ops->do_calibration(mem, op);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(spi_mem_do_calibration);
+
 static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
 				      u64 offs, size_t len, void *buf)
 {
diff -Naur --no-dereference a/drivers/tty/serial/8250/8250_pruss.c b/drivers/tty/serial/8250/8250_pruss.c
--- a/drivers/tty/serial/8250/8250_pruss.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/tty/serial/8250/8250_pruss.c	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Serial Port driver for PRUSS UART on TI platforms
+ *
+ *  Copyright (C) 2020-2021 by Texas Instruments Incorporated - http://www.ti.com/
+ *  Author: Bin Liu <b-liu@ti.com>
+ */
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/serial_reg.h>
+#include <linux/serial_core.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/remoteproc.h>
+#include "8250.h"
+
+#define DEFAULT_CLK_SPEED	192000000
+
+/* extra registers */
+#define PRUSS_UART_PEREMU_MGMT	12
+#define PRUSS_UART_TX_EN	BIT(14)
+#define PRUSS_UART_RX_EN	BIT(13)
+#define PRUSS_UART_FREE_RUN	BIT(0)
+
+#define PRUSS_UART_MDR			13
+#define PRUSS_UART_MDR_OSM_SEL_MASK	BIT(0)
+#define PRUSS_UART_MDR_16X_MODE		0
+#define PRUSS_UART_MDR_13X_MODE		1
+
+struct pruss8250_info {
+	int type;
+	int line;
+};
+
+static inline void uart_writel(struct uart_port *p, u32 offset, int value)
+{
+	writel(value, p->membase + (offset << p->regshift));
+}
+
+static int pruss8250_startup(struct uart_port *port)
+{
+	int ret;
+
+	uart_writel(port, PRUSS_UART_PEREMU_MGMT, 0);
+
+	ret = serial8250_do_startup(port);
+	if (!ret)
+		uart_writel(port, PRUSS_UART_PEREMU_MGMT, PRUSS_UART_TX_EN |
+							  PRUSS_UART_RX_EN |
+							  PRUSS_UART_FREE_RUN);
+	return ret;
+}
+
+static unsigned int pruss8250_get_divisor(struct uart_port *port,
+					  unsigned int baud,
+					  unsigned int *frac)
+{
+	unsigned int uartclk = port->uartclk;
+	unsigned int div_13, div_16;
+	unsigned int abs_d13, abs_d16;
+	u16 quot;
+
+	/* Old custom speed handling */
+	if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) {
+		quot = port->custom_divisor & UART_DIV_MAX;
+		if (port->custom_divisor & (1 << 16))
+			*frac = PRUSS_UART_MDR_13X_MODE;
+		else
+			*frac = PRUSS_UART_MDR_16X_MODE;
+
+		return quot;
+	}
+
+	div_13 = DIV_ROUND_CLOSEST(uartclk, 13 * baud);
+	div_16 = DIV_ROUND_CLOSEST(uartclk, 16 * baud);
+	div_13 = div_13 ? : 1;
+	div_16 = div_16 ? : 1;
+
+	abs_d13 = abs(baud - uartclk / 13 / div_13);
+	abs_d16 = abs(baud - uartclk / 16 / div_16);
+
+	if (abs_d13 >= abs_d16) {
+		*frac = PRUSS_UART_MDR_16X_MODE;
+		quot = div_16;
+	} else {
+		*frac = PRUSS_UART_MDR_13X_MODE;
+		quot = div_13;
+	}
+
+	return quot;
+}
+
+static void pruss8250_set_divisor(struct uart_port *port, unsigned int baud,
+				  unsigned int quot, unsigned int quot_frac)
+{
+	serial8250_do_set_divisor(port, baud, quot);
+	/*
+	 * quot_frac holds the MDR over-sampling mode
+	 * which is set in pruss8250_get_divisor()
+	 */
+	quot_frac &= PRUSS_UART_MDR_OSM_SEL_MASK;
+	serial_port_out(port, PRUSS_UART_MDR, quot_frac);
+}
+
+static int pruss8250_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct uart_8250_port port8250;
+	struct uart_port *up = &port8250.port;
+	struct pruss8250_info *info;
+	struct resource resource;
+	unsigned int port_type;
+	struct clk *clk;
+	int ret;
+
+	port_type = (unsigned long)of_device_get_match_data(&pdev->dev);
+	if (port_type == PORT_UNKNOWN)
+		return -EINVAL;
+
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	memset(&port8250, 0, sizeof(port8250));
+
+	ret = of_address_to_resource(np, 0, &resource);
+	if (ret) {
+		dev_err(&pdev->dev, "invalid address\n");
+		return ret;
+	}
+
+	ret = of_alias_get_id(np, "serial");
+	if (ret > 0)
+		up->line = ret;
+
+	clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(clk)) {
+		if (PTR_ERR(clk) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		up->uartclk = DEFAULT_CLK_SPEED;
+	} else {
+		up->uartclk = clk_get_rate(clk);
+		devm_clk_put(&pdev->dev, clk);
+	}
+
+	up->dev = &pdev->dev;
+	up->mapbase = resource.start;
+	up->mapsize = resource_size(&resource);
+	up->type = port_type;
+	up->iotype = UPIO_MEM;
+	up->regshift = 2;
+	up->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT |
+		    UPF_FIXED_TYPE | UPF_IOREMAP;
+	up->irqflags |= IRQF_SHARED;
+	up->startup = pruss8250_startup;
+	up->rs485_config = serial8250_em485_config;
+	up->get_divisor = pruss8250_get_divisor;
+	up->set_divisor = pruss8250_set_divisor;
+
+	ret = of_irq_get(np, 0);
+	if (ret < 0) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "missing irq\n");
+		return ret;
+	}
+
+	up->irq = ret;
+	spin_lock_init(&port8250.port.lock);
+	port8250.capabilities = UART_CAP_FIFO | UART_CAP_AFE;
+
+	ret = serial8250_register_8250_port(&port8250);
+	if (ret < 0)
+		goto err_dispose;
+
+	info->type = port_type;
+	info->line = ret;
+	platform_set_drvdata(pdev, info);
+
+	return 0;
+
+err_dispose:
+	irq_dispose_mapping(port8250.port.irq);
+	return ret;
+}
+
+static void pruss8250_remove(struct platform_device *pdev)
+{
+	struct pruss8250_info *info = platform_get_drvdata(pdev);
+
+	serial8250_unregister_port(info->line);
+}
+
+static const struct of_device_id pruss8250_table[] = {
+	{ .compatible = "ti,pruss-uart", .data = (void *)PORT_16550A, },
+	{ /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, pruss8250_table);
+
+static struct platform_driver pruss8250_driver = {
+	.driver = {
+		.name = "pruss8250",
+		.of_match_table = pruss8250_table,
+	},
+	.probe = pruss8250_probe,
+	.remove = pruss8250_remove,
+};
+
+module_platform_driver(pruss8250_driver);
+
+MODULE_AUTHOR("Bin Liu <b-liu@ti.com");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Serial Port driver for PRUSS UART on TI platforms");
diff -Naur --no-dereference a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
--- a/drivers/tty/serial/8250/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/tty/serial/8250/Kconfig	2025-10-23 09:30:40.286462238 -0400
@@ -568,6 +568,16 @@
 	  including DMA support and high accuracy BAUD rates, say
 	  Y to this option. If unsure, say N.
 
+config SERIAL_8250_PRUSS
+	tristate "TI PRU-ICSS UART support"
+	depends on SERIAL_8250
+	depends on PRU_REMOTEPROC && TI_PRUSS_INTC
+	help
+	  This driver is to support the UART module in PRU-ICSS which is
+	  available in some TI platforms.
+	  Say 'Y' here if you wish to use PRU-ICSS UART.
+	  Otherwise, say 'N'.
+
 config SERIAL_OF_PLATFORM
 	tristate "Devicetree based probing for 8250 ports"
 	depends on SERIAL_8250 && OF
diff -Naur --no-dereference a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
--- a/drivers/tty/serial/8250/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/tty/serial/8250/Makefile	2025-10-23 09:30:40.286462238 -0400
@@ -46,6 +46,7 @@
 obj-$(CONFIG_SERIAL_8250_PCI)		+= 8250_pci.o
 obj-$(CONFIG_SERIAL_8250_PCI1XXXX)	+= 8250_pci1xxxx.o
 obj-$(CONFIG_SERIAL_8250_PERICOM)	+= 8250_pericom.o
+obj-$(CONFIG_SERIAL_8250_PRUSS)		+= 8250_pruss.o
 obj-$(CONFIG_SERIAL_8250_PXA)		+= 8250_pxa.o
 obj-$(CONFIG_SERIAL_8250_RT288X)	+= 8250_rt288x.o
 obj-$(CONFIG_SERIAL_8250_CS)		+= serial_cs.o
diff -Naur --no-dereference a/drivers/usb/dwc3/dwc3-am62.c b/drivers/usb/dwc3/dwc3-am62.c
--- a/drivers/usb/dwc3/dwc3-am62.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/usb/dwc3/dwc3-am62.c	2025-10-23 09:30:40.286462238 -0400
@@ -108,6 +108,9 @@
 
 #define DWC3_AM62_AUTOSUSPEND_DELAY	100
 
+#define USBSS_DEBUG_CFG_OFF		0x0
+#define USBSS_DEBUG_CFG_DISABLED	0x7
+
 struct dwc3_am62 {
 	struct device *dev;
 	void __iomem *usbss;
@@ -117,6 +120,7 @@
 	unsigned int offset;
 	unsigned int vbus_divider;
 	u32 wakeup_stat;
+	void __iomem *phy_regs;
 };
 
 static const int dwc3_ti_rate_table[] = {	/* in KHZ */
@@ -185,15 +189,47 @@
 	return 0;
 }
 
+static int dwc3_ti_init(struct dwc3_am62 *am62)
+{
+	int ret;
+	u32 reg;
+
+	/* Read the syscon property and set the rate code */
+	ret = phy_syscon_pll_refclk(am62);
+	if (ret)
+		return ret;
+
+	/* Workaround Errata i2409 */
+	if (am62->phy_regs) {
+		reg = readl(am62->phy_regs + USB_PHY_PLL_REG12);
+		reg |= USB_PHY_PLL_LDO_REF_EN | USB_PHY_PLL_LDO_REF_EN_EN;
+		writel(reg, am62->phy_regs + USB_PHY_PLL_REG12);
+	}
+
+	/* VBUS divider select */
+	reg = dwc3_ti_readl(am62, USBSS_PHY_CONFIG);
+	if (am62->vbus_divider)
+		reg |= 1 << USBSS_PHY_VBUS_SEL_SHIFT;
+
+	dwc3_ti_writel(am62, USBSS_PHY_CONFIG, reg);
+
+	clk_prepare_enable(am62->usb2_refclk);
+
+	/* Set mode valid bit to indicate role is valid */
+	reg = dwc3_ti_readl(am62, USBSS_MODE_CONTROL);
+	reg |= USBSS_MODE_VALID;
+	dwc3_ti_writel(am62, USBSS_MODE_CONTROL, reg);
+
+	return 0;
+}
+
 static int dwc3_ti_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *node = pdev->dev.of_node;
 	struct dwc3_am62 *am62;
 	unsigned long rate;
-	void __iomem *phy;
 	int i, ret;
-	u32 reg;
 
 	am62 = devm_kzalloc(dev, sizeof(*am62), GFP_KERNEL);
 	if (!am62)
@@ -229,29 +265,17 @@
 
 	am62->rate_code = i;
 
-	/* Read the syscon property and set the rate code */
-	ret = phy_syscon_pll_refclk(am62);
-	if (ret)
-		return ret;
-
-	/* Workaround Errata i2409 */
-	phy = devm_platform_ioremap_resource(pdev, 1);
-	if (IS_ERR(phy)) {
+	am62->phy_regs = devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(am62->phy_regs)) {
 		dev_err(dev, "can't map PHY IOMEM resource. Won't apply i2409 fix.\n");
-		phy = NULL;
-	} else {
-		reg = readl(phy + USB_PHY_PLL_REG12);
-		reg |= USB_PHY_PLL_LDO_REF_EN | USB_PHY_PLL_LDO_REF_EN_EN;
-		writel(reg, phy + USB_PHY_PLL_REG12);
+		am62->phy_regs = NULL;
 	}
 
-	/* VBUS divider select */
 	am62->vbus_divider = device_property_read_bool(dev, "ti,vbus-divider");
-	reg = dwc3_ti_readl(am62, USBSS_PHY_CONFIG);
-	if (am62->vbus_divider)
-		reg |= 1 << USBSS_PHY_VBUS_SEL_SHIFT;
 
-	dwc3_ti_writel(am62, USBSS_PHY_CONFIG, reg);
+	ret = dwc3_ti_init(am62);
+	if (ret)
+		return ret;
 
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
@@ -259,7 +283,6 @@
 	 * Don't ignore its dependencies with its children
 	 */
 	pm_suspend_ignore_children(dev, false);
-	clk_prepare_enable(am62->usb2_refclk);
 	pm_runtime_get_noresume(dev);
 
 	ret = of_platform_populate(node, NULL, NULL, dev);
@@ -268,11 +291,6 @@
 		goto err_pm_disable;
 	}
 
-	/* Set mode valid bit to indicate role is valid */
-	reg = dwc3_ti_readl(am62, USBSS_MODE_CONTROL);
-	reg |= USBSS_MODE_VALID;
-	dwc3_ti_writel(am62, USBSS_MODE_CONTROL, reg);
-
 	/* Device has capability to wakeup system from sleep */
 	device_set_wakeup_capable(dev, true);
 	ret = device_wakeup_enable(dev);
@@ -340,6 +358,9 @@
 		dwc3_ti_writel(am62, USBSS_WAKEUP_STAT, USBSS_WAKEUP_STAT_CLR);
 	}
 
+	/* just to track if module resets on suspend */
+	dwc3_ti_writel(am62, USBSS_DEBUG_CFG, USBSS_DEBUG_CFG_DISABLED);
+
 	clk_disable_unprepare(am62->usb2_refclk);
 
 	return 0;
@@ -350,7 +371,14 @@
 	struct dwc3_am62 *am62 = dev_get_drvdata(dev);
 	u32 reg;
 
-	clk_prepare_enable(am62->usb2_refclk);
+	reg = dwc3_ti_readl(am62, USBSS_DEBUG_CFG);
+	if (reg != USBSS_DEBUG_CFG_DISABLED) {
+		/* lost power/context */
+		dwc3_ti_init(am62);
+	} else {
+		dwc3_ti_writel(am62, USBSS_DEBUG_CFG, USBSS_DEBUG_CFG_OFF);
+		clk_prepare_enable(am62->usb2_refclk);
+	}
 
 	if (device_may_wakeup(dev)) {
 		/* Clear wakeup config enable bits */
diff -Naur --no-dereference a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
--- a/drivers/video/logo/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/video/logo/Kconfig	2025-10-23 09:30:40.286462238 -0400
@@ -30,6 +30,10 @@
 	bool "Standard 224-color Linux logo"
 	default y
 
+config LOGO_BEAGLE_CLUT224
+	bool "224-color Linux logo with BeagleBoard.org mascot Boris"
+	default y
+
 config LOGO_DEC_CLUT224
 	bool "224-color Digital Equipment Corporation Linux logo"
 	depends on MACH_DECSTATION || ALPHA
diff -Naur --no-dereference a/drivers/video/logo/logo_beagle_clut224.ppm b/drivers/video/logo/logo_beagle_clut224.ppm
--- a/drivers/video/logo/logo_beagle_clut224.ppm	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/video/logo/logo_beagle_clut224.ppm	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,1123 @@
+P3
+80 80
+255
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+6 6 6  6 6 6  10 10 10  10 10 10  10 10 10  6 6 6
+6 6 6  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  6 6 6  10 10 10  14 14 14
+22 22 22  26 26 26  30 30 30  34 34 34  30 30 30  30 30 30
+26 26 26  18 18 18  14 14 14  10 10 10  6 6 6  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 1
+0 0 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  6 6 6  14 14 14  26 26 26  42 42 42
+54 54 54  66 66 66  78 78 78  78 78 78  78 78 78  74 74 74
+66 66 66  54 54 54  42 42 42  26 26 26  18 18 18  10 10 10
+6 6 6  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 1  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  10 10 10  22 22 22  42 42 42  66 66 66  86 86 86
+66 66 66  38 38 38  38 38 38  22 22 22  26 26 26  34 34 34
+54 54 54  66 66 66  86 86 86  70 70 70  46 46 46  26 26 26
+14 14 14  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 1  0 0 1
+0 0 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+10 10 10  26 26 26  50 50 50  82 82 82  58 58 58  6 6 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  6 6 6  54 54 54  86 86 86  66 66 66
+38 38 38  18 18 18  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  6 6 6
+22 22 22  50 50 50  78 78 78  34 34 34  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  6 6 6  70 70 70
+78 78 78  46 46 46  22 22 22  6 6 6  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 1  0 0 1
+0 0 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  6 6 6  18 18 18
+42 42 42  82 82 82  26 26 26  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  14 14 14  46 46 46  34 34 34  6 6 6  2 2 6
+42 42 42  78 78 78  42 42 42  18 18 18  6 6 6  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 1  0 0 0
+0 0 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  10 10 10  30 30 30
+66 66 66  58 58 58  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  26 26 26  86 86 86  101 101 101  46 46 46  10 10 10
+2 2 6  58 58 58  70 70 70  34 34 34  10 10 10  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 1  0 0 1
+0 0 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  14 14 14  42 42 42
+86 86 86  10 10 10  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  30 30 30  94 94 94  94 94 94  58 58 58  26 26 26
+2 2 6  6 6 6  78 78 78  54 54 54  22 22 22  6 6 6
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  6 6 6  22 22 22  62 62 62
+62 62 62  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  26 26 26  54 54 54  38 38 38  18 18 18  10 10 10
+2 2 6  2 2 6  34 34 34  82 82 82  38 38 38  14 14 14
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 1
+0 0 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  6 6 6  30 30 30  78 78 78
+30 30 30  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  10 10 10  10 10 10  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  78 78 78  50 50 50  18 18 18
+6 6 6  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 1  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  38 38 38  86 86 86
+14 14 14  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  54 54 54  66 66 66  26 26 26
+6 6 6  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 1
+0 0 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  14 14 14  42 42 42  82 82 82
+2 2 6  2 2 6  2 2 6  6 6 6  10 10 10  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  6 6 6  14 14 14  10 10 10  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  18 18 18  82 82 82  34 34 34
+10 10 10  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 1  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  14 14 14  46 46 46  86 86 86
+2 2 6  2 2 6  6 6 6  6 6 6  22 22 22  34 34 34
+6 6 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+18 18 18  34 34 34  10 10 10  50 50 50  22 22 22  2 2 6
+2 2 6  2 2 6  2 2 6  10 10 10  86 86 86  42 42 42
+14 14 14  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 1  0 0 1
+0 0 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  14 14 14  46 46 46  86 86 86
+2 2 6  2 2 6  38 38 38  116 116 116  94 94 94  22 22 22
+22 22 22  2 2 6  2 2 6  2 2 6  14 14 14  86 86 86
+138 138 138  162 162 162  158 155 152  38 38 38  26 26 26  6 6 6
+2 2 6  2 2 6  2 2 6  2 2 6  86 86 86  46 46 46
+14 14 14  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  14 14 14  46 46 46  86 86 86
+2 2 6  14 14 14  138 138 138  198 198 198  195 195 195  116 116 116
+10 10 10  2 2 6  2 2 6  6 6 6  101 98 89  187 187 187
+210 210 210  218 218 218  218 218 218  138 138 138  14 14 14  6 6 6
+2 2 6  2 2 6  2 2 6  2 2 6  86 86 86  50 50 50
+18 18 18  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 1  0 0 0  0 0 1  0 0 1
+0 0 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  14 14 14  46 46 46  86 86 86
+2 2 6  54 54 54  218 218 218  195 195 195  226 226 226  246 246 246
+58 58 58  2 2 6  2 2 6  30 30 30  210 210 210  253 253 253
+171 170 170  123 123 123  221 221 221  234 234 234  74 74 74  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  70 70 70  58 58 58
+22 22 22  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  14 14 14  46 46 46  82 82 82
+2 2 6  106 106 106  171 170 170  26 26 26  86 86 86  226 226 226
+123 123 123  10 10 10  14 14 14  46 46 46  231 231 231  190 190 190
+6 6 6  70 70 70  90 90 90  238 238 238  158 158 158  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  70 70 70  58 58 58
+22 22 22  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 1  0 0 0  0 0 1  0 0 1
+0 0 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  14 14 14  42 42 42  86 86 86
+6 6 6  116 116 116  106 106 106  6 6 6  70 70 70  144 144 144
+128 128 128  18 18 18  38 38 38  54 54 54  221 221 221  106 106 106
+2 2 6  14 14 14  46 46 46  190 190 190  198 198 198  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  74 74 74  62 62 62
+22 22 22  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 1  0 0 0  0 0 1  0 0 0
+0 0 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  14 14 14  42 42 42  94 94 94
+14 14 14  101 101 101  128 128 128  2 2 6  18 18 18  116 116 116
+118 98 46  121 92 8  121 92 8  98 77 21  162 162 162  106 106 106
+2 2 6  2 2 6  2 2 6  195 195 195  195 195 195  6 6 6
+2 2 6  2 2 6  2 2 6  2 2 6  74 74 74  62 62 62
+22 22 22  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 1  0 0 1  0 0 1  0 0 0
+0 0 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  38 38 38  90 90 90
+14 14 14  58 58 58  210 210 210  26 26 26  61 42 6  156 107 11
+226 170 11  236 186 11  225 175 15  184 144 12  225 175 15  175 146 61
+37 26 9  2 2 6  70 70 70  246 246 246  138 138 138  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  70 70 70  66 66 66
+26 26 26  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  38 38 38  86 86 86
+14 14 14  10 10 10  195 195 195  188 164 115  192 133 9  225 175 15
+239 182 13  236 186 11  232 195 16  232 195 16  246 215 20  241 208 19
+232 195 16  184 144 12  218 194 134  219 214 185  42 42 42  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  50 50 50  74 74 74
+30 30 30  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  34 34 34  86 86 86
+14 14 14  2 2 6  121 87 25  192 133 9  219 162 10  239 182 13
+236 186 11  232 195 16  241 208 19  246 215 20  246 215 20  246 215 20
+246 215 20  241 208 19  241 208 19  226 184 13  121 87 25  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  50 50 50  82 82 82
+34 34 34  10 10 10  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  34 34 34  82 82 82
+30 30 30  61 42 6  180 123 7  206 145 10  230 174 11  239 182 13
+236 186 11  238 202 15  241 208 19  235 218 115  246 215 20  246 215 20
+246 215 20  246 215 20  226 184 13  225 175 15  184 144 12  6 6 6
+2 2 6  2 2 6  2 2 6  2 2 6  26 26 26  94 94 94
+42 42 42  14 14 14  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  30 30 30  78 78 78
+50 50 50  104 69 6  192 133 9  216 158 10  236 178 12  236 186 11
+232 195 16  241 208 19  246 215 20  246 215 20  246 215 20  246 215 20
+241 208 19  200 144 11  200 144 11  216 158 10  163 110 8  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  6 6 6  90 90 90
+54 54 54  18 18 18  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  30 30 30  78 78 78
+46 46 46  22 22 22  137 92 6  210 162 10  239 182 13  236 186 11
+238 202 15  241 208 19  246 215 20  246 215 20  241 208 19  210 162 10
+185 133 11  210 150 10  216 158 10  210 150 10  104 69 6  2 2 6
+6 6 6  54 54 54  14 14 14  2 2 6  2 2 6  62 62 62
+74 74 74  30 30 30  10 10 10  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  34 34 34  78 78 78
+50 50 50  6 6 6  92 69 23  138 101 21  190 146 13  226 184 13
+232 195 16  232 195 16  225 175 15  190 146 13  167 114 7  192 133 9
+210 150 10  213 154 11  190 142 34  188 164 115  101 98 89  2 2 6
+2 2 6  78 78 78  116 116 116  58 58 58  2 2 6  22 22 22
+90 90 90  46 46 46  18 18 18  6 6 6  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  38 38 38  86 86 86
+50 50 50  6 6 6  128 128 128  172 154 116  156 107 11  167 114 7
+200 144 11  184 144 12  197 138 11  200 144 11  206 145 10  206 145 10
+197 138 11  188 164 115  195 195 195  198 198 198  171 170 170  14 14 14
+2 2 6  22 22 22  116 116 116  116 116 116  22 22 22  2 2 6
+74 74 74  70 70 70  30 30 30  10 10 10  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  6 6 6  18 18 18  50 50 50  101 101 101
+26 26 26  10 10 10  138 138 138  190 190 190  172 154 116  156 107 11
+197 138 11  200 144 11  197 138 11  192 133 9  180 123 7  190 142 34
+181 170 141  187 187 187  202 202 202  221 221 221  218 218 218  66 66 66
+2 2 6  2 2 6  50 50 50  62 62 62  6 6 6  2 2 6
+10 10 10  90 90 90  50 50 50  18 18 18  6 6 6  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  10 10 10  34 34 34  74 74 74  74 74 74
+2 2 6  6 6 6  144 144 144  198 198 198  190 190 190  181 170 141
+150 121 62  156 107 11  156 107 11  166 123 43  172 154 116  187 187 187
+190 190 190  210 210 210  246 246 246  253 253 253  253 253 253  182 182 182
+6 6 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  62 62 62  74 74 74  34 34 34  14 14 14  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  10 10 10  22 22 22  54 54 54  94 94 94  18 18 18
+2 2 6  46 46 46  234 234 234  221 221 221  190 190 190  190 190 190
+190 190 190  187 187 187  187 187 187  190 190 190  190 190 190  195 195 195
+218 218 218  242 242 242  253 253 253  253 253 253  253 253 253  253 253 253
+82 82 82  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  14 14 14  86 86 86  54 54 54  22 22 22  6 6 6
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+6 6 6  18 18 18  46 46 46  90 90 90  46 46 46  18 18 18
+6 6 6  182 182 182  253 253 253  246 246 246  206 206 206  190 190 190
+190 190 190  190 190 190  190 190 190  190 190 190  206 206 206  231 231 231
+250 250 250  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+202 202 202  14 14 14  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  42 42 42  86 86 86  42 42 42  18 18 18
+6 6 6  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  6 6 6
+14 14 14  38 38 38  74 74 74  66 66 66  2 2 6  6 6 6
+90 90 90  250 250 250  253 253 253  253 253 253  238 238 238  138 138 138
+97 87 74  110 93 64  119 103 79  103 95 84  108 105 106  238 238 238
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  82 82 82  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  78 78 78  70 70 70  34 34 34
+14 14 14  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  14 14 14
+34 34 34  66 66 66  78 78 78  6 6 6  2 2 6  18 18 18
+218 218 218  253 253 253  253 253 253  210 210 210  80 72 61  103 75 39
+169 127 44  169 127 44  167 127 47  207 184 137  167 127 47  104 86 63
+234 234 234  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  182 182 182  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  18 18 18  90 90 90  62 62 62
+30 30 30  10 10 10  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  10 10 10  26 26 26
+58 58 58  90 90 90  18 18 18  2 2 6  2 2 6  108 105 106
+253 253 253  253 253 253  218 218 218  103 75 39  169 127 44  143 114 43
+118 84 23  169 127 44  169 127 44  188 164 115  183 152 86  169 127 44
+97 87 74  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  231 231 231  18 18 18  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  18 18 18  94 94 94
+54 54 54  26 26 26  10 10 10  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  6 6 6  22 22 22  50 50 50
+90 90 90  26 26 26  2 2 6  2 2 6  14 14 14  195 195 195
+250 250 250  253 253 253  89 81 69  166 123 43  169 127 44  169 127 44
+98 77 21  163 123 43  120 94 48  156 118 43  225 216 182  161 124 51
+80 72 61  171 170 170  253 253 253  253 253 253  253 253 253  253 253 253
+250 250 250  242 242 242  54 54 54  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  38 38 38
+86 86 86  50 50 50  22 22 22  6 6 6  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  6 6 6  14 14 14  38 38 38  82 82 82
+34 34 34  2 2 6  2 2 6  2 2 6  42 42 42  195 195 195
+246 246 246  231 231 231  104 86 51  169 127 44  169 127 44  169 127 44
+121 87 25  105 82 38  72 65 62  105 82 38  211 190 148  239 232 219
+154 139 110  89 81 69  210 210 210  250 250 250  246 246 246  238 238 238
+226 226 226  231 231 231  101 101 101  6 6 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+38 38 38  82 82 82  42 42 42  14 14 14  6 6 6  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  10 10 10  26 26 26  62 62 62  66 66 66
+2 2 6  2 2 6  2 2 6  6 6 6  70 70 70  171 170 170
+206 206 206  101 98 89  157 117 39  169 127 44  169 127 44  169 127 44
+163 123 43  105 82 38  163 123 43  169 127 44  211 190 148  255 255 255
+255 255 255  253 253 253  144 144 144  90 90 90  190 190 190  202 202 202
+198 198 198  202 202 202  182 182 182  18 18 18  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  62 62 62  66 66 66  30 30 30  10 10 10  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  14 14 14  42 42 42  82 82 82  18 18 18
+2 2 6  2 2 6  2 2 6  10 10 10  94 94 94  182 182 182
+210 210 210  99 81 49  169 127 44  169 127 44  169 127 44  169 127 44
+169 127 44  98 77 21  169 127 44  188 164 115  252 252 252  255 255 255
+255 255 255  255 255 255  255 255 255  158 155 152  108 105 106  138 138 138
+195 195 195  195 195 195  210 210 210  158 158 158  6 6 6  14 14 14
+50 50 50  14 14 14  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  6 6 6  86 86 86  46 46 46  18 18 18  6 6 6
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  6 6 6  22 22 22  54 54 54  70 70 70  2 2 6
+2 2 6  10 10 10  2 2 6  22 22 22  169 168 166  231 231 231
+128 128 128  143 114 43  169 127 44  169 127 44  169 127 44  169 127 44
+169 127 44  118 84 23  167 127 47  247 245 242  255 255 255  255 255 255
+255 255 255  255 255 255  182 182 182  116 116 116  128 128 128  38 38 38
+206 206 206  206 206 206  198 198 198  226 226 226  94 94 94  2 2 6
+6 6 6  38 38 38  30 30 30  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  62 62 62  66 66 66  26 26 26  10 10 10
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  10 10 10  30 30 30  74 74 74  50 50 50  2 2 6
+26 26 26  26 26 26  2 2 6  106 106 106  238 238 238  253 253 253
+89 81 66  169 127 44  169 127 44  169 127 44  169 127 44  169 127 44
+169 127 44  157 117 39  138 113 67  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  202 202 202  50 50 50  34 34 34  50 50 50
+231 231 231  246 246 246  218 218 218  202 202 202  210 210 210  14 14 14
+2 2 6  2 2 6  30 30 30  22 22 22  2 2 6  2 2 6
+2 2 6  2 2 6  18 18 18  86 86 86  42 42 42  14 14 14
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  14 14 14  42 42 42  90 90 90  22 22 22  2 2 6
+42 42 42  2 2 6  18 18 18  218 218 218  253 253 253  253 253 253
+104 86 63  169 127 44  169 127 44  169 127 44  169 127 44  169 127 44
+166 123 43  156 118 43  105 82 38  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  221 221 221  182 182 182  90 90 90
+232 232 232  253 253 253  248 248 248  221 221 221  218 218 218  101 101 101
+2 2 6  14 14 14  18 18 18  38 38 38  10 10 10  2 2 6
+2 2 6  2 2 6  2 2 6  78 78 78  58 58 58  22 22 22
+6 6 6  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+6 6 6  18 18 18  54 54 54  82 82 82  2 2 6  26 26 26
+22 22 22  2 2 6  123 123 123  253 253 253  253 253 253  253 253 253
+89 81 66  169 127 44  169 127 44  169 127 44  169 127 44  166 123 43
+141 109 45  157 117 39  118 84 23  240 237 231  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  226 226 226  97 87 74  72 54 38
+253 253 253  253 253 253  251 251 250  250 250 250  238 238 238  198 198 198
+6 6 6  38 38 38  58 58 58  26 26 26  38 38 38  2 2 6
+2 2 6  2 2 6  2 2 6  46 46 46  78 78 78  30 30 30
+10 10 10  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+10 10 10  30 30 30  74 74 74  58 58 58  2 2 6  42 42 42
+2 2 6  22 22 22  231 231 231  253 253 253  253 253 253  253 253 253
+162 161 160  104 86 51  169 127 44  169 127 44  156 118 43  141 109 45
+145 111 45  105 82 38  157 117 39  216 197 160  255 255 255  203 202 203
+158 155 152  116 116 116  72 65 62  95 51 32  175 118 6  145 90 47
+250 250 250  253 253 253  252 252 252  253 253 253  253 253 253  246 246 246
+46 46 46  38 38 38  42 42 42  14 14 14  38 38 38  14 14 14
+2 2 6  2 2 6  2 2 6  6 6 6  86 86 86  46 46 46
+14 14 14  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  6 6 6
+14 14 14  42 42 42  90 90 90  18 18 18  18 18 18  26 26 26
+2 2 6  116 116 116  253 253 253  253 253 253  253 253 253  253 253 253
+248 248 248  138 138 138  99 81 49  105 82 38  125 96 44  121 87 25
+98 77 21  125 96 44  169 127 44  216 197 160  255 255 255  190 190 190
+108 105 106  70 70 70  58 58 58  72 54 38  192 133 9  120 94 48
+250 250 250  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+94 94 94  6 6 6  2 2 6  2 2 6  10 10 10  34 34 34
+2 2 6  2 2 6  2 2 6  2 2 6  74 74 74  58 58 58
+22 22 22  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  10 10 10
+26 26 26  66 66 66  82 82 82  2 2 6  38 38 38  6 6 6
+14 14 14  210 210 210  253 253 253  253 253 253  253 253 253  253 253 253
+101 101 101  90 90 90  244 244 244  89 81 69  145 111 45  161 124 51
+197 178 128  207 184 137  216 197 160  218 218 218  171 170 170  151 148 137
+141 130 107  80 72 61  169 168 166  226 226 226  109 101 93  187 187 187
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+144 144 144  2 2 6  2 2 6  2 2 6  2 2 6  46 46 46
+2 2 6  2 2 6  2 2 6  2 2 6  42 42 42  74 74 74
+30 30 30  10 10 10  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  6 6 6  14 14 14
+42 42 42  90 90 90  26 26 26  6 6 6  42 42 42  2 2 6
+74 74 74  250 250 250  253 253 253  253 253 253  253 253 253  253 253 253
+106 106 106  131 116 91  210 209 209  110 93 64  169 127 44  233 229 220
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  239 232 219
+169 127 44  120 94 48  244 244 244  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+182 182 182  2 2 6  2 2 6  2 2 6  2 2 6  46 46 46
+2 2 6  2 2 6  2 2 6  2 2 6  10 10 10  86 86 86
+38 38 38  10 10 10  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  10 10 10  26 26 26
+66 66 66  82 82 82  2 2 6  22 22 22  18 18 18  2 2 6
+144 144 144  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+171 170 170  125 96 44  103 95 84  110 93 64  175 146 61  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+183 152 86  145 111 45  195 195 194  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  252 252 252  253 253 253  253 253 253  253 253 253
+206 206 206  2 2 6  2 2 6  2 2 6  2 2 6  38 38 38
+2 2 6  2 2 6  2 2 6  2 2 6  6 6 6  86 86 86
+46 46 46  14 14 14  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  6 6 6  18 18 18  46 46 46
+86 86 86  18 18 18  2 2 6  34 34 34  10 10 10  6 6 6
+210 210 210  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+246 246 246  100 88 68  145 111 45  120 94 48  159 135 84  249 249 249
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+152 137 111  156 118 43  158 158 158  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  251 251 250  253 253 253  253 253 253  253 253 253
+221 221 221  6 6 6  2 2 6  2 2 6  6 6 6  30 30 30
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  82 82 82
+54 54 54  18 18 18  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  26 26 26  66 66 66
+62 62 62  2 2 6  2 2 6  38 38 38  10 10 10  26 26 26
+238 238 238  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  144 144 144  138 113 67  166 123 43  138 119 85  246 246 246
+255 255 255  242 242 242  255 255 255  255 255 255  234 234 234  255 255 255
+152 137 111  156 118 43  162 161 160  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  250 250 250  253 253 253  253 253 253  253 253 253
+231 231 231  6 6 6  2 2 6  2 2 6  10 10 10  30 30 30
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  66 66 66
+58 58 58  22 22 22  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  38 38 38  78 78 78
+6 6 6  2 2 6  2 2 6  46 46 46  14 14 14  42 42 42
+246 246 246  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  250 250 250  94 90 86  154 122 46  138 119 85  253 253 253
+244 243 244  195 195 194  255 255 255  244 244 244  182 182 182  255 255 255
+147 140 128  145 111 45  187 187 187  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  249 249 249  249 249 249  253 253 253  253 253 253
+234 234 234  10 10 10  2 2 6  2 2 6  22 22 22  14 14 14
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  66 66 66
+62 62 62  22 22 22  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  6 6 6  18 18 18  50 50 50  74 74 74
+2 2 6  2 2 6  14 14 14  70 70 70  34 34 34  62 62 62
+250 250 250  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  231 231 231  104 86 63  141 130 107  255 255 255
+246 246 246  182 182 182  255 255 255  231 231 231  196 195 196  255 255 255
+147 140 128  119 100 63  242 242 242  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  242 242 242  253 253 253  253 253 253
+234 234 234  14 14 14  2 2 6  2 2 6  30 30 30  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  66 66 66
+62 62 62  22 22 22  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  6 6 6  18 18 18  54 54 54  62 62 62
+2 2 6  2 2 6  2 2 6  30 30 30  46 46 46  70 70 70
+250 250 250  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  210 210 210  89 81 66  152 137 111  255 255 255
+254 254 254  171 170 170  255 255 255  218 218 218  210 209 209  255 255 255
+151 148 137  123 99 54  169 168 166  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  252 252 252  253 253 253  253 253 253
+226 226 226  10 10 10  2 2 6  6 6 6  30 30 30  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  66 66 66
+58 58 58  22 22 22  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  6 6 6  22 22 22  58 58 58  62 62 62
+2 2 6  2 2 6  2 2 6  2 2 6  30 30 30  78 78 78
+250 250 250  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  249 249 249  97 87 74  169 127 44  152 137 111  255 255 255
+255 255 255  171 170 170  255 255 255  203 202 203  226 226 226  255 255 255
+158 155 152  169 127 44  120 94 48  234 234 234  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+206 206 206  2 2 6  22 22 22  34 34 34  18 14 6  22 22 22
+26 26 26  18 18 18  6 6 6  2 2 6  2 2 6  82 82 82
+54 54 54  18 18 18  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  6 6 6  26 26 26  62 62 62  106 106 106
+78 53 15  185 133 11  210 162 10  121 92 8  6 6 6  62 62 62
+238 238 238  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  238 238 238  110 93 64  166 123 43  162 161 160  255 255 255
+255 255 255  108 105 106  94 94 94  82 82 82  244 244 244  255 255 255
+202 202 202  150 121 62  141 109 45  202 202 202  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+158 158 158  18 18 18  14 14 14  2 2 6  2 2 6  2 2 6
+6 6 6  18 18 18  66 66 66  38 38 38  6 6 6  94 94 94
+50 50 50  18 18 18  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  6 6 6
+10 10 10  10 10 10  18 18 18  38 38 38  78 78 78  141 130 107
+216 158 10  242 186 14  246 190 14  246 190 14  163 110 8  10 10 10
+90 90 90  238 238 238  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  252 252 252  144 144 144  80 72 61  218 218 218  255 255 255
+206 206 206  123 123 123  253 253 253  128 128 128  169 168 166  254 254 254
+254 254 254  101 98 89  128 128 128  252 252 252  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  225 216 182  219 191 94  219 191 94
+180 133 36  37 26 9  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  38 38 38  46 46 46  26 26 26  106 106 106
+54 54 54  18 18 18  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  6 6 6  14 14 14  22 22 22
+30 30 30  38 38 38  50 50 50  70 70 70  106 106 106  190 142 34
+226 170 11  242 186 14  246 190 14  246 190 14  246 190 14  156 107 11
+6 6 6  74 74 74  226 226 226  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  182 182 182  108 105 106  116 116 116
+123 123 123  244 244 244  253 253 253  244 244 244  128 128 128  116 116 116
+116 116 116  169 168 166  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  201 174 68  241 196 14  241 208 19
+232 195 16  38 30 10  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  6 6 6  30 30 30  26 26 26  210 162 10  159 135 84
+66 66 66  26 26 26  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  6 6 6  18 18 18  38 38 38  58 58 58
+78 78 78  86 86 86  101 101 101  123 123 123  175 146 61  210 150 10
+234 174 13  246 186 14  246 190 14  246 190 14  246 190 14  236 186 11
+104 69 6  2 2 6  46 46 46  198 198 198  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  234 234 234  242 242 242
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  201 174 68  242 186 14  241 196 14
+210 162 10  22 18 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  6 6 6  121 92 8  238 202 15  232 195 16
+82 82 82  34 34 34  10 10 10  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  14 14 14  38 38 38  70 70 70  154 122 46
+190 142 34  200 144 11  197 138 11  197 138 11  213 154 11  226 170 11
+242 186 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+225 175 15  45 32 11  2 2 6  22 22 22  158 158 158  250 250 250
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  250 250 250  242 242 242  201 174 68  239 182 13  236 186 11
+213 154 11  45 32 11  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  61 42 6  225 175 15  236 186 11  236 186 11
+119 103 79  42 42 42  14 14 14  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  6 6 6  22 22 22  54 54 54  154 122 46  213 154 11
+226 170 11  230 174 11  226 170 11  226 170 11  236 178 12  242 186 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+241 196 14  184 144 12  10 10 10  2 2 6  6 6 6  116 116 116
+242 242 242  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  231 231 231  198 198 198  201 174 68  236 178 12  236 178 12
+210 150 10  137 92 6  18 14 6  2 2 6  2 2 6  2 2 6
+6 6 6  61 42 6  200 144 11  236 178 12  239 182 13  239 182 13
+124 112 88  58 58 58  22 22 22  6 6 6  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  10 10 10  30 30 30  70 70 70  180 133 36  226 170 11
+239 182 13  242 186 14  242 186 14  246 186 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  232 195 16  104 69 6  2 2 6  2 2 6  2 2 6
+66 66 66  221 221 221  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  206 206 206  198 198 198  201 174 68  230 174 11  230 174 11
+216 158 10  192 133 9  163 110 8  116 81 8  104 69 6  116 81 8
+167 114 7  197 138 11  226 170 11  239 182 13  242 186 14  242 186 14
+165 145 105  78 78 78  34 34 34  14 14 14  6 6 6  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  6 6 6  30 30 30  78 78 78  190 142 34  226 170 11
+239 182 13  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  241 196 14  210 162 10  22 18 6  2 2 6  2 2 6
+2 2 6  38 38 38  218 218 218  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+250 250 250  206 206 206  198 198 198  201 174 68  226 170 11  236 178 12
+224 166 10  210 150 10  200 144 11  197 138 11  192 133 9  197 138 11
+210 150 10  226 170 11  242 186 14  246 190 14  246 190 14  246 186 14
+225 175 15  124 112 88  62 62 62  30 30 30  14 14 14  6 6 6
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  10 10 10  30 30 30  78 78 78  167 127 47  224 166 10
+239 182 13  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  241 196 14  138 101 21  2 2 6  2 2 6
+2 2 6  2 2 6  78 78 78  250 250 250  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+250 250 250  218 218 218  198 198 198  190 142 34  219 162 10  236 178 12
+234 174 13  224 166 10  216 158 10  213 154 11  213 154 11  216 158 10
+226 170 11  239 182 13  246 190 14  246 190 14  246 190 14  246 190 14
+242 186 14  197 166 45  101 101 101  58 58 58  30 30 30  14 14 14
+6 6 6  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  10 10 10  30 30 30  74 74 74  167 127 47  216 158 10
+236 178 12  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  241 196 14  226 184 13  61 42 6  2 2 6
+2 2 6  2 2 6  22 22 22  238 238 238  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  226 226 226  187 187 187  180 133 36  216 158 10  236 178 12
+239 182 13  236 178 12  230 174 11  226 170 11  226 170 11  230 174 11
+236 178 12  242 186 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 186 14  239 182 13  197 166 45  106 106 106  66 66 66  34 34 34
+14 14 14  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  6 6 6  26 26 26  70 70 70  163 133 67  213 154 11
+236 178 12  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  241 196 14  190 146 13  18 14 6
+2 2 6  2 2 6  46 46 46  246 246 246  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  221 221 221  86 86 86  156 107 11  216 158 10  236 178 12
+242 186 14  246 186 14  242 186 14  239 182 13  239 182 13  242 186 14
+242 186 14  246 186 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  242 186 14  225 175 15  142 114 66  66 66 66
+30 30 30  10 10 10  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  6 6 6  26 26 26  70 70 70  163 133 67  210 150 10
+236 178 12  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  232 195 16  121 92 8
+34 34 34  106 106 106  221 221 221  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+242 242 242  82 82 82  18 14 6  163 110 8  216 158 10  236 178 12
+242 186 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  242 186 14  163 133 67
+46 46 46  18 18 18  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  10 10 10  30 30 30  78 78 78  163 133 67  210 150 10
+236 178 12  246 186 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  241 196 14  225 175 15
+181 170 141  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  218 218 218
+58 58 58  2 2 6  22 18 6  167 114 7  216 158 10  236 178 12
+246 186 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 186 14  242 186 14  190 142 34
+54 54 54  22 22 22  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  14 14 14  38 38 38  86 86 86  180 133 36  213 154 11
+236 178 12  246 186 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  232 195 16
+190 146 13  218 218 218  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  250 250 250  171 170 170  26 26 26
+2 2 6  2 2 6  37 26 9  163 110 8  219 162 10  239 182 13
+246 186 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 186 14  236 178 12  224 166 10  142 114 66
+46 46 46  18 18 18  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+6 6 6  18 18 18  50 50 50  109 101 93  192 133 9  224 166 10
+242 186 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  242 186 14  226 184 13
+210 162 10  141 109 45  226 226 226  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  253 253 253  253 253 253  253 253 253  253 253 253
+253 253 253  253 253 253  198 198 198  66 66 66  2 2 6  2 2 6
+2 2 6  2 2 6  45 32 11  156 107 11  219 162 10  239 182 13
+246 186 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  242 186 14  234 174 13  213 154 11  154 122 46  66 66 66
+30 30 30  10 10 10  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+6 6 6  22 22 22  58 58 58  150 121 62  206 145 10  234 174 13
+242 186 14  246 186 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 186 14  236 178 12
+210 162 10  163 110 8  61 42 6  138 138 138  218 218 218  250 250 250
+253 253 253  253 253 253  253 253 253  250 250 250  242 242 242  210 210 210
+144 144 144  66 66 66  6 6 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  61 42 6  163 110 8  216 158 10  236 178 12
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  239 182 13
+230 174 11  216 158 10  190 142 34  124 112 88  70 70 70  38 38 38
+18 18 18  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+6 6 6  22 22 22  62 62 62  166 123 43  206 145 10  224 166 10
+236 178 12  239 182 13  242 186 14  242 186 14  246 186 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  236 178 12
+216 158 10  175 118 6  78 53 15  2 2 6  6 6 6  30 30 30
+54 54 54  62 62 62  50 50 50  38 38 38  14 14 14  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  6 6 6  78 53 15  167 114 7  213 154 11  236 178 12
+246 190 14  246 190 14  246 190 14  246 190 14  246 190 14  246 190 14
+246 190 14  242 186 14  239 182 13  239 182 13  230 174 11  210 150 10
+167 127 47  124 112 88  82 82 82  54 54 54  34 34 34  18 18 18
+6 6 6  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+6 6 6  18 18 18  50 50 50  157 117 39  192 133 9  200 144 11
+216 158 10  219 162 10  224 166 10  226 170 11  230 174 11  236 178 12
+239 182 13  239 182 13  242 186 14  246 186 14  246 190 14  246 190 14
+246 190 14  246 190 14  246 190 14  246 190 14  246 186 14  230 174 11
+210 150 10  163 110 8  104 69 6  10 10 10  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  6 6 6  85 60 19  167 114 7  206 145 10  230 174 11
+242 186 14  246 190 14  246 190 14  246 190 14  246 186 14  242 186 14
+239 182 13  230 174 11  224 166 10  213 154 11  180 133 36  124 112 88
+86 86 86  58 58 58  38 38 38  22 22 22  10 10 10  6 6 6
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  14 14 14  34 34 34  70 70 70  141 109 45  157 117 39
+167 114 7  180 123 7  192 133 9  197 138 11  200 144 11  206 145 10
+213 154 11  219 162 10  224 166 10  230 174 11  239 182 13  242 186 14
+246 186 14  246 186 14  246 186 14  246 186 14  239 182 13  216 158 10
+185 133 11  152 99 6  104 69 6  18 14 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  2 2 6  2 2 6  2 2 6  2 2 6  2 2 6
+2 2 6  6 6 6  78 53 15  152 99 6  192 133 9  219 162 10
+236 178 12  239 182 13  246 186 14  242 186 14  239 182 13  236 178 12
+224 166 10  206 145 10  192 133 9  150 121 62  94 94 94  62 62 62
+42 42 42  22 22 22  14 14 14  6 6 6  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  6 6 6  18 18 18  34 34 34  58 58 58  78 78 78
+101 98 89  124 112 88  141 109 45  156 107 11  163 110 8  167 114 7
+175 118 6  180 123 7  185 133 11  197 138 11  210 150 10  219 162 10
+226 170 11  236 178 12  236 178 12  234 174 13  219 162 10  197 138 11
+163 110 8  137 92 6  85 60 19  10 10 10  2 2 6  2 2 6
+18 18 18  38 38 38  38 38 38  38 38 38  38 38 38  38 38 38
+38 38 38  38 38 38  38 38 38  38 38 38  26 26 26  2 2 6
+2 2 6  6 6 6  61 42 6  137 92 6  175 118 6  200 144 11
+219 162 10  230 174 11  234 174 13  230 174 11  219 162 10  210 150 10
+192 133 9  163 110 8  124 112 88  82 82 82  50 50 50  30 30 30
+14 14 14  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  6 6 6  14 14 14  22 22 22  34 34 34
+42 42 42  58 58 58  74 74 74  86 86 86  101 98 89  119 100 63
+125 96 44  121 87 25  137 92 6  152 99 6  163 110 8  180 123 7
+185 133 11  197 138 11  206 145 10  200 144 11  180 123 7  156 107 11
+137 92 6  104 69 6  45 32 11  54 54 54  108 105 106  101 98 89
+86 86 86  82 82 82  78 78 78  78 78 78  78 78 78  78 78 78
+78 78 78  78 78 78  78 78 78  82 82 82  86 86 86  94 94 94
+106 106 106  101 101 101  86 66 32  116 81 8  156 107 11  180 123 7
+192 133 9  200 144 11  206 145 10  200 144 11  192 133 9  175 118 6
+138 101 21  109 101 93  70 70 70  42 42 42  22 22 22  10 10 10
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  6 6 6  10 10 10
+14 14 14  22 22 22  30 30 30  38 38 38  50 50 50  62 62 62
+74 74 74  90 90 90  101 98 89  119 103 79  121 87 25  116 81 8
+137 92 6  152 99 6  152 99 6  152 99 6  137 92 6  116 81 8
+104 69 6  86 66 32  101 98 89  82 82 82  58 58 58  46 46 46
+38 38 38  34 34 34  34 34 34  34 34 34  34 34 34  34 34 34
+34 34 34  34 34 34  34 34 34  34 34 34  38 38 38  42 42 42
+54 54 54  82 82 82  97 87 74  85 60 19  137 92 6  156 107 11
+167 114 7  175 118 6  175 118 6  167 114 7  152 99 6  121 87 25
+101 98 89  62 62 62  34 34 34  18 18 18  6 6 6  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  6 6 6  6 6 6  10 10 10  18 18 18  22 22 22
+30 30 30  42 42 42  50 50 50  66 66 66  86 86 86  101 98 89
+104 86 63  104 69 6  104 69 6  104 69 6  104 69 6  85 60 19
+86 66 32  90 90 90  62 62 62  38 38 38  22 22 22  14 14 14
+10 10 10  10 10 10  10 10 10  10 10 10  10 10 10  10 10 10
+6 6 6  10 10 10  10 10 10  10 10 10  10 10 10  14 14 14
+22 22 22  42 42 42  70 70 70  89 81 66  78 53 15  104 69 6
+116 81 8  137 92 6  137 92 6  116 81 8  99 81 49  86 86 86
+58 58 58  30 30 30  14 14 14  6 6 6  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  6 6 6
+10 10 10  14 14 14  18 18 18  26 26 26  38 38 38  54 54 54
+70 70 70  86 86 86  97 87 74  89 81 66  89 81 66  86 86 86
+74 74 74  50 50 50  30 30 30  14 14 14  6 6 6  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+6 6 6  18 18 18  34 34 34  58 58 58  82 82 82  89 81 66
+89 81 66  89 81 66  100 88 68  97 87 74  74 74 74  50 50 50
+26 26 26  14 14 14  6 6 6  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  6 6 6  6 6 6  14 14 14  18 18 18
+30 30 30  38 38 38  46 46 46  54 54 54  50 50 50  42 42 42
+30 30 30  18 18 18  10 10 10  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  6 6 6  14 14 14  26 26 26  38 38 38  50 50 50
+58 58 58  58 58 58  54 54 54  42 42 42  30 30 30  18 18 18
+10 10 10  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  6 6 6
+6 6 6  10 10 10  14 14 14  18 18 18  18 18 18  14 14 14
+10 10 10  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  6 6 6  14 14 14  18 18 18
+22 22 22  22 22 22  18 18 18  14 14 14  10 10 10  6 6 6
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
diff -Naur --no-dereference a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
--- a/drivers/video/logo/logo.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/video/logo/logo.c	2025-10-23 09:30:40.286462238 -0400
@@ -100,6 +100,10 @@
 		/* SuperH Linux logo */
 		logo = &logo_superh_clut224;
 #endif
+#ifdef CONFIG_LOGO_BEAGLE_CLUT224
+		/* Generic Linux logo */
+		logo = &logo_beagle_clut224;
+#endif
 	}
 	return logo;
 }
diff -Naur --no-dereference a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile
--- a/drivers/video/logo/Makefile	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/video/logo/Makefile	2025-10-23 09:30:40.286462238 -0400
@@ -5,6 +5,7 @@
 obj-$(CONFIG_LOGO_LINUX_MONO)		+= logo_linux_mono.o
 obj-$(CONFIG_LOGO_LINUX_VGA16)		+= logo_linux_vga16.o
 obj-$(CONFIG_LOGO_LINUX_CLUT224)	+= logo_linux_clut224.o
+obj-$(CONFIG_LOGO_BEAGLE_CLUT224)	+= logo_beagle_clut224.o
 obj-$(CONFIG_LOGO_DEC_CLUT224)		+= logo_dec_clut224.o
 obj-$(CONFIG_LOGO_MAC_CLUT224)		+= logo_mac_clut224.o
 obj-$(CONFIG_LOGO_PARISC_CLUT224)	+= logo_parisc_clut224.o
diff -Naur --no-dereference a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c
--- a/drivers/watchdog/rti_wdt.c	2025-06-19 09:32:38.000000000 -0400
+++ b/drivers/watchdog/rti_wdt.c	2025-10-23 09:30:40.286462238 -0400
@@ -35,7 +35,8 @@
 #define RTIWWDRXCTRL	0xa4
 #define RTIWWDSIZECTRL	0xa8
 
-#define RTIWWDRX_NMI	0xa
+#define RTIWWDRXN_RST	0x5
+#define RTIWWDRXN_NMI	0xa
 
 #define RTIWWDSIZE_50P		0x50
 #define RTIWWDSIZE_25P		0x500
@@ -63,22 +64,29 @@
 
 static int heartbeat;
 
+struct rti_wdt_data {
+	bool reset;
+};
+
 /*
  * struct to hold data for each WDT device
  * @base - base io address of WD device
  * @freq - source clock frequency of WDT
  * @wdd  - hold watchdog device as is in WDT core
+ * @data - hold configuration data
  */
 struct rti_wdt_device {
 	void __iomem		*base;
 	unsigned long		freq;
 	struct watchdog_device	wdd;
+	const struct rti_wdt_data *data;
 };
 
 static int rti_wdt_start(struct watchdog_device *wdd)
 {
 	u32 timer_margin;
 	struct rti_wdt_device *wdt = watchdog_get_drvdata(wdd);
+	u8 reaction;
 	int ret;
 
 	ret = pm_runtime_resume_and_get(wdd->parent);
@@ -101,8 +109,12 @@
 	 */
 	wdd->min_hw_heartbeat_ms = 520 * wdd->timeout + MAX_HW_ERROR;
 
-	/* Generate NMI when wdt expires */
-	writel_relaxed(RTIWWDRX_NMI, wdt->base + RTIWWDRXCTRL);
+	/* Generate reset or NMI when timer expires/serviced outside of window */
+	reaction = RTIWWDRXN_NMI;
+	if (wdt->data->reset)
+		reaction = RTIWWDRXN_RST;
+
+	writel_relaxed(reaction, wdt->base + RTIWWDRXCTRL);
 
 	/* Open window size 50%; this is the largest window size available */
 	writel_relaxed(RTIWWDSIZE_50P, wdt->base + RTIWWDSIZECTRL);
@@ -255,6 +267,8 @@
 	wdd->timeout = DEFAULT_HEARTBEAT;
 	wdd->parent = dev;
 
+	wdt->data = of_device_get_match_data(dev);
+
 	watchdog_set_drvdata(wdd, wdt);
 	watchdog_set_nowayout(wdd, 1);
 	watchdog_set_restart_priority(wdd, 128);
@@ -370,8 +384,17 @@
 	pm_runtime_disable(&pdev->dev);
 }
 
+static struct rti_wdt_data j7_wdt = {
+	.reset = false,
+};
+
+static struct rti_wdt_data am62l_wdt = {
+	.reset = true,
+};
+
 static const struct of_device_id rti_wdt_of_match[] = {
-	{ .compatible = "ti,j7-rti-wdt", },
+	{ .compatible = "ti,j7-rti-wdt", .data = &j7_wdt },
+	{ .compatible = "ti,am62l-rti-wdt", .data = &am62l_wdt },
 	{},
 };
 MODULE_DEVICE_TABLE(of, rti_wdt_of_match);
diff -Naur --no-dereference a/firmware/am335x-bone-scale-data.bin b/firmware/am335x-bone-scale-data.bin
--- a/firmware/am335x-bone-scale-data.bin	1969-12-31 19:00:00.000000000 -0500
+++ b/firmware/am335x-bone-scale-data.bin	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1 @@
+W#d$m$$m$$l$†$l$†d$m$$m$$l$†$l$†
\ No newline at end of file
diff -Naur --no-dereference a/firmware/am335x-evm-scale-data.bin b/firmware/am335x-evm-scale-data.bin
--- a/firmware/am335x-evm-scale-data.bin	1969-12-31 19:00:00.000000000 -0500
+++ b/firmware/am335x-evm-scale-data.bin	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1 @@
+Wd-%d-%+
\ No newline at end of file
diff -Naur --no-dereference a/firmware/am335x-pm-firmware.bin b/firmware/am335x-pm-firmware.bin
--- a/firmware/am335x-pm-firmware.bin	1969-12-31 19:00:00.000000000 -0500
+++ b/firmware/am335x-pm-firmware.bin	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,34 @@
+™éíñõùý•••••••••••••••••É••••••••••••••å•E
Y
�
±
•••Å
Ù
í
)=Qey�¡µÉJhCôÉs`pG0áDð<¹KD›hpG¿ÊD8KD›`pG¿ÊD8KJh›²`pG,áDœKhZ*	ØJëƒëƒ˜h0¿ pG pG¿œ#J$Khhð´#Mð"J/`"NÃóÀp!L"HÃó!JÃó€%7`ÃóÀ#p%pHhJh`S��hÐHI€è0P`˜Dëƒ›hHð¼GiðÑI	h)Ð˜IÄë„dh±T`éçI˜ÄQø$@,öÑáç<áD8áD°™¬˜¨0áD4áDœ¸Oðÿ3´HLIJ#``]øK``pG4áD0áD8áD<áDJhCôÉs`pG0áDJh›²Cê@`pG¿,áDJh#ðÿC`pG¿@áDKJhëƒëƒ|pG¿œKJhëƒëƒX|pG¿œµð×ü$ðÜü F4ð¨ü4,ùÑKöŒJhšBÐÿ÷œÿðrøðòùðþù ð�ü5 ð~üÿ÷¤ÿ ðøOôÉrI ð½ø ½ Fð‚üàç¿¼X$µÿ÷Çÿ0¿ýç¿µÿ÷‘ÿ@¿½¿µÿ÷‹ÿ@¿" ð}ü½è@" ðP¼µÿ÷ÿ" ðrü½è@" ðE¼¿µ$ FðSü F4ðcü4,öÑKöŒJhšBÐðøð›ù ð,ü5 ð)ü ðÜÿ ÿ÷Uÿ@¿½ Fð2ü FðCüæç¼pG¿pG¿pG¿pG¿pG¿2±FÉ²Dø“BûÑpG¿xC!±ø+*úÑFpGøµLF!h
+MI±K«B#`¿Kp¿#` ø½Oê8Fÿ÷×ÿ9Fîç¿ 8µFx8±%Fÿ÷Ûÿø(ùÑ`8½¿øµFxx±i±F<F}à¬B	Ðÿ÷Çÿø(÷Ñàø½Fø½0Fø½¿´K0µh‚°ƒBÚ °½è0@°pGïó…r¶KJhRø  LH`ð>û«FD˜“ðøD
+ ÿ÷—ÿ…óˆ F°½è0@°pG¿T€$”$K`pG¿T-éðO$F‹F'F‘°®Feà(tÐÿ÷rÿ¶FvFøë%(!FòÑ/òÑ;FOð :Fžø— ñ#u¼ñWòè�ßèðÿææææææ æ%.........ææææææææææææææææææææææææææææææPææææææææææUËæææÞË^æcæm|Žæ“Æ\ææ÷æú F°½èð�
+ �Þ#ô€iñÚ�Ú@ñé�ñ#ðÓø ñô€oÐºñ¼¿IôyÊñ
+	ô€^#rF�ø0ŽF
ñSF”FàfF³ûðòû3·Lã\Y±£ña¼ñŒ¿OðOð £ëÛ²´Fø;F*åÑ«óœ“ô€sqF“
+ÐºñÐ›+ðï�›+ðï�ôs“ðE�›ð€	ñ“ð‹�- Lÿ÷“þ›S±ºñÐ›+ðù�›+ð�¹ñðM�0xP±ÿ÷~þø
4(øÑ¹ñ?ôü®›+?ôø®š£ë	¹ñ÷ñ®	ñÿ6>@Fÿ÷dþsùÑLDææ �cçpxCð@.F÷æpxCô€s.Fòæÿ÷Qþ4Õæñc�Ûøñ(�Àò¸�px.FàæpxCô€c.FÛæpxCð€.FÖæpxCôc.FÑæôj@ðc�pxOð0.FÈæ–ø� ñ0©ñ0	(˜¿ôjò¹€.FëŒ	ëLøŸ¬ñ0©ñ0	(óÙHFºñ�¿eFbF•¦æ Cô€S�çÛøñ4ÿ÷ûý³FæpxCð.F“æ˜@ñ3�#ðpxCð.F‰æÞñì€Ø@ñC�"FÛøãÁé#ñaæ �Þæš*@ð�Cô€s �Ûø #ô€iñßæpxCð.FcæÛø�ñ‘¹ñð&�HF“’ÿ÷¬ýš›Õ�B’FØF‚F™¡ë"êâvñÃ€ñÿ;>±ñÿ;@Fÿ÷�ý»ñÿ?÷ÑQFHFÿ÷Âý4DDÝø°æpxCð .F+æÞCô€iñ’€Ú@ñÓ€
+ ñ#ðñÓø ��æ@ñˆ€#ðCð,ç¥ëpFÿ÷˜ý'DïåHÿ÷„ýDÝæHF.FôjOç¿Ä$ô$ð€	AÑ¸ñ0Ð›ƒ±š›+“Ýñÿ9	ñÿ9@Fÿ÷Fý¹ñÿ?÷Ñ›D›+@ðÓ€›+±ºñÐOð	¦æ›ƒ±š›+“Ýñÿ9	ñÿ9@Fÿ÷'ý¹ñÿ?÷Ñ›D0x(?ô¥­Oð	šæ�Ûø ñ+æ›+?ô�®ºñ?ô‹®}æ¸ñ0´ÑpæžëÔšéÔ^çÔ{Õ»ø ñæÛø0ñ`{å
+ Ûø �ñæpxCð.FˆåpxÛø .Fñ�åHFQFÿ÷
+ýñÿ9D>±	ñÿ9@Fÿ÷Õü¹ñÿ?÷Ñ4DÝø°Tå#ô€søævx ñ0¦ñ0	(±Fö¥®0FbF.F]åpxCð.FXå›3“æ›3“æž¹Ô˜·ÔZµÔOð
+*Õ»ù �ñ·å™£ÔZ¡Ô'ÕÛø0ñ€å ßøX�Üæ0 4ÿ÷�üæpxžƒð€vB–.F#å^õg¯›ø ñ’åZõ^¯›ø �ñ‰åXõu¯Ûø0ñpðä!FOð	Îåì$´µƒ°«SøF“ÿ÷Úü°]øë°pG¿þç¿JKšB
ÒÑCD
H!ð1FDSøƒBBøùÑH	IOðˆB¸¿@ø+úÛÿ÷Ç»¿Ä4*Àþç¿þç¿þç¿þç¿þç¿þç¿þç¿þç¿µ ð6ú¹þç ½ñŠA¡õá`pGñŠ@ õáhpG#ABððX¿JB(¸¿0@€ñ`@“@õa@`pG#ABððX¿JB(úó¸¿0J@Bø 0pG€áà#ABððX¿JB(úó¸¿0J@Bø 0pG€âàJhCð`pGíàJhCð`pGíàµ ÿ÷Äÿ ðùûKh`½¿ßDµ ÿ÷¶ÿÿ÷0úÿ÷8ú¨±ÿ÷áúFH¹ÿ÷ëú°¹ÿ÷Dú½è@ ÿ÷�¿ ÿ÷0û½è@ ÿ÷‡¿ ÿ÷¶ú½è@ ÿ÷¿ Fÿ÷,û½è@ ÿ÷w¿¿µ! ÿ÷†ÿ½è@! ð¹»¿µ$ Fÿ÷{ÿ F4ÿ÷‹ÿ4,öÑKöŒ	JhšBÐ½è@ÿ÷º Fÿ÷hÿ Fÿ÷yÿ½è@ÿ÷ý¹¿¼µ# ÿ÷Zÿ½è@# ð�»¿µ$ ÿ÷Pÿ½è@$ ðƒ»¿µ( ÿ÷Fÿ½è@( ðy»¿µ) ÿ÷<ÿ½è@) ðo»¿µ* ÿ÷2ÿ½è@* ðe»¿µ+ ÿ÷(ÿ½è@+ ð[»¿µ, ÿ÷ÿ½è@, ðQ»¿µ- ÿ÷ÿ½è@- ðG»¿µ. ÿ÷
+ÿ½è@. ð=»¿µ/ ÿ÷ÿ½è@/ ð3»¿µ0 ÿ÷öþ½è@0 ð)»¿µ1 ÿ÷ìþ½è@1 ð»¿µ2 ÿ÷âþ½è@2 ð»¿µ3 ÿ÷Øþ½è@3 ð»¿µ4 ÿ÷Îþ½è@4 ð»¿µ5 ÿ÷Äþÿ÷>ùÿ÷Fùˆ±ÿ÷ïù0¹ÿ÷Vù½è@5 ÿ÷¡¾ ÿ÷Bú½è@5 ÿ÷™¾ ÿ÷Èù½è@5 ÿ÷‘¾¿KhhhÛüÔpG¿KhhhÛüÕpG¿KhSø  h#ð`pG¿KhSø  hCð`pG¿KöDKh“BÐKöŒ“BÐpGKJ`pGKJ`pG¿¼�)ˆ&"K`Z`š`Ú`aZapG¿ KöDKh“BÐKöŒ“BÐpG	K	H
+I
+J˜aÙabpGKH	I	J˜aÙabpG¿¼ `)())à)¨)˜)
+Jp´jëAëÁmhTø1›h-hÔÐPf`¥``p¼ pG¿ Kp´Ûi„ˆEyYk˜iÚiÄóÁŒ@Åó@$ê‘@hXh!CÅó€!ê‚@žhÜh
+CÅóÀi"ê @C1±[iÅó�@ ê(Cp¼pG Jy‘ip´Êj
hHhð”@Ãó€$êiMi‚@"CÃóÀŒh"ê¨@ÉhCÃó ê‹@Cp¼pG Kë@jë�Rø0 [h`pG¿ KjëÀChhðpG¿ 
+Kj“è	hhJ@’Ð pGÚh™hhhX@ð¿ pG¿ µDh‰ð¡üÿ÷Yý x˜!¿ðOô€0¿$ÿ÷Uý€ ÿ÷Xý€! Dÿ÷NýKh,Ð½ðSùð£ÿ Fð„ÿ½è@ ð¿¿œ8µ7K7JhFëƒëƒ›|Dh+YÑ(‰ðhüàˆÀó�ðû h.K@³ÀóOðÝú Fÿ÷.ÿF Fÿ÷Xÿ!ÿ÷ÿ!(Fÿ÷ÿðùðùðÍý ðHÿðbÿ#xÛÕKx+³þçFöu ð¹úÚçð¢úKöDKh“BÐKöŒ“BêÑ ÿ÷]ÿ(åÑJ hCð`ÿ÷{þ ÿ÷bþKx+ÙÑ½è8@ ð¿ð›û¢çKh+ßÑÉç¿œþÿ¨¼ áD´8µ"K"JhFëƒëƒ›|Dh‹»(‰ðëû#xÛ(ÕàˆÀó�ð…ú hK@Ó±ÀóOð]ú Fÿ÷®þF Fÿ÷Øþ!ÿ÷�þ!(Fÿ÷‹þðQý ðÌþKx[±þçFöu ðBúãçð+úÓçðFûÊç ½è8@ð¸¾œþÿ¨8µ!K!JhFëƒëƒ›|Dhs»(‰ð�û#xÛ%ÕàˆÀó�ð7ú hK@»±ÀóOðú Fÿ÷`þF Fÿ÷Šþ!ÿ÷Aþ!(Fÿ÷=þðý
Kx[±þçFöu ð÷ùæçðàùÖçðûúÍç ½è8@ðm¾¿œþÿ¨8µKJhFëƒëƒ›|DhS»(‰ðQûàˆÀó�ðîù hK@Ë±ÀóOðÆù Fÿ÷þF Fÿ÷Aþ!ÿ÷øý!(Fÿ÷ôý ð7þ	Kx±þç8½Föu ð¬ùäçð³úÑçœþÿ¨µChØˆÀó�ð¹ù½è@ ð¾8µF lhð ý(‰ð	ûàˆÀó�ð¦ù Fÿ÷×ýF Fÿ÷þ!ÿ÷¸ý(F!ÿ÷´ý#yð+Ð ð„ÿ½è8@ ðí½¿pG¿pµFþ÷Jþ(EÐ(M)L+hëƒëƒÛh+;Ð˜G0Fþ÷ÜþkhxÛÔðDùh‰ð«ú+hëƒëƒ›|C» ðCÿ$ Fÿ÷�û F4ÿ÷­û4,öÑKöŒJhšBÑ Fÿ÷Žû Fÿ÷Ÿûþ÷_ÿðßø ÿ÷pû5 ÿ÷mû½èp@ ð¿þçðGú+hëƒëƒ£|+ÏÑËçœ¼pG¿KöDKµh“B!ÐKöŒ“B!Ðÿ÷»ýF ÿ÷�ý ÿ÷šý ð�ýð“ýð5üðAÿð+ÿ Fþ÷dþð ù½è@ ðo½Kh+ÝÐ ÿ÷¨ü ÿ÷‘üÖç¼´µÿ÷�ýF ÿ÷oý ÿ÷lý ðSýð	üðÿ Fþ÷:þðvù½è@ ðE½¿µÿ÷qýF ÿ÷Sý ÿ÷Pý ð7ýðíû Fþ÷ þ@¿½è@ðY¹¿µÿ÷YýF ÿ÷;ý ÿ÷8ýðÒþð8ý Fþ÷	þðEù½è@ ð½µð=ù½è@ ð½µÿ÷9ýF ÿ÷ý ÿ÷ýðýð°þ Fþ÷éýð%ù ðöü½è@ ð
¼¿KFhAð€q`h›üÔpG$@ßDKFh!ð€q`h›üÕpG$@ßD"µK`Z`ÿ÷Eü½è@ð
¼¿œ
KHhIµJÃó4``hJÃó#`ðHüðþýÿ÷4üðüû½è@ÿ÷¼áD¼´@áD¸J hCô3`pG¿páDJ h#ô3`pG¿páDJhC`pG¿páDOôqKJ`hC`pG¿ßDßDJh#ôs`pGßD8µIKñˆt`d#h+,Ñch+/Ñ#j+2Ñ#i+5Ñci+8Ñ£i+;Ñ£h+>Ñãh+AÑãi+DÑKöŒ9M*hšBGÐ£j+dÑ#k+]Ñãj+MÑKöŒ*hšBPÐ8½! ÿ÷óùch+ÏÐ( ÿ÷íù#j+ÌÐ3 ÿ÷çù#i+ÉÐ- ÿ÷áùci+ÆÐ. ÿ÷Ûù£i+ÃÐ/ ÿ÷Õù£h+ÀÐ* ÿ÷Ïùãh+½Ð, ÿ÷Éùãi+ºÐ2 ÿ÷ÃùKöŒM*hšB·Ñck+´Ð ÿ÷·ùOôqKJ`hC`¨ç0 ÿ÷«ùKöŒ*hšB®Ñ½è8@4 ÿ÷¡¹$ ÿ÷žù�ç# ÿ÷šù–ç¿D¼ßDßD"8µ"K! `ÿ÷�ù( ÿ÷šù) ÿ÷—ù* ÿ÷”ù+ ÿ÷‘ù, ÿ÷Žù- ÿ÷‹ù. ÿ÷ˆù/ ÿ÷…ù0 ÿ÷‚ù1 ÿ÷ù2 ÿ÷|ù3 ÿ÷yù# ÿ÷vù$ ÿ÷sùKöŒM,hœBÐ8½	J h#ôs`ÿ÷dù+h£BóÑ½è8@4 ÿ÷\¹D¼ßDµðÛùð%ùð½ù
Kx±ÿ÷ŠþðŒù ÿ÷Áú ðtú ðqú ðnú ðkú½è@ ðfº˜µ ðzú ðwú ðtú ðqú ðnú ÿ÷�úðIù ð¼üðlù	KxC¹ðùøKöDJhšBÐ½ÿ÷Vþóç½è@ð›¹¿˜¼8µOöÿs˜BÐF ð¿üF ð•üõ ð?ûF
± F8½ ðœü F8½$ F8½¿ÿ÷à¿Kx±æpG¿˜Kx±æpG¿˜KöŒIð´hINMLH	h6hK-h$hh‘B`^`�`Ü`aÑIJ	hhYašað¼pG¿áD¼áDáD@áDDáDHHáDLáDøµÿ÷ËÿKh#¹
Kh;+
ÙJK
O
NMLIH:`2`+`#``ø½
JhCð€S`ëç¿´°ð?‹àÿ@áDDáDáDáDáD‹	 ÿáD8µÿ÷•ÿMKLHIJ+`#```h+Ð+Ð8½Oð`oðbIK``8½%Oðÿ0
JhCô€s`Dø<\Aø@8½¿@áDð?DáDHáDLáD°áDáD`áDKöDKh“BÐKöŒ“BÐpGÿ÷·¿ÿ÷¿¿¼KöDJð´h™BÐKöŒKHh]hLŸh`Þh%`iM‡`.`dhŠBÑšiXiIK``ð¼pGKh+àÑ
Kh;+ÛØIh#ð€S`Õç¿¼HáDáD@áDHáDLáD´°áD !	KF``hAð@`hðAð``h›üÕpG¿áDKh+¿"KJK`pG°áDµ	Kx¹½ ðFû#IJ	h ‹@`½è@ðM»¿™¬”qàDµ	Kx¹½ ð,û#IJ	h ‹@`½è@ð3»¿™¬�qàDKh+ÑJhCðC`pG°áDKh+ÑJh#ðC`pG°áD Jð´h,:Ð#hY7ÐPhÃëÃPø3PëÃ.hJh2C*`Pø3PJi.h2C*`Pø3`�hÍh2h=C*C2`Pø3P
+i.h2C*`Pø3PŽi*h"ê*`Pø3 Íih#ê`KjŠj	jChBüÑTø?ZÈÑð¼pGd#Jðµh.@Ð3hY=Ð¶FUhÃëÃUø4 ëÄhÃiC`j‚jhBüÐUø4 ƒihC`jBjhBüÐUø4i
+h^ø?"ê
+`Uø4pÁh†h:h1C"ê:`Uø4Gi
+h"ê
+`Uø4@h
+h"ê
+`ZÃÑð½¿dKÀëÀZh´ëÁÔjë€ h ðAð!`k˜`h+üÑ]øKpGd
+KÀëÀZhë€›hëÁÐjð)`ÐpGkh+üÐpG¿dKÀëÀ[hëÀCkhÀ²pGd"Kš`Ú`aZašapGdKöDKh“B
+ÐKöŒ“BÐpG	K	I
+JY``pG	JK	IhY`*ñÐJ`pG¿¼d''´p%`%µK„°
ñËéLª#h+´¿ÃóAsÃó�SëƒSø°½¿ü&@áDKöDKh“BÐKöŒ“BÐpGKH	I	JƒèpGKHI	JƒèpG¿¼€d(<(4(Ø(¬(¤(K(hOðSø! h#ð¿CðCð`pG¿€8µF	hJÐFà8¹(Fÿ÷áÿTøK÷Ñ8½8½ ûç¿KhSø 8±hð ñ°ú€ð@	pG€KhSø  h#ðCð`pG¿€KhSø  h#ðCð`pG¿€K Yh»ç€K Yhµç€K ™h¯ç€-éðOOð	FFhJiKÒø€ßø°á³øÀfMgHgI¾øà(ð-ˆ‡°ˆ	ˆ`úŒò£ø�’úŽò’ª²sxø{’‚²’Š²Gê'’ÿ÷%ÿFHFÿ÷áþ-¸¿5/¿;F#­•ûóóëÓrRQñ�€ÿ)@ó�€ÿ!Oô‚r›;ñ�€ÿ+@ó…€ÿ#%OôBOöÿwBH€BM€8+€ øˆ>KAI€€€²x*DÐœFHòkßøø ßøø�ŽFl09Oôzsà;PÐ
ˆíúÔ®øpfxUªø`’²¦©ø 2Fí²ë¬ø°#D®øpøKšB€úÑ5Oôzrtà[Ô:Ðˆ›²ðöÐOöÿrOðÿ0 K€°½èð�®øpr]*ÄÑ ½øPKI€J
€½øPL€½øP%€½ø@€½ø0!ø„<Bø¤Œ°½èð�OöÿrOðÿ0K€°½èð�#€ç!"uç‰²sç›²yç¿°àD¤°àD°°àD´°àD¸°àD(°àD,°àD¬°àD˜°àDhZ5Ðð´F%Jh`¹Wø#@Oöÿr `à:Ð#hÃóC+øÑVø?j\ÐFêçë…
à<¥BÐ(úÑ"hOöÿsWø"`à;ñÐ
+hô@?ùÑ<¥BíÑ ð¼pG pG¿ŒKöDKh“BÐKöŒ“BÐpGKH	I	JƒèpGKHI	JƒèpG¿¼ŒÀ&¨&�&$%%ø$"IOöÿs	hQø 
+`à;Ð
+hô@?ùÑpGŒ#IOöÿr	hQø `à:ÐhÃóC+øÑpG¿ŒKhSø 0hð ñ°ú€ð@	pG¿ŒµK Yhÿ÷\ÿ ½ŒµK Yhÿ÷Rÿ ½ŒµK ™hÿ÷Hÿ ½ŒµK ™hÿ÷>ÿ ½ŒBooted version 0x%x of CM3 PM Firmware. $¤$¬$´$¼$[%08x]%s:   ERR WARN INFO DEBUG0123456789abcdefghijklmnopqrstuvwxyz(null)0x
+	ÿÿÿÿÿÿÿÿLàD(àDÐàDàD¸àDäàDààDÜàDdàD àD`àDàD,àDÿÿÿÿáD€ áDŒàDpàDœàDáD€ áD˜àDHàDTàDáD€ áD”àD4àD@àDˆàD àD,àD�àD\àDhàDàDàD
+	ÿÿÿÿ
ÿÿÿÿ8*ßD �ßD0�ßDh+ßD@+ßD(ŠßD ˆßD@ˆßD¨ˆßD ˆßD ŒßD ƒßDPˆßD8�ßD ”ßDKÀ]¨a�eÿÿÿÿáD€ áDà-ßDä-ßDì-ßDáD€ áD .ßD$.ßD,.ßDáD€ áD -ßD¤-ßD¬-ßD`-ßDd-ßDl-ßD -ßD$-ßD,-ßDÿÿÿÿ
ÿÿÿÿ)ßDƒßD“ßD’ßD�ßD‹ßDˆßDŠßDŒßD�ßD”ßD+ßDÿÿÿÿ

+	ÿÿÿÿàDPàDDàD@àDàDàDàDàDàDHàD,àDàDàDßDßDßDßD	
+
+	@ßD@ßDàDàDàDàD €€@GNUe‚‰â½geÛWÓ…;°¨q2W¸I…¸I…¬ ¥‰¬ ¥‰”ˆ¡ù”ˆ¡ù|=1|=1ÅpÕapÕaXq¡-dY‘€ ƒ ëÔ€üÿêÔƒüßêÔ…üßêÔ€üßêÔ…üßêÔ€üßlog_buf
\ No newline at end of file
diff -Naur --no-dereference a/firmware/am335x-pm-firmware.elf b/firmware/am335x-pm-firmware.elf
--- a/firmware/am335x-pm-firmware.elf	1969-12-31 19:00:00.000000000 -0500
+++ b/firmware/am335x-pm-firmware.elf	2025-10-23 09:30:40.286462238 -0400
@@ -0,0 +1,388 @@
+ELF(4M4 (4*4*4*ÀQåtd™éíñõùý•••••••••••••••••É••••••••••••••å•E
Y
�
±
•••Å
Ù
í
)=Qey�¡µÉJhCôÉs`pG0áDð<¹KD›hpG¿ÊD8KD›`pG¿ÊD8KJh›²`pG,áDœKhZ*	ØJëƒëƒ˜h0¿ pG pG¿œ#J$Khhð´#Mð"J/`"NÃóÀp!L"HÃó!JÃó€%7`ÃóÀ#p%pHhJh`S��hÐHI€è0P`˜Dëƒ›hHð¼GiðÑI	h)Ð˜IÄë„dh±T`éçI˜ÄQø$@,öÑáç<áD8áD°™¬˜¨0áD4áDœ¸Oðÿ3´HLIJ#``]øK``pG4áD0áD8áD<áDJhCôÉs`pG0áDJh›²Cê@`pG¿,áDJh#ðÿC`pG¿@áDKJhëƒëƒ|pG¿œKJhëƒëƒX|pG¿œµð×ü$ðÜü F4ð¨ü4,ùÑKöŒJhšBÐÿ÷œÿðrøðòùðþù ð�ü5 ð~üÿ÷¤ÿ ðøOôÉrI ð½ø ½ Fð‚üàç¿¼X$µÿ÷Çÿ0¿ýç¿µÿ÷‘ÿ@¿½¿µÿ÷‹ÿ@¿" ð}ü½è@" ðP¼µÿ÷ÿ" ðrü½è@" ðE¼¿µ$ FðSü F4ðcü4,öÑKöŒJhšBÐðøð›ù ð,ü5 ð)ü ðÜÿ ÿ÷Uÿ@¿½ Fð2ü FðCüæç¼pG¿pG¿pG¿pG¿pG¿2±FÉ²Dø“BûÑpG¿xC!±ø+*úÑFpGøµLF!h
+MI±K«B#`¿Kp¿#` ø½Oê8Fÿ÷×ÿ9Fîç¿ 8µFx8±%Fÿ÷Ûÿø(ùÑ`8½¿øµFxx±i±F<F}à¬B	Ðÿ÷Çÿø(÷Ñàø½Fø½0Fø½¿´K0µh‚°ƒBÚ °½è0@°pGïó…r¶KJhRø  LH`ð>û«FD˜“ðøD
+ ÿ÷—ÿ…óˆ F°½è0@°pG¿T€$”$K`pG¿T-éðO$F‹F'F‘°®Feà(tÐÿ÷rÿ¶FvFøë%(!FòÑ/òÑ;FOð :Fžø— ñ#u¼ñWòè�ßèðÿææææææ æ%.........ææææææææææææææææææææææææææææææPææææææææææUËæææÞË^æcæm|Žæ“Æ\ææ÷æú F°½èð�
+ �Þ#ô€iñÚ�Ú@ñé�ñ#ðÓø ñô€oÐºñ¼¿IôyÊñ
+	ô€^#rF�ø0ŽF
ñSF”FàfF³ûðòû3·Lã\Y±£ña¼ñŒ¿OðOð £ëÛ²´Fø;F*åÑ«óœ“ô€sqF“
+ÐºñÐ›+ðï�›+ðï�ôs“ðE�›ð€	ñ“ð‹�- Lÿ÷“þ›S±ºñÐ›+ðù�›+ð�¹ñðM�0xP±ÿ÷~þø
4(øÑ¹ñ?ôü®›+?ôø®š£ë	¹ñ÷ñ®	ñÿ6>@Fÿ÷dþsùÑLDææ �cçpxCð@.F÷æpxCô€s.Fòæÿ÷Qþ4Õæñc�Ûøñ(�Àò¸�px.FàæpxCô€c.FÛæpxCð€.FÖæpxCôc.FÑæôj@ðc�pxOð0.FÈæ–ø� ñ0©ñ0	(˜¿ôjò¹€.FëŒ	ëLøŸ¬ñ0©ñ0	(óÙHFºñ�¿eFbF•¦æ Cô€S�çÛøñ4ÿ÷ûý³FæpxCð.F“æ˜@ñ3�#ðpxCð.F‰æÞñì€Ø@ñC�"FÛøãÁé#ñaæ �Þæš*@ð�Cô€s �Ûø #ô€iñßæpxCð.FcæÛø�ñ‘¹ñð&�HF“’ÿ÷¬ýš›Õ�B’FØF‚F™¡ë"êâvñÃ€ñÿ;>±ñÿ;@Fÿ÷�ý»ñÿ?÷ÑQFHFÿ÷Âý4DDÝø°æpxCð .F+æÞCô€iñ’€Ú@ñÓ€
+ ñ#ðñÓø ��æ@ñˆ€#ðCð,ç¥ëpFÿ÷˜ý'DïåHÿ÷„ýDÝæHF.FôjOç¿Ä$ô$ð€	AÑ¸ñ0Ð›ƒ±š›+“Ýñÿ9	ñÿ9@Fÿ÷Fý¹ñÿ?÷Ñ›D›+@ðÓ€›+±ºñÐOð	¦æ›ƒ±š›+“Ýñÿ9	ñÿ9@Fÿ÷'ý¹ñÿ?÷Ñ›D0x(?ô¥­Oð	šæ�Ûø ñ+æ›+?ô�®ºñ?ô‹®}æ¸ñ0´ÑpæžëÔšéÔ^çÔ{Õ»ø ñæÛø0ñ`{å
+ Ûø �ñæpxCð.FˆåpxÛø .Fñ�åHFQFÿ÷
+ýñÿ9D>±	ñÿ9@Fÿ÷Õü¹ñÿ?÷Ñ4DÝø°Tå#ô€søævx ñ0¦ñ0	(±Fö¥®0FbF.F]åpxCð.FXå›3“æ›3“æž¹Ô˜·ÔZµÔOð
+*Õ»ù �ñ·å™£ÔZ¡Ô'ÕÛø0ñ€å ßøX�Üæ0 4ÿ÷�üæpxžƒð€vB–.F#å^õg¯›ø ñ’åZõ^¯›ø �ñ‰åXõu¯Ûø0ñpðä!FOð	Îåì$´µƒ°«SøF“ÿ÷Úü°]øë°pG¿þç¿JKšB
ÒÑCD
H!ð1FDSøƒBBøùÑH	IOðˆB¸¿@ø+úÛÿ÷Ç»¿Ä4*Àþç¿þç¿þç¿þç¿þç¿þç¿þç¿þç¿µ ð6ú¹þç ½ñŠA¡õá`pGñŠ@ õáhpG#ABððX¿JB(¸¿0@€ñ`@“@õa@`pG#ABððX¿JB(úó¸¿0J@Bø 0pG€áà#ABððX¿JB(úó¸¿0J@Bø 0pG€âàJhCð`pGíàJhCð`pGíàµ ÿ÷Äÿ ðùûKh`½¿ßDµ ÿ÷¶ÿÿ÷0úÿ÷8ú¨±ÿ÷áúFH¹ÿ÷ëú°¹ÿ÷Dú½è@ ÿ÷�¿ ÿ÷0û½è@ ÿ÷‡¿ ÿ÷¶ú½è@ ÿ÷¿ Fÿ÷,û½è@ ÿ÷w¿¿µ! ÿ÷†ÿ½è@! ð¹»¿µ$ Fÿ÷{ÿ F4ÿ÷‹ÿ4,öÑKöŒ	JhšBÐ½è@ÿ÷º Fÿ÷hÿ Fÿ÷yÿ½è@ÿ÷ý¹¿¼µ# ÿ÷Zÿ½è@# ð�»¿µ$ ÿ÷Pÿ½è@$ ðƒ»¿µ( ÿ÷Fÿ½è@( ðy»¿µ) ÿ÷<ÿ½è@) ðo»¿µ* ÿ÷2ÿ½è@* ðe»¿µ+ ÿ÷(ÿ½è@+ ð[»¿µ, ÿ÷ÿ½è@, ðQ»¿µ- ÿ÷ÿ½è@- ðG»¿µ. ÿ÷
+ÿ½è@. ð=»¿µ/ ÿ÷ÿ½è@/ ð3»¿µ0 ÿ÷öþ½è@0 ð)»¿µ1 ÿ÷ìþ½è@1 ð»¿µ2 ÿ÷âþ½è@2 ð»¿µ3 ÿ÷Øþ½è@3 ð»¿µ4 ÿ÷Îþ½è@4 ð»¿µ5 ÿ÷Äþÿ÷>ùÿ÷Fùˆ±ÿ÷ïù0¹ÿ÷Vù½è@5 ÿ÷¡¾ ÿ÷Bú½è@5 ÿ÷™¾ ÿ÷Èù½è@5 ÿ÷‘¾¿KhhhÛüÔpG¿KhhhÛüÕpG¿KhSø  h#ð`pG¿KhSø  hCð`pG¿KöDKh“BÐKöŒ“BÐpGKJ`pGKJ`pG¿¼�)ˆ&"K`Z`š`Ú`aZapG¿ KöDKh“BÐKöŒ“BÐpG	K	H
+I
+J˜aÙabpGKH	I	J˜aÙabpG¿¼ `)())à)¨)˜)
+Jp´jëAëÁmhTø1›h-hÔÐPf`¥``p¼ pG¿ Kp´Ûi„ˆEyYk˜iÚiÄóÁŒ@Åó@$ê‘@hXh!CÅó€!ê‚@žhÜh
+CÅóÀi"ê @C1±[iÅó�@ ê(Cp¼pG Jy‘ip´Êj
hHhð”@Ãó€$êiMi‚@"CÃóÀŒh"ê¨@ÉhCÃó ê‹@Cp¼pG Kë@jë�Rø0 [h`pG¿ KjëÀChhðpG¿ 
+Kj“è	hhJ@’Ð pGÚh™hhhX@ð¿ pG¿ µDh‰ð¡üÿ÷Yý x˜!¿ðOô€0¿$ÿ÷Uý€ ÿ÷Xý€! Dÿ÷NýKh,Ð½ðSùð£ÿ Fð„ÿ½è@ ð¿¿œ8µ7K7JhFëƒëƒ›|Dh+YÑ(‰ðhüàˆÀó�ðû h.K@³ÀóOðÝú Fÿ÷.ÿF Fÿ÷Xÿ!ÿ÷ÿ!(Fÿ÷ÿðùðùðÍý ðHÿðbÿ#xÛÕKx+³þçFöu ð¹úÚçð¢úKöDKh“BÐKöŒ“BêÑ ÿ÷]ÿ(åÑJ hCð`ÿ÷{þ ÿ÷bþKx+ÙÑ½è8@ ð¿ð›û¢çKh+ßÑÉç¿œþÿ¨¼ áD´8µ"K"JhFëƒëƒ›|Dh‹»(‰ðëû#xÛ(ÕàˆÀó�ð…ú hK@Ó±ÀóOð]ú Fÿ÷®þF Fÿ÷Øþ!ÿ÷�þ!(Fÿ÷‹þðQý ðÌþKx[±þçFöu ðBúãçð+úÓçðFûÊç ½è8@ð¸¾œþÿ¨8µ!K!JhFëƒëƒ›|Dhs»(‰ð�û#xÛ%ÕàˆÀó�ð7ú hK@»±ÀóOðú Fÿ÷`þF Fÿ÷Šþ!ÿ÷Aþ!(Fÿ÷=þðý
Kx[±þçFöu ð÷ùæçðàùÖçðûúÍç ½è8@ðm¾¿œþÿ¨8µKJhFëƒëƒ›|DhS»(‰ðQûàˆÀó�ðîù hK@Ë±ÀóOðÆù Fÿ÷þF Fÿ÷Aþ!ÿ÷øý!(Fÿ÷ôý ð7þ	Kx±þç8½Föu ð¬ùäçð³úÑçœþÿ¨µChØˆÀó�ð¹ù½è@ ð¾8µF lhð ý(‰ð	ûàˆÀó�ð¦ù Fÿ÷×ýF Fÿ÷þ!ÿ÷¸ý(F!ÿ÷´ý#yð+Ð ð„ÿ½è8@ ðí½¿pG¿pµFþ÷Jþ(EÐ(M)L+hëƒëƒÛh+;Ð˜G0Fþ÷ÜþkhxÛÔðDùh‰ð«ú+hëƒëƒ›|C» ðCÿ$ Fÿ÷�û F4ÿ÷­û4,öÑKöŒJhšBÑ Fÿ÷Žû Fÿ÷Ÿûþ÷_ÿðßø ÿ÷pû5 ÿ÷mû½èp@ ð¿þçðGú+hëƒëƒ£|+ÏÑËçœ¼pG¿KöDKµh“B!ÐKöŒ“B!Ðÿ÷»ýF ÿ÷�ý ÿ÷šý ð�ýð“ýð5üðAÿð+ÿ Fþ÷dþð ù½è@ ðo½Kh+ÝÐ ÿ÷¨ü ÿ÷‘üÖç¼´µÿ÷�ýF ÿ÷oý ÿ÷lý ðSýð	üðÿ Fþ÷:þðvù½è@ ðE½¿µÿ÷qýF ÿ÷Sý ÿ÷Pý ð7ýðíû Fþ÷ þ@¿½è@ðY¹¿µÿ÷YýF ÿ÷;ý ÿ÷8ýðÒþð8ý Fþ÷	þðEù½è@ ð½µð=ù½è@ ð½µÿ÷9ýF ÿ÷ý ÿ÷ýðýð°þ Fþ÷éýð%ù ðöü½è@ ð
¼¿KFhAð€q`h›üÔpG$@ßDKFh!ð€q`h›üÕpG$@ßD"µK`Z`ÿ÷Eü½è@ð
¼¿œ
KHhIµJÃó4``hJÃó#`ðHüðþýÿ÷4üðüû½è@ÿ÷¼áD¼´@áD¸J hCô3`pG¿páDJ h#ô3`pG¿páDJhC`pG¿páDOôqKJ`hC`pG¿ßDßDJh#ôs`pGßD8µIKñˆt`d#h+,Ñch+/Ñ#j+2Ñ#i+5Ñci+8Ñ£i+;Ñ£h+>Ñãh+AÑãi+DÑKöŒ9M*hšBGÐ£j+dÑ#k+]Ñãj+MÑKöŒ*hšBPÐ8½! ÿ÷óùch+ÏÐ( ÿ÷íù#j+ÌÐ3 ÿ÷çù#i+ÉÐ- ÿ÷áùci+ÆÐ. ÿ÷Ûù£i+ÃÐ/ ÿ÷Õù£h+ÀÐ* ÿ÷Ïùãh+½Ð, ÿ÷Éùãi+ºÐ2 ÿ÷ÃùKöŒM*hšB·Ñck+´Ð ÿ÷·ùOôqKJ`hC`¨ç0 ÿ÷«ùKöŒ*hšB®Ñ½è8@4 ÿ÷¡¹$ ÿ÷žù�ç# ÿ÷šù–ç¿D¼ßDßD"8µ"K! `ÿ÷�ù( ÿ÷šù) ÿ÷—ù* ÿ÷”ù+ ÿ÷‘ù, ÿ÷Žù- ÿ÷‹ù. ÿ÷ˆù/ ÿ÷…ù0 ÿ÷‚ù1 ÿ÷ù2 ÿ÷|ù3 ÿ÷yù# ÿ÷vù$ ÿ÷sùKöŒM,hœBÐ8½	J h#ôs`ÿ÷dù+h£BóÑ½è8@4 ÿ÷\¹D¼ßDµðÛùð%ùð½ù
Kx±ÿ÷ŠþðŒù ÿ÷Áú ðtú ðqú ðnú ðkú½è@ ðfº˜µ ðzú ðwú ðtú ðqú ðnú ÿ÷�úðIù ð¼üðlù	KxC¹ðùøKöDJhšBÐ½ÿ÷Vþóç½è@ð›¹¿˜¼8µOöÿs˜BÐF ð¿üF ð•üõ ð?ûF
± F8½ ðœü F8½$ F8½¿ÿ÷à¿Kx±æpG¿˜Kx±æpG¿˜KöŒIð´hINMLH	h6hK-h$hh‘B`^`�`Ü`aÑIJ	hhYašað¼pG¿áD¼áDáD@áDDáDHHáDLáDøµÿ÷ËÿKh#¹
Kh;+
ÙJK
O
NMLIH:`2`+`#``ø½
JhCð€S`ëç¿´°ð?‹àÿ@áDDáDáDáDáD‹	 ÿáD8µÿ÷•ÿMKLHIJ+`#```h+Ð+Ð8½Oð`oðbIK``8½%Oðÿ0
JhCô€s`Dø<\Aø@8½¿@áDð?DáDHáDLáD°áDáD`áDKöDKh“BÐKöŒ“BÐpGÿ÷·¿ÿ÷¿¿¼KöDJð´h™BÐKöŒKHh]hLŸh`Þh%`iM‡`.`dhŠBÑšiXiIK``ð¼pGKh+àÑ
Kh;+ÛØIh#ð€S`Õç¿¼HáDáD@áDHáDLáD´°áD !	KF``hAð@`hðAð``h›üÕpG¿áDKh+¿"KJK`pG°áDµ	Kx¹½ ðFû#IJ	h ‹@`½è@ðM»¿™¬”qàDµ	Kx¹½ ð,û#IJ	h ‹@`½è@ð3»¿™¬�qàDKh+ÑJhCðC`pG°áDKh+ÑJh#ðC`pG°áD Jð´h,:Ð#hY7ÐPhÃëÃPø3PëÃ.hJh2C*`Pø3PJi.h2C*`Pø3`�hÍh2h=C*C2`Pø3P
+i.h2C*`Pø3PŽi*h"ê*`Pø3 Íih#ê`KjŠj	jChBüÑTø?ZÈÑð¼pGd#Jðµh.@Ð3hY=Ð¶FUhÃëÃUø4 ëÄhÃiC`j‚jhBüÐUø4 ƒihC`jBjhBüÐUø4i
+h^ø?"ê
+`Uø4pÁh†h:h1C"ê:`Uø4Gi
+h"ê
+`Uø4@h
+h"ê
+`ZÃÑð½¿dKÀëÀZh´ëÁÔjë€ h ðAð!`k˜`h+üÑ]øKpGd
+KÀëÀZhë€›hëÁÐjð)`ÐpGkh+üÐpG¿dKÀëÀ[hëÀCkhÀ²pGd"Kš`Ú`aZašapGdKöDKh“B
+ÐKöŒ“BÐpG	K	I
+JY``pG	JK	IhY`*ñÐJ`pG¿¼d''´p%`%µK„°
ñËéLª#h+´¿ÃóAsÃó�SëƒSø°½¿ü&@áDKöDKh“BÐKöŒ“BÐpGKH	I	JƒèpGKHI	JƒèpG¿¼€d(<(4(Ø(¬(¤(K(hOðSø! h#ð¿CðCð`pG¿€8µF	hJÐFà8¹(Fÿ÷áÿTøK÷Ñ8½8½ ûç¿KhSø 8±hð ñ°ú€ð@	pG€KhSø  h#ðCð`pG¿€KhSø  h#ðCð`pG¿€K Yh»ç€K Yhµç€K ™h¯ç€-éðOOð	FFhJiKÒø€ßø°á³øÀfMgHgI¾øà(ð-ˆ‡°ˆ	ˆ`úŒò£ø�’úŽò’ª²sxø{’‚²’Š²Gê'’ÿ÷%ÿFHFÿ÷áþ-¸¿5/¿;F#­•ûóóëÓrRQñ�€ÿ)@ó�€ÿ!Oô‚r›;ñ�€ÿ+@ó…€ÿ#%OôBOöÿwBH€BM€8+€ øˆ>KAI€€€²x*DÐœFHòkßøø ßøø�ŽFl09Oôzsà;PÐ
ˆíúÔ®øpfxUªø`’²¦©ø 2Fí²ë¬ø°#D®øpøKšB€úÑ5Oôzrtà[Ô:Ðˆ›²ðöÐOöÿrOðÿ0 K€°½èð�®øpr]*ÄÑ ½øPKI€J
€½øPL€½øP%€½ø@€½ø0!ø„<Bø¤Œ°½èð�OöÿrOðÿ0K€°½èð�#€ç!"uç‰²sç›²yç¿°àD¤°àD°°àD´°àD¸°àD(°àD,°àD¬°àD˜°àDhZ5Ðð´F%Jh`¹Wø#@Oöÿr `à:Ð#hÃóC+øÑVø?j\ÐFêçë…
à<¥BÐ(úÑ"hOöÿsWø"`à;ñÐ
+hô@?ùÑ<¥BíÑ ð¼pG pG¿ŒKöDKh“BÐKöŒ“BÐpGKH	I	JƒèpGKHI	JƒèpG¿¼ŒÀ&¨&�&$%%ø$"IOöÿs	hQø 
+`à;Ð
+hô@?ùÑpGŒ#IOöÿr	hQø `à:ÐhÃóC+øÑpG¿ŒKhSø 0hð ñ°ú€ð@	pG¿ŒµK Yhÿ÷\ÿ ½ŒµK Yhÿ÷Rÿ ½ŒµK ™hÿ÷Hÿ ½ŒµK ™hÿ÷>ÿ ½ŒBooted version 0x%x of CM3 PM Firmware. $¤$¬$´$¼$[%08x]%s:   ERR WARN INFO DEBUG0123456789abcdefghijklmnopqrstuvwxyz(null)0x
+	ÿÿÿÿÿÿÿÿLàD(àDÐàDàD¸àDäàDààDÜàDdàD àD`àDàD,àDÿÿÿÿáD€ áDŒàDpàDœàDáD€ áD˜àDHàDTàDáD€ áD”àD4àD@àDˆàD àD,àD�àD\àDhàDàDàD
+	ÿÿÿÿ
ÿÿÿÿ8*ßD �ßD0�ßDh+ßD@+ßD(ŠßD ˆßD@ˆßD¨ˆßD ˆßD ŒßD ƒßDPˆßD8�ßD ”ßDKÀ]¨a�eÿÿÿÿáD€ áDà-ßDä-ßDì-ßDáD€ áD .ßD$.ßD,.ßDáD€ áD -ßD¤-ßD¬-ßD`-ßDd-ßDl-ßD -ßD$-ßD,-ßDÿÿÿÿ
ÿÿÿÿ)ßDƒßD“ßD’ßD�ßD‹ßDˆßDŠßDŒßD�ßD”ßD+ßDÿÿÿÿ

+	ÿÿÿÿàDPàDDàD@àDàDàDàDàDàDHàD,àDàDàDßDßDßDßD	
+
+	@ßD@ßDàDàDàDàD €€@GNUe‚‰â½geÛWÓ…;°¨q2W¸I…¸I…¬ ¥‰¬ ¥‰”ˆ¡ù”ˆ¡ù|=1|=1ÅpÕapÕaXq¡-dY‘€ ƒ ëÔ€üÿêÔƒüßêÔ…üßêÔ€üßêÔ…üßêÔ€üßlog_bufŠ‡ö‡Üá0*PP�%`GP9Î!	Æolz¯…@5	]N
[xSíMêÕNPQçúRPgSPCVPÿXPYPÍZPO[P`\P¦^P)_P0`PzaPßbPecPìePTjP	p
+³qP
+crPHm6nê
rtcoÎ
rawsçvs
+EwW
+4xs
+Cyy
+–zy
+ß}á
+�~s
+Ìs
+£€ò
+M�ù
+¸‚%
+íƒ%
+h„%ìì6áøš‡Preg‡Q��Eï�Preg�®×]ïÙP”œâ4ìPE!QÿÛ½"$Þ9'.;`$,œ4$ìN0‚ ÿ0œ-o "@œO!.P!9Q"0•Pœ~#ÿP˜�$õŸ%d,œ"©�ÄœZ%id«Z¤³¬Pc­Pj®Pq¯P&ÿ�±ÿÑ&ÿ’0¶'&ÿ´H½1'&ÿÄ`¾J'(ò)Pœ*int"½ÏT,œ&"TxÑœ9å.ù&"Z˜ÒÂ9."&"^°Óè97.K#"`ÈÔ9`.t E€œe+QSÿ€ÛB‰"ŒÞ9�.±"€á”œØæáZÄ,ïãPåÿ”åµ"ž
+è9.+"ë¨œKjëZ>,ïíP_ÿ¨ï(}"²
+ò9‘.¥$°ú%¼œ$åÿ%Øœ-A.§7P/X6œ0€²1²~/q)¢/öZ°/Ô%™/Z¬/º%˜/Â%¨.Ç.‰.0.O.x.L.Ö.9.42jjFÀ‡‡àU*`J£intÿØ0aHm3,VÑ·verhnum hT!·Ÿ"ÎhÇ	Ç~hÝ
+Ç�%«&h4'V
+ÇÀ,*Mda+hlen,hT-h
.MV]	ÇÍD1š»2zŸ4š*5Ýà6hª	ÇÍHôlœ‘iH¸
úÐ
ÛæöPt
ñ
 ü
$
(.-PO4AP5
8(>3]P0J>€P3QX$R
+’TæPt­GH`
+œ´
fªv5,÷9]Äˆˆ+àà,²²)½½’}}²²9¨¨:88(®®‘ÃÃ––	
+ é‡ú‡l–·*`ê±±UJáe“€;0¬	·
+‰ž
$×intÃÐæ±	¸l
+œþ
+ÄîrÖPóP
óxœuæ±¸zP
+Ä0~ÖPóP†ádP"�ìP"
Â&�œÓæ&±Q–Ö®PóPœáÂP"¦ìP"
j/¨Xœºi1±r¸ä
+N!
+Ä´êÖP0²÷5PtºáIPtÎÒ
ØìnPOÞì‚P5ä•P;ô÷©PtúáPtïRœv5,€€œqq*88(²²)}}²²9¥¥(91‡‡z2!%œßf‡O‡ø¾H0[g‹œ‹s‹Pc�Èn%écs”		int
+šQ`%(œ×s×'ret
%R
+Ýšbý‡‚‡<†H0[n	~<<œ~c	~‚f\PwRuwint¬~xœÆstrÆ¶	™Æá
+†>ÓQÌ¦~”.œ(strÆ
Ÿ%s	™Æ 
+®>±9?H‘?v?gg¯Ü‡Ø‡Äx“[–íÄlœílvlí¾fmtô‘t¼%øretí	ap‘d
+ø‘ÂP”$QtRóP2$€$"
+œÝP‘\Q‘`§P:
intQúÂ		)0œBlvl)íPÌíT÷íôtt~èŒ€$dœœïïnno‡Q	‡<V[á>*^^�%`1	R——padRžqR—	retT—
+intQ	BÿÿL	BÿnumB^»B—n	B	C3	pEÿ	cEžž—ïZ—<8œ‡
fmtZ‡)
apZ’–L	`«‘´pa‡´‚	a‡chb—nb—&
+numc^}
+»d—+tmpd—ïh	d—£g	e—Ñ
b	fž¬9	g3Îreth—¼i%¶Š	y%	
+*	>	÷J“	j¥‚R ’áÿÖ4ËLÀaµ ‚RìÏõJehAÔ€]uh‹tFPxeòä€“uò‹	FPxe¢	,W€Éu¢	‹°	FPxeà	9™€ÿuà	‹î	FPxe€
+çÖ€5u‹’
+FPx XF!FóP- @F šF FF!ÐQ"Py!	\<PyQz d	\!p	g\Pô$!€
+\vPyQz"FP0�"ž#Â©$	©%&ž»'» ~(œQ—tœ )fmtQ‡‘p*+apS’‘d+retT—PˆP‘PQ‘T&�0'»$s	;AÄ$" ,nn,``,¦¦,¬¬áO
+‡¨	‡”L÷*`š	È”œc§˜Hœ}Á	©}`Ò	©}ÒÙ,	ç	,	È	,	ò	,	þ	,
+Æ¿¿E~
Ú	\¯­­ª"‡
+‡èN 
+èœ^
+ìœL
+ðœ;
+ ôœ�
+&øœ�
+,üœp
+2œ,
+8œCQ‡p‡(¨*`…°°¬
+QÝ
+9í
+[¦Ç
+ø
+	
+ŽÀ
f.Ñ
+$int¯°œà;	P>
+Cœval,Preg°‹º
+ ,$œ;reg °À
™™.5‡Þ‡0˜	80(œfÏfóf$þmSint`²X(œµÏfMófnþmSq&€(œöÏ&f—ó(f¸þ)mSˆ1¨œÖ3mSà;¸œÖ=mS»£‡	
‡ÈFj	*`øÈœ=
RÐ:oP@ÖEP@int('ä^œ^ì:®PO	ðP	ô[	úf	
q	
|
+
‡îPO
’P2
+"
‡PO(
�'P1
+2
‡:PO8
¨NPtB
‡POJCD
œ˜L
:‡P!V
EP![JX
DœiLáb
:ÎPtj
³âPt
‚
|ˆ
:ÿPtŽ
³Pt
–
|l]œ
œW¤
:FP#®
EP#}d°
œ‘¸
:€P$Â
EP$g
kÄ
œËÌ
:ºP(Ö
EP(x
rØ
œà
:ôP)ê
EP)‰
yì
œ?ô
:.P*þ
EP*€œy:hP+EP+‡œ³:¢P,&EP,9Ž(œí0:ÜP-:EP-V
•<œ'D:P.NEP.E
œPœaX:PP/bEP/,
£dœ›l:ŠP0vEP0ÖªxœÕ€:ÄP1ŠEP1£±Œœ”:þP2žEP2´¸ œI¨:8P3²EP3Å¿´œƒ¼:rP4ÆEP4çÆÈFœ/Ð:¬P5	ÔP	Ø[	Þf	ä|
+î‡äP5ô’÷P2
+þ‡P5�P1‡P5v5,²²)ŽŽ00—õõ˜°°™ååš›88(óó€€œÂÂqq*Q‚
‡Ç
‡�š
+ HHÿ
Ý
`§
œqid%P'!$œ“id!%Pš
'8œÂid'%Pval)HSç
1Pœñid1%Pval3HSö
;h8œ	
+Hv5H
4?)·
O))I‡y‡9*`ê¢¢UJáe“€;0¬	·
+‰ž
$×intÀ¹¹~	$
+PÖ$%	©ëë¹	+
+8!%	Ûë¹
+^)'ø$	ÿ¼‡ñ‡ ¨�*`Q0úR,gS,CV,ÿX,Y,ÍZ,O[,`\,¦^,)_,0`,za,ßb,ec,ìe,Tj,C,T§ŽŸ0"ñ•#,ç$,ý%,«&,Ë',¿(,�),ÿ*,’+, #,,$m-,(ñ.,,÷81¦¼2,3,<4,45,L6,`7,,8,®9,�:, ÿ;,$’<,(#=,,m>,0ñ?,4–BË˜C,qD,oüá,º,‡,,.	var,
+‰,
+),Em,S	valm,	vm,Rg,x	valg,	vg,Ìa,�	vala,	va,å[,Â	val[,	v[,Ît,ç	valt,	vt,¤U,	valU,	vU,ÙO,1	valO,	vO,TI,V	valI,	vI,\z,{	valz,	vz,.¤¬¬	pd¤7À¦,t§,int
1( œ
C2¸Xœ‚?,0œval?,.pd?7M€,@\œî4€înv‚,�Â@ „cÝ�ÒSJ8‡¬nc£üJPi"Ñ.zhˆI> ü†p"B3Ê�,œHœL4�îUv�,vVœ€‘qvfŠ
™äœnpd™7Pž,œ–pdž7¯l²¬0œ$à´¬{¶ó‹Ð•ä ÷{.º‹.•S 
+¢58; TúQ<W ñm@s ¦!Ëˆ"ˆ~Â!x #v5,#;#¢W!sÌ$#× Á#²;#W#xý Á|²‡=‡È*`”ffäÄ²¼€int£8"Ï$÷$Y $˜!$í"$Ç#$1$$'%$­'$ „($$ )$(+$,y,$0‰-$4	92
+2~mœOp%"	dd
+2+eOz`%TvC‡Í‡
 @@ÿ
Ý
`^WW~@tˆ&G¢‡ì‡HŽj
á0*`G79µ!	Æolz¯…@5	]N
[xSíMÑÕN7QÎúR7gS7CV7ÿX7Y7ÍZ7O[7`\7¦^7)_70`7za7ßb7ec7ìe7Tj7pï	³q7	cr7
+HmnÑrtcoµrawsÎvZ	Ew>	4xZ	Cy`	–z`
+
ïß}È	�~Z	ÌZ	£€Ù	M�à	¸‚%	íƒ%	h„%ÓÓ

È
ß…cc¬
+QÝ
+9í
+[¦Ç
+ø
+	
+ŽÀ
f.Ñ
+$intêcáUJáe“€;0¬	·
+‰ž
$×C7þ§Ž”c9äÄ²¼€ 7\ÿ
Ý
Ý!H\œ)4!Óâ#)>$7QRV"n-ËP@<$Q˜t8ßP€|-óQ€ŠCŽN”YPtžYP?
µºP¤üœ©4PÓlâR©Õ‰S7óDT7'ØUc:ÄÎdÞoäz¾Ptì…ÒPtò�åQ0ú�þPuQ1þ›C¦Y,P1N&oJP
+uj,±F¼fP1ZÇyP0`ÒŒP0rYŸP?vÝ
Ñ™ œœÂ4™Ó\â›©·‰œ7ÊD�7ó¾ÎdÞoäz/Ptì…CPtò�VQ0ú�oPuQ1þ¦Y‹P1o P
+uj± Ý,YP?KË<˜œÂ4ËÓâÍ©a‰Î7tDÏ7�Zjdzo€zBPtˆ…VPtŽ�iQ0–�‚PuQ1š¦ªo P
+uj°±¶ÝÂYP?kõÔ„œ²	4õÓ°â÷©TDø7ý‰ù7òüdoz@	Pt…T	Pt �g	Q0(�€	PuQ1.Y“	P1@o¨	P
+ujFÝüXœ
+4Ó.â©OfdpYP1ŒpRœó
+4Órâ!©ž‰"7±D#7Ï|èj
+P3‚Œd’z�
+Ptš…¤
+Pt �·
+Q0¨�Ð
+PuQ1¸óã
+P5ÂYP1¤;Äœ4;ÓP ŽAÈ¼œ4hAcâ!iCcÐþð	iPvü*ŽP15¢Pt&@¶Pt<5ÊPtB@ÞPtFKJVPaPOVaP5`**P;fl"$}„œÙˆˆpœ%
àŠc[¢wª‚ˆP1°‚›P0¶�®P?º˜¾£Â®Æ¹ÌÄæPtÐÏÚ�
P1èÚ
P0#îåP0‰®ø6œÌ
à°cyþw‚g
P1‚z
P0��
P?£¹ Ä³
Pt$Ï.�P1èÊ0.œ[àÌc—6w>‚P1D‚!P0J�4P?N£TÄQPt$^Ïä`0œïàæcµfwn‚�P1t‚°P0x¹|ð‚ÄÖPt†Ï��P1,ú�œ–Ï �P1� 6œÅàcÓ¦w®‚`P1´‚sP0¸˜¼¹ÂÄ™PtÆÏÌ�µP1ÖûP3%ÊÐ&%'v57'¸67'X‡(g)'qˆö'Â�%*wwF*¯¯	G*CC	I*º
+º
+	H*íí,*¢¢+*WW)*//@*]]?*N*ÊÊO*‚‚J*88-*ºº0*QQ<*L*ç
ç
*''*''C*~~3*––)*õõ˜*�*ÀÀ=*FFG*¥¥(*²²
+)*qq
+**}}*²²9*88
+(*¯¯D*llQ*

K***ÌÌ,*ZZ1*		+*ïï.*€€œ*vvA*š
š
*§
§
*��-*ÙÙ4ìó‡‡Øàªá0*PP�%`êÎÎUJáe“€;0¬	·
+‰ž
$×int”ÎäÄ²¼€ P3ÿ
Ý
GP9ª!	Æolz¯…@5	]N
[xS	íMÆ
+ÕNP	QÃ
+úRP
+gSP
+CVP
+ÿXP
+YP
+ÍZP
+O[P
+`\P
+¦^P
+)_P
+0`P
+zaP
+ßbP
+ecP
+ìeP
+TjPpä³qPcrP
HmnÆrtcoªrawsÃ	vOEw34xOCyU–zU
+äPŽvarP‰P)P~u¦=
wÎ&�¾=
ƒÎAAØØCÎWOòØQÎ¾ØœËñØðœ,å²;œTÜç¨D$Lœ¦varFP;HòLýPT\QVÎpœøvXPY\vZ ‚l wl lYÀaÎ„œJvcP‚\Še ‚• w© l‚]l˜œ§!ùlÎ¿vnPà\œp ‚ó w làŽ¬œÄš¦Èœá²//‘Ø8œ@!ì‘ÎS"ŽÂ³,#Âšœ$J)@%P!$V)T%P($b)h%P3$n)|%P-$z)�%P.$†)¤%P/$’)¸%P*$ž)Ì%P,$ª)à%P2$Â)ó%P@$Ú)%P0&î)%P4$ô)/%P$'ü)%P#vÎœœÈ(¦€˜éx)˜²¯$4Œ%P!$$4 %P($*4´%P)$04È%P*$64Ü%P+$<4ð%P,$B4%P-$H4%P.$N4,%P/$T4@%P0$Z4T%P1$`4h%P2$f4|%P3$l4�%P#$r4¤%P$$�4·%P@* 4%P4'ó¬Hœœ	"¾º
+û		#º
++ËÄò²?¶JºUÈ`$Îk@	%P1$ÔvS	%P4$Úvf	%P2$àvy	%P1$ævŒ	%P0*ðv%P3,¯ôdœ…
+-Ø(°Û	)°+åD$ü�î	%P3$�
+%P0$�
+%P1$�'
+%P2$�:
+%P4$ŒM
+%P1—$$¢i
+%P1(­2¸NÃ.F1ÎX:œ1/–1UÓ0n311ret4Î
)È2«7%N$jÎ÷
+%P4$r¢
+%P4$zÙ %Pt€€ 'ˆä%P47H¾˜œ`+Ë òØ¨œ‚+å°3è4PD4v6P¼4¸7P´4§8P¸5X‡5ºŽ%611G6ss86××(6ÃÃ'6CCH6ˆˆ96ö
ö
688	(6²²	)6((
+6’’
+6
+6··
+6ç
ç
6~~36ÙÙ46š
š
666
+6¥¥(6ÎÎ
+6
+
+
+6
+6ll*6¡¡6––)‡L‡�*`ê¢¢UJáe“€;0¬	·
+‰ž
$×intÀ¹¹~	$
+iÖÀ&	©ëë¹	+
+w#¨&	Û
+1,�&	ÛnŽ‡Ò‡¸èäá0*PP�%`êÎÎUJáe“€;0¬	·
+‰ž
$×int	"=
+:#=
+¥$=
+è%=
+¸'=
+(=
+F)=
+Å*=[ô/�Zd
var\PD¸dœ$>lœŸvar?PS"DLˆxœØXÀ@ÎXaŽD’z$œLs
+‚$Œœ#var„PS6�°0œHvarŸPt·¶à œÎ¾4œ‘[�P3&fP3Ê44œÉD[¹P3ZfP3(×hœîvarÙP’æ„œvarèP¥±-ÜHv5P¸6Pö‹ÎÔŒ%�Î¥¥(––)ÚD‡º‡ 8;*`”nnäÄ²¼€int£8*Ï,÷,Y ,˜!,í",Ç#,1$,'%,­', „(,$ ),(+,,y,,0‰-,4	a!M
+Ñ!3var#,ºv ˆœœ
ixn¸*²f{6Ì²fAß	SJ¿
+ÑJ3varL,Z(”œ
+
i�nX œ<à„¨l à³ ~‡¼4œ/Ñ‡3¾ Ù‘ð0œTÑ‘3ß ˆš, œŒÑš3!
valœ,!!s¥8œ¯
i§n9!ˆ­LTœÜº, 8œ÷¯¼‘hÖ½n‰!~n÷£)h/upEdK3,`•Plv5,¸6,/’œ�‡K­e¸¢žÈ‡qØ¢|Ü‡ð‡U*`”ffäÄ²¼€int£8"Ï$÷$Y $˜!$í"$Ç#$1$$'%$­'$ „($$ )$(+$,y,$0‰-$4	92
+2~mžO'"	dd
+2+qOz'T0m‡‡§`*íMGÕNQDúRgSCVÿXYÍZO[`\¦^)_0`zaßbecìeTjpe³qcrHm“nG	rtco+	rawsD
+Çe¸
+‰nep
+0e¬
+O-e 
+x@e”
+LQeˆ
+Öae|
+9~ed
+4‡eX‡º‡Ø üá0*PP�%`…ÔÔ¬
+QÝ
+9í
+[¦Ç
+ø
+	
+ŽÀ
f.Ñ
+$int	P

+varP‰P)PV,0
+reg,Ô
var.Pî5S
+reg5Ô
var7P…>Ôyÿ>Ô
+id>W×ØTœS, (œUc¾!nQøcn
6 A6 $ß!Û< 
+1öëß!0F C<F GSÛF :öëqHÔT &œ¹ÿHÔò!idsH¹B"retJÔy"iKÔÆ"j SPu ¿!W"™Q%|  œûidQWæ"varSP##W^œ œt$id^WP
  `6#  $S#Û¦ 1f#öz#ëS##c¸ œí$idcWP0¼ e<Ž#¼ G«#ÛÂ :¾#öÒ#ë«##¢hÔ œ%Ü UP1#Ìmà œ7%è UP2#�rì œ\%ô UP2&³m€ s!P&­¹„&3¹ˆ'v5P(s°)'˜»!¥(¿Ë)'¦Ö!À',æ!À'cö!¥'B!À'Ø!À/9‡ü‡*`…¨¨¬
+QÝ
+9í
+[¦Ç
+ø
+	
+ŽÀ
f.Ñ
+$intÆ¿¿~	$
+cÜd(	¯ññ¿		+
+B!<(	áñ¿
+Ø/-4(	/¬‡‡z*`…¨¨¬
+QÝ
+9í
+[¦Ç
+ø
+	
+ŽÀ
f.Ñ
+$intÆ¿¿~	$
+˜ÜØ(	¯ññ¿
+	+
+¦!¬(	áñ¿
+,0-¤(	‡B‡ÚC::§Ž`Ÿ0"Þ•#:ç$:ý%:«&:Ë':¿(:�):ÿ*:’+: #,:$m-:(ñ.:,÷81“¼2:3:<4:45:L6:`7:,8:®9:�:: ÿ;:$’<:(#=:,m>:0ñ?:4–B¸˜C:qD:²É`)A#ß()Þ	ûô
+ô~“x4)ääœ‡é‡ø Ô:*`”nnäÄ²¼€into,˜val,˜reg,n		1˜»reg1n
+D6	}=nèret?ni@n	¿NnretPniQn
ÛT˜3bÑbn
ÿdn
™en
©fn
àgnsclhn
%in
jn¡�nø Ôœ¸¶�¸æ#len‘¾o$Ñ’˜Ž$e“ÊX
*”˜
�•˜
 –˜
 —˜
˜˜uü ¦'Œ�Ÿ!0œD¯¬$Ÿ!X�a¯Á$Ÿ!xž~¯Ö$Ÿ! Ÿ›¯ë$Ÿ!À ¸¯%R!è«š&%è1?%<G]%Rp%]Ž%h¬%sâ%uš!Š;Œ?&�T&u¨!0‹]Œh&�u®!ŒŒ}&�V!Ñ^!ÜPyuœ!H®ÀŒ’&�§&u !h±æŒ½&�Ò&»´!ˆ²u´!ˆ9Œç&�ü&uÂ! ÀBŒ'�&'uÈ!¸º`Œ�uÌ!Ð½~Œ�ÃÐ!è¶õèÓ<'Þ]'»Ð!IÞuÐ!9Œ©'�Ë'ŸÔ!@C¯uÒ!XÇŒí'�(»"ÃQu"9Œ<(�Q(è"pÉ×pøf(‡( �£!
Ÿ&"U¯Ó(»0"¨^u0"¨9Œè(�
+)uL"ÈÎýŒ,)�A)uN"èÑ#ŒU)�j)uX"ÒIŒ~)�“)u`"(ÓoŒ§)�¼)uj"Ô•ŒÐ)�å)up"ÕŒù)�*"ÅH#¾[$ÜÜ;$ˆˆ6vi!‡P‡p @@ÿ
Ý
`^WW~@·
t�)GÈ!‡}‡Ì"ŒÀá0*`êµµUJáe“€;0¬	·
+‰ž
$×int•9Ý	reg9µ
+i;µ¤/þ	reg/µ
+i1µkC%	regCµ²HµÌ"|œ»
ÿHµ"*idsH»\*iJµ•*¼Þ"NŽÈË*Þ"Óä*Ý#Ré7+#ôQ+Á>ÃH#Tœ¥Wœ#$œ!idW>PÝœ#@Yé¤+@ôÁ+–\À#(œkid\>P¼À#`^È,`Ó1,la%è# œ¬ida>„,þì#c¥,8kµ$œÕ$P0ïsµ$œþ($P2í{µ0$œ'<$P0	‚µD$œPP$P2IaŒg7?»�e»” v57!g¤" P¯™!Á¿" 8Ê´ ^Ú´ iê™ wú´ 1
+´ª#‡Æ‡ÃC::§Ž`Ÿ0"Þ•#:ç$:ý%:«&:Ë':¿(:�):ÿ*:’+: #,:$m-:(ñ.:,÷81“¼2:3:<4:45:L6:`7:,8:®9:�:: ÿ;:$’<:(#=:,m>:0ñ?:4–B¸˜C:qD:Éà)A¢#ß¨)Þ	ûô
+ô~“2˜)ä%:;I$>I:;(I:;:;
:;I
8	:;
+
:;I8:;
:;I

:;II'I'.?:;'I :;I.?:;' :;I4:;I.:;'@—B:;I1XY411XY1:;I‰‚•B1 .1@—B!1".?:;'@—B#1RUXY$.?:;'I@—B%4:;I&1RUXY'1(‰‚•B)Š‚‘B*$>+41,4:;I-4:;I.4:;I?</4:;I?0I1!I/2.?<n:;%U$>$>:;I:;
:;I8
:;I8I	!I/
+!I.?:;'I@—B4:;I
‰‚1‰‚1Š‚‘B‰‚1.?:;'I‡@—B4:;I?<4:;I?.?<n:;%$>I:;((
$>.?:;' :;I	.1@—B
+1‰‚1Š‚‘B
.?:;'@—B:;I1XY‰‚1‰‚•B14:;I‰‚1.?:;'@—B4:;I?<.?<n:;%.?:;' .1@—B%U:;I$>.?:;'I@—B:;I:;I4:;I	$>
+I&I%:;I$>.?:;'I@—B:;I‰‚1Š‚‘B$>	4:;I
+‰‚1I&I
:;I4:;I4:;I?<.?<n%$>.?:;'I@—B:;I:;I4:;I4:;I	4:;I
+‰‚1Š‚‘B‰‚1
$>I&I:;
I84.?:;'@—B4:;II!I/.?<n:;%$>:;II:;(.:;'I :;I:;I	4:;I
+$>I.?:;'I@—B
:;I4:;I4:;I4:;I4:;I
+:;
+:;
+:;1XY141141‰‚1Š‚‘B1XY1RUXYU ‰‚1!‰‚1"&I#:;$
I84%&I'!I/(.?:;'I@—B):;I*+4:;I,.?<n:;%$>.?:;'‡@—B.?:;'@—B4:;I4:;I‰‚•B1I	4:;I?<
+I!I/
4:;I?.?<n:;%.?:;'‡@—B%$>I:;((
$>.?:;'I@—B‰‚1	Š‚‘B
+.?:;'@—B:;I:;I
.?<n:;%.?:;'@—B:;I4:;I4:;I$>$>.?:;'@—B%$>.?:;'@—B4:;I‰‚1Š‚‘B‰‚1$>	‰‚1
+‰‚•B1‰‚•B14:;I
‰‚•B14:;I?<.?<n:;%I:;($>.?:;'@—B:;I4:;I.?:;'@—B	4:;I
+I&I4:;I?<
I!%$>I:;((
$>I!I/	&I
+4:;I?%$>:;
:;I
8I:;(
:;I8.:;'I 	:;I
+:;I4:;I$>
.?:;'@—B.?:;'I@—B:;I:;I4:;I1RUXY111RUXY1XYI.?:;'@—B:;I1XY411414:;I &I!I"!I/#4:;I?<$!%$>I:;((
$>:;
:;I8	I
+!I/&I4:;I?%I:;($>I!I/&I4:;I?%:;I$>I:;(:;
:;I
8:;	
:;I8
+:;
:;I
:;I
I'I'(
$>.?:;'@—B:;I4:;I‰‚1‰‚1Š‚‘B‰‚•B1‰‚•B14:;I.?:;'@—B:;I4:;I:;I .?:;'@–B!4:;I".?:;'@—B#‰‚1$‰‚•B1%4:;I&&I'4:;I?<(I)!*.?<n:;%:;I$>I:;(I:;(
$>	:;
+
:;I
8:;
:;I8
:;
:;I
:;II.:;'I :;I:;I.?:;' 4:;I.?:;' 4:;I.1@—B41.?:;'@—B‰‚1‰‚•B14:;I.?:;'I@—B1XY 1!:;I"1XY#$‰‚1%Š‚‘B&‰‚•B1'‰‚1(1RUXY)U*‰‚•B1+41,.?:;'@—B-1RUXY..?:;'I@—B/:;I04:;I14:;I24:;I34:;I44:;I?54:;I?<6.?<n:;%$>I:;((
$>I!I/	&I
+4:;I?%:;I$>I:;(I:;(
$>	:;
+
:;I8.?:;' .?:;' 
4:;I.1@—B.?:;'@—B4:;I‰‚1.1@—B4141‰‚•B14:;I.?:;'@—B‰‚1Š‚‘B‰‚•B14:;I4:;I?<.?<n:;%$>I:;((
$>:;
:;I8	.:;' 
+:;I4:;I.?:;'@—B
4:;I1XY1411RUXYU:;I.?:;'I@—B.?:;'@—B4:;I4:;II!I/&II4:;I?<!%$>I:;((
$>:;
:;I8	I
+!I/&I4:;I?%$>:;
:;I
8:;
:;I8:;
:;I	
:;I
+4:;I?%:;I$>I:;(I:;(
$>	.:;'I 
+:;I:;I.:;' 
4:;I.?:;'I .?:;'@—B.1@—B11U111XY4141.:;'I@—B:;I:;I4:;I‰‚1Š‚‘B I!&I".?:;'I@—B#.?:;'@—B$:;I%‰‚•B1&4:;I'4:;I?<(I)!%$>I:;((
$>I!I/	&I
+4:;I?%$>I:;((
$>I!I/	&I
+4:;I?%I:;($>:;
:;I84:;I?&I	I
+!I/%$>I:;((
$>.:;' :;I	.:;'I 
+.:;' 4:;I
4:;I:;I.?:;'I@—B:;I4:;I4:;I4:;I1RUXY11U41411XY‰‚1‰‚1Š‚‘B1RUXY1XY U!41"I#&I$.?<n:;%I:;($>I!I/&I4:;I?%:;I$>I:;((
$>.:;' 	:;I
+4:;I.:;'I .:;'I@—B
:;I:;I4:;I1XY1411XYI&I.?:;'@—B.?:;'@—B:;I1RUXYU.?:;'I@—B‰‚1Š‚‘B4:;I 4:;I?<!I"!%I:;($>:;
:;I84:;I?&I	I
+!I/S2Ÿ2ŸSPóPŸ P (óPŸ8>1Ÿ¾ÎSÎÙœÚ<Sx~5Ÿ<L2Ÿ<L	ÿŸLN3ŸLN	ÿŸNT4ŸNT	ÿŸTV5ŸTV	ÿŸhl2Ÿtv2ŸtvS|†P†�óPŸ‚†S†�P|€1Ÿ†ˆ1Ÿ†ˆP�šPš¤óPŸ˜šSš¤P�”6Ÿšœ6ŸšœPTPtŸ`TP
+óPŸP$óPŸPóPŸ$)P):óPŸ<@0Ÿ@JTJMPMNtŸN”Tx€0ŸQ&óQŸRrŸP$S(,P,4S48sŸ(.0Ÿ.0p s"Ÿ08QP V &P&<V<BPBNTNTtŸ@BPBFTFTUTVóPŸX^P^jWjntŸnvTv~tŸ~‚W‚†tŸX`Q`jqŸ~€qŸ\^P^†WPóPŸ.P.lóPŸ VU:VTVlPPU^@FVFU
+ÈUÈÔVÔâvŸò8UQ,QüVvŸV˜ÞY¼ÊV<HYP,>P>@~”ÿŸFP
+~”ÿŸ
+P\|#Ÿ@BPBF|#ŸFHPHP|#ŸPRPRZ|#ŸZ]PbdPd~|#Ÿ~€P€ˆ|#ŸˆŠPŠ’|#Ÿ’”P”œ|#Ÿœ¦P¦®|#Ÿ®¶P¶ÔYØâYâôPôü|#ŸüP	|#ŸP|#ŸP,|#Ÿ,4P4J|#ŸJLPLP|#ŸP^P^n|#ŸnpPpx|#ŸxŒPŒ“|#ŸÞàPàè|#ŸèúPú|#ŸP|#Ÿ$P$'|#Ÿ8LYÊÖ|#Ÿð<|#ŸdtPtx|0Ÿx‚V‚„P„Ž|#Ÿž¤P¤Ö|#ŸÖØPØÞ|#Ÿè,|#Ÿ®¶0Ÿ¶Ì\Øò\¦®R8L\jp0Ÿp„\
+0Ÿ.@ZhnZ
+Z.8ZLÊZÐðZ
+Z$ZŽžZ¶¾ZÞèZZZ,8Z@‘¤Pn@Ÿè:Ÿ.8‘¤LÊ‘¤ÊÌ:ŸÖ
+‘¤$:Ÿdj@ŸŽž‘¤ž¾:ŸÞè‘¤ø‘¤:Ÿ,8‘¤˜œSœÎ‘ ÎÒSÒ@‘ .8‘ LÊ‘ Öè‘ èðSŽ”‘ ”–S–œ‘ œžSÞè‘ ,8‘ @0Ÿ@‘œ
+0Ÿ
+ä‘œü‘œ$@Y@p‘œpxPxð‘œò²‘œ²ÞVÞ.‘œ8d‘œdjSj†‘œ¢¨S¨‘œ<‘œ<dVdÞ‘œèêPêô‘œôöVö8‘œ@R
+R@]RbîRò	R:RJRRn“R“˜‘¤˜¤RÞôR'R8LR$<Rj€R„ŽR¾ÄRÖÞRèøR@ Ÿ
+ Ÿ
+0Ÿ*W,.1Ÿ.8W
+0ŸQT,ZQZ\T\¢^¢ÙQÙÚtŸÚäT
+tŸ
+T<>ty"Ÿ>@T@]Q]bTb	Q	
+tŸ
+T>Q>JTJ€Q€ÞTÞ"Q".T68T8jQ¸¼t‘œ"ŸÊÖQÖèTè
+Q
+T<Q<dTdÀQÀÞTèQ,T@S
+SÈY@]Sb	S@SJhShnYn“S“˜‘¨˜ªSÞîSîYS'S8LSLPYÊÖYð
+Y
+S$Y$<SdŽSŽ¾Y¾ÎSÖÞSèøSøY$SFP~0.ŸP\r0.Ÿ\˜q0.ŸF˜òÖF˜‘¤F\Z\^R^fSŒ�S�˜RF’‘´Ÿ’”S”˜‘´ŸF\‘´Ÿ\^V^jvŸjV.8VLÊVÖðVŽžVÞèV,8Vj‚S,0Y02V28vŸ8<V¶ºVºÀ[ÀÆ{ŸÆÌ[fjSjnYntyŸtzY¤¨S¨¬Y¬²yŸ²¸YJPYPVyŸV\Y S &s|Ÿ&(SQq€€€Ø{Ÿq€ÀðØ{Ÿ P $p€€€Ø{Ÿ$&p€ÀðØ{Ÿ&(óPŸP(óPŸp Ÿ(óP Ÿ(BPBPóPŸ(Bp ŸBPóP ŸPjPjxóPŸPjp ŸjxóP Ÿ�”0Ÿ”žTž¡P¡¢tŸ¢¶TºÊTp˜P˜ qp„Q„ óQŸ ®P®üóPŸ ¦0Ÿ¦®
+p”3&ÿŸ®äu3&ÿŸ¦®p”3&ÿs$Ÿ®äóP#”3&ÿs$Ÿ¦äsäôóP#”	ÿ$3&ÿŸæôQü
+P
+DóPŸü0Ÿüp”ÿŸS`hPhxóPŸxŽ0Ÿ‚ŽQ„†R–˜PP\óPŸT,0	tÿp"Ÿ\vPvžUžÖóPŸÖàUà*óPŸ*-P-0U0XóPŸr$T*XTž P ÖUà$U0XU¤©Ps2!ŸSXpPpžUžÄóPŸÄÔUÔ×P×ÚUÚôóPŸnàTž P ÄUÚàU¤©PôP:U:ZóPŸZjUjmPmpUpŒóPŸ
+vT:<P<ZUpvU@EPŒ¤P¤ÌUÌðóPŸðúUúýPýUÒ×PÌÎPÎðUP(óPŸpóP#(.P.LULzóPŸ0tTLNPNtURWP€‡P‡VóPŸ<VÎÐ0ŸÐÚTÚÝPÝÞtŸÞT\^P^ŒT¸ºPºàTðòPòT "P"BT`bPbˆT
+q@D$!Ÿ
+Q"	qÿÿÿwŸ"0QR^SdjSž¢Sž¢@=$Ÿ²¶S²¶0Ÿ²¶@=$ŸÀÊPÊÔóPŸÄÆSÄÊPÄÊ
+ÿÿŸàâSôøsÿýŸøSPlóPŸlnPnqDq8óPŸöøS®²sÿýŸ²´S€ŽPŽ´óPŸ´¸P¸ºóPŸ€¤0Ÿ¤¬P¬´T´¶0Ÿ¶ºT”´U"S
+QQ¼ÂSØÞS0ŸS $V$,R.0V0HRHJvJLVL`R`budlSlnrˆœ0Ÿœ¬Sª®Q®´SÂÄQÄÊSØR2P2PóPŸPdPd€óPŸ€†P†˜óPŸ�’pÿŸ˜ž0Ÿž 1Ÿ ¢2Ÿ¢¤3Ÿ¤¦4Ÿ¦¬5ŸsHJ$Ÿ"sHC$Ÿ"&ST^P^|óPŸdhS|ŠPŠšUšœóPŸœžUž P ¢óPŸ|‚Q‚ŠTŠžóQŸž¢T|Š0ŸŠŒPŒ’0Ÿ’šPœžPž¢0Ÿ|Š0Ÿž¢0Ÿ¤¬P¬ÄóPŸ°´p3Ÿ´¸P¸¼pŸÄØp2$€"ÎÒSÎÖ1ŸÎÖ3Ÿàôp2$€"êîSêò2Ÿêò3Ÿ P LTLZVZÄTÄtŸRrŸ"RNTtŸŠœtŸœÔTÆÞRPTtZ¬WœÔW>¤Ÿ>D,ŸDN°ŸNR´ŸRZ¸ŸZ¬w
+ÿÿŸœÔw
+ÿÿŸ`bPblUflUv¤UœÔUz”S ªS”–syŸ–¢SœžSª¬S€‚r{Ÿ‚ŽQŽ’r{Ÿ ¢Q¢¤r{Ÿ¦¨Q¨ªr{Ÿ¢°°Ÿ¢°0Ÿ°¶´Ÿ¶º¸ŸºÀ¤ŸºÀ€ŸÀÂ0ŸÀÂ	ÿŸÂÄ(ŸÂÄ	ÿŸ¤Ÿ†Ÿîò0ŸŠ–	ÿŸäæ
+ésŸæè
+èsŸèò
+ésŸŠ”
+èsŸîò(ŸŠ–(Ÿîò	ÿŸŠ–	ÿŸTœŸ$T$@p@Dœ°àDJNp(Ÿ	ÿŸ8D	ÿŸJN0Ÿ&,
+érŸ,.
+èrŸ.8
+érŸJN
+érŸ.2$Ÿ8D(ŸJN(Ÿ8D	ÿŸJN	ÿŸT`¤ŸT`0Ÿ`d°Ÿ`d‘Ldl´Ÿdl‘Hlr¸Ÿlr‘Drx¤Ÿrx‘Tx€,Ÿx€‘PnPnróPŸrtPt|óPŸBQBpuŸpróQŸr|Q0Ÿ2U2BRr|0Ÿs2$w"0Ÿ1Ÿ @<$rŸ "
+ÿÿrŸ",@<$rŸLXt2$w"LX0ŸXZ1ŸZ\@<$sŸ\^
+ÿÿsŸ^l@<$sŸÐàp2$Œ"Ðà0Ÿàâ1Ÿâä@<$sŸäæ
+ÿÿsŸæî@<$sŸôp2$Œ"ô0Ÿ1Ÿ@<$rŸ
+
+ÿÿrŸ
+@<$rŸ&P&<óPŸ&p2$Œ"Ü$Žôl`
+Øl–ü9(<†‚Äx5<V¨”L�è;(‚0˜»ÈFz#�Ï$ü% ¨ÿ-/ù/HŽBØàðN
P¸èS 8]WÝX[Ø -``a“bªdø Ô’klÌ"Œp8:<>xz|~z|~€œž®°¬®²´<@DFJLBDLNFHRTHJTVô``j<DHJ\ ¢¤¦ªÚÜäªÚÜäÚÜäôüþ¨ª¬´PVhnŒ¦ª°œØÜTVXZ^n8<48<>"&>D*,DFLN .0NR "02RTXZZ¤¬²´ºÞäœÔ¢¤¬°°²´¶¤¨º¼¾À¨¬²´ÀÂ¼¾ÂÄÊÐÐÔöúÔØþØÚÜÞäòŠŽ’–ØÚîòŠŽ’–ÜÞèêÚÜ&<@DJN&*.88<@DJNTVZ\^`VZ\^bd`bdhjlhjlrÐÒÔØÚôôöøüþQvû
src/sys_execsrc/includemsg.cmsg.hprcm_core.hpm_state_data.hstddef.hsync.héÓ./µ.“Jâ.KQ†s q  |\œ#j_!J
 =">!P.1 -";O ).W *  r 
 "&//1Yu /JwIäB>.B Ãf½.Ã.“±Ó./µ.ÐJ§Ý.!«.ÚX�ç./¡ éXuwu^û
src/sys_exec/home/a0274052local/toolchains/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/includesrc/includesys_init.cstdint.hrsc_table.hprcm_core.hcm3.hmsg.htrace.hsync.hdebug.hô
+ 22!-2j0001=>3>ke.	`Ç'2¿mû
src/sys_execsrc/includesync.cmsg.hcm3.htrace.hprcm_core.hhwmod.hl!/Az /
+ >-@!1>-N$"=#+5k01=CJ<=$.=f@+û
src/sys_exectrace.c!X>û
src/libsrc/includestring.ctypes.hK-11…u<û
src/libsrc/includeputs.ctypes.h<	!!"$!","0z.	Ö "=-[1 "t/-w„Vû
src/libsrc/includedebug.cprintf.hputs.h<built-in>Ä%%%/ sX?Ÿ!"!>?0!ÙØcû
src/libsrc/includeprintf.cputs.hstring.hstddef.h<built-in><Ú
.s .t  =0+�.	tÖaª~Jô  /0= ‚</=0¨~.°gó>ÓJX=LMY",>2!1.=MMM/-03JJ•~t=;ì.¸~.ù ?„.ý ˆ.)&(/!"=K!l<Dx.	 0u. v.,# Yc.#.-0\‚" K-0I$Ð‚>´.K>.C.> "==¾.Ç.>=¶�× 2K3y &-//0�.ä "ó.</"Lò~.Y;�<I!z J�.ò   ¡ ß.0K�‚2=/“<_y (j ç~X\ ±�<</ª~XK;×</N‰.�~XK;ä<0ð~tï Xy�SJ000/IXÇt—.é ŸJF.<g. Ó<ð~J�.ð~ =;’<x x<E<0;!:^ Ä<¼.ª.LjJ000K•.ë ®<00/tÔ<!Ü~J/j.Œ.=X=“.í ²<=‡º<A!2S/û
src/foundationstartup.c”È_.¼,",	 
�
V:û
src/foundationexception_handlers.cè4444444dHû
src/foundationsrc/includertc.cclockdomain.h!]1jYV+û
src/foundationcm3.c0„r"O„0•„0•/0N/0,�û
src/foundationsrc/includeext_intr_handlers.ccm3.hpm_handlers.hmsg.hsync.hprcm_core.hÈ"=A/]!>0CMA2-v<<-s<<-y<D-O!>-O$"=#+3l-*=@-]!>-O!>-O!>-O!>-O!>-O!>-O!>-O!>-O!>-O!>-O!>-O!>-O!>-O!>-O!>-O!>4?B2-y<D-u<<-›lû
src/pm_servicessrc/includeldo.cprcm_core.hldo_335x.hldo_43xx.hldo.h>=M>=MY/\Y/\hYH
PJû
src/pm_servicessrc/includehwmod_335x.chwmod.h7�û
src/pm_servicessrc/includepowerdomain.cio.hmsg.hpowerdomain.hprcm_core.hpowerdomain_335x.hpowerdomain_43xx.h (=!!!!\jY/!!!z./!!!	."//-!!/!!#:fu u  !“ ×t© ×J© ótMn k  (Ÿ[Úgfv/-!"V/"XNHû
src/includesrc/pm_servicesdpll.hdpll_335x.cLFû
src/includesrc/pm_servicesldo.hldo_335x.c<Áû
src/pm_servicessrc/includepm_handlers.cmsg.hclockdomain.hhwmod.hpowerdomain.hdpll.hldo.hprcm_core.hrtc.hcm3.htrace.hstddef.hH!!#?0&z !Ah>LZ11	<y.f&z<&S%1>[KNKA?M010>1<UJX0fLZ$">/AN-H<'<<%7%T$#??[KNK??M0>pJxXz< <#+ž%7%T$#??[KNK??M0rJxXz<<#+²%7%T$#>[KNK??L>sXvX¬#i-@ %$0>ZK??LY?-O4 	 K�2">K0>	ta<$ =",4g=?01=@-`J5ä.9#<P>=>>0000>1-g<L= ‚#>=>>00>1-
+J#>=>>0?#-	<#>=>/0>1-C!1-	<#>=>00>0?-â¶û
src/pm_servicessrc/includeprcm_core.cio.hhwmod.hdpll.hldo.hmsg.hpowerdomain.hclockdomain.hcm3.hddr.hi2c.hstddef.hØÀ$">=>$">=á}<!/"0-\"#&/!"!L///0-¿'y @ Ä.#M'y µ Ï.#Mª.Ú<\?#!†1	f!#+#M????????f???Mf>=>=>=>=>=>=>=>=>f=H<?#!Ê<>Z-z<G
Èz &##/=============>žtä œ #á<1@+–!00Ì.¸X0>===>-\!====>>1><.H<0 -t$YK=Y%*@u. [‚PJû
src/pm_servicessrc/includehwmod_43xx.chwmod.hSgû
src/pm_servicessrc/includeddr.cprcm_core.hmsg.hhwmod.hstddef.h¸/y.!'z !"!"z ""!"y !!"!"!!!!"L#1<`$!#!&u.!#!&o.//‚#1/!!"!!!"D>4z.&z &v.!)//"/XhY,^8$<y.=/$$"!">/!"m.KL/0f# p ##!?"/-!#=N?,0”!M>L1-”!M>L1-•L//kL//pû
src/pm_servicessrc/includedpll.cdpll.hprcm_core.hdpll_335x.hdpll_43xx.h ö#¬tu/#/!!#/-!/#/!!#/!/#/!/[6<LN#L‚u/?@/!!?@/" _./#/-!=#/!/#/!/ kI!ge%=[ :">x‡M¢kY/!)/!/	 !![(x !"?0/	NHû
src/includesrc/pm_servicesdpll.hdpll_43xx.cQKû
src/includesrc/pm_servicesmsg.hpm_state_data.c û
src/pm_servicessrc/includeclockdomain.cio.hprcm_core.hclockdomain_335x.hclockdomain_43xx.hstddef.hclockdomain.hØjY/!zJ/! J!%j.h<#t M #X!;M)D[#u?P.h<J2XT._<#J.Xjj\Vû
src/pm_servicessrc/includeclockdomain_43xx.cclockdomain.h\Vû
src/pm_servicessrc/includeclockdomain_335x.cclockdomain.h\Vû
src/includesrc/pm_servicespowerdomain.hpowerdomain_43xx.c2Bû
src/pm_servicessrc/includei2c.cdpll.hø �ž.â. s ˜ è ˜.ð��.Ý £ ð.� )3õX‹<õJ‹.: ><>H"/=>h!>¨J†ú~<•Ó ¼<q. k.Œ.ô~.�.ô~ ˜.è~<™X-è~ ˜ ’f)`.#.X<œ.ä~.«.Õ~<†.ú~<¨X1Õ~<‰.÷~.«.«<)LFû
src/includesrc/pm_servicesldo.hldo_43xx.cÿ€û
src/pm_servicessrc/includehwmod.cprcm_core.hhwmod_335x.hhwmod_43xx.hstddef.hhwmod.hÌ"È93;o h/J¾//` h/J3G‚jY/!zJ/!8JZ' Y '.Y L/)f_" ^ ".^ L/$‚b.</˜"[M"[M![M![\Vû
src/includesrc/pm_servicespowerdomain.hpowerdomain_335x.cCMD_ID_CPUIDLE_V2cmd_datapd_mpu_ram_ret_statemsg_cmd_read_idCMD_ID_DS2_V2CMD_ID_STANDBY_V2a8_reset_handlercmd_handlerssizetypeGNU C11 5.3.1 20160113 -mcpu=cortex-m3 -mthumb -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g -O2 -fno-delete-null-pointer-checks -fno-strict-overflow -fno-exceptionsCMD_ID_STANDALONEcmd_idspd_mpu_l2_ret_stateparam2param3param4CMD_ID_CPUIDLE/home/a0274052local/git-repos/amx3-cm3m3_firmware_versiondebug_haltpd_mpu_l1_ret_stateboolcmd_stat_valuemsg_cmd_is_validmsg_cmd_dispatcherdeep_sleep_datapd_per_icss_mem_ret_statevdd_mpu_valds0_data_hsCMD_ID_VERSIONinit_m3_state_machinemsg_cmd_stat_updatea8_version_handlersoc_typemsg_cmd_needs_triggerCMD_ID_RTC_FASTds2_datastate_handlerrtc_datasrc/sys_exec/msg.cCMD_ID_RTCCMD_ID_RESETCMD_ID_INVALIDds0_dataidle_datai2c_sleep_offsetreservedCMD_ID_STANDBYCMD_ID_DS0_V2pd_per_ocmc_ret_statefalsei2c_wake_offsetpd_per_stateparam1io_isolationrtc_mode_datartc_timeout_valmsg_cmd_fast_triggermosc_statevtt_gpio_pinshort unsigned inttrue_Boolpd_per_mem_ret_statecmd_idds1_data_hscmd_global_datado_ddrCMD_ID_DS0CMD_ID_DS1CMD_ID_DS2msg_writemsg_readcmd_handlerCMD_ID_DS1_V2m3_param_reseths_datavtt_togglepd_per_ocmc2_ret_statemem_typepd_mpu_statedeep_sleepmsg_cmd_wakeup_reason_updateidle_v2_datacustom_state_dataCMD_ID_COUNTres1res2wakeup_sourceds1_datagp_datastandby_datadebug_printfshort intmainnvic_disable_irqa8_notifyam335_inituint8_tscr_enable_sleeponexitrsc_tablong long intnamesrc/sys_exec/sys_init.ccm3_trace_hdrnvic_enable_irqunsigned charlong long unsigned intuint32_tsoc_idtrace_initscr_enable_sleepdeepfw_rsc_hdrsetup_socpm_resetbasefw_rsc_tracecm3_resource_tablecm3_tracehwmod_ida8_m3_low_power_syncHWMOD_COUNTHWMOD_OTFA_EMIFHWMOD_OCPWPHWMOD_L4FWHWMOD_L3_INSTRHWMOD_EMIFHWMOD_CLKDIV32KHWMOD_GPIO0nvic_clear_irqHWMOD_L3HWMOD_MPUHWMOD_I2C0HWMOD_OCMCRAMHWMOD_L4HSHWMOD_L4LSa8_m3_low_power_fastHWMOD_ENDHWMOD_EMIF_FWtimer_syncsrc/sys_exec/sync.cHWMOD_IEEE5000src/sys_exec/trace.ctrace_set_current_possize_tsrc/lib/string.cstrlenmemsetputchar_logbuf_endsrc/lib/puts.c_logbuf_startmaxlenputsnputslogbuf_posflags__va_listdebug_levelsrc/lib/debug.clevelsvprintfdebug_idxdebug_set_level__apksprintnupperhandle_signput_padstophandle_nosignnbufsrc/lib/printf.cpadcdwidthlenphex2ascii_datapercentreswitchnumberdummy_handlersrc/foundation/startup.cpulsrc_end_textpuldestvector_table_end_stack_start_data_end_datasrc/foundation/exception_handlers.cpendsv_handlerbusfault_handlermemmanage_handlerhardfault_handlerdebugmon_handlersvc_handlerusagefault_handlernmi_handlerCLKDM_L3S_TSCrtc_reg_readCLKDM_L3SCLKDM_COUNTCLKDM_CLK_24MHZCLKDM_EMIFCLKDM_L4FWCLKDM_CPSWCLKDM_LCDCCLKDM_L4HSCLKDM_ENDCLKDM_WKUPCLKDM_DSSrtc_reg_writeCLKDM_MPUCLKDM_ICSSCLKDM_RTCsrc/foundation/rtc.cclkdm_idCLKDM_L4LSclkdm_activeCLKDM_L3rtc_enable_checkCLKDM_OCPWP_L3irq_noscr_regsrc/foundation/cm3.creg_offsetirq_regextint43_handlerextint44_handlerextint31_handlerextint45_handlerextint33_handlerextint34_handlerextint35_handlerextint36_handlergeneric_wake_handlerextint50_handlerextint51_handlerextint52_handlerextint49_handlerextint53_handlerextint16_handlersrc/foundation/ext_intr_handlers.cextint48_handlerreg_valextint47_handlerextint46_handlerextint40_handlerextint41_handlerextint42_handlerldo_power_upldo_wait_for_onam43xx_ldo_regssrc/pm_services/ldo.cLDO_COUNTldo_power_downldo_initLDO_CORELDO_MPUam335x_ldo_regsldo_idldo_wait_for_retam335x_essential_hwmodsam335x_hwmodsam335x_interconnect_hwmodssrc/pm_services/hwmod_335x.cpowerdomain_regsPD_MPUicss_retst_shiftl1_retst_shiftper_powerst_changestctrl_next_valsrc/pm_services/powerdomain.cam335x_pd_regsper_retst_shiftverify_pd_transitionpowerdomain_initmpu_ram_ret_state_changepwrst_maskam43xx_pd_regspwrstst_prev_valstctrlpd_mpu_bitsl2_retst_shiftstctrl_prev_valget_pd_mpu_stctrl_valresultram_retst_shiftpd_per_bitsget_pd_per_stctrl_valam335x_mpu_bitsbit_valpowerdomain_resetpowerdomain_idocmc_mem_ret_state_changeverify_pd_transitionspd_state_changelogicretst_maskam335x_per_bitsam43xx_mpu_bitspd_statesper_mem_ret_state_changeicss_mem_ret_state_changelpstchg_shiftpd_state_restorepd_read_stateicss_retst_maskram1_retst_maskram2_retst_maskmpu_powerst_changepowerdomain_statelpstchg_maskPD_PERram_retst_maskmpu_l2_ret_state_changeper_retst_maskl1_retst_maskmpu_l1_ret_state_changepwrst_shiftl2_retst_maskam43xx_per_bitsvar_modlogicretst_shiftram1_retst_shiftocmc2_mem_ret_state_changeram2_retst_shiftpwrststidlest_regpgoodout_status_bitret_bitponout_status_bitDPLL_COREDPLL_COUNTiso_bitdpll_pwr_sw_ctrl_regDPLL_DDRreset_bitsw_ctrl_dpll_bitclkmode_regDPLL_DISPDPLL_PERponin_bitpgoodin_bitsrc/pm_services/dpll_335x.cisoscan_bitam335x_pg2_power_down_pllsDPLL_ENDclksel_regdpll_idam335x_dpll_regsdpll_pwr_sw_status_regDPLL_MPUsrc/pm_services/ldo_335x.ca8_wake_ds2_handlera8_cpuidle_handlera8_wake_standby_handlerds_saveconfigure_wake_sourcesa8_i2c_wake_handlerplls_power_upwakeup_reasonclear_wake_sourcesper_stclkdms_standby_wakea8_standalone_handlera8_lp_ds0_handlerclkdms_waketempa8_lp_rtc_handleressential_hwmods_enableclkdm_waketimeouta8_lp_ds1_handlera8_wake_cpuidle_handlermpu_sta8_lp_ds2_handlerconfigure_deepsleep_counta8_i2c_sleep_handlera8_cpuidle_v2_handlerclkdms_sleepds_restoreplls_power_downhalt_on_resumea8_wake_ds0_handlerinterconnect_hwmods_disableinterconnect_hwmods_enablea8_wake_rtc_handleressential_hwmods_disabledisable_master_oscillatora8_standby_handlerpll_bypassa8_wake_ds1_handlera8_wake_cpuidle_v2_handlersoc_revenable_master_oscillatorpll_locklocal_cmdsrc/pm_services/pm_handlers.cddr_io_resumeclear_ddr_resetset_ddr_resetvtp_enableprcm_enable_isolationprcm_disable_isolationdmemdpll_resetenable_iodpll_initddr_io_suspendi2c_writewas_enabledvtp_disablehwmod_initvtt_highclockdomain_initcmd_wake_sourcesds_countsrc/pm_services/prcm_core.cvtt_lowdisable_ioam43xx_interconnect_hwmodssrc/pm_services/hwmod_43xx.cam43xx_hwmodsam43xx_essential_hwmodsddr_am437x_io_suspendcmd1_ioctrlio_ctxdata0_ioctrldata3_ioctrlsrc/pm_services/ddr.ccmd2_ioctrlddr_io_save_contextdata1_ioctrlddr_io_contextddr_am335x_io_suspendcmd0_ioctrldata2_ioctrldpll_power_updpll_power_downam43xx_power_down_pllsdpll_get_divpll_modeam43xx_dpll_regsxtal_freqssrc/pm_services/dpll.cdpllindexget_master_xtal_khzsrc/pm_services/dpll_43xx.csrc/pm_services/pm_state_data.cam335x_standby_clkdmsam43xx_sleep_clkdms_clkdm_sleepam43xx_clkdmsclkdms_state_changeclkdm_state_changeam335x_clkdmsam335x_sleep_clkdmssrc/pm_services/clockdomain.cam43xx_standby_clkdms_clkdm_wakeupsrc/pm_services/clockdomain_43xx.csrc/pm_services/clockdomain_335x.csrc/pm_services/powerdomain_43xx.corig_sysci2c_reg_writei2c_wait_for_bborig_irq_enn2_divorig_pscper_clkoutm2sequencei2c_wait_for_ardyspeed_khzstati2c_fclksrc/pm_services/i2c.cxtal_freqi2c_reg_readorig_sclhorig_scllorig_coni2c_program_freqi2c_ack_allsrc/pm_services/ldo_43xx.c_hwmod_is_enabledsrc/pm_services/hwmod.c_hwmod_disable_hwmod_enablehwmods_state_changesrc/pm_services/powerdomain_335x.cGCC: (Linaro GCC 5.3-2016.02) 5.3.1 20160113A6aeabi,Cortex-M3
+M	
+"ÿÿÿÿ|
,0@Pd,$�ÄE„…†‡k
+ÇÆÅÄAT,C„HÄ€”¨¼Øÿÿÿÿ|
ôlA„Ž`
+AƒŽÿÿÿÿ|
Dl
+AƒŽDxAƒŽHÎÃD�AƒŽGÎÃD¨XA„ŽDÿÿÿÿ|
ÌÌÌÌÿÿÿÿ|
(ÿÿÿÿ|
L<<Aƒ„…†‡ŽLxAƒ„…ŽL”.Aƒ„…†‡Žÿÿÿÿ|
D¸ÄlA�‚ƒB„…ŽB D
+BÎÅÄAÃÂÁA\BÄÅÎAÁÂÃ¸0ÿÿÿÿ|
, <8B$„	…†‡ˆ‰Š‹ŽEh|
+$B0 tA€�‚ƒAŽA HBÎAÃÂÁÀÿÿÿÿ|
”””˜Hÿÿÿÿ|
ÄèÄìÄðÄôÄøÄüÄÄÿÿÿÿ|
TAƒŽTT$ÿÿÿÿ|
œ0(œX(œ€(œ¨œ¸ÿÿÿÿ|
üÈAƒŽ0üä^A„ŽS
+ÎÄCE
+ÄÎCE
+ÄÎCEÄÎüD
AƒŽEÎÃ üX
DA„ŽR
+ÎÄBHÄÎüœ
AƒŽEÎÃü°
AƒŽEÎÃüÄ
AƒŽEÎÃüØ
AƒŽEÎÃüì
AƒŽEÎÃüAƒŽEÎÃüAƒŽEÎÃü(AƒŽEÎÃü<AƒŽEÎÃüPAƒŽEÎÃüdAƒŽEÎÃüxAƒŽEÎÃüŒAƒŽEÎÃü AƒŽEÎÃü´AƒŽEÎÃ(üÈFAƒŽO
+ÎÃCE
+ÃÎCEÃÎÿÿÿÿ|
hh$h8hPhh8ÿÿÿÿ|
È È¸XÈ0B„…†QÆÅÄÈ@\B„…†iÆÅÄÈœHD„…†]ÆÅÄÈäÈÈ0ÿÿÿÿ|
ˆH\A„ŽgÎÄ$ˆ¤üAƒ„…Žc
+ÎÅÄÃC ˆ œAƒ„…ŽCÎÅÄÃ ˆ<˜Aƒ„…Ž@ÎÅÄÃˆÔ„Aƒ„…ŽˆXAƒŽHÎÃ ˆpRAƒ„…ŽeÎÅÄÃˆÄ$ˆÈ¼A„…†ŽH
+ÎÆÅÄCˆ„ˆˆpD„Žb
+ÎÄCˆø6A„ŽWÎÄˆ0.A„ŽTÎÄˆ`0A„ŽTÎÄˆ�AƒŽDÎÃˆ 6A„ŽWÎÄÿÿÿÿ|
t
+Øt
+ðt
+BƒŽGÎÃt
+$LE„ŽUÎÄt
+pt
+„t
+˜t
+¬t
+È$t
+Ø8Aƒ„…Ž‡
+ÎÅÄÃC t
+œBƒ„…ŽCÎÅÄÃt
+¬HAƒŽ^ÎÃt
+ôdAƒŽjÎÃt
+X:Aƒ„…Žt
+”t
+˜t
+¨ÿÿÿÿ|
 ü¸dD„…†‡ZÇÆÅÄülAƒ„…†‡ŽüˆxAƒ„…Žü$$ü$ŒD„…†‡]
+ÇÆÅÄAü°0üà ü4AƒŽPÎÃü44AƒŽPÎÃühü„ÿÿÿÿ|
 
 ˆB„…†‡ÇÆÅÄ
(”B„…†‡Ž
¼4E„RÄ
ð0
 
8
LT
 8A„ŽBSÿÿÿÿ|
ì
ØTì
, (ì
T &Aƒ„…Žì
|  ì
œ ì
¸ ì
Ô ì
à ì
ì ÿÿÿÿ|
8˜ø ÔB$„	…†‡ˆ‰Š‹ŽU@Œ
+$B^
+$BG
+$Bÿÿÿÿ|
 äÌ"|D„…†‡tÇÆÅÄäH#Täœ#$äÀ#(äè# ä$AƒŽä$AƒŽä0$AƒŽäD$AƒŽ.symtab.strtab.shstrtab.text.data.resource_table.bss.aux_data.logbuf.debug_info.debug_abbrev.debug_loc.debug_aranges.debug_ranges.debug_line.debug_str.comment.ARM.attributes.debug_frameÄ	
+
ñÿ”ÅÔà¤ñÿ!(,4-<@LP\dˆ� Tp€�”¤¨¸¼ÐØìEWñÿôX`ÄX$bñÿlüTiñÿÜqñÿ,zñÿ<lx�\ŒñÿÄ 08€$”€$T›T”$§È±ñÿ<Ž>€	ˆ	ptÄ$ºÄ$%ì$0ÉñÿèÔÞñÿdäñÿ0|€¤¨´¸Ä¬êñÿÈàä˜
œ
þñÿ $48LPdh�x
ñÿø$ñÿ ´¸ð<@˜œàäüD ( 28;<D@ØLñÿ`%Xñÿˆ&cñÿH ¤„ ,<ÄÔHXx„ðø˜qñÿØ}Ùìðšñ $\p€„”˜¨¬ÀÈÔØ ¬ðôPX¤¨´D¸D„
+Éñÿ�&Öñÿ¸ø\ˆÜ $ˆ°Üàô(4\h|„˜HÜHãñÿ $(¸¼ìð 48HL„ Ðü&dêdúhl,

ñÿ'ñÿX)ñÿØ , P T 7U &˜ œ ´ ¸ Ð Ô Ü à è ì ô €K€R„_ˆü
nñÿ4(�ñÿ¤(”ñÿ)§ñÿø ¨"¨­ñÿ�)¸ñÿÌ"ÀÍ"|D#H#|#œ#¼#À#ä#è#$$$$,$0$@$D$T$ŒÔŒÛ�ì”ôñÿ˜)=<�&6ÉAÅWá c0y•"‰”¨)8¤¥ü¶™HÄ)Ó	Üõdç�Hýu'�)%”.>TK˜)Z`%u$�¡œŸ!¬•"½´Åí Ù±
êlX
•"0.ñ07Y
DHeYù Ôcq)”‹Ù
œ©³É‰xß•"ï‘�•"%Ø(@3•"CõTqnI#TyÄƒ1“)¤œ·Õ„Ê•"Úyß•"ï½4ú'ˆÅ
.•"?1H•"YynU,}ˆp•ñ§•"¸�Ì	Ù‰pí•"ý	$‘.˜;å^LY(]¡8qe,‚4‹•"œÙT­É¾ÊýÖY:êÉFûm
+	•"	½+	á 7	•"H	iV	4*`	…p	Q�	Ù8˜	1$´	•"Å	•Ó	¹Xä	 ð	µ
+p%
+¸
+(
+=80
+%Œ>
+•"N
+()8^
+¸l
+•"}
+�
+•"ž
+¹µ
+QÄ
+$%<Ò
+�(á
+¹ ì
+•"ý
+•"¤($Y7©L•"]9hí
y©–•"§µÉ¼Ê•.Ð54Ø•"éø$9à)0/•"@Qñÿ\¹dp~ù6’y£¨&»a0Ó=äë¼ò�#$ÿa
+
%L

.
	?
QO
©Xe
do
•"€
é# ‘
™œ
E$·
œÇ
- (Ú
ùí
•"ý
±0}   !¬*¡;� G•"X•"i­Hqˆ&�1(‘¡£$²åÃ¨ÎõlÙ4(ïd(@ý¬
+…2
HqR^•r%ƒÀŒíži8§²�
ÃÙØ%ð•"AéI\)Õ 6¡ˆFE
W•"h™~=˜�|™•®¬(,Â™ÜÄDä¡6ÿ`)0Ål)#1.7A\M%Z•"k•"|Ä’£­­…Æ•"Ö<((êÀ&<øÁ#(‘ÄMT#°,•"startup.c$tzero_loop$dmsg.ca8_version_handlera8_reset_handlercustom_state_datasys_init.csync.ctrace.cstring.cputs.clogbuf_posdebug.clevelsdebug_leveldebug_idxprintf.chex2ascii_dataexception_handlers.crtc.ccm3.cext_intr_handlers.cldo.cldo_regshwmod_335x.cpowerdomain.cpd_statesmpu_bitsper_bitspd_regsdpll_335x.cldo_335x.cpm_handlers.cprcm_core.cprcm_enable_isolation.part.0prcm_disable_isolation.part.1cmd_wake_sourceshwmod_43xx.cddr.cio_ctxdpll.cpower_down_pllsdpll_regspll_modedpll_43xx.cpm_state_data.cclockdomain.cclkdms_state_changeclkdmssleep_clkdmsstandby_clkdmsclockdomain_43xx.cclockdomain_335x.cpowerdomain_43xx.ci2c.cldo_43xx.chwmod.chwmods_state_changehwmodsessential_hwmodsinterconnect_hwmodspowerdomain_335x.cputcharam43xx_interconnect_hwmodsdisable_ioa8_standalone_handlervtp_disableverify_pd_transitionsextint8_handlertimer_syncam335x_per_bitsa8_lp_ds0_handlerreset_handleram43xx_pd_regspm_resetds_restoreget_pd_mpu_stctrl_valprintfam43xx_dpll_regsam43xx_ldo_regsds1_data_aux_data_startcmd_handlersam335x_pd_regsam335x_pg2_power_down_pllsessential_hwmods_enablea8_lp_ds1_handlerdpll_get_divextint27_handlersoc_revclkdms_standby_wakeextint36_handlerddr_am335x_io_suspendidle_v2_dataextint26_handlerpd_state_changepll_lockextint34_handlerextint48_handleri2c_writepd_read_stateplls_power_up_start_dataextint41_handlerprcm_disable_isolationtrace_set_current_posddr_am437x_io_suspendextint4_handlera8_m3_low_power_fastextint50_handlerextint0_handleram335x_clkdmsextint7_handlerbusfault_handlerdisable_master_oscillatorhwmod_init_end_datadebug_set_levelextint45_handlerclear_wake_sourcesa8_standby_handlerextint9_handlerputssystick_handlerpll_bypassam43xx_power_down_pllsds1_data_hsextint40_handlerextint37_handlermsg_readextint12_handlera8_m3_low_power_syncm3_param_resettrace_initstandby_datamemmanage_handlerextint30_handlerm3_firmware_versiontrace_updatea8_wake_ds0_handlerextint5_handleressential_hwmods_disablea8_wake_cpuidle_handlerio_isolationextint31_handlernvic_disable_irqget_master_xtal_khzmsg_cmd_is_validvtt_highextint19_handlerclockdomain_initextint16_handler_start_textsvc_handlera8_i2c_wake_handlerextint53_handlera8_notifyextint1_handlermsg_cmd_needs_triggerclkdms_wakeextint15_handlerset_ddr_reset_end_textclear_ddr_resetextint47_handlerconfigure_wake_sourcesinterconnect_hwmods_disableextint18_handlerdummy_handlerpowerdomain_initds0_data_hsextint52_handleram335x_dpll_regssoc_typevector_tablevprintfddr_io_resumeextint6_handleram43xx_per_bitsrtc_mode_dataextint23_handlerldo_wait_for_onextint20_handlerscr_enable_sleeponexitldo_power_downam335x_hwmodsnvic_clear_irqclkdm_wakeextint38_handlerextint22_handleram335x_standby_clkdmsa8_cpuidle_handlerscr_enable_sleepdeepextint39_handlerdpll_resetextint42_handlermsg_cmd_wakeup_reason_updateextint21_handler_logbuf_startgeneric_wake_handlerputsnvtt_lowextint32_handleram335x_interconnect_hwmods_aux_data_endldo_power_upam335x_mpu_bitsextint28_handlerdebugmon_handler_end_stackddr_io_save_contextrtc_reg_writea8_wake_ds1_handlerextint49_handleram43xx_essential_hwmodsa8_wake_standby_handlerextint46_handlermemsetsoc_idhwmod_enablemainsetup_socpendsv_handlerextint43_handlerrtc_enable_checkmsg_cmd_read_idinit_m3_state_machineidle_dataextint25_handlerhwmod_is_enabledvtt_toggleinterconnect_hwmods_enablecmd_global_dataclkdm_state_changeusagefault_handlerextint3_handlervtp_enableclkdm_active_logbuf_endds0_dataextint51_handlerclkdm_sleepextint24_handlerextint10_handlerds_saveam335x_ldo_regsnvic_enable_irqpowerdomain_resetddr_io_suspendpd_state_restoredebug_haltam335_initam43xx_standby_clkdmsam43xx_clkdmsvtt_gpio_pin_end_resource_tablea8_wake_rtc_handlertrace_get_current_posa8_cpuidle_v2_handlermsg_cmd_stat_updateldo_wait_for_ret_end_bsshardfault_handlerldo_init_start_bssextint35_handlermsg_cmd_fast_triggeram335x_essential_hwmodsextint14_handlermsg_writenmi_handlera8_lp_rtc_handlerclkdms_sleepplls_power_downextint33_handlerextint13_handlerprcm_enable_isolationa8_lp_ds2_handlerds2_dataa8_i2c_sleep_handleram335x_sleep_clkdmsconfigure_deepsleep_countrsc_taba8_wake_cpuidle_v2_handleram43xx_mpu_bitsdebug_printfstrlena8_wake_ds2_handlerget_pd_per_stctrl_valrtc_reg_readextint29_handlerextint11_handler_start_resource_tableextint44_handlerenable_ioenable_master_oscillatorextint2_handleram43xx_sleep_clkdmsam43xx_hwmodshwmod_disablemsg_cmd_dispatcherdpll_initmem_typeextint17_handler4*!Ä'ÄÄD7¸<FN3rZ;t'$hb˜Â,s$ÅÐ‚ôÈ€�tÎ#œ0—èé§0€-°p­7Àä¸œÍlp$U	Ü:=
\ No newline at end of file
diff -Naur --no-dereference a/firmware/am43x-evm-scale-data.bin b/firmware/am43x-evm-scale-data.bin
--- a/firmware/am43x-evm-scale-data.bin	1969-12-31 19:00:00.000000000 -0500
+++ b/firmware/am43x-evm-scale-data.bin	2025-10-23 09:30:40.287462269 -0400
@@ -0,0 +1 @@
+Wd$k$Š$g$†d$k$™$g$†
\ No newline at end of file
diff -Naur --no-dereference a/firmware/regulatory.db b/firmware/regulatory.db
--- a/firmware/regulatory.db	1969-12-31 19:00:00.000000000 -0500
+++ b/firmware/regulatory.db	2025-10-23 09:30:40.287462269 -0400
@@ -0,0 +1,34 @@
+RGDB00˜ADêAE°AFÂAIÛALæAMANÂAR´AS…ATôAU«AWÂAZ¸BAêBBáBDþBEïBF£BGïBHBLÂBM…BNÑBOûBRXBSäBTÂBYÂBZCAqCFœCHùCI£CLÔCNÊCO´CRCU=CXäCYïCZïDEïDKïDMzDO}DZÞECJEEžEGESïETÂFIïFM…FRôGBþGD�GE»GFÛGH£GLÛGPÛGRïGT@GUvGYHKaHN«HRÙHT…HUïIDFIEïILâINIRÓISêITïJM£JO·JP�KE]KHÂKNÍKP‰KR)KWKYSKZÆLB£LCÍLIêLK˜LSÂLTïLUïLVïMAØMCæMDæMEæMFÛMH…MKêMNìMO3MP…MQÛMRÂMTïMUðMVÖMWÂMX§MYNA²NGøNI…NLïNOùNPÑNZeOM!PAjPE´PFÛPG£PH¼PKnPLïPMÛPR�PTïPW…PYèQAREÛROïRSÁRU
+RW£SAÅSEïSG.SIïSKïSN£SRÂSV”SYTCôTDÂTG%TH°TN¿TRÏTT£TWNTZÞUAUGäUS¤UYáUZ¿VCÂVEVI…VN8VU£WFÛWS YE�YTÛZAÉZWÂ#4JJ#4FJÐ…8)Ðu
+
> è¸
Ãp
Ë@Ð¸
Ë@	À>€¸
ö8	À u
ùXhè¸	À)@¸$Ÿ%¸@œ@Ð$Ÿ%å,œ@Ð$Ÿ%å,œ@Ð$Ÿ%å,œ@ü$Ÿ%å,œ@ý$Ÿ%å,œ@
+Š$Ÿ%å,œ@
+Š$Ÿ%å,œ@¸$Ÿ%å,œ@å$Ÿ%å,œ@$Ÿ%å,œ@$Ÿ%å,œ@¸$Ÿ&% œ@Ð$¦Ð%¸@œ@¸$¦Ð%¸@œ@Ð$¦Ð%ßPN Ð$¦Ð%ßPœ@
+Š$¦Ð%ßPœ@¸$¦Ð%ßPœ@$¦Ð%ßPœ@Ð$¦Ð%å,œ@Ð%}¨%ßPN Ð%À&0N 	Ð%À&0N üJë°L$0œ@üN•0OÍ°œ@¢N•0PÐ8€¤N•0PÐ8€ÐN•0PÐ8€ÐN•0PÐ8€²üN•0PÐ8€üN•0PÐ8€üN•0PÐ8€²ýN•0PÐ8€ýN•0PÐ8€ýN•0PÐ8€²ýN•0PÐ8€ýN•0PÐ8€²	]N•0PÐ8€
+ŒN•0PÐ8€¸N•0PÐ8€¸N•0PÐ8€N•0PÐ8€ÐN•0Q¢p8€ýN•0Q¢p8€ýN•0Q¢p8€
+ýN•0Q¢p8€¤N•0Q¢pqÐN•0Q¢pqýN•0Q¢pq¤NãPPÐN ÐNãPPÐN ¸NãPPÐN ¤NãPPÐœ@ÐNãPPÐœ@¤NãPPÐ8€NãPPÐ8€ÐNãPPÐ8€ÐNãPPÐ8€²ÐNãPPÐ8€üNãPPÐ8€ýNãPPÐ8€	`NãPPÐ8€	`NãPPÐ8€²¸NãPPÐ8€¤OÍ°PÐN ÐPÐQTPN üPÐQTPN 	`PÐQTPN ¸PÐQTPN ÐPÐQTPœ@	`PÐQTPœ@PÐQTP8€ÐPÐQTP8€ÐPÐQTP8€²ÐPÐQTP8€²ÐPÐQTP8€üPÐQTP8€	`PÐQTP8€	`PÐQTP8€²¸PÐQTP8€¸PÐQTP8€¤PÐQ¢p8€ÐPÐQ¢p8€ÐPÐQ¢p8€ÐPÐQ¢p8€²0PÐQ¢p8€üPÐQ¢p8€üPÐQ¢p8€ýPÐQ¢p8€ýPÐQ¢p8€ýPÐQ¢p8€²ýPÐQ¢p8€	]PÐQ¢p8€	`PÐQ¢p8€	`PÐQ¢p8€
+ŒPÐQ¢p8€
+ŒPÐQ¢p8€¸PÐQ¢p8€	`Sw0Us8€
+ŠSw0Us8€	]Sw0W[H8€	`Sw0W[H8€
+ŒSw0W[H8€
+ŒSw0W[H8€ÐSw0W[HqÐSw0W[HqÐSw0W[Hq²0Sw0W[Hq4Sw0W[HqýSw0W[Hq	]Sw0W[Hq	]Sw0W[Hq	`Sw0W[Hq
+ŠSw0W[Hq²
+ŠSw0W[Hq
+ŠSw0W[Hq²
+ŠSw0W[Hq²
+ŒSw0W[Hq
+ŒSw0W[Hq²
+ŒSw0W[Hq¸Sw0W[HqüSw0WnÐq	]Sw0WnÐq	`Sw0WnÐq
+ŠSw0WnÐq
+ŠSw0WnÐq²
+ŒSw0WnÐq¸Sw0WnÐq	`Sw0Xáèq
+ŒSw0YC�q¤Sw0Y¥8q¸SÅPUè0N ¸SÅPV6PqüSÅPV„pq
+ŒSÅPW °œ@
+ŒSÅPW °q
+ŒSÅPW °q²¸SÅPW °q¸SÅPW °q	`SÅPWnÐN ¸SÅPWnÐN 	`SÅPWnÐœ@ÐSÅPWnÐqüSÅPWnÐq	`SÅPWnÐq	`SÅPWnÐq²	`V6PWnÐ8€
+ŠV6PWnÐ8€ÐV6PYC�qýW[HXáè8€ÐW[HYC�8€ÐW[HYC�8€üW[HYC�8€ýW[HYC�8€ýW[HYC�8€ýW[HYC�8€	`W[HYC�8€	`W[HYC�8€	`W[HYC�8€
+ŠW[HYC�8€¸W[HYC�8€¸W[HYC�8€äW[HYC�8€W[HYC�8€	`W[HY¥8œ@uW[HY¥88€uW[HY¥88€ÐW[HY¥88€üW[HY¥88€	`W[HY¥88€¸W[HY¥88€W[HY¥88€¸WnÐYC�8€WnÐYC�8€WnÐYC�8€¸W‚XXºØN ¸W‚XXºØ8€¸W‚XYøN W‚XYøN ¸W‚XYøœ@ÐW‚XYø8€ÐW‚XYø8€¸W‚XYø8€uYC�Y¥8N ýYC�Y¥8N 	`YC�Y¥8N 
+ŒYC�YóXœ@¸Y¥8ZhˆN xZhˆb	¨qÐZhˆb	¨q	]Zhˆb	¨q°Zhˆb	¨â
+°Zhˆb	¨âxZhˆb	¨âÐZhˆb	¨âüZhˆb	¨âüZhˆb	¨âýZhˆb	¨âýZhˆb	¨â	]Zhˆb	¨â	]Zhˆb	¨â²	`Zhˆb	¨âÜZhˆl¸q°Zhˆl¸â
+°Zhˆl¸âÜZhˆl¸â	]Zhˆl¸â¸Zhˆl¸âüZ¶¨b	¨âüZ¶¨b	¨â²ýZ¶¨b	¨âýZ¶¨b	¨â²	]Z¶¨b	¨âýb	¨c�H8€€c�Hhçxâ€hçxl¸q eÀ@Ð� õ€ÌeÀ@Ð� õ€èeÀ@ï€ õ€eÀ@ï€ õ€BeÀ@ï€ õ€	`eÀ@ï€ õ€ eÀ@ï€ õ€ eÀ@ï€ õ€ eÀ@ï€ õ€ÌeÀ@ï€ õ€ eÀ@;_À õ€ÍeÀ@;_À õ€ eÀ@;_ÀƒÖ
+ðiiÀŠ_@ õ€iiÀÌJ@ õ€ iiÀ;_À õ€0Š_@ÌJ@ õ€
+ðÌJ@í?À õ€	º
+*2Ç$Áˆ	¾ÎÚm3³…;€ÂÆÒÖO]Ö�ÕŒÊÒi/q9¥Éå|ÚF/–‘ùlÚO<��ùxÚO<¦]	dÚO<½eÑùhÚS/‰IhÚS/u„�”ÚW	Á2hÚ\DÚ`+EÚdLª�2hÚi/¢a.Úi/¸…7Úm3ª�.Úm3ª�.hÚm3ª�2hÚm3ª�2xÚm3ª�;xÚm3ÞU
xÚŽ}‘lÚ–óÚš=álÚÏ'ëÞJ3�I.`ÞiQ‰‰ùlÞiQšYÍlÞÏ+½lâ†ïýpæ:à+…Mtê`+Úm@hê`Hçm	hêi+¯qlê’uQ	îŠžiDHL\òžAPö>8’möO<Îm.hörUÒ•éxöveÆqxúB'y}ùþS@ã¡Ýþ~aã™xþ‚iÊyT•.S]m5Å¢ì±¶Å¶Å"¶,ÅÓ,Å¦ä÷©.6¾(X¢è±¢ì±®ø ¹²ô¶,Å¶,Åé¶,ÅíŒ¶,Å	¶,Åºü.ºü.h¾¾¾&¾ñ¾­¾½¾½é¾ÂËÿËÅÓ,ÅÓ,ÅéÓ,ÅõÓ,Å.×0ÅÅÅÅÜ#ûÅzY¦•Ë(ÅËÅÅ"ªðµÙ*&m3	l
\ No newline at end of file
diff -Naur --no-dereference a/firmware/regulatory.db.p7s b/firmware/regulatory.db.p7s
--- a/firmware/regulatory.db.p7s	1969-12-31 19:00:00.000000000 -0500
+++ b/firmware/regulatory.db.p7s	2025-10-23 09:30:40.287462269 -0400
@@ -0,0 +1,4 @@
+0‚9	*†H†÷
 ‚*0‚&10
	`†He0	*†H†÷
 ‚«0‚§0‚�aÀ8e«ÜùKÐ¬ðlrHÛÆ0
	*†H†÷
01
0Uwens0 
231201074114Z21231107074114Z01
0Uwens0‚"0
	*†H†÷
‚0‚
+‚©z,xM§-2R .lïˆÅ¶iTCyS·®ˆþÀ·]GŽáï³�†ÚÓd�Î]žKnX>²o^BGAô,¸¨ÔªÀæHð¨ÎË®7¯ö@9ËUo[O…4æiPr^N�Lº86
Îs8×'*yá¬Ï°'…†“«ìBw7eŠDËÖB“’ã9EÅnJËB+%Œ¸;6YÞBÎ!æ¶Çn^&÷ŠWž¥–r·2ë+sâOfXšë¶«P‹Ã�ú
+™Â%¿-kªæ>_ëm›]MBƒ-9¸É¬Û:‘Pß»±vmsýÆækqžg6"ƒy±Ö¸„R¯–[ÃcNxpW0
	*†H†÷
‚$(î"t|úl³ÑÂ=})Bˆ­‚¥±ŠÐì\‘ ö‚ýÕg`_1õ½ˆ‘p½¸¹ŒˆþSÉT›CÄzCtkÝ°±;3EFx£ïTh÷…œäQo¯�Û*{{o¨œgØËÉ‘@®Ù¡ŸÝ¦C({ªé„ÛvdBpÉÀë®„hN„ž~’6î;cëy„�¯ÈšÇ4Ó”KÑ(—¾ÑEuÜ5b¬··‡È˜À$1V�íÛÆF¿Km¦Õ«Ì`üå7¶S}X•©VÇ÷îÃ v÷eMSúÿ_v3Zú†’ZúüòŒBm·~·´ðÇƒ»¢�-Ô*c?÷1.@3\F¼›Á¥ENÃ1‚R0‚N0'01
0UwensaÀ8e«ÜùKÐ¬ðlrHÛÆ0
	`†He0
	*†H†÷
‚‰—«ô¸¯‡Cûd÷TN’ô´+-’¦ôždâÊ=�ula{á¸?ÊêcaŠ¿V�È‘•…íèw{
+$d9×´KÌo8t œjïb¿Þ�j]êËäÃçš¢·�t"ÜÁ9ñnc{y™lA-~Z+©ãêÐhÎ0,
`óË
§W#~leÿùì?˜a`Ÿeov’@Lõœo~××dpºÀ7Í	z“¦Ì
R§Ö�#½_¨Ê8ê7xß[öbü8'WE5ú%ÅJuG?E!ÀÞi5E˜û“7ÀÁ<‡ñ¾ú<|‘­aFÎ˜ï(sÆ±™Ùµõ)xj®ZÑúP5�
\ No newline at end of file
diff -Naur --no-dereference a/.github/FUNDING.yml b/.github/FUNDING.yml
--- a/.github/FUNDING.yml	1969-12-31 19:00:00.000000000 -0500
+++ b/.github/FUNDING.yml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: beagleboard # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: beagleboard # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: https://paypal.me/beagleboard # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff -Naur --no-dereference a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
--- a/.github/ISSUE_TEMPLATE/bug_report.md	1969-12-31 19:00:00.000000000 -0500
+++ b/.github/ISSUE_TEMPLATE/bug_report.md	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,20 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**Describe how to reproduce the bug**
+List all the steps needed to reproduce the bug
+
+**REQUIRED INFORMATION**
+Run this command and paste the output here:
+```
+sudo beagle-version
+```
diff -Naur --no-dereference a/.gitlab-ci.yml b/.gitlab-ci.yml
--- a/.gitlab-ci.yml	1969-12-31 19:00:00.000000000 -0500
+++ b/.gitlab-ci.yml	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,41 @@
+image: robertcnelson/beagle-devscripts-kernel-debian-12-amd64:latest
+# https://openbeagle.org/beagleboard/ci-docker-images
+
+before_script:
+  - export PATH=/usr/lib/ccache:$PATH
+  - echo "Acquire::http::Proxy \"http://192.168.1.10:3142\";" > /etc/apt/apt.conf.d/00aptproxy
+  - apt-get update
+  - apt-get upgrade -yq
+  - cd /opt/linux-src/ ; git pull ; cd -
+
+cache:
+  key: "$CI_PROJECT_NAME-ti-linux-arm32-6.12.y"
+  paths:
+    - ccache.tar.lz4
+
+build:
+  tags:
+    - docker-amd64
+  stage: build
+  script:
+    - mkdir -p /root/.cache/ccache/ || true
+    - tar --use-compress-program=lz4 -xf ccache.tar.lz4 -C / || true
+    - ccache -z
+    - CORES=$(getconf _NPROCESSORS_ONLN)
+    - make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- clean
+    - make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bb.org_defconfig
+    - echo "make -j${CORES} ARCH=arm KBUILD_DEBARCH=armhf CROSS_COMPILE=arm-linux-gnueabihf- LOCALVERSION=-ti-arm32-r$CI_JOB_ID KDEB_SOURCENAME=linux-upstream KDEB_COMPRESS=xz bindeb-pkg"
+    - DEB_BUILD_PROFILES=pkg.linux-upstream.nokernelheaders make -j${CORES} ARCH=arm KBUILD_DEBARCH=armhf KDEB_PKGVERSION=1xross CROSS_COMPILE=arm-linux-gnueabihf- LOCALVERSION=-ti-arm32-r$CI_JOB_ID KDEB_SOURCENAME=linux-upstream KDEB_COMPRESS=xz bindeb-pkg
+    - mv ../*.deb ./
+    - ccache -sv
+    - tar --use-compress-program=lz4 -cf ccache.tar.lz4 /root/.cache/ccache/
+  rules:
+    - if: $CI_COMMIT_TAG
+      when: never
+    - when: always
+  artifacts:
+    expire_in: 28 days
+    when: on_success
+    name: "$CI_PROJECT_NAME-ti-linux-arm32-6.12.y-$CI_JOB_ID"
+    paths:
+      - "linux-image-*.deb"
diff -Naur --no-dereference a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
--- a/include/drm/drm_mipi_dsi.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/drm/drm_mipi_dsi.h	2025-10-23 09:30:40.287462269 -0400
@@ -291,6 +291,7 @@
 				  const void *payload, size_t size);
 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
 			      size_t num_params, void *data, size_t size);
+u32 drm_mipi_dsi_get_input_bus_fmt(enum mipi_dsi_pixel_format dsi_format);
 
 #define mipi_dsi_msleep(ctx, delay)	\
 	do {				\
diff -Naur --no-dereference a/include/dt-bindings/board/am335x-bone-pins.h b/include/dt-bindings/board/am335x-bone-pins.h
--- a/include/dt-bindings/board/am335x-bone-pins.h	1969-12-31 19:00:00.000000000 -0500
+++ b/include/dt-bindings/board/am335x-bone-pins.h	2025-10-23 09:30:40.287462269 -0400
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 Deepak Khatri <deepaklorkhatri7@gmail.com>
+ * See Cape Interface Spec page for more info on Bone Buses
+ * https://elinux.org/Beagleboard:BeagleBone_cape_interface_spec
+ */
+
+#ifndef _DT_BINDINGS_BOARD_AM335X_BONE_PINS_H
+#define _DT_BINDINGS_BOARD_AM335X_BONE_PINS_H
+
+#define bb_device 0
+#define board_soc AM335X
+
+#define gpio_P8_03 &gpio1 6
+#define gpio_P8_04 &gpio1 7
+#define gpio_P8_05 &gpio1 2
+#define gpio_P8_06 &gpio1 3
+#define gpio_P8_07 &gpio2 2
+#define gpio_P8_08 &gpio2 3
+#define gpio_P8_09 &gpio2 5
+#define gpio_P8_10 &gpio2 4
+#define gpio_P8_11 &gpio1 13
+#define gpio_P8_12 &gpio1 12
+#define gpio_P8_13 &gpio0 23
+#define gpio_P8_14 &gpio0 26
+#define gpio_P8_15 &gpio1 15
+#define gpio_P8_16 &gpio1 14
+#define gpio_P8_17 &gpio0 27
+#define gpio_P8_18 &gpio2 1
+#define gpio_P8_19 &gpio0 22
+#define gpio_P8_20 &gpio1 31
+#define gpio_P8_21 &gpio1 30
+#define gpio_P8_22 &gpio1 5
+#define gpio_P8_23 &gpio1 4
+#define gpio_P8_24 &gpio1 1
+#define gpio_P8_25 &gpio1 0
+#define gpio_P8_26 &gpio1 29
+#define gpio_P8_27 &gpio2 22
+#define gpio_P8_28 &gpio2 24
+#define gpio_P8_29 &gpio2 23
+#define gpio_P8_30 &gpio2 25
+#define gpio_P8_31 &gpio0 10
+#define gpio_P8_32 &gpio0 11
+#define gpio_P8_33 &gpio0 9
+#define gpio_P8_34 &gpio2 17
+#define gpio_P8_35 &gpio0 8
+#define gpio_P8_36 &gpio2 16
+#define gpio_P8_37 &gpio2 14
+#define gpio_P8_38 &gpio2 15
+#define gpio_P8_39 &gpio2 12
+#define gpio_P8_40 &gpio2 13
+#define gpio_P8_41 &gpio2 10
+#define gpio_P8_42 &gpio2 11
+#define gpio_P8_43 &gpio2 8
+#define gpio_P8_44 &gpio2 9
+#define gpio_P8_45 &gpio2 6
+#define gpio_P8_46 &gpio2 7
+#define gpio_P9_11 &gpio0 30
+#define gpio_P9_12 &gpio1 28
+#define gpio_P9_13 &gpio0 31
+#define gpio_P9_14 &gpio1 18
+#define gpio_P9_15 &gpio1 16
+#define gpio_P9_16 &gpio1 19
+#define gpio_P9_17 &gpio0 5
+#define gpio_P9_18 &gpio0 4
+#define gpio_P9_19 &gpio0 13
+#define gpio_P9_20 &gpio0 12
+#define gpio_P9_21 &gpio0 3
+#define gpio_P9_22 &gpio0 2
+#define gpio_P9_23 &gpio1 17
+#define gpio_P9_24 &gpio0 15
+#define gpio_P9_25 &gpio3 21
+#define gpio_P9_26 &gpio0 14
+#define gpio_P9_27 &gpio3 19
+#define gpio_P9_28 &gpio3 17
+#define gpio_P9_29 &gpio3 15
+#define gpio_P9_30 &gpio3 16
+#define gpio_P9_31 &gpio3 14
+#define gpio_P9_41 &gpio0 20
+#define gpio_P9_41A &gpio0 20
+#define gpio_P9_41B &gpio3 20
+#define gpio_P9_91 &gpio3 20
+#define gpio_P9_42 &gpio0 7
+#define gpio_P9_42A &gpio0 7
+#define gpio_P9_42B &gpio3 18
+#define gpio_P9_92 &gpio3 18
+#define gpio_A15 &gpio0 19
+
+#define P8_03(mode) AM33XX_IOPAD(0x0818, mode)  /* R9: gpmc_ad6 */
+#define P8_04(mode) AM33XX_IOPAD(0x081c, mode)  /* T9: gpmc_ad7 */
+#define P8_05(mode) AM33XX_IOPAD(0x0808, mode)  /* R8: gpmc_ad2 */
+#define P8_06(mode) AM33XX_IOPAD(0x080c, mode)  /* T8: gpmc_ad3 */
+#define P8_07(mode) AM33XX_IOPAD(0x0890, mode)  /* R7: gpmc_advn_ale */
+#define P8_08(mode) AM33XX_IOPAD(0x0894, mode)  /* T7: gpmc_oen_ren */
+#define P8_09(mode) AM33XX_IOPAD(0x089c, mode)  /* T6: gpmc_be0n_cle */
+#define P8_10(mode) AM33XX_IOPAD(0x0898, mode)  /* U6: gpmc_wen */
+#define P8_11(mode) AM33XX_IOPAD(0x0834, mode)  /* R12: gpmc_ad13 */
+#define P8_12(mode) AM33XX_IOPAD(0x0830, mode)  /* T12: gpmc_ad12 */
+#define P8_13(mode) AM33XX_IOPAD(0x0824, mode)  /* T10: gpmc_ad9 */
+#define P8_14(mode) AM33XX_IOPAD(0x0828, mode)  /* T11: gpmc_ad10 */
+#define P8_15(mode) AM33XX_IOPAD(0x083c, mode)  /* U13: gpmc_ad15 */
+#define P8_16(mode) AM33XX_IOPAD(0x0838, mode)  /* V13: gpmc_ad14 */
+#define P8_17(mode) AM33XX_IOPAD(0x082c, mode)  /* U12: gpmc_ad11 */
+#define P8_18(mode) AM33XX_IOPAD(0x088c, mode)  /* V12: gpmc_clk */
+#define P8_19(mode) AM33XX_IOPAD(0x0820, mode)  /* U10: gpmc_ad8 */
+#define P8_20(mode) AM33XX_IOPAD(0x0884, mode)  /* V9: gpmc_csn2 */
+#define P8_21(mode) AM33XX_IOPAD(0x0880, mode)  /* U9: gpmc_csn1 */
+#define P8_22(mode) AM33XX_IOPAD(0x0814, mode)  /* V8: gpmc_ad5 */
+#define P8_23(mode) AM33XX_IOPAD(0x0810, mode)  /* U8: gpmc_ad4 */
+#define P8_24(mode) AM33XX_IOPAD(0x0804, mode)  /* V7: gpmc_ad1 */
+#define P8_25(mode) AM33XX_IOPAD(0x0800, mode)  /* U7: gpmc_ad0 */
+#define P8_26(mode) AM33XX_IOPAD(0x087c, mode)  /* V6: gpmc_csn0 */
+#define P8_27(mode) AM33XX_IOPAD(0x08e0, mode)  /* U5: lcd_vsync */
+#define P8_28(mode) AM33XX_IOPAD(0x08e8, mode)  /* V5: lcd_pclk */
+#define P8_29(mode) AM33XX_IOPAD(0x08e4, mode)  /* R5: lcd_hsync */
+#define P8_30(mode) AM33XX_IOPAD(0x08ec, mode)  /* R6: lcd_ac_bias_en */
+#define P8_31(mode) AM33XX_IOPAD(0x08d8, mode)  /* V4: lcd_data14 */
+#define P8_32(mode) AM33XX_IOPAD(0x08dc, mode)  /* T5: lcd_data15 */
+#define P8_33(mode) AM33XX_IOPAD(0x08d4, mode)  /* V3: lcd_data13 */
+#define P8_34(mode) AM33XX_IOPAD(0x08cc, mode)  /* U4: lcd_data11 */
+#define P8_35(mode) AM33XX_IOPAD(0x08d0, mode)  /* V2: lcd_data12 */
+#define P8_36(mode) AM33XX_IOPAD(0x08c8, mode)  /* U3: lcd_data10 */
+#define P8_37(mode) AM33XX_IOPAD(0x08c0, mode)  /* U1: lcd_data8 */
+#define P8_38(mode) AM33XX_IOPAD(0x08c4, mode)  /* U2: lcd_data9 */
+#define P8_39(mode) AM33XX_IOPAD(0x08b8, mode)  /* T3: lcd_data6 */
+#define P8_40(mode) AM33XX_IOPAD(0x08bc, mode)  /* T4: lcd_data7 */
+#define P8_41(mode) AM33XX_IOPAD(0x08b0, mode)  /* T1: lcd_data4 */
+#define P8_42(mode) AM33XX_IOPAD(0x08b4, mode)  /* T2: lcd_data5 */
+#define P8_43(mode) AM33XX_IOPAD(0x08a8, mode)  /* R3: lcd_data2 */
+#define P8_44(mode) AM33XX_IOPAD(0x08ac, mode)  /* R4: lcd_data3 */
+#define P8_45(mode) AM33XX_IOPAD(0x08a0, mode)  /* R1: lcd_data0 */
+#define P8_46(mode) AM33XX_IOPAD(0x08a4, mode)  /* R2: lcd_data1 */
+#define P9_11(mode) AM33XX_IOPAD(0x0870, mode)  /* T17: gpmc_wait0 */
+#define P9_12(mode) AM33XX_IOPAD(0x0878, mode)  /* U18: gpmc_be1n */
+#define P9_13(mode) AM33XX_IOPAD(0x0874, mode)  /* U17: gpmc_wpn */
+#define P9_14(mode) AM33XX_IOPAD(0x0848, mode)  /* U14: gpmc_a2 */
+#define P9_15(mode) AM33XX_IOPAD(0x0840, mode)  /* R13: gpmc_a0 */
+#define P9_16(mode) AM33XX_IOPAD(0x084c, mode)  /* T14: gpmc_a3 */
+#define P9_17(mode) AM33XX_IOPAD(0x095c, mode)  /* A16: spi0_cs0 */
+#define P9_18(mode) AM33XX_IOPAD(0x0958, mode)  /* B16: spi0_d1 */
+#define P9_19(mode) AM33XX_IOPAD(0x097c, mode)  /* D17: uart1_rtsn */
+#define P9_20(mode) AM33XX_IOPAD(0x0978, mode)  /* D18: uart1_ctsn */
+#define P9_21(mode) AM33XX_IOPAD(0x0954, mode)  /* B17: spi0_d0 */
+#define P9_22(mode) AM33XX_IOPAD(0x0950, mode)  /* A17: spi0_sclk */
+#define P9_23(mode) AM33XX_IOPAD(0x0844, mode)  /* V14: gpmc_a1 */
+#define P9_24(mode) AM33XX_IOPAD(0x0984, mode)  /* D15: uart1_txd */
+#define P9_25(mode) AM33XX_IOPAD(0x09ac, mode)  /* A14: mcasp0_ahclkx */
+#define P9_26(mode) AM33XX_IOPAD(0x0980, mode)  /* D16: uart1_rxd */
+#define P9_27(mode) AM33XX_IOPAD(0x09a4, mode)  /* C13: mcasp0_fsr */
+#define P9_28(mode) AM33XX_IOPAD(0x099c, mode)  /* C12: mcasp0_ahclkr */
+#define P9_29(mode) AM33XX_IOPAD(0x0994, mode)  /* B13: mcasp0_fsx */
+#define P9_30(mode) AM33XX_IOPAD(0x0998, mode)  /* D12: mcasp0_axr0 */
+#define P9_31(mode) AM33XX_IOPAD(0x0990, mode)  /* A13: mcasp0_aclkx */
+#define P9_41(mode) AM33XX_IOPAD(0x09b4, mode)  /* D14: xdma_event_intr1 */
+#define P9_41A(mode) AM33XX_IOPAD(0x09b4, mode) /* D14: xdma_event_intr1 */
+#define P9_41B(mode) AM33XX_IOPAD(0x09a8, mode) /* D13: mcasp0_axr1 */
+#define P9_91(mode) AM33XX_IOPAD(0x09a8, mode) /* D13: mcasp0_axr1 */
+#define P9_42(mode) AM33XX_IOPAD(0x0964, mode) /* C18: P0_in_PWM0_out */
+#define P9_42A(mode) AM33XX_IOPAD(0x0964, mode) /* C18: P0_in_PWM0_out */
+#define P9_42B(mode) AM33XX_IOPAD(0x09a0, mode) /* B12: mcasp0_aclkr */
+#define P9_92(mode) AM33XX_IOPAD(0x09a0, mode) /* B12: mcasp0_aclkr */
+
+#define gpio_P1_02 &gpio2 23
+#define gpio_P1_04 &gpio2 25
+#define gpio_P1_06 &gpio0 5
+#define gpio_P1_08 &gpio0 2
+#define gpio_P1_10 &gpio0 3
+#define gpio_P1_12 &gpio0 4
+#define gpio_P1_20 &gpio0 20
+#define gpio_P1_26 &gpio0 12
+#define gpio_P1_28 &gpio0 13
+#define gpio_P1_29 &gpio3 21
+#define gpio_P1_30 &gpio1 11
+#define gpio_P1_31 &gpio3 18
+#define gpio_P1_32 &gpio1 10
+#define gpio_P1_33 &gpio3 15
+#define gpio_P1_34 &gpio0 26
+#define gpio_P1_35 &gpio2 24
+#define gpio_P1_36 &gpio3 14
+#define gpio_P2_01 &gpio1 18
+#define gpio_P2_02 &gpio1 27
+#define gpio_P2_03 &gpio0 23
+#define gpio_P2_04 &gpio1 26
+#define gpio_P2_05 &gpio0 30
+#define gpio_P2_06 &gpio1 25
+#define gpio_P2_07 &gpio0 31
+#define gpio_P2_08 &gpio1 28
+#define gpio_P2_09 &gpio0 15
+#define gpio_P2_10 &gpio1 20
+#define gpio_P2_11 &gpio0 14
+#define gpio_P2_17 &gpio2 1
+#define gpio_P2_18 &gpio1 15
+#define gpio_P2_19 &gpio0 27
+#define gpio_P2_20 &gpio2 0
+#define gpio_P2_22 &gpio1 14
+#define gpio_P2_24 &gpio1 12
+#define gpio_P2_25 &gpio1 9
+#define gpio_P2_27 &gpio1 8
+#define gpio_P2_28 &gpio3 20
+#define gpio_P2_29 &gpio0 7
+#define gpio_P2_30 &gpio3 17
+#define gpio_P2_31 &gpio0 19
+#define gpio_P2_32 &gpio3 16
+#define gpio_P2_33 &gpio1 13
+#define gpio_P2_34 &gpio3 19
+#define gpio_P2_35 &gpio2 22
+
+#define P1_02(mode) AM33XX_IOPAD(0x08e4, mode)  /* R5: lcd_hsync */
+#define P1_04(mode) AM33XX_IOPAD(0x08ec, mode)  /* R6: lcd_ac_bias_en */
+#define P1_06(mode) AM33XX_IOPAD(0x095c, mode)  /* A16: spi0_cs0 */
+#define P1_08(mode) AM33XX_IOPAD(0x0950, mode)  /* A17: spi0_sclk */
+#define P1_10(mode) AM33XX_IOPAD(0x0954, mode)  /* B17: spi0_d0 */
+#define P1_12(mode) AM33XX_IOPAD(0x0958, mode)  /* B16: spi0_d1 */
+#define P1_20(mode) AM33XX_IOPAD(0x09b4, mode)  /* D14: xdma_event_intr1 */
+#define P1_26(mode) AM33XX_IOPAD(0x0978, mode)  /* D18: uart1_ctsn */
+#define P1_28(mode) AM33XX_IOPAD(0x097c, mode)  /* D17: uart1_rtsn */
+#define P1_29(mode) AM33XX_IOPAD(0x09ac, mode)  /* A14: mcasp0_ahclkx */
+#define P1_30(mode) AM33XX_IOPAD(0x0974, mode)  /* E16: uart0_txd */
+#define P1_31(mode) AM33XX_IOPAD(0x09a0, mode)  /* B12: mcasp0_aclkr */
+#define P1_32(mode) AM33XX_IOPAD(0x0970, mode)  /* E15: uart0_rxd */
+#define P1_33(mode) AM33XX_IOPAD(0x0994, mode)  /* B13: mcasp0_fsx */
+#define P1_34(mode) AM33XX_IOPAD(0x0828, mode)  /* T11: gpmc_ad10 */
+#define P1_35(mode) AM33XX_IOPAD(0x08e8, mode)  /* V5: lcd_pclk */
+#define P1_36(mode) AM33XX_IOPAD(0x0990, mode)  /* A13: mcasp0_aclkx */
+#define P2_01(mode) AM33XX_IOPAD(0x0848, mode)  /* U14: gpmc_a2 */
+#define P2_02(mode) AM33XX_IOPAD(0x086c, mode)  /* V17: gpmc_a11 */
+#define P2_03(mode) AM33XX_IOPAD(0x0824, mode)  /* T10: gpmc_ad9 */
+#define P2_04(mode) AM33XX_IOPAD(0x0868, mode)  /* T16: gpmc_a10 */
+#define P2_05(mode) AM33XX_IOPAD(0x0870, mode)  /* T17: gpmc_wait0 */
+#define P2_06(mode) AM33XX_IOPAD(0x0864, mode)  /* U16: gpmc_a9 */
+#define P2_07(mode) AM33XX_IOPAD(0x0874, mode)  /* U17: gpmc_wpn */
+#define P2_08(mode) AM33XX_IOPAD(0x0878, mode)  /* U18: gpmc_be1n */
+#define P2_09(mode) AM33XX_IOPAD(0x0984, mode)  /* D15: uart1_txd */
+#define P2_10(mode) AM33XX_IOPAD(0x0850, mode)  /* R14: gpmc_a4 */
+#define P2_11(mode) AM33XX_IOPAD(0x0980, mode)  /* D16: uart1_rxd */
+#define P2_17(mode) AM33XX_IOPAD(0x088c, mode)  /* V12: gpmc_clk */
+#define P2_18(mode) AM33XX_IOPAD(0x083c, mode)  /* U13: gpmc_ad15 */
+#define P2_19(mode) AM33XX_IOPAD(0x082c, mode)  /* U12: gpmc_ad11 */
+#define P2_20(mode) AM33XX_IOPAD(0x0888, mode)  /* T13: gpmc_csn3 */
+#define P2_22(mode) AM33XX_IOPAD(0x0838, mode)  /* V13: gpmc_ad14 */
+#define P2_24(mode) AM33XX_IOPAD(0x0830, mode)  /* T12: gpmc_ad12 */
+#define P2_25(mode) AM33XX_IOPAD(0x096c, mode)  /* E17: uart0_rtsn */
+#define P2_27(mode) AM33XX_IOPAD(0x0968, mode)  /* E18: uart0_ctsn */
+#define P2_28(mode) AM33XX_IOPAD(0x09a8, mode)  /* D13: mcasp0_axr1 */
+#define P2_29(mode) AM33XX_IOPAD(0x0964, mode)  /* C18: eCAP0_in_PWM0_out */
+#define P2_30(mode) AM33XX_IOPAD(0x099c, mode)  /* C12: mcasp0_ahclkr */
+#define P2_31(mode) AM33XX_IOPAD(0x09b0, mode)  /* A15: xdma_event_intr0 */
+#define P2_32(mode) AM33XX_IOPAD(0x0998, mode)  /* D12: mcasp0_axr0 */
+#define P2_33(mode) AM33XX_IOPAD(0x0834, mode)  /* R12: gpmc_ad13 */
+#define P2_34(mode) AM33XX_IOPAD(0x09a4, mode)  /* C13: mcasp0_fsr */
+#define P2_35(mode) AM33XX_IOPAD(0x08e0, mode)  /* U5: lcd_vsync */
+
+#endif
diff -Naur --no-dereference a/include/dt-bindings/mailbox/miv-ihc.h b/include/dt-bindings/mailbox/miv-ihc.h
--- a/include/dt-bindings/mailbox/miv-ihc.h	1969-12-31 19:00:00.000000000 -0500
+++ b/include/dt-bindings/mailbox/miv-ihc.h	2025-10-23 09:30:40.287462269 -0400
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+/*
+ * Copyright (c) 2021 Microchip Technology Inc. All rights reserved.
+ */
+
+#ifndef __DT_BINDINGS_MIV_IHC_H
+#define __DT_BINDINGS_MIV_IHC_H
+
+#define IHC_CONTEXT_A	5
+#define IHC_CONTEXT_B	6
+
+#define IHC_HART1_INT	180
+#define IHC_HART2_INT	179
+#define IHC_HART3_INT	178
+#define IHC_HART4_INT	177
+
+#endif
diff -Naur --no-dereference a/include/dt-bindings/pinctrl/omap.h b/include/dt-bindings/pinctrl/omap.h
--- a/include/dt-bindings/pinctrl/omap.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/dt-bindings/pinctrl/omap.h	2025-10-23 09:30:40.287462269 -0400
@@ -64,8 +64,12 @@
 #define OMAP3_WKUP_IOPAD(pa, val)	OMAP_IOPAD_OFFSET((pa), 0x2a00) (val)
 #define DM814X_IOPAD(pa, val)		OMAP_IOPAD_OFFSET((pa), 0x0800) (val)
 #define DM816X_IOPAD(pa, val)		OMAP_IOPAD_OFFSET((pa), 0x0800) (val)
-#define AM33XX_IOPAD(pa, val)		OMAP_IOPAD_OFFSET((pa), 0x0800) (val) (0)
-#define AM33XX_PADCONF(pa, conf, mux)	OMAP_IOPAD_OFFSET((pa), 0x0800) (conf) (mux)
+//Mainline
+//#define AM33XX_IOPAD(pa, val)		OMAP_IOPAD_OFFSET((pa), 0x0800) (val) (0)
+//#define AM33XX_PADCONF(pa, conf, mux)	OMAP_IOPAD_OFFSET((pa), 0x0800) (conf) (mux)
+//BeagleBoard.org (compabitliy with ancient overlays)
+#define AM33XX_IOPAD(pa, val)		OMAP_IOPAD_OFFSET((pa), 0x0800) (val)
+#define AM33XX_PADCONF(pa, dir, mux)	OMAP_IOPAD_OFFSET((pa), 0x0800) ((dir) | (mux))
 
 /*
  * Macros to allow using the offset from the padconf physical address
diff -Naur --no-dereference a/include/linux/byteorder/generic.h b/include/linux/byteorder/generic.h
--- a/include/linux/byteorder/generic.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/byteorder/generic.h	2025-10-23 09:30:40.287462269 -0400
@@ -196,6 +196,14 @@
 		dst[i] = cpu_to_be32(src[i]);
 }
 
+static inline void cpu_to_be64_array(__be64 *dst, const u64 *src, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++)
+		dst[i] = cpu_to_be64(src[i]);
+}
+
 static inline void be32_to_cpu_array(u32 *dst, const __be32 *src, size_t len)
 {
 	size_t i;
diff -Naur --no-dereference a/include/linux/crc64.h b/include/linux/crc64.h
--- a/include/linux/crc64.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/crc64.h	2025-10-23 09:30:40.287462269 -0400
@@ -7,9 +7,11 @@
 
 #include <linux/types.h>
 
+#define CRC64_ISO3309_STRING "crc64-iso3309"
 #define CRC64_ROCKSOFT_STRING "crc64-rocksoft"
 
 u64 __pure crc64_be(u64 crc, const void *p, size_t len);
+u64 __pure crc64_iso3309_generic(u64 crc, const void *p, size_t len);
 u64 __pure crc64_rocksoft_generic(u64 crc, const void *p, size_t len);
 
 u64 crc64_rocksoft(const unsigned char *buffer, size_t len);
diff -Naur --no-dereference a/include/linux/if_hsr.h b/include/linux/if_hsr.h
--- a/include/linux/if_hsr.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/if_hsr.h	2025-10-23 09:30:40.287462269 -0400
@@ -13,6 +13,15 @@
 	PRP_V1,
 };
 
+enum hsr_port_type {
+	HSR_PT_NONE = 0,	/* Must be 0, used by framereg */
+	HSR_PT_SLAVE_A,
+	HSR_PT_SLAVE_B,
+	HSR_PT_INTERLINK,
+	HSR_PT_MASTER,
+	HSR_PT_PORTS,	/* This must be the last item in the enum */
+};
+
 /* HSR Tag.
  * As defined in IEC-62439-3:2010, the HSR tag is really { ethertype = 0x88FB,
  * path, LSDU_size, sequence Nr }. But we let eth_header() create { h_dest,
@@ -32,6 +41,8 @@
 #if IS_ENABLED(CONFIG_HSR)
 extern bool is_hsr_master(struct net_device *dev);
 extern int hsr_get_version(struct net_device *dev, enum hsr_version *ver);
+struct net_device *hsr_get_port_ndev(struct net_device *ndev,
+				     enum hsr_port_type pt);
 #else
 static inline bool is_hsr_master(struct net_device *dev)
 {
@@ -42,6 +53,12 @@
 {
 	return -EINVAL;
 }
+
+static inline struct net_device *hsr_get_port_ndev(struct net_device *ndev,
+						   enum hsr_port_type pt)
+{
+	return ERR_PTR(-EINVAL);
+}
 #endif /* CONFIG_HSR */
 
 #endif /*_LINUX_IF_HSR_H_*/
diff -Naur --no-dereference a/include/linux/interrupt.h b/include/linux/interrupt.h
--- a/include/linux/interrupt.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/interrupt.h	2025-10-23 09:30:40.287462269 -0400
@@ -616,6 +616,53 @@
 extern void raise_softirq_irqoff(unsigned int nr);
 extern void raise_softirq(unsigned int nr);
 
+/*
+ * With forced-threaded interrupts enabled a raised softirq is deferred to
+ * ksoftirqd unless it can be handled within the threaded interrupt. This
+ * affects timer_list timers and hrtimers which are explicitly marked with
+ * HRTIMER_MODE_SOFT.
+ * With PREEMPT_RT enabled more hrtimers are moved to softirq for processing
+ * which includes all timers which are not explicitly marked HRTIMER_MODE_HARD.
+ * Userspace controlled timers (like the clock_nanosleep() interface) is divided
+ * into two categories: Tasks with elevated scheduling policy including
+ * SCHED_{FIFO|RR|DL} and the remaining scheduling policy. The tasks with the
+ * elevated scheduling policy are woken up directly from the HARDIRQ while all
+ * other wake ups are delayed to softirq and so to ksoftirqd.
+ *
+ * The ksoftirqd runs at SCHED_OTHER policy at which it should remain since it
+ * handles the softirq in an overloaded situation (not handled everything
+ * within its last run).
+ * If the timers are handled at SCHED_OTHER priority then they competes with all
+ * other SCHED_OTHER tasks for CPU resources are possibly delayed.
+ * Moving timers softirqs to a low priority SCHED_FIFO thread instead ensures
+ * that timer are performed before scheduling any SCHED_OTHER thread.
+ */
+DECLARE_PER_CPU(struct task_struct *, ktimerd);
+DECLARE_PER_CPU(unsigned long, pending_timer_softirq);
+void raise_ktimers_thread(unsigned int nr);
+
+static inline unsigned int local_timers_pending_force_th(void)
+{
+	return __this_cpu_read(pending_timer_softirq);
+}
+
+static inline void raise_timer_softirq(unsigned int nr)
+{
+	lockdep_assert_in_irq();
+	if (force_irqthreads())
+		raise_ktimers_thread(nr);
+	else
+		__raise_softirq_irqoff(nr);
+}
+
+static inline unsigned int local_timers_pending(void)
+{
+	if (force_irqthreads())
+		return local_timers_pending_force_th();
+	else
+		return local_softirq_pending();
+}
+
 DECLARE_PER_CPU(struct task_struct *, ksoftirqd);
 
 static inline struct task_struct *this_cpu_ksoftirqd(void)
diff -Naur --no-dereference a/include/linux/iommu.h b/include/linux/iommu.h
--- a/include/linux/iommu.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/iommu.h	2025-10-23 09:30:40.287462269 -0400
@@ -784,7 +784,6 @@
 	};
 }
 
-extern int bus_iommu_probe(const struct bus_type *bus);
 extern bool iommu_present(const struct bus_type *bus);
 extern bool device_iommu_capable(struct device *dev, enum iommu_cap cap);
 extern bool iommu_group_has_isolated_msi(struct iommu_group *group);
diff -Naur --no-dereference a/include/linux/linux_logo.h b/include/linux/linux_logo.h
--- a/include/linux/linux_logo.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/linux_logo.h	2025-10-23 09:30:40.287462269 -0400
@@ -42,6 +42,7 @@
 extern const struct linux_logo logo_superh_vga16;
 extern const struct linux_logo logo_superh_clut224;
 extern const struct linux_logo logo_spe_clut224;
+extern const struct linux_logo logo_beagle_clut224;
 
 extern const struct linux_logo *fb_find_logo(int depth);
 #ifdef CONFIG_FB_LOGO_EXTRA
diff -Naur --no-dereference a/include/linux/mfd/tps65219.h b/include/linux/mfd/tps65219.h
--- a/include/linux/mfd/tps65219.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/mfd/tps65219.h	2025-10-23 09:30:40.287462269 -0400
@@ -1,25 +1,24 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Functions to access TPS65219 Power Management IC.
+ * Functions to access TPS65215/TPS65219 Power Management Integrated Chips
  *
  * Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
  */
 
 #ifndef MFD_TPS65219_H
 #define MFD_TPS65219_H
 
 #include <linux/bitops.h>
-#include <linux/notifier.h>
+#include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 
-struct regmap;
-struct regmap_irq_chip_data;
-
-#define TPS65219_1V35					1350000
-#define TPS65219_1V8					1800000
-
-/* TPS chip id list */
-#define TPS65219					0xF0
+/* Chip id list*/
+enum pmic_id {
+	TPS65214,
+	TPS65215,
+	TPS65219,
+};
 
 /* I2C ID for TPS65219 part */
 #define TPS65219_I2C_ID					0x24
@@ -29,15 +28,23 @@
 #define TPS65219_REG_NVM_ID				0x01
 #define TPS65219_REG_ENABLE_CTRL			0x02
 #define TPS65219_REG_BUCKS_CONFIG			0x03
+#define TPS65214_REG_LOCK				0x03
 #define TPS65219_REG_LDO4_VOUT				0x04
+#define TPS65214_REG_LDO1_VOUT_STBY			0x04
 #define TPS65219_REG_LDO3_VOUT				0x05
+#define TPS65215_REG_LDO2_VOUT                          0x05
+#define TPS65214_REG_LDO1_VOUT				0x05
 #define TPS65219_REG_LDO2_VOUT				0x06
+#define TPS65214_REG_LDO2_VOUT				0x06
 #define TPS65219_REG_LDO1_VOUT				0x07
+#define TPS65214_REG_LDO2_VOUT_STBY			0x07
 #define TPS65219_REG_BUCK3_VOUT				0x8
 #define TPS65219_REG_BUCK2_VOUT				0x9
 #define TPS65219_REG_BUCK1_VOUT				0xA
 #define TPS65219_REG_LDO4_SEQUENCE_SLOT			0xB
 #define TPS65219_REG_LDO3_SEQUENCE_SLOT			0xC
+#define TPS65215_REG_LDO2_SEQUENCE_SLOT                 0xC
+#define TPS65214_REG_LDO1_SEQUENCE_SLOT			0xC
 #define TPS65219_REG_LDO2_SEQUENCE_SLOT			0xD
 #define TPS65219_REG_LDO1_SEQUENCE_SLOT			0xE
 #define TPS65219_REG_BUCK3_SEQUENCE_SLOT		0xF
@@ -46,15 +53,21 @@
 #define TPS65219_REG_nRST_SEQUENCE_SLOT			0x12
 #define TPS65219_REG_GPIO_SEQUENCE_SLOT			0x13
 #define TPS65219_REG_GPO2_SEQUENCE_SLOT			0x14
+#define TPS65214_REG_GPIO_GPI_SEQUENCE_SLOT		0x14
 #define TPS65219_REG_GPO1_SEQUENCE_SLOT			0x15
+#define TPS65214_REG_GPO_SEQUENCE_SLOT			0x15
 #define TPS65219_REG_POWER_UP_SLOT_DURATION_1		0x16
 #define TPS65219_REG_POWER_UP_SLOT_DURATION_2		0x17
+/* _SLOT_DURATION_3 doesn't apply to TPS65215*/
 #define TPS65219_REG_POWER_UP_SLOT_DURATION_3		0x18
 #define TPS65219_REG_POWER_UP_SLOT_DURATION_4		0x19
+#define TPS65214_REG_BUCK3_VOUT_STBY				0x19
 #define TPS65219_REG_POWER_DOWN_SLOT_DURATION_1		0x1A
 #define TPS65219_REG_POWER_DOWN_SLOT_DURATION_2		0x1B
 #define TPS65219_REG_POWER_DOWN_SLOT_DURATION_3		0x1C
+#define TPS65214_REG_BUCK2_VOUT_STBY				0x1C
 #define TPS65219_REG_POWER_DOWN_SLOT_DURATION_4		0x1D
+#define TPS65214_REG_BUCK1_VOUT_STBY				0x1D
 #define TPS65219_REG_GENERAL_CONFIG			0x1E
 #define TPS65219_REG_MFP_1_CONFIG			0x1F
 #define TPS65219_REG_MFP_2_CONFIG			0x20
@@ -72,9 +85,19 @@
 #define TPS65219_REG_DISCHARGE_CONFIG			0x2A
 /* main irq registers */
 #define TPS65219_REG_INT_SOURCE				0x2B
-/* 'sub irq' registers */
+
+/* TPS65219 'sub irq' registers */
 #define TPS65219_REG_INT_LDO_3_4			0x2C
 #define TPS65219_REG_INT_LDO_1_2			0x2D
+
+/* TPS65215 specific 'sub irq' registers */
+#define TPS65215_REG_INT_LDO_2				0x2C
+#define TPS65215_REG_INT_LDO_1				0x2D
+
+/* TPS65214 specific 'sub irq' register */
+#define TPS65214_REG_INT_LDO_1_2			0x2D
+
+/* Common TPS65215 & TPS65219 'sub irq' registers */
 #define TPS65219_REG_INT_BUCK_3				0x2E
 #define TPS65219_REG_INT_BUCK_1_2			0x2F
 #define TPS65219_REG_INT_SYSTEM				0x30
@@ -91,6 +114,17 @@
 #define TPS65219_REG_INT_TO_RV_POS			6
 #define TPS65219_REG_INT_PB_POS				7
 
+#define TPS65215_REG_INT_LDO_2_POS			0
+#define TPS65215_REG_INT_LDO_1_POS			1
+
+#define TPS65214_REG_INT_LDO_1_2_POS		0
+#define TPS65214_REG_INT_BUCK_3_POS			1
+#define TPS65214_REG_INT_BUCK_1_2_POS			2
+#define TPS65214_REG_INT_SYS_POS			3
+#define TPS65214_REG_INT_RV_POS				4
+#define TPS65214_REG_INT_TO_RV_POS			5
+#define TPS65214_REG_INT_PB_POS				6
+
 #define TPS65219_REG_USER_NVM_CMD			0x34
 #define TPS65219_REG_POWER_UP_STATUS			0x35
 #define TPS65219_REG_SPARE_2				0x36
@@ -112,6 +146,8 @@
 #define TPS65219_ENABLE_LDO1_EN_MASK			BIT(3)
 #define TPS65219_ENABLE_LDO2_EN_MASK			BIT(4)
 #define TPS65219_ENABLE_LDO3_EN_MASK			BIT(5)
+#define TPS65215_ENABLE_LDO2_EN_MASK                    BIT(5)
+#define TPS65214_ENABLE_LDO1_EN_MASK			BIT(5)
 #define TPS65219_ENABLE_LDO4_EN_MASK			BIT(6)
 /* power ON-OFF sequence slot */
 #define TPS65219_BUCKS_LDOS_SEQUENCE_OFF_SLOT_MASK	GENMASK(3, 0)
@@ -163,20 +199,27 @@
 #define TPS65219_REG_MASK_EFFECT_MASK			GENMASK(2, 1)
 #define TPS65219_REG_MASK_INT_FOR_PB_MASK		BIT(7)
 /* UnderVoltage - Short to GND - OverCurrent*/
-/* LDO3-4 */
+/* LDO3-4: only for TPS65219*/
 #define TPS65219_INT_LDO3_SCG_MASK			BIT(0)
 #define TPS65219_INT_LDO3_OC_MASK			BIT(1)
 #define TPS65219_INT_LDO3_UV_MASK			BIT(2)
 #define TPS65219_INT_LDO4_SCG_MASK			BIT(3)
 #define TPS65219_INT_LDO4_OC_MASK			BIT(4)
 #define TPS65219_INT_LDO4_UV_MASK			BIT(5)
-/* LDO1-2 */
+/* LDO1-2: TPS65214 & TPS65219 */
 #define TPS65219_INT_LDO1_SCG_MASK			BIT(0)
 #define TPS65219_INT_LDO1_OC_MASK			BIT(1)
 #define TPS65219_INT_LDO1_UV_MASK			BIT(2)
 #define TPS65219_INT_LDO2_SCG_MASK			BIT(3)
 #define TPS65219_INT_LDO2_OC_MASK			BIT(4)
 #define TPS65219_INT_LDO2_UV_MASK			BIT(5)
+/* TPS65215 LDO1-2*/
+#define TPS65215_INT_LDO1_SCG_MASK			BIT(0)
+#define TPS65215_INT_LDO1_OC_MASK			BIT(1)
+#define TPS65215_INT_LDO1_UV_MASK			BIT(2)
+#define TPS65215_INT_LDO2_SCG_MASK			BIT(0)
+#define TPS65215_INT_LDO2_OC_MASK			BIT(1)
+#define TPS65215_INT_LDO2_UV_MASK			BIT(2)
 /* BUCK3 */
 #define TPS65219_INT_BUCK3_SCG_MASK			BIT(0)
 #define TPS65219_INT_BUCK3_OC_MASK			BIT(1)
@@ -191,12 +234,13 @@
 #define TPS65219_INT_BUCK2_OC_MASK			BIT(5)
 #define TPS65219_INT_BUCK2_NEG_OC_MASK			BIT(6)
 #define TPS65219_INT_BUCK2_UV_MASK			BIT(7)
-/* Thermal Sensor  */
+/* Thermal Sensor: TPS65219/TPS65215 */
 #define TPS65219_INT_SENSOR_3_WARM_MASK			BIT(0)
+#define TPS65219_INT_SENSOR_3_HOT_MASK			BIT(4)
+/* Thermal Sensor: TPS65219/TPS65215/TPS65214 */
 #define TPS65219_INT_SENSOR_2_WARM_MASK			BIT(1)
 #define TPS65219_INT_SENSOR_1_WARM_MASK			BIT(2)
 #define TPS65219_INT_SENSOR_0_WARM_MASK			BIT(3)
-#define TPS65219_INT_SENSOR_3_HOT_MASK			BIT(4)
 #define TPS65219_INT_SENSOR_2_HOT_MASK			BIT(5)
 #define TPS65219_INT_SENSOR_1_HOT_MASK			BIT(6)
 #define TPS65219_INT_SENSOR_0_HOT_MASK			BIT(7)
@@ -207,6 +251,8 @@
 #define TPS65219_INT_LDO1_RV_MASK			BIT(3)
 #define TPS65219_INT_LDO2_RV_MASK			BIT(4)
 #define TPS65219_INT_LDO3_RV_MASK			BIT(5)
+#define TPS65215_INT_LDO2_RV_MASK			BIT(5)
+#define TPS65214_INT_LDO2_RV_MASK			BIT(5)
 #define TPS65219_INT_LDO4_RV_MASK			BIT(6)
 /* Residual Voltage ShutDown */
 #define TPS65219_INT_BUCK1_RV_SD_MASK			BIT(0)
@@ -215,6 +261,8 @@
 #define TPS65219_INT_LDO1_RV_SD_MASK			BIT(3)
 #define TPS65219_INT_LDO2_RV_SD_MASK			BIT(4)
 #define TPS65219_INT_LDO3_RV_SD_MASK			BIT(5)
+#define TPS65215_INT_LDO2_RV_SD_MASK			BIT(5)
+#define TPS65214_INT_LDO1_RV_SD_MASK			BIT(5)
 #define TPS65219_INT_LDO4_RV_SD_MASK			BIT(6)
 #define TPS65219_INT_TIMEOUT_MASK			BIT(7)
 /* Power Button */
@@ -240,7 +288,15 @@
 	TPS65219_INT_LDO4_SCG,
 	TPS65219_INT_LDO4_OC,
 	TPS65219_INT_LDO4_UV,
-	/* LDO1-2 */
+	/* TPS65215 LDO1*/
+	TPS65215_INT_LDO1_SCG,
+	TPS65215_INT_LDO1_OC,
+	TPS65215_INT_LDO1_UV,
+	/* TPS65215 LDO2*/
+	TPS65215_INT_LDO2_SCG,
+	TPS65215_INT_LDO2_OC,
+	TPS65215_INT_LDO2_UV,
+	/* LDO1-2: TPS65219/TPS65214 */
 	TPS65219_INT_LDO1_SCG,
 	TPS65219_INT_LDO1_OC,
 	TPS65219_INT_LDO1_UV,
@@ -276,6 +332,8 @@
 	TPS65219_INT_BUCK3_RV,
 	TPS65219_INT_LDO1_RV,
 	TPS65219_INT_LDO2_RV,
+	TPS65215_INT_LDO2_RV,
+	TPS65214_INT_LDO2_RV,
 	TPS65219_INT_LDO3_RV,
 	TPS65219_INT_LDO4_RV,
 	/* Residual Voltage ShutDown */
@@ -283,6 +341,8 @@
 	TPS65219_INT_BUCK2_RV_SD,
 	TPS65219_INT_BUCK3_RV_SD,
 	TPS65219_INT_LDO1_RV_SD,
+	TPS65214_INT_LDO1_RV_SD,
+	TPS65215_INT_LDO2_RV_SD,
 	TPS65219_INT_LDO2_RV_SD,
 	TPS65219_INT_LDO3_RV_SD,
 	TPS65219_INT_LDO4_RV_SD,
@@ -292,6 +352,23 @@
 	TPS65219_INT_PB_RISING_EDGE_DETECT,
 };
 
+enum tps65214_regulator_id {
+	/*
+	 * DCDC's same as TPS65219
+	 * LDO1 maps to TPS65219's LDO3
+	 * LDO2 is the same as TPS65219
+	 *
+	 */
+	TPS65214_LDO_1 = 3,
+	TPS65214_LDO_2 = 4,
+};
+
+enum tps65215_regulator_id {
+	/* DCDC's same as TPS65219 */
+	/* LDO1 is the same as TPS65219 */
+	TPS65215_LDO_2 = 4,
+};
+
 enum tps65219_regulator_id {
 	/* DCDC's */
 	TPS65219_BUCK_1,
@@ -305,11 +382,40 @@
 };
 
 /* Number of step-down converters available */
-#define TPS65219_NUM_DCDC		3
+#define TPS6521X_NUM_BUCKS		3
 /* Number of LDO voltage regulators available */
 #define TPS65219_NUM_LDO		4
+#define TPS65215_NUM_LDO		2
+#define TPS65214_NUM_LDO		2
 /* Number of total regulators available */
-#define TPS65219_NUM_REGULATOR		(TPS65219_NUM_DCDC + TPS65219_NUM_LDO)
+#define TPS65219_NUM_REGULATOR		(TPS6521X_NUM_BUCKS + TPS65219_NUM_LDO)
+#define TPS65215_NUM_REGULATOR		(TPS6521X_NUM_BUCKS + TPS65215_NUM_LDO)
+#define TPS65214_NUM_REGULATOR		(TPS6521X_NUM_BUCKS + TPS65214_NUM_LDO)
+
+/* Define the TPS65214 IRQ numbers */
+enum tps65214_irqs {
+	/* INT source registers */
+	TPS65214_TO_RV_SD_SET_IRQ,
+	TPS65214_RV_SET_IRQ,
+	TPS65214_SYS_SET_IRQ,
+	TPS65214_BUCK_1_2_SET_IRQ,
+	TPS65214_BUCK_3_SET_IRQ,
+	TPS65214_LDO_1_2_SET_IRQ,
+	TPS65214_PB_SET_IRQ = 7,
+};
+
+/* Define the TPS65215 IRQ numbers */
+enum tps65215_irqs {
+	/* INT source registers */
+	TPS65215_TO_RV_SD_SET_IRQ,
+	TPS65215_RV_SET_IRQ,
+	TPS65215_SYS_SET_IRQ,
+	TPS65215_BUCK_1_2_SET_IRQ,
+	TPS65215_BUCK_3_SET_IRQ,
+	TPS65215_LDO_1_SET_IRQ,
+	TPS65215_LDO_2_SET_IRQ,
+	TPS65215_PB_SET_IRQ,
+};
 
 /* Define the TPS65219 IRQ numbers */
 enum tps65219_irqs {
@@ -332,14 +438,12 @@
  * @dev: MFD device
  * @regmap: Regmap for accessing the device registers
  * @irq_data: Regmap irq data used for the irq chip
- * @nb: notifier block for the restart handler
  */
 struct tps65219 {
 	struct device *dev;
 	struct regmap *regmap;
 
 	struct regmap_irq_chip_data *irq_data;
-	struct notifier_block nb;
 };
 
 #endif /* MFD_TPS65219_H */
diff -Naur --no-dereference a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
--- a/include/linux/mtd/spinand.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/mtd/spinand.h	2025-10-23 09:30:40.287462269 -0400
@@ -122,6 +122,12 @@
 		   SPI_MEM_OP_DUMMY(ndummy, 4),				\
 		   SPI_MEM_OP_DATA_IN(len, buf, 4))
 
+#define SPINAND_PAGE_READ_FROM_CACHE_OCTALIO_OP(addr, ndummy, buf, len) \
+	SPI_MEM_OP(SPI_MEM_OP_CMD(0xcb, 1),				\
+		   SPI_MEM_OP_ADDR(2, addr, 8),				\
+		   SPI_MEM_OP_DUMMY(ndummy, 8),				\
+		   SPI_MEM_OP_DATA_IN(len, buf, 8))
+
 #define SPINAND_PROG_EXEC_OP(addr)					\
 	SPI_MEM_OP(SPI_MEM_OP_CMD(0x10, 1),				\
 		   SPI_MEM_OP_ADDR(3, addr, 1),				\
@@ -140,6 +146,12 @@
 		   SPI_MEM_OP_NO_DUMMY,					\
 		   SPI_MEM_OP_DATA_OUT(len, buf, 4))
 
+#define SPINAND_PROG_LOAD_OCTALIO(reset, addr, buf, len)		\
+	SPI_MEM_OP(SPI_MEM_OP_CMD(reset ? 0xc2 : 0xc4, 1),		\
+		   SPI_MEM_OP_ADDR(2, addr, 8),				\
+		   SPI_MEM_OP_NO_DUMMY,					\
+		   SPI_MEM_OP_DATA_OUT(len, buf, 8))
+
 /**
  * Standard SPI NAND flash commands
  */
@@ -359,6 +371,7 @@
 			     unsigned int target);
 	int (*set_cont_read)(struct spinand_device *spinand,
 			     bool enable);
+	int (*late_init)(struct spinand_device *spinand);
 };
 
 #define SPINAND_ID(__method, ...)					\
@@ -387,6 +400,9 @@
 #define SPINAND_CONT_READ(__set_cont_read)				\
 	.set_cont_read = __set_cont_read,
 
+#define SPINAND_LATE_INIT(__late_init)					\
+	.late_init = __late_init,
+
 #define SPINAND_INFO(__model, __id, __memorg, __eccreq, __op_variants,	\
 		     __flags, ...)					\
 	{								\
@@ -469,6 +485,7 @@
 	bool cont_read_possible;
 	int (*set_cont_read)(struct spinand_device *spinand,
 			     bool enable);
+	int (*late_init)(struct spinand_device *spinand);
 };
 
 /**
@@ -538,4 +555,8 @@
 int spinand_write_reg_op(struct spinand_device *spinand, u8 reg, u8 val);
 int spinand_select_target(struct spinand_device *spinand, unsigned int target);
 
+int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val);
+int spinand_write_reg_op(struct spinand_device *spinand, u8 reg, u8 val);
+int spinand_write_enable_op(struct spinand_device *spinand);
+
 #endif /* __LINUX_MTD_SPINAND_H */
diff -Naur --no-dereference a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/netdevice.h	2025-10-23 09:30:40.287462269 -0400
@@ -4576,6 +4576,9 @@
 /* General hardware address lists handling functions */
 int __hw_addr_sync(struct netdev_hw_addr_list *to_list,
 		   struct netdev_hw_addr_list *from_list, int addr_len);
+int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
+			    struct netdev_hw_addr_list *from_list,
+			    int addr_len);
 void __hw_addr_unsync(struct netdev_hw_addr_list *to_list,
 		      struct netdev_hw_addr_list *from_list, int addr_len);
 int __hw_addr_sync_dev(struct netdev_hw_addr_list *list,
diff -Naur --no-dereference a/include/linux/remoteproc.h b/include/linux/remoteproc.h
--- a/include/linux/remoteproc.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/remoteproc.h	2025-10-23 09:30:40.287462269 -0400
@@ -42,6 +42,7 @@
 #include <linux/completion.h>
 #include <linux/idr.h>
 #include <linux/of.h>
+#include <linux/dma-buf.h>
 
 /**
  * struct resource_table - firmware resource table header
@@ -562,6 +563,7 @@
 	struct list_head traces;
 	int num_traces;
 	struct list_head carveouts;
+	struct list_head dmabufs;
 	struct list_head mappings;
 	u64 bootaddr;
 	struct list_head rvdevs;
@@ -584,7 +586,7 @@
 	u8 elf_class;
 	u16 elf_machine;
 	struct cdev cdev;
-	bool cdev_put_on_release;
+	struct device_dma_parameters dma_parms;
 	DECLARE_BITMAP(features, RPROC_MAX_FEATURES);
 };
 
@@ -673,6 +675,10 @@
 
 void rproc_add_carveout(struct rproc *rproc, struct rproc_mem_entry *mem);
 
+int rproc_attach_dmabuf(struct rproc *rproc, struct dma_buf *dmabuf);
+int rproc_dmabuf_get_da(struct rproc *rproc, struct dma_buf *dmabuf, dma_addr_t *dma);
+int rproc_detach_dmabuf(struct rproc *rproc, struct dma_buf *dmabuf);
+
 struct rproc_mem_entry *
 rproc_mem_entry_init(struct device *dev,
 		     void *va, dma_addr_t dma, size_t len, u32 da,
diff -Naur --no-dereference a/include/linux/soc/ti/k3-ringacc.h b/include/linux/soc/ti/k3-ringacc.h
--- a/include/linux/soc/ti/k3-ringacc.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/soc/ti/k3-ringacc.h	2025-10-23 09:30:40.287462269 -0400
@@ -8,8 +8,12 @@
 #ifndef __SOC_TI_K3_RINGACC_API_H_
 #define __SOC_TI_K3_RINGACC_API_H_
 
+#include <linux/platform_device.h>
 #include <linux/types.h>
 
+#define K3_RINGACC_RT_INT_STATUS_COMPLETE	BIT(0)
+#define K3_RINGACC_RT_INT_STATUS_TR			BIT(2)
+
 struct device_node;
 
 /**
@@ -158,6 +162,9 @@
  */
 int k3_ringacc_get_ring_irq_num(struct k3_ring *ring);
 
+u32 k3_ringacc_ring_get_irq_status(struct k3_ring *ring);
+void k3_ringacc_ring_clear_irq(struct k3_ring *ring);
+
 /**
  * k3_ringacc_ring_cfg - ring configure
  * @ring: pointer on ring
@@ -262,6 +269,7 @@
 	const struct ti_sci_handle *tisci;
 	u32 tisci_dev_id;
 	u32 num_rings;
+	void __iomem *base_rt;
 };
 
 struct k3_ringacc *k3_ringacc_dmarings_init(struct platform_device *pdev,
diff -Naur --no-dereference a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
--- a/include/linux/soc/ti/ti_sci_protocol.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/soc/ti/ti_sci_protocol.h	2025-10-23 09:30:40.287462269 -0400
@@ -195,6 +195,37 @@
 			u64 *current_freq);
 };
 
+/* TISCI LPM IO isolation control values */
+#define TISCI_MSG_VALUE_IO_ENABLE			1
+#define TISCI_MSG_VALUE_IO_DISABLE			0
+
+/* TISCI LPM constraint state values */
+#define TISCI_MSG_CONSTRAINT_SET			1
+#define TISCI_MSG_CONSTRAINT_CLR			0
+
+/**
+ * struct ti_sci_pm_ops - Low Power Mode (LPM) control operations
+ * @lpm_wake_reason: Get the wake up source that woke the SoC from LPM
+ *		- source: The wake up source that woke soc from LPM.
+ *		- timestamp: Timestamp at which soc woke.
+ * @set_device_constraint: Set LPM constraint on behalf of a device
+ *		- id: Device Identifier
+ *		- state: The desired state of device constraint: set or clear.
+ * @set_latency_constraint: Set LPM resume latency constraint
+ *		- latency: maximum acceptable latency to wake up from low power mode
+ *		- state: The desired state of latency constraint: set or clear.
+ * @lpm_abort: Abort entry to LPM
+ */
+struct ti_sci_pm_ops {
+	int (*lpm_wake_reason)(const struct ti_sci_handle *handle,
+			       u32 *source, u64 *timestamp, u8 *pin, u8 *mode);
+	int (*set_device_constraint)(const struct ti_sci_handle *handle,
+				     u32 id, u8 state);
+	int (*set_latency_constraint)(const struct ti_sci_handle *handle,
+				      u16 latency, u8 state);
+	int (*lpm_abort)(const struct ti_sci_handle *handle);
+};
+
 /**
  * struct ti_sci_resource_desc - Description of TI SCI resource instance range.
  * @start:	Start index of the first resource range.
@@ -539,6 +570,7 @@
 	struct ti_sci_core_ops core_ops;
 	struct ti_sci_dev_ops dev_ops;
 	struct ti_sci_clk_ops clk_ops;
+	struct ti_sci_pm_ops pm_ops;
 	struct ti_sci_rm_core_ops rm_core_ops;
 	struct ti_sci_rm_irq_ops rm_irq_ops;
 	struct ti_sci_rm_ringacc_ops rm_ring_ops;
diff -Naur --no-dereference a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
--- a/include/linux/spi/spi-mem.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/linux/spi/spi-mem.h	2025-10-23 09:30:40.287462269 -0400
@@ -261,6 +261,12 @@
  * @poll_status: poll memory device status until (status & mask) == match or
  *               when the timeout has expired. It fills the data buffer with
  *               the last status value.
+ * @do_calibration: perform calibration needed for high SPI clock speed
+ *		    operation. Should be called after the SPI memory device has
+ *		    been completely initialized. The op passed should contain
+ *		    a template for the read operation used for the device so
+ *		    the controller can decide what type of calibration is
+ *		    required for this type of read.
  *
  * This interface should be implemented by SPI controllers providing an
  * high-level interface to execute SPI memory operation, which is usually the
@@ -291,6 +297,8 @@
 			   unsigned long initial_delay_us,
 			   unsigned long polling_rate_us,
 			   unsigned long timeout_ms);
+	void (*do_calibration)(struct spi_mem *mem,
+			       const struct spi_mem_op *op);
 };
 
 /**
@@ -365,6 +373,7 @@
 #endif /* CONFIG_SPI_MEM */
 
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op);
+int spi_mem_do_calibration(struct spi_mem *mem, const struct spi_mem_op *op);
 
 bool spi_mem_supports_op(struct spi_mem *mem,
 			 const struct spi_mem_op *op);
diff -Naur --no-dereference a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h
--- a/include/uapi/linux/media-bus-format.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/uapi/linux/media-bus-format.h	2025-10-23 09:30:40.287462269 -0400
@@ -121,7 +121,7 @@
 #define MEDIA_BUS_FMT_YUV16_1X48		0x202a
 #define MEDIA_BUS_FMT_UYYVYY16_0_5X48		0x202b
 
-/* Bayer - next is	0x3021 */
+/* Bayer - next is	0x3029 */
 #define MEDIA_BUS_FMT_SBGGR8_1X8		0x3001
 #define MEDIA_BUS_FMT_SGBRG8_1X8		0x3013
 #define MEDIA_BUS_FMT_SGRBG8_1X8		0x3002
@@ -154,6 +154,14 @@
 #define MEDIA_BUS_FMT_SGBRG16_1X16		0x301e
 #define MEDIA_BUS_FMT_SGRBG16_1X16		0x301f
 #define MEDIA_BUS_FMT_SRGGB16_1X16		0x3020
+#define MEDIA_BUS_FMT_SRGGI10_1X10		0x3021
+#define MEDIA_BUS_FMT_SGRIG10_1X10		0x3022
+#define MEDIA_BUS_FMT_SBGGI10_1X10		0x3023
+#define MEDIA_BUS_FMT_SGBIG10_1X10		0x3024
+#define MEDIA_BUS_FMT_SGIRG10_1X10		0x3025
+#define MEDIA_BUS_FMT_SIGGR10_1X10		0x3026
+#define MEDIA_BUS_FMT_SGIBG10_1X10		0x3027
+#define MEDIA_BUS_FMT_SIGGB10_1X10		0x3028
 
 /* JPEG compressed formats - next is	0x4002 */
 #define MEDIA_BUS_FMT_JPEG_1X8			0x4001
diff -Naur --no-dereference a/include/uapi/linux/remoteproc_cdev.h b/include/uapi/linux/remoteproc_cdev.h
--- a/include/uapi/linux/remoteproc_cdev.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/uapi/linux/remoteproc_cdev.h	2025-10-23 09:30:40.287462269 -0400
@@ -34,4 +34,22 @@
  */
 #define RPROC_GET_SHUTDOWN_ON_RELEASE _IOR(RPROC_MAGIC, 2, __s32)
 
+/**
+ * struct rproc_dma_buf_attach_data - metadata passed from userspace
+ * @fd:		DMA-BUF fd
+ * @da:		populated with device address of DMA-BUF
+ */
+struct rproc_dma_buf_attach_data {
+	__u32 fd;
+	__u64 da;
+};
+
+/**
+ * DOC: RPROC_IOC_DMA_BUF_ATTACH - Attach and map DMA-BUF a remote processor
+ *
+ * Takes a rproc_dma_buf_data struct containing a fd for a physically contiguous
+ * buffer. Pins this buffer and populates phys field with the device address.
+ */
+#define RPROC_IOC_DMA_BUF_ATTACH _IOWR(RPROC_MAGIC, 0, struct rproc_dma_buf_attach_data)
+
 #endif
diff -Naur --no-dereference a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
--- a/include/uapi/linux/v4l2-controls.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/uapi/linux/v4l2-controls.h	2025-10-23 09:30:40.287462269 -0400
@@ -110,8 +110,10 @@
 #define V4L2_CID_COLORFX_CBCR			(V4L2_CID_BASE+42)
 #define V4L2_CID_COLORFX_RGB			(V4L2_CID_BASE+43)
 
+#define V4L2_CID_IR_EXPOSURE				(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 */
 
@@ -445,6 +447,8 @@
 	V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC	= 1,
 };
 
+#define V4L2_CID_MPEG_VIDEO_BACKGROUND_DETECTION	(V4L2_CID_CODEC_BASE+238)
+
 /* CIDs for the MPEG-2 Part 2 (H.262) codec */
 #define V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL			(V4L2_CID_CODEC_BASE+270)
 enum v4l2_mpeg_video_mpeg2_level {
@@ -1213,6 +1217,7 @@
 #define V4L2_CID_TEST_PATTERN_GREENB		(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 7)
 #define V4L2_CID_UNIT_CELL_SIZE			(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 8)
 #define V4L2_CID_NOTIFY_GAINS			(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 9)
+#define V4L2_CID_IR_ANALOGUE_GAIN			(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 10)
 
 
 /* Image processing controls */
@@ -1225,6 +1230,7 @@
 #define V4L2_CID_TEST_PATTERN			(V4L2_CID_IMAGE_PROC_CLASS_BASE + 3)
 #define V4L2_CID_DEINTERLACING_MODE		(V4L2_CID_IMAGE_PROC_CLASS_BASE + 4)
 #define V4L2_CID_DIGITAL_GAIN			(V4L2_CID_IMAGE_PROC_CLASS_BASE + 5)
+#define V4L2_CID_IR_DIGITAL_GAIN		(V4L2_CID_IMAGE_PROC_CLASS_BASE + 6)
 
 /*  DV-class control IDs defined by V4L2 */
 #define V4L2_CID_DV_CLASS_BASE			(V4L2_CTRL_CLASS_DV | 0x900)
diff -Naur --no-dereference a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
--- a/include/uapi/linux/videodev2.h	2025-06-19 09:32:38.000000000 -0400
+++ b/include/uapi/linux/videodev2.h	2025-10-23 09:30:40.287462269 -0400
@@ -734,6 +734,15 @@
 #define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6') /* 16  GBGB.. RGRG.. */
 #define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6') /* 16  GRGR.. BGBG.. */
 #define V4L2_PIX_FMT_SRGGB16 v4l2_fourcc('R', 'G', '1', '6') /* 16  RGRG.. GBGB.. */
+	/* 10bit raw bayer with IR (4x4) */
+#define V4L2_PIX_FMT_SRGGI10 v4l2_fourcc('R', 'G', 'I', '0') /* 10 RGBG.. GIrGIr.. */
+#define V4L2_PIX_FMT_SGRIG10 v4l2_fourcc('G', 'R', 'I', '0') /* 10 GRGB.. IrGIrG.. */
+#define V4L2_PIX_FMT_SBGGI10 v4l2_fourcc('B', 'G', 'I', '0') /* 10 BGRG.. GIrGIr.. */
+#define V4L2_PIX_FMT_SGBIG10 v4l2_fourcc('G', 'B', 'I', '0') /* 10 GBGR.. IrGIrG.. */
+#define V4L2_PIX_FMT_SGIRG10 v4l2_fourcc('G', 'I', 'R', '0') /* 10 GIrGIr.. RGBG.. */
+#define V4L2_PIX_FMT_SIGGR10 v4l2_fourcc('I', 'G', 'R', '0') /* 10 IrGIrG.. GRGB.. */
+#define V4L2_PIX_FMT_SGIBG10 v4l2_fourcc('G', 'I', 'B', '0') /* 10 GIrGIr.. BGRG.. */
+#define V4L2_PIX_FMT_SIGGB10 v4l2_fourcc('I', 'G', 'B', '0') /* 10 IrGIrG.. GBGR.. */
 
 /* HSV formats */
 #define V4L2_PIX_FMT_HSV24 v4l2_fourcc('H', 'S', 'V', '3')
diff -Naur --no-dereference a/kernel/configs/no_smp.config b/kernel/configs/no_smp.config
--- a/kernel/configs/no_smp.config	1969-12-31 19:00:00.000000000 -0500
+++ b/kernel/configs/no_smp.config	2025-10-23 09:30:40.287462269 -0400
@@ -0,0 +1,6 @@
+##################################################
+# NO SMP Config
+##################################################
+
+CONFIG_SMP=n
+CONFIG_CPUSETS=n
diff -Naur --no-dereference a/kernel/configs/ti_arm64_prune.config b/kernel/configs/ti_arm64_prune.config
--- a/kernel/configs/ti_arm64_prune.config	1969-12-31 19:00:00.000000000 -0500
+++ b/kernel/configs/ti_arm64_prune.config	2025-10-23 09:30:40.287462269 -0400
@@ -0,0 +1,496 @@
+# Add config flags here that appear in the defconfig but are not
+# used by a kernel targeting only the currently supported TI EVMs
+
+# Do not set system time from RTC on startup. This should be handled by
+# userspace utilities since most boards do not have a battery backed RTC.
+CONFIG_RTC_HCTOSYS=n
+
+# Non-TI Architectures
+CONFIG_ARCH_ACTIONS=n
+CONFIG_ARCH_AIROHA=n
+CONFIG_ARCH_SUNXI=n
+CONFIG_ARCH_ALPINE=n
+CONFIG_ARCH_APPLE=n
+CONFIG_ARCH_BCM=n
+CONFIG_ARCH_BCM2835=n
+CONFIG_ARCH_BCM_IPROC=n
+CONFIG_ARCH_BCMBCA=n
+CONFIG_ARCH_BRCMSTB=n
+CONFIG_ARCH_BERLIN=n
+CONFIG_ARCH_EXYNOS=n
+CONFIG_ARCH_SPARX5=n
+CONFIG_ARCH_LG1K=n
+CONFIG_ARCH_HISI=n
+CONFIG_ARCH_KEEMBAY=n
+CONFIG_ARCH_MEDIATEK=n
+CONFIG_ARCH_MESON=n
+CONFIG_ARCH_MVEBU=n
+CONFIG_ARCH_NXP=n
+CONFIG_ARCH_LAYERSCAPE=n
+CONFIG_ARCH_MXC=n
+CONFIG_ARCH_S32=n
+CONFIG_ARCH_MA35=n
+CONFIG_ARCH_NPCM=n
+CONFIG_ARCH_QCOM=n
+CONFIG_ARCH_REALTEK=n
+CONFIG_ARCH_RENESAS=n
+CONFIG_ARCH_ROCKCHIP=n
+CONFIG_ARCH_SEATTLE=n
+CONFIG_ARCH_INTEL_SOCFPGA=n
+CONFIG_ARCH_STM32=n
+CONFIG_ARCH_SYNQUACER=n
+CONFIG_ARCH_TEGRA=n
+CONFIG_ARCH_TESLA_FSD=n
+CONFIG_ARCH_SPRD=n
+CONFIG_ARCH_THUNDER=n
+CONFIG_ARCH_THUNDER2=n
+CONFIG_ARCH_UNIPHIER=n
+CONFIG_ARCH_VEXPRESS=n
+CONFIG_ARCH_VISCONTI=n
+CONFIG_ARCH_XGENE=n
+CONFIG_ARCH_ZYNQMP=n
+
+CONFIG_QCOM_FALKOR_ERRATUM_1003=n
+CONFIG_QCOM_FALKOR_ERRATUM_1009=n
+CONFIG_QCOM_QDF2400_ERRATUM_0065=n
+CONFIG_QCOM_FALKOR_ERRATUM_E1041=n
+
+CONFIG_CAVIUM_ERRATUM_22375=n
+CONFIG_CAVIUM_ERRATUM_23144=n
+CONFIG_CAVIUM_ERRATUM_23154=n
+CONFIG_CAVIUM_ERRATUM_27456=n
+CONFIG_CAVIUM_ERRATUM_30115=n
+
+CONFIG_HISILICON_ERRATUM_161600802=n
+
+# Disable Errata fixes not relevant for Cortex A53 and Cortext A72 cores.
+# The Socionext Synquacer GICv3 pre-ITS workaround is used on K3 devices
+# as well, thats why its left enabled.
+CONFIG_AMPERE_ERRATUM_AC03_CPU_38=n
+CONFIG_ARM64_ERRATUM_832075=n
+CONFIG_ARM64_ERRATUM_1024718=n
+CONFIG_ARM64_ERRATUM_1418040=n
+CONFIG_ARM64_ERRATUM_1165522=n
+CONFIG_ARM64_ERRATUM_1530923=n
+CONFIG_ARM64_ERRATUM_2441007=n
+CONFIG_ARM64_ERRATUM_1286807=n
+CONFIG_ARM64_ERRATUM_1463225=n
+CONFIG_ARM64_ERRATUM_1542419=n
+CONFIG_ARM64_ERRATUM_1508412=n
+CONFIG_ARM64_ERRATUM_2051678=n
+CONFIG_ARM64_ERRATUM_2077057=n
+CONFIG_ARM64_ERRATUM_2658417=n
+CONFIG_ARM64_ERRATUM_2054223=n
+CONFIG_ARM64_ERRATUM_2067961=n
+CONFIG_ARM64_ERRATUM_2441009=n
+CONFIG_ARM64_ERRATUM_2457168=n
+CONFIG_ARM64_ERRATUM_2645198=n
+CONFIG_ARM64_ERRATUM_2966298=n
+CONFIG_ARM64_ERRATUM_3117295=n
+CONFIG_CAVIUM_TX2_ERRATUM_219=n
+CONFIG_FUJITSU_ERRATUM_010001=n
+CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=n
+CONFIG_ROCKCHIP_ERRATUM_3588001=n
+
+# Serial
+CONFIG_SERIAL_8250_FSL=n
+CONFIG_SERIAL_8250_DW=n
+CONFIG_SERIAL_AMBA_PL011=n
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=n
+CONFIG_SERIAL_XILINX_PS_UART=n
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=n
+
+CONFIG_ARM_SCPI_PROTOCOL=n
+CONFIG_ARM_SCPI_POWER_DOMAIN=n
+CONFIG_ARM_SCPI_CPUFREQ=n
+CONFIG_SENSORS_ARM_SCPI=n
+CONFIG_COMMON_CLK_SCPI=n
+
+CONFIG_ARM_MHU=n
+CONFIG_PLATFORM_MHU=n
+
+CONFIG_ACPI=n
+
+CONFIG_NUMA=n
+
+CONFIG_XEN=n
+CONFIG_KVM=n
+
+CONFIG_ARM_BIG_LITTLE_CPUFREQ=n
+
+CONFIG_PCI_XGENE=n
+CONFIG_PCI_HISI=n
+CONFIG_PCIE_KIRIN=n
+
+# DRM
+CONFIG_DRM_NOUVEAU=n
+CONFIG_DRM_I2C_ADV7511=n
+CONFIG_DRM_ETNAVIV=n
+CONFIG_DRM_HISI_HIBMC=n
+CONFIG_DRM_HISI_KIRIN=n
+CONFIG_DRM_MXSFB=n
+CONFIG_DRM_PL111=n
+CONFIG_DRM_LIMA=n
+CONFIG_DRM_PANFROST=n
+
+# Video
+CONFIG_VGA_ARB=n
+CONFIG_FB_EFI=n
+
+# V4L2
+CONFIG_RC_CORE=n
+
+# Sound
+CONFIG_SND_SPI=n
+CONFIG_SND_SOC_FSL_SAI=n
+CONFIG_SND_SOC_AK4613=n
+CONFIG_SND_SOC_ES7134=n
+CONFIG_SND_SOC_ES7241=n
+CONFIG_SND_SOC_TAS571X=n
+
+# USB
+CONFIG_USB_MUSB_HDRC=n
+CONFIG_USB_DWC2=n
+CONFIG_USB_CHIPIDEA=n
+CONFIG_USB_ISP1760=n
+CONFIG_USB_HSIC_USB3503=n
+
+# Generic kernel
+
+# We recommend to turn off Real-Time group scheduling in the
+# kernel when using systemd. RT group scheduling effectively
+# makes RT scheduling unavailable for most userspace, since it
+# requires explicit assignment of RT budgets to each unit whose
+# processes making use of RT. As there's no sensible way to
+# assign these budgets automatically this cannot really be
+# fixed, and it's best to disable group scheduling hence.
+CONFIG_RT_GROUP_SCHED=n
+
+# Remove debug features.
+CONFIG_SLUB_DEBUG=n
+
+# We are not a crash kernel
+CONFIG_CRASH_DUMP=n
+
+# ARM Scalable Vector Extension (SVE) is available only with ARMv8.2-A
+# and above. Since current TI SoCs are based on ARMv8.0, disable SVE
+CONFIG_ARM64_SVE=n
+
+# Plan 9 is a distributed resource sharing protocol thats not
+# typically used on TI processors
+CONFIG_NET_9P=n
+
+# Non-TI hardware vendor specific drivers
+CONFIG_KEYBOARD_CROS_EC=n
+CONFIG_I2C_CROS_EC_TUNNEL=n
+CONFIG_QRTR=n
+CONFIG_SPI_NXP_FLEXSPI=n
+CONFIG_GPIO_ALTERA=n
+CONFIG_GPIO_DWAPB=n
+CONFIG_GPIO_MB86S7X=n
+CONFIG_GPIO_PL061=n
+CONFIG_GPIO_XGENE=n
+CONFIG_POWER_RESET_XGENE=n
+CONFIG_ARM_SP805_WATCHDOG=n
+CONFIG_ARM_SBSA_WATCHDOG=n
+CONFIG_DW_WATCHDOG=n
+CONFIG_MFD_SEC_CORE=n
+CONFIG_REGULATOR_QCOM_SPMI=n
+CONFIG_DRM_MALI_DISPLAY=n
+CONFIG_DRM_RCAR_DW_HDMI=n
+CONFIG_DRM_DW_HDMI_AHB_AUDIO=n
+CONFIG_DRM_DW_HDMI_CEC=n
+CONFIG_FB_SSD1307=n
+CONFIG_MMC_ARMMMCI=n
+CONFIG_MMC_SDHCI_XENON=n
+CONFIG_RTC_DRV_S5M=n
+CONFIG_RTC_DRV_CROS_EC=n
+CONFIG_RTC_DRV_PL031=n
+CONFIG_FSL_EDMA=n
+CONFIG_MV_XOR_V2=n
+CONFIG_PL330_DMA=n
+CONFIG_QCOM_HIDMA_MGMT=n
+CONFIG_QCOM_HIDMA=n
+CONFIG_CHROME_PLATFORMS=n
+CONFIG_CROS_EC=n
+CONFIG_CROS_EC_I2C=n
+CONFIG_CROS_EC_SPI=n
+CONFIG_CROS_EC_CHARDEV=n
+CONFIG_SURFACE_PLATFORMS=n
+CONFIG_COMMON_CLK_S2MPS11=n
+CONFIG_COMMON_CLK_VC5=n
+CONFIG_COMMON_CLK_BD718XX=n
+CONFIG_FSL_ERRATUM_A008585=n
+CONFIG_HISILICON_ERRATUM_161010101=n
+CONFIG_RPMSG_QCOM_GLINK_RPM=n
+CONFIG_SOUNDWIRE_QCOM=n
+CONFIG_EXTCON_USBC_CROS_EC=n
+CONFIG_QCOM_SPMI_ADC5=n
+CONFIG_IIO_CROS_EC_SENSORS_CORE=n
+CONFIG_IIO_CROS_EC_SENSORS=n
+CONFIG_IIO_CROS_EC_LIGHT_PROX=n
+CONFIG_IIO_CROS_EC_BARO=n
+CONFIG_PWM_CROS_EC=n
+CONFIG_SLIM_QCOM_CTRL=n
+CONFIG_SPI_PL022=n
+CONFIG_SLIMBUS=n
+CONFIG_REGMAP_SLIMBUS=n
+CONFIG_SCSI_HISI_SAS=n
+CONFIG_AHCI_CEVA=n
+CONFIG_AHCI_XGENE=n
+CONFIG_AHCI_QORIQ=n
+CONFIG_SATA_SIL24=n
+CONFIG_BCMGENET=n
+CONFIG_SYSTEMPORT=n
+CONFIG_HNS_DSAF=n
+CONFIG_HNS_ENET=n
+CONFIG_HNS3=n
+CONFIG_NET_VENDOR_NVIDIA=n
+CONFIG_NET_VENDOR_RENESAS=n
+CONFIG_NET_VENDOR_SAMSUNG=n
+CONFIG_NET_VENDOR_STMICRO=n
+CONFIG_NET_VENDOR_XILINX=n
+CONFIG_BROADCOM_PHY=n
+CONFIG_BCM54140_PHY=n
+CONFIG_ROCKCHIP_PHY=n
+CONFIG_PCS_XPCS=n
+CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=n
+CONFIG_HW_RANDOM_CN10K=n
+CONFIG_I2C_CADENCE=n
+CONFIG_I2C_DESIGNWARE_SLAVE=n
+CONFIG_I2C_DESIGNWARE_PLATFORM=n
+CONFIG_I2C_RK3X=n
+CONFIG_PINCTRL_MAX77620=n
+CONFIG_DRM_RCAR_USE_LVDS=n
+CONFIG_DRM_RCAR_USE_MIPI_DSI=n
+CONFIG_SND_SOC_FSL_ASRC=n
+CONFIG_SND_SOC_FSL_AUDMIX=n
+CONFIG_SND_SOC_FSL_SSI=n
+CONFIG_SND_SOC_FSL_SPDIF=n
+CONFIG_SND_SOC_FSL_ESAI=n
+CONFIG_SND_SOC_FSL_MICFIL=n
+CONFIG_SND_SOC_IMX_AUDMUX=n
+CONFIG_MMC_SDHCI_OF_DWCMSHC=n
+CONFIG_MMC_SDHCI_CADENCE=n
+CONFIG_MMC_SDHCI_F_SDH30=n
+CONFIG_MMC_DW=n
+CONFIG_MMC_MTK=n
+CONFIG_PCIE_ALTERA=n
+CONFIG_PCI_HOST_THUNDER_PEM=n
+CONFIG_PCI_HOST_THUNDER_ECAM=n
+CONFIG_PCI_MESON=n
+CONFIG_BRCMSTB_GISB_ARB=n
+CONFIG_VEXPRESS_CONFIG=n
+CONFIG_MTD_NAND_DENALI_DT=n
+CONFIG_MTD_NAND_BRCMNAND=n
+CONFIG_B53=n
+CONFIG_NET_DSA_BCM_SF2=n
+CONFIG_CAN_FLEXCAN=n
+CONFIG_SPI_DESIGNWARE=n
+CONFIG_SPI_ROCKCHIP=n
+CONFIG_DRM_HDLCD=n
+CONFIG_DRM_KOMEDA=n
+CONFIG_COMMON_CLK_RK808=n
+CONFIG_COMMON_CLK_XGENE=n
+CONFIG_SOC_BRCMSTB=n
+CONFIG_NET_VENDOR_ALACRITECH=n
+CONFIG_NET_VENDOR_AMAZON=n
+CONFIG_NET_VENDOR_AMD=n
+CONFIG_NET_VENDOR_AQUANTIA=n
+CONFIG_NET_VENDOR_ARC=n
+CONFIG_NET_VENDOR_ASIX=n
+CONFIG_NET_VENDOR_CORTINA=n
+CONFIG_NET_VENDOR_DAVICOM=n
+CONFIG_NET_VENDOR_ENGLEDER=n
+CONFIG_NET_VENDOR_EZCHIP=n
+CONFIG_NET_VENDOR_GOOGLE=n
+CONFIG_NET_VENDOR_HISILICON=n
+CONFIG_NET_VENDOR_LITEX=n
+CONFIG_NET_VENDOR_MICREL=n
+CONFIG_NET_VENDOR_MICROCHIP=n
+CONFIG_NET_VENDOR_MICROSEMI=n
+CONFIG_NET_VENDOR_NATSEMI=n
+CONFIG_NET_VENDOR_NI=n
+CONFIG_NET_VENDOR_QUALCOMM=n
+CONFIG_NET_VENDOR_ROCKER=n
+CONFIG_NET_VENDOR_SEEQ=n
+CONFIG_NET_VENDOR_SMSC=n
+CONFIG_NET_VENDOR_SOCIONEXT=n
+CONFIG_NET_VENDOR_SOLARFLARE=n
+CONFIG_NET_VENDOR_SYNOPSYS=n
+CONFIG_NET_VENDOR_VERTEXCOM=n
+CONFIG_NET_VENDOR_VIA=n
+CONFIG_NET_VENDOR_WANGXUN=n
+CONFIG_NET_VENDOR_WIZNET=n
+CONFIG_NET_VENDOR_BROADCOM=n
+CONFIG_NET_VENDOR_MICROSOFT=n
+CONFIG_NET_VENDOR_FUNGIBLE=n
+CONFIG_NET_VENDOR_CAVIUM=n
+CONFIG_NET_VENDOR_PENSANDO=n
+CONFIG_NET_VENDOR_CADENCE=n
+CONFIG_NET_VENDOR_MELLANOX=n
+CONFIG_NET_VENDOR_NETRONOME=n
+CONFIG_NET_VENDOR_MARVELL=n
+CONFIG_NET_VENDOR_INTEL=n
+CONFIG_NET_VENDOR_HUAWEI=n
+CONFIG_NET_VENDOR_META=n
+CONFIG_GOOGLE_FIRMWARE=n
+CONFIG_KEYBOARD_IMX_BBM_SCMI=n
+CONFIG_IMX_SCMI_BBM_EXT=n
+
+# Serial Power Management Interface (SPMI) has not been used on TI
+# platforms (yet)
+CONFIG_SPMI=n
+
+# DVB and TV tuner cards are rarely used on TI platforms, if at all
+CONFIG_CXD2880_SPI_DRV=n
+CONFIG_MEDIA_TUNER_E4000=n
+CONFIG_MEDIA_TUNER_FC0011=n
+CONFIG_MEDIA_TUNER_FC0012=n
+CONFIG_MEDIA_TUNER_FC0013=n
+CONFIG_MEDIA_TUNER_FC2580=n
+CONFIG_MEDIA_TUNER_IT913X=n
+CONFIG_MEDIA_TUNER_M88RS6000T=n
+CONFIG_MEDIA_TUNER_MAX2165=n
+CONFIG_MEDIA_TUNER_MC44S803=n
+CONFIG_MEDIA_TUNER_MSI001=n
+CONFIG_MEDIA_TUNER_MT2060=n
+CONFIG_MEDIA_TUNER_MT2063=n
+CONFIG_MEDIA_TUNER_MT20XX=n
+CONFIG_MEDIA_TUNER_MT2131=n
+CONFIG_MEDIA_TUNER_MT2266=n
+CONFIG_MEDIA_TUNER_MXL301RF=n
+CONFIG_MEDIA_TUNER_MXL5005S=n
+CONFIG_MEDIA_TUNER_MXL5007T=n
+CONFIG_MEDIA_TUNER_QM1D1B0004=n
+CONFIG_MEDIA_TUNER_QM1D1C0042=n
+CONFIG_MEDIA_TUNER_QT1010=n
+CONFIG_MEDIA_TUNER_R820T=n
+CONFIG_MEDIA_TUNER_SI2157=n
+CONFIG_MEDIA_TUNER_SIMPLE=n
+CONFIG_MEDIA_TUNER_TDA18212=n
+CONFIG_MEDIA_TUNER_TDA18218=n
+CONFIG_MEDIA_TUNER_TDA18250=n
+CONFIG_MEDIA_TUNER_TDA18271=n
+CONFIG_MEDIA_TUNER_TDA827X=n
+CONFIG_MEDIA_TUNER_TDA8290=n
+CONFIG_MEDIA_TUNER_TDA9887=n
+CONFIG_MEDIA_TUNER_TEA5761=n
+CONFIG_MEDIA_TUNER_TEA5767=n
+CONFIG_MEDIA_TUNER_TUA9001=n
+CONFIG_MEDIA_TUNER_XC2028=n
+CONFIG_MEDIA_TUNER_XC4000=n
+CONFIG_MEDIA_TUNER_XC5000=n
+CONFIG_DVB_M88DS3103=n
+CONFIG_DVB_MXL5XX=n
+CONFIG_DVB_STB0899=n
+CONFIG_DVB_STB6100=n
+CONFIG_DVB_STV090x=n
+CONFIG_DVB_STV0910=n
+CONFIG_DVB_STV6110x=n
+CONFIG_DVB_STV6111=n
+CONFIG_DVB_DRXK=n
+CONFIG_DVB_MN88472=n
+CONFIG_DVB_MN88473=n
+CONFIG_DVB_SI2165=n
+CONFIG_DVB_TDA18271C2DD=n
+CONFIG_DVB_CX24110=n
+CONFIG_DVB_CX24116=n
+CONFIG_DVB_CX24117=n
+CONFIG_DVB_CX24120=n
+CONFIG_DVB_CX24123=n
+CONFIG_DVB_DS3000=n
+CONFIG_DVB_MB86A16=n
+CONFIG_DVB_MT312=n
+CONFIG_DVB_S5H1420=n
+CONFIG_DVB_SI21XX=n
+CONFIG_DVB_STB6000=n
+CONFIG_DVB_STV0288=n
+CONFIG_DVB_STV0299=n
+CONFIG_DVB_STV0900=n
+CONFIG_DVB_STV6110=n
+CONFIG_DVB_TDA10071=n
+CONFIG_DVB_TDA10086=n
+CONFIG_DVB_TDA8083=n
+CONFIG_DVB_TDA8261=n
+CONFIG_DVB_TDA826X=n
+CONFIG_DVB_TS2020=n
+CONFIG_DVB_TUA6100=n
+CONFIG_DVB_TUNER_CX24113=n
+CONFIG_DVB_TUNER_ITD1000=n
+CONFIG_DVB_VES1X93=n
+CONFIG_DVB_ZL10036=n
+CONFIG_DVB_ZL10039=n
+CONFIG_DVB_AF9013=n
+CONFIG_DVB_CX22700=n
+CONFIG_DVB_CX22702=n
+CONFIG_DVB_CXD2820R=n
+CONFIG_DVB_CXD2841ER=n
+CONFIG_DVB_DIB3000MB=n
+CONFIG_DVB_DIB3000MC=n
+CONFIG_DVB_DIB7000M=n
+CONFIG_DVB_DIB7000P=n
+CONFIG_DVB_DIB9000=n
+CONFIG_DVB_DRXD=n
+CONFIG_DVB_EC100=n
+CONFIG_DVB_L64781=n
+CONFIG_DVB_MT352=n
+CONFIG_DVB_NXT6000=n
+CONFIG_DVB_RTL2830=n
+CONFIG_DVB_RTL2832=n
+CONFIG_DVB_RTL2832_SDR=n
+CONFIG_DVB_S5H1432=n
+CONFIG_DVB_SI2168=n
+CONFIG_DVB_SP887X=n
+CONFIG_DVB_STV0367=n
+CONFIG_DVB_TDA10048=n
+CONFIG_DVB_TDA1004X=n
+CONFIG_DVB_ZD1301_DEMOD=n
+CONFIG_DVB_ZL10353=n
+CONFIG_DVB_CXD2880=n
+CONFIG_DVB_STV0297=n
+CONFIG_DVB_TDA10021=n
+CONFIG_DVB_TDA10023=n
+CONFIG_DVB_VES1820=n
+CONFIG_DVB_AU8522_DTV=n
+CONFIG_DVB_AU8522_V4L=n
+CONFIG_DVB_BCM3510=n
+CONFIG_DVB_LG2160=n
+CONFIG_DVB_LGDT3305=n
+CONFIG_DVB_LGDT3306A=n
+CONFIG_DVB_LGDT330X=n
+CONFIG_DVB_MXL692=n
+CONFIG_DVB_NXT200X=n
+CONFIG_DVB_OR51132=n
+CONFIG_DVB_OR51211=n
+CONFIG_DVB_S5H1409=n
+CONFIG_DVB_S5H1411=n
+CONFIG_DVB_DIB8000=n
+CONFIG_DVB_MB86A20S=n
+CONFIG_DVB_S921=n
+CONFIG_DVB_MN88443X=n
+CONFIG_DVB_TC90522=n
+CONFIG_DVB_PLL=n
+CONFIG_DVB_TUNER_DIB0070=n
+CONFIG_DVB_TUNER_DIB0090=n
+CONFIG_DVB_A8293=n
+CONFIG_DVB_AF9033=n
+CONFIG_DVB_ASCOT2E=n
+CONFIG_DVB_ATBM8830=n
+CONFIG_DVB_HELENE=n
+CONFIG_DVB_HORUS3A=n
+CONFIG_DVB_ISL6405=n
+CONFIG_DVB_ISL6421=n
+CONFIG_DVB_ISL6423=n
+CONFIG_DVB_IX2505V=n
+CONFIG_DVB_LGS8GL5=n
+CONFIG_DVB_LGS8GXX=n
+CONFIG_DVB_LNBH25=n
+CONFIG_DVB_LNBH29=n
+CONFIG_DVB_LNBP21=n
+CONFIG_DVB_LNBP22=n
+CONFIG_DVB_M88RS2000=n
+CONFIG_DVB_TDA665x=n
+CONFIG_DVB_DRX39XYJ=n
+CONFIG_DVB_CXD2099=n
+CONFIG_DVB_SP2=n
diff -Naur --no-dereference a/kernel/configs/ti_early_display.config b/kernel/configs/ti_early_display.config
--- a/kernel/configs/ti_early_display.config	1969-12-31 19:00:00.000000000 -0500
+++ b/kernel/configs/ti_early_display.config	2025-10-23 09:30:40.287462269 -0400
@@ -0,0 +1,235 @@
+##################################################
+# TI Early Display configs
+##################################################
+
+# Time measurements were perfomed on AM62x-SK and AM62Px-SK
+
+# Configurations that add to boot time have to be reduced
+# in order for display to come up as fast as possible
+
+### Necessary reduction ###
+
+# This config adds support for a virtual file system
+# that developers use to put debugging files into
+#
+# This reduces kernel image size by 335.9KB and boot time by 48ms
+CONFIG_DEBUG_FS=n
+
+# This config adds support for normal Windows file systems
+#
+# This reduces kernel image size by 131.1KB and boot time by 32ms
+CONFIG_VFAT_FS=m
+
+# Kernel can apply read-only permissions to linear aliases of VM areas. This
+# provides extra layer of protection against advertent/inadvertent modification
+# of read-only data through the linear alias. While its a useful security
+# feature, it has a performance impact.
+#
+#This reduces kernel image size by 0KB and boot time by 144ms
+CONFIG_RODATA_FULL_DEFAULT_ENABLED=n
+
+# Remove SPI support
+#
+# This reduces kernel image size by 208.9KB and reduces boot time by 16ms
+CONFIG_SPI=n
+
+# This adds support for PTP support used to precisely synchronize
+# distributed clocks over Ethernet networks
+#
+# This reduces kernel image size by 69.6KB and reduces boot time by 64ms
+CONFIG_PTP_1588_CLOCK=m
+
+# Remove MMC support
+#
+# This reduces kernel image size by 137.2KB and reduces boot time by 32ms
+CONFIG_MMC=m
+
+
+### Additional reduction ###
+
+# These configs reduce boot time by 64ms
+CONFIG_PPS=m
+CONFIG_PSTORE=m
+CONFIG_CPU_FREQ=n
+
+CONFIG_OVERLAY_FS=n
+CONFIG_SQUASHFS=m
+
+CONFIG_COMMON_CLK_SCMI=m
+CONFIG_COMMON_CLK_RS9_PCIE=n
+CONFIG_RESET_SCMI=m
+
+CONFIG_PHY_CADENCE_SIERRA=m
+CONFIG_PHY_XGENE=m
+CONFIG_REALTEK_PHY=m
+
+CONFIG_REGULATOR_AXP20X=m
+CONFIG_MEDIA_CEC_SUPPORT=n
+CONFIG_TCG_TPM=m
+
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_CMDLINE_PARTS=m
+CONFIG_MTD_COMPLEX_MAPPINGS=n
+CONFIG_MTD_RAW_NAND=m
+CONFIG_MTD_SPI_NAND=m
+CONFIG_MTD_UBI=m
+CONFIG_UBIFS_FS=m
+
+CONFIG_MULTIPLEXER=m
+CONFIG_MUX_MMIO=m
+CONFIG_SECTION_MISMATCH_WARN_ONLY=n
+
+CONFIG_KEXEC=n
+CONFIG_KEXEC_FILE=n
+CONFIG_TASKSTATS=n
+CONFIG_ATA=m
+
+CONFIG_RUNTIME_TESTING_MENU=n
+CONFIG_STACKTRACE=n
+CONFIG_SYMBOLIC_ERRNAME=n
+CONFIG_INDIRECT_PIO=n
+CONFIG_QUOTA=n
+
+CONFIG_XDP_SOCKETS=n
+CONFIG_COMMON_CLK_VC3=m
+
+# Disable ARMv8.1+ architecture features. TI K3 processors
+# are based on ARMv8.0, and these features are not applicable.
+CONFIG_ARM64_CNP=n
+CONFIG_ARM64_HW_AFDBM=n
+CONFIG_ARM64_PAN=n
+CONFIG_ARM64_RAS_EXTN=n
+CONFIG_ARM64_USE_LSE_ATOMICS=n
+# End of architecture features
+
+CONFIG_SOCIONEXT_SYNQUACER_PREITS=n
+CONFIG_MEMORY_HOTPLUG=n
+
+CONFIG_BSD_PROCESS_ACCT=n
+CONFIG_CPU_ISOLATION=n
+CONFIG_IRQ_TIME_ACCOUNTING=n
+CONFIG_POSIX_MQUEUE=n
+CONFIG_PROFILING=n
+
+CONFIG_RD_BZIP2=n
+CONFIG_RD_LZ4=n
+CONFIG_RD_LZMA=n
+CONFIG_RD_LZO=n
+CONFIG_RD_XZ=n
+CONFIG_RD_ZSTD=n
+
+CONFIG_EXTCON=m
+CONFIG_FPGA=m
+CONFIG_HWMON=m
+CONFIG_HWSPINLOCK=n
+CONFIG_I2C_ALGOBIT=m
+CONFIG_IIO=m
+CONFIG_INTERCONNECT=n
+CONFIG_MD=n
+CONFIG_MEMORY=n
+CONFIG_NEW_LEDS=n
+CONFIG_PCI=n
+CONFIG_PWM=n
+CONFIG_RTC_CLASS=n
+CONFIG_SOUND=m
+
+CONFIG_STAGING=n
+CONFIG_THERMAL=n
+CONFIG_USB_SUPPORT=n
+CONFIG_VFIO=m
+CONFIG_VHOST_MENU=n
+CONFIG_VIRTIO_MENU=n
+CONFIG_AT803X_PHY=m
+CONFIG_FSL_RCPM=n
+CONFIG_INPUT_MATRIXKMAP=m
+CONFIG_INPUT_MISC=n
+CONFIG_INPUT_MOUSE=n
+CONFIG_INPUT_TOUCHSCREEN=n
+CONFIG_MDIO_BUS_MUX_MMIOREG=m
+CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m
+CONFIG_MICROSEMI_PHY=m
+CONFIG_MOTORCOMM_PHY=m
+
+CONFIG_PHY_AM654_SERDES=m
+CONFIG_PHY_CADENCE_TORRENT=m
+
+CONFIG_RESET_SIMPLE=n
+CONFIG_RPMSG_KDRV=m
+CONFIG_RPMSG_KDRV_ETH_SWITCH=m
+CONFIG_RPMSG_VIRTIO=m
+CONFIG_SCSI=m
+CONFIG_SERIO_AMBAKMI=m
+CONFIG_SERIO_LIBPS2=m
+CONFIG_TUN=m
+CONFIG_VIRTIO_NET=m
+CONFIG_VITESSE_PHY=m
+CONFIG_WLAN=n
+CONFIG_GPIO_GENERIC_PLATFORM=m
+CONFIG_I2C_SLAVE=n
+CONFIG_GPIO_TPS65219=m
+CONFIG_GPIO_SYSCON=m
+
+CONFIG_MFD_HI6421_PMIC=m
+CONFIG_MFD_MAX77620=n
+CONFIG_MFD_MT6397=m
+CONFIG_MFD_ROHM_BD718XX=m
+CONFIG_MFD_RK8XX=n
+CONFIG_MFD_RK8XX_I2C=n
+
+CONFIG_POWER_RESET_BRCMSTB=n
+
+CONFIG_REGULATOR_BD9571MWV=m
+CONFIG_REGULATOR_FAN53555=m
+CONFIG_REGULATOR_MP8859=m
+CONFIG_REGULATOR_PCA9450=m
+CONFIG_REGULATOR_PF8X00=m
+CONFIG_REGULATOR_PFUZE100=m
+CONFIG_REGULATOR_TPS65219=m
+CONFIG_SERIAL_FSL_LINFLEXUART=m
+CONFIG_SERIAL_FSL_LPUART=m
+CONFIG_REGULATOR_RAA215300=n
+CONFIG_REGULATOR_RK808=n
+
+CONFIG_LEGACY_TIOCSTI=n
+
+CONFIG_TI_K3_AM65_CPSW_NUSS=m
+CONFIG_MARVELL_10G_PHY=n
+CONFIG_MDIO_BCM_UNIMAC=n
+
+CONFIG_HID_A4TECH=n
+CONFIG_HID_BELKIN=n
+CONFIG_HID_CHERRY=n
+CONFIG_HID_CYPRESS=n
+CONFIG_HID_EZKEY=n
+CONFIG_HID_ITE=n
+CONFIG_HID_KENSINGTON=n
+CONFIG_HID_REDRAGON=n
+CONFIG_HID_MICROSOFT=n
+CONFIG_HID_MONTEREY=n
+
+# These configs enable Display drivers and add 600KB to the kernel Image.
+# Note that SK-AM62A does not support OLDI and has support for HDMI alone.
+# In an early display scenario for SK-AM62A, the following configs are not useful.
+CONFIG_DRM=y
+CONFIG_DRM_TIDSS=y
+CONFIG_FB_SIMPLE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_DRM_PANEL_LVDS=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=n
+CONFIG_LOGO=n
+
+# Disable additional Docker configs
+CONFIG_MEMCG_SWAP=n
+CONFIG_CFS_BANDWIDTH=n
+CONFIG_CGROUP_NET_PRIO=n
+CONFIG_IP_VS_NFCT=n
+CONFIG_IP_VS_PROTO_TCP=n
+CONFIG_IP_VS_PROTO_UDP=n
+CONFIG_BLK_DEV_THROTTLING=n
+CONFIG_SECURITY_SELINUX=n
+CONFIG_SECURITY_APPARMOR=n
+CONFIG_XFRM=n
+CONFIG_XFRM_USER=n
+CONFIG_XFRM_ALGO=n
+CONFIG_INET_ESP=n
diff -Naur --no-dereference a/kernel/configs/ti_multi_v7_prune.config b/kernel/configs/ti_multi_v7_prune.config
--- a/kernel/configs/ti_multi_v7_prune.config	1969-12-31 19:00:00.000000000 -0500
+++ b/kernel/configs/ti_multi_v7_prune.config	2025-10-23 09:30:40.287462269 -0400
@@ -0,0 +1,178 @@
+# Add config flags here that appear in the multi_v7_defconfig but are not
+# used by a kernel targeting only the currently supported TI EVMs
+
+# Do not set system time from RTC on startup. This should be handled by
+# userspace utilities since most boards do not have a battery backed RTC.
+CONFIG_RTC_HCTOSYS=n
+
+# Non-TI Architectures
+CONFIG_ARCH_AIROHA=n
+CONFIG_ARCH_ACTIONS=n
+CONFIG_ARCH_ALPINE=n
+CONFIG_ARCH_ARTPEC=n
+CONFIG_ARCH_ASPEED=n
+CONFIG_ARCH_AT91=n
+CONFIG_ARCH_BCM=n
+CONFIG_ARCH_BCM_CYGNUS=n
+CONFIG_ARCH_BCM_NSP=n
+CONFIG_ARCH_BCM_5301X=n
+CONFIG_ARCH_BCM_281XX=n
+CONFIG_ARCH_BCM_21664=n
+CONFIG_ARCH_BRCMSTB=n
+CONFIG_ARCH_BERLIN=n
+CONFIG_ARCH_DIGICOLOR=n
+CONFIG_ARCH_HIGHBANK=n
+CONFIG_ARCH_HISI=n
+CONFIG_ARCH_HI3xxx=n
+CONFIG_ARCH_HIP01=n
+CONFIG_ARCH_HIP04=n
+CONFIG_ARCH_HIX5HD2=n
+CONFIG_ARCH_HPE=n
+CONFIG_ARCH_HPE_GXP=n
+CONFIG_ARCH_INTEL_SOCFPGA=n
+CONFIG_ARCH_MESON=n
+CONFIG_ARCH_MXC=n
+CONFIG_ARCH_MEDIATEK=n
+CONFIG_ARCH_MILBEAUT=n
+CONFIG_ARCH_QCOM=n
+CONFIG_ARCH_MMP=n
+CONFIG_ARCH_MSM8X60=n
+CONFIG_ARCH_MSM8960=n
+CONFIG_ARCH_MSM8974=n
+CONFIG_ARCH_ROCKCHIP=n
+CONFIG_ARCH_SOCFPGA=n
+CONFIG_ARCH_SPEAR13XX=n
+CONFIG_ARCH_STI=n
+CONFIG_ARCH_EXYNOS=n
+CONFIG_ARCH_SHMOBILE_MULTI=n
+CONFIG_ARCH_EMEV2=n
+CONFIG_ARCH_R7S72100=n
+CONFIG_ARCH_R8A73A4=n
+CONFIG_ARCH_R8A7740=n
+CONFIG_ARCH_R8A7778=n
+CONFIG_ARCH_R8A7779=n
+CONFIG_ARCH_R8A7790=n
+CONFIG_ARCH_R8A7791=n
+CONFIG_ARCH_R8A7793=n
+CONFIG_ARCH_R8A7794=n
+CONFIG_ARCH_RENESAS=n
+CONFIG_ARCH_SH73A0=n
+CONFIG_ARCH_SUNPLUS=y
+CONFIG_ARCH_SUNXI=n
+CONFIG_ARCH_STM32=n
+CONFIG_ARCH_SIRF=n
+CONFIG_ARCH_TEGRA=n
+CONFIG_ARCH_TEGRA_2x_SOC=n
+CONFIG_ARCH_TEGRA_3x_SOC=n
+CONFIG_ARCH_TEGRA_114_SOC=n
+CONFIG_ARCH_TEGRA_124_SOC=n
+CONFIG_ARCH_UNIPHIER=n
+CONFIG_ARCH_U8500=n
+CONFIG_ARCH_VEXPRESS=n
+CONFIG_ARCH_VEXPRESS_TC2_PM=n
+CONFIG_ARCH_WM8850=n
+CONFIG_ARCH_ZYNQ=n
+CONFIG_ARCH_VIRT=n
+CONFIG_ARCH_MVEBU=n
+CONFIG_PLAT_SPEAR=n
+CONFIG_CHROME_PLATFORMS=n
+
+# Multifunction device drivers
+CONFIG_MFD_AS3711=n
+CONFIG_MFD_AS3722=n
+CONFIG_MFD_ATMEL_FLEXCOM=n
+CONFIG_MFD_ATMEL_HLCDC=n
+CONFIG_MFD_BCM590XX=n
+CONFIG_MFD_AXP20X_I2C=n
+CONFIG_MFD_DA9063=n
+CONFIG_MFD_MAX14577=n
+CONFIG_MFD_MAX77686=n
+CONFIG_MFD_MAX77693=n
+CONFIG_MFD_MAX8907=n
+CONFIG_MFD_MAX8997=n
+CONFIG_MFD_MAX8998=n
+CONFIG_MFD_PM8XXX=n
+CONFIG_MFD_RK808=n
+CONFIG_MFD_RN5T618=n
+CONFIG_MFD_SEC_CORE=n
+CONFIG_MFD_STMPE=n
+
+# Regulators
+CONFIG_REGULATOR_ACT8865=n
+CONFIG_REGULATOR_DA9210=n
+CONFIG_REGULATOR_FAN53555=n
+CONFIG_REGULATOR_LP872X=n
+CONFIG_REGULATOR_MAX8952=n
+CONFIG_REGULATOR_MAX8973=n
+CONFIG_REGULATOR_PWM=n
+CONFIG_REGULATOR_TPS51632=n
+CONFIG_REGULATOR_TWL4030=n
+
+# RTC drivers
+CONFIG_RTC_DRV_HYM8563=n
+CONFIG_RTC_DRV_RS5C372=n
+CONFIG_RTC_DRV_BQ32K=n
+CONFIG_RTC_DRV_S35390A=n
+CONFIG_RTC_DRV_RX8581=n
+CONFIG_RTC_DRV_EM3027=n
+
+# Watchdog Device Drivers
+CONFIG_XILINX_WATCHDOG=n
+CONFIG_DW_WATCHDOG=n
+
+# GPIO
+CONFIG_GPIO_DWAPB=n
+CONFIG_GPIO_XILINX=n
+CONFIG_GPIO_TPS6586X=n
+
+# Sound
+CONFIG_SND_ARM=n
+CONFIG_SND_SPI=n
+CONFIG_SND_ATMEL_SOC=n
+CONFIG_SND_SOC_FSL_SAI=n
+CONFIG_SND_SOC_AK4642=n
+CONFIG_SND_SOC_CPCAP=n
+CONFIG_SND_SOC_SGTL5000=n
+CONFIG_SND_SOC_STI_SAS=n
+CONFIG_SND_SOC_WM8978=n
+
+# DRM
+CONFIG_VGA_ARB=n
+CONFIG_DRM_I2C_ADV7511=n
+CONFIG_DRM_NOUVEAU=n
+CONFIG_DRM_EXYNOS=n
+CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=n
+CONFIG_DRM_NXP_PTN3460=n
+CONFIG_DRM_PARADE_PS8622=n
+CONFIG_DRM_STI=n
+CONFIG_DRM_PANEL_SAMSUNG_LD9040=n
+CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=n
+CONFIG_DRM_DUMB_VGA_DAC=n
+CONFIG_DRM_HISI_KIRIN=n
+CONFIG_DRM_RCAR_LVDS=n
+CONFIG_DRM_FSL_DCU=n
+CONFIG_DRM_SII9234=n
+CONFIG_DRM_MXSFB=n
+CONFIG_DRM_HISI_HIBMC=n
+CONFIG_DRM_ATMEL_HLCDC=n
+CONFIG_DRM_STM=n
+CONFIG_DRM_PANEL_ORISETECH_OTM8009A=n
+CONFIG_DRM_PANEL_RAYDIUM_RM68200=n
+CONFIG_DRM_TOSHIBA_TC358764=n
+CONFIG_DRM_ETNAVIV=n
+CONFIG_DRM_PL111=n
+CONFIG_DRM_LIMA=n
+CONFIG_DRM_PANFROST=n
+
+# Video
+CONFIG_LCD_CLASS_DEVICE=n
+CONFIG_FB_EFI=n
+CONFIG_FB_SIMPLE=n
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=n
+CONFIG_FB_ARMCLCD=n
+CONFIG_XEN_FBDEV_FRONTEND=n
+
+# USB
+CONFIG_USB_DWC2=n
+CONFIG_USB_CHIPIDEA=n
+CONFIG_USB_ISP1760=n
diff -Naur --no-dereference a/kernel/configs/ti_rt.config b/kernel/configs/ti_rt.config
--- a/kernel/configs/ti_rt.config	1969-12-31 19:00:00.000000000 -0500
+++ b/kernel/configs/ti_rt.config	2025-10-23 09:30:40.287462269 -0400
@@ -0,0 +1,231 @@
+##################################################
+# Real Time Linux Configs
+##################################################
+
+CONFIG_EXPERT=y
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_RT=y
+
+# max out the kernel's tick
+#
+# Ideally this is a balance. Increasing this means we
+# spend more time in the scheduler deciding what we
+# should do and less time on doing it however this
+# also minimizes the time spent running a low-priority
+# task while a real-time priority task is awake
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+
+# omit scheduling ticks for CPUs with a single task
+#
+# If a CPU has only one runnable task there is little
+# need to contiguously interrupt it as there is no other
+# task for it to switch to. This comes at the cost of having
+# to offload the CPU's RCU callbacks to another CPU with
+# an active tick.
+#
+# For workloads with many short-lived tasks HZ_PERIODIC may
+# be the better selection as adaptive-tick modes does not
+# come without tradeoffs. For example the user-to kernel
+# transitions are slightly more expensive
+CONFIG_NO_HZ_FULL=y
+CONFIG_CONTEXT_TRACKING_USER=y
+
+# track our RCU callbacks
+#
+# there are situations in which idle CPUs cannot enter
+# a dynctick or adaptive-tick mode, the most common reason
+# being when a CPU has RCU callbacks pending. However boosting
+# this thread will compete with the realtime task. So let's
+# disable this for now.
+CONFIG_RCU_NOCB_CPU_DEFAULT_ALL=n
+CONFIG_RCU_BOOST=n
+
+# memory management tuning
+#
+# The SLUB allocator (default allocator used by the kernel)
+# uses per-cpu caches to accelerate allocation and freeing of
+# objects local to that processor. This comes at the cost of
+# more indeterminism when freeing. Remove this to remove jitter
+CONFIG_SLUB_CPU_PARTIAL=n
+
+# RCU system tuning
+#
+# The scheduler heavily utilizes the RCU subsystem to avoid
+# large amounts of locking that would be needed otherwise.
+# Removing this is showing to improve the am62x latency numbers
+# using stress-ng and cyclictest.
+CONFIG_RCU_TRACE=n
+
+# remove have kmemleak support
+#
+# Even-though the kmemleak detector is disabled, removing it
+# completely from the build is showing improvements for the
+# am62x latency numbers when monitoring with cyclictest and
+# stress-ng to generate a synthetic background load.
+CONFIG_HAVE_DEBUG_KMEMLEAK=n
+
+# Disable debug features
+
+# CoreSight debug and trace drivers are not typically used in
+# production. Keep them disabled by default. Users can enable
+# when debugging is needed.
+CONFIG_CORESIGHT=n
+
+# Remove support for symbolic crash dumps. These are useful
+# while debugging and not must have for production. This also
+# helps reduce kernel size.
+CONFIG_KALLSYMS=n
+
+# Disable profiling support. Not needed on a production system.
+CONFIG_PROFILING=n
+
+# Disable support for performance events. These are used only
+# for development and debug. Not needed on production system.
+CONFIG_PERF_EVENTS=n
+
+# Disable eBPF support which is typically used for tracing and
+# profiling. This prevents users from loading eBPF programs
+# but BPF usage within the kernel should still work. Disabling
+# JIT compiler will slow down packet filtering.
+CONFIG_BPF_SYSCALL=n
+CONFIG_BPF_JIT=n
+
+# Fine granularity IRQ time accounting is not needed on a
+# production system.
+CONFIG_IRQ_TIME_ACCOUNTING=n
+
+# Disable ARMv8.1+ architecture featurres. TI processors are based
+# on ARMv8.0, and these feaures are not applicable. If enabled
+# they increase worst case latency from 41 usec to 83 usec when
+# tested on AM62x silicon with 1 hour cyclictest.
+CONFIG_ARM64_HW_AFDBM=n
+CONFIG_ARM64_PAN=n
+CONFIG_ARM64_USE_LSE_ATOMICS=n
+CONFIG_ARM64_RAS_EXTN=n
+CONFIG_ARM64_CNP=n
+CONFIG_ARM64_PTR_AUTH=n
+CONFIG_ARM64_AMU_EXTN=n
+CONFIG_ARM64_TLB_RANGE=n
+CONFIG_ARM64_BTI=n
+CONFIG_ARM64_E0PD=n
+
+# Disable group scheduling. We already disable RT_GROUP_SCHEDULING since
+# there is no way to meaningfully use it (see kernel/configs/ti_arm64_prune.config).
+# Disable group scheduling as such on RT kernel - the main focus anyway
+# is on RT tasks there.
+CONFIG_SCHED_AUTOGROUP=n
+
+# Disable symmetric multi-threading scheduler. Its not used on ARM64
+CONFIG_SCHED_SMT=n
+
+# Kernel stack base address randomization helps frustate attacks that depend on
+# stack address determinism. But it has an impact on RT latency. Using 1 hour
+# cyclictest on AM62x, it was found to increase worst case latency from 50 usecs
+# to 69 usecs. For RT kernel alone, be biased towards better latency over extra
+# security.
+CONFIG_RANDOMIZE_KSTACK_OFFSET=n
+
+# Kernel can apply read-only permissions to linear aliases of VM areas. This
+# provides extra layer of protection against advertent/inadvertent modification
+# of read-only data through the linear alias. While its a useful security
+# feature, it has performance and RT latency impact. When testing on AM62x
+# hardware using cyclictest running for 1 hour, the worst case latency increased
+# from 50 usecs to 58 usecs when this feature was enabled.
+CONFIG_RODATA_FULL_DEFAULT_ENABLED=n
+
+# Kernel page table isolation (KAISER)  unmaps kernel page tables when in EL0
+# to mitigate speculation attacks that enable privilege bypass. Note that CPUs
+# used on K3 SoCs are not impacted by meltdown vulnerability (CVE-2017-5754).
+# Using a 6 hour cyclictest, enabling KAISER was seen to increase worst case
+# latency by about 20 usecs (increase from 50 usecs to 70 usecs on AM62x hardware
+# using cutdown configuration designed to minimizeRT latency)
+CONFIG_UNMAP_KERNEL_AT_EL0=n
+
+# We have little need for page pool statistics. Because this has a impact for the
+# CPU when allocating and recycling pages just disable it.
+CONFIG_PAGE_POOL_STATS=n
+
+# While process accounting statistics is useful, the number of processes and
+# all the accounting needed for them has an affect on RT reponsiveness.
+CONFIG_BSD_PROCESS_ACCT=n
+CONFIG_TASKSTATS=n
+
+# Disable control groups which are not minimum required by systemd and docker.
+# These can be enabled as per need of end application.
+#
+# Keeping device control group enabled as docker example does not start without
+# it.
+#
+# Having these enabled has an impact on RT latency. Using AM62x, using cyclictest,
+# a 40 usecs latency impact was seen (worst case latency went from 50 usecs to 90
+# usecs)
+CONFIG_MEMCG=n
+CONFIG_BLK_CGROUP=n
+CONFIG_CGROUP_SCHED=n
+CONFIG_CGROUP_PIDS=n
+CONFIG_CGROUP_FREEZER=n
+CONFIG_CGROUP_HUGETLB=n
+CONFIG_CPUSETS=n
+CONFIG_CGROUP_CPUACCT=n
+CONFIG_CGROUP_PERF=n
+CONFIG_CGROUP_BPF=n
+
+# HACK: Remove security features with real-time latency effects.
+# Unless you have aggressive latency goals you will most likely
+# want these feature enabled. ;)
+CONFIG_ARM64_TAGGED_ADDR_ABI=n
+CONFIG_SECCOMP=n
+CONFIG_STACKPROTECTOR=n
+CONFIG_VMAP_STACK=n
+CONFIG_GCC_PLUGINS=n
+CONFIG_RANDOMIZE_BASE=n
+
+#Disable PM features
+CONFIG_HOTPLUG_CPU=n
+CONFIG_CPU_IDLE=n
+CONFIG_CPU_FREQ=n
+CONFIG_SUSPEND=n
+
+# Following configs are required in non-RT kernels to enable complete docker functionality.
+# However, disable them in RT kernels since they impact latency test results.
+CONFIG_DUMMY=n
+CONFIG_MEMCG_SWAP=n
+CONFIG_CFS_BANDWIDTH=n
+CONFIG_CGROUP_NET_PRIO=n
+CONFIG_IPVLAN=n
+CONFIG_NF_NAT_FTP=n
+CONFIG_NF_NAT_TFTP=n
+CONFIG_NF_CONNTRACK_FTP=n
+CONFIG_NF_CONNTRACK_TFTP=n
+CONFIG_NETFILTER_XT_MATCH_BPF=n
+CONFIG_IP_VS_NFCT=n
+CONFIG_IP_VS_PROTO_TCP=n
+CONFIG_IP_VS_PROTO_UDP=n
+CONFIG_IP_VS_RR=n
+CONFIG_IP_NF_TARGET_REDIRECT=n
+CONFIG_NET_CLS_CGROUP=n
+CONFIG_BLK_DEV_THROTTLING=n
+CONFIG_VXLAN=n
+CONFIG_SECURITY_SELINUX=n
+CONFIG_SECURITY_APPARMOR=n
+CONFIG_CRYPTO_SEQIV=n
+CONFIG_XFRM=n
+CONFIG_XFRM_USER=n
+CONFIG_XFRM_ALGO=n
+CONFIG_INET_ESP=n
+# Following configs aren't required for full docker functionality, but end up getting enabled
+# or changing values (y -> m) compared to what they were before the docker configs were enabled.
+# Hence explictly state their correct values for RT.
+CONFIG_CGROUP_NET_CLASSID=n
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CTR=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_GHASH=m
+CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,ipe,bpf"
+CONFIG_NETFILTER_XT_TARGET_REDIRECT=n
+CONFIG_NETWORK_SECMARK=n
+CONFIG_NET_L3_MASTER_DEV=n
+CONFIG_SECURITY_NETWORK=n
+CONFIG_SECURITY_PATH=n
diff -Naur --no-dereference a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
--- a/kernel/rcu/rcutorture.c	2025-06-19 09:32:38.000000000 -0400
+++ b/kernel/rcu/rcutorture.c	2025-10-23 09:30:40.287462269 -0400
@@ -2440,6 +2440,14 @@
 		WARN_ON_ONCE(!t);
 		sp.sched_priority = 2;
 		sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
+#ifdef CONFIG_IRQ_FORCED_THREADING
+		if (force_irqthreads()) {
+			t = per_cpu(ktimerd, cpu);
+			WARN_ON_ONCE(!t);
+			sp.sched_priority = 2;
+			sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
+		}
+#endif
 	}
 
 	/* Don't allow time recalculation while creating a new task. */
diff -Naur --no-dereference a/kernel/softirq.c b/kernel/softirq.c
--- a/kernel/softirq.c	2025-06-19 09:32:38.000000000 -0400
+++ b/kernel/softirq.c	2025-10-23 09:30:40.287462269 -0400
@@ -649,6 +649,24 @@
 #endif
 }
 
+#ifdef CONFIG_IRQ_FORCED_THREADING
+DEFINE_PER_CPU(struct task_struct *, ktimerd);
+DEFINE_PER_CPU(unsigned long, pending_timer_softirq);
+
+static void wake_timersd(void)
+{
+	struct task_struct *tsk = __this_cpu_read(ktimerd);
+
+	if (tsk)
+		wake_up_process(tsk);
+}
+
+#else
+
+static inline void wake_timersd(void) { }
+
+#endif
+
 static inline void __irq_exit_rcu(void)
 {
 #ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED
@@ -661,6 +679,10 @@
 	if (!in_interrupt() && local_softirq_pending())
 		invoke_softirq();
 
+	if (IS_ENABLED(CONFIG_IRQ_FORCED_THREADING) && force_irqthreads() &&
+	    local_timers_pending_force_th() && !(in_nmi() | in_hardirq()))
+		wake_timersd();
+
 	tick_irq_exit();
 }
 
@@ -996,12 +1018,57 @@
 	.thread_comm		= "ksoftirqd/%u",
 };
 
+#ifdef CONFIG_IRQ_FORCED_THREADING
+static void ktimerd_setup(unsigned int cpu)
+{
+	/* Above SCHED_NORMAL to handle timers before regular tasks. */
+	sched_set_fifo_low(current);
+}
+
+static int ktimerd_should_run(unsigned int cpu)
+{
+	return local_timers_pending_force_th();
+}
+
+void raise_ktimers_thread(unsigned int nr)
+{
+	trace_softirq_raise(nr);
+	__this_cpu_or(pending_timer_softirq, BIT(nr));
+}
+
+static void run_ktimerd(unsigned int cpu)
+{
+	unsigned int timer_si;
+
+	ksoftirqd_run_begin();
+
+	timer_si = local_timers_pending_force_th();
+	__this_cpu_write(pending_timer_softirq, 0);
+	or_softirq_pending(timer_si);
+
+	__do_softirq();
+
+	ksoftirqd_run_end();
+}
+
+static struct smp_hotplug_thread timer_thread = {
+	.store			= &ktimerd,
+	.setup			= ktimerd_setup,
+	.thread_should_run	= ktimerd_should_run,
+	.thread_fn		= run_ktimerd,
+	.thread_comm		= "ktimers/%u",
+};
+#endif
+
 static __init int spawn_ksoftirqd(void)
 {
 	cpuhp_setup_state_nocalls(CPUHP_SOFTIRQ_DEAD, "softirq:dead", NULL,
 				  takeover_tasklets);
 	BUG_ON(smpboot_register_percpu_thread(&softirq_threads));
-
+#ifdef CONFIG_IRQ_FORCED_THREADING
+	if (force_irqthreads())
+		BUG_ON(smpboot_register_percpu_thread(&timer_thread));
+#endif
 	return 0;
 }
 early_initcall(spawn_ksoftirqd);
diff -Naur --no-dereference a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
--- a/kernel/time/hrtimer.c	2025-06-19 09:32:38.000000000 -0400
+++ b/kernel/time/hrtimer.c	2025-10-23 09:30:40.287462269 -0400
@@ -1869,7 +1869,7 @@
 	if (!ktime_before(now, cpu_base->softirq_expires_next)) {
 		cpu_base->softirq_expires_next = KTIME_MAX;
 		cpu_base->softirq_activated = 1;
-		raise_softirq_irqoff(HRTIMER_SOFTIRQ);
+		raise_timer_softirq(HRTIMER_SOFTIRQ);
 	}
 
 	__hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD);
@@ -1964,7 +1964,7 @@
 	if (!ktime_before(now, cpu_base->softirq_expires_next)) {
 		cpu_base->softirq_expires_next = KTIME_MAX;
 		cpu_base->softirq_activated = 1;
-		raise_softirq_irqoff(HRTIMER_SOFTIRQ);
+		raise_timer_softirq(HRTIMER_SOFTIRQ);
 	}
 
 	__hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD);
diff -Naur --no-dereference a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
--- a/kernel/time/tick-sched.c	2025-06-19 09:32:38.000000000 -0400
+++ b/kernel/time/tick-sched.c	2025-10-23 09:30:40.287462269 -0400
@@ -865,7 +865,7 @@
 
 static inline bool local_timer_softirq_pending(void)
 {
-	return local_softirq_pending() & BIT(TIMER_SOFTIRQ);
+	return local_timers_pending() & BIT(TIMER_SOFTIRQ);
 }
 
 /*
diff -Naur --no-dereference a/kernel/time/timer.c b/kernel/time/timer.c
--- a/kernel/time/timer.c	2025-06-19 09:32:38.000000000 -0400
+++ b/kernel/time/timer.c	2025-10-23 09:30:40.287462269 -0400
@@ -2500,7 +2500,7 @@
 		 */
 		if (time_after_eq(jiffies, READ_ONCE(base->next_expiry)) ||
 		    (i == BASE_DEF && tmigr_requires_handle_remote())) {
-			raise_softirq(TIMER_SOFTIRQ);
+			raise_timer_softirq(TIMER_SOFTIRQ);
 			return;
 		}
 	}
diff -Naur --no-dereference a/lib/crc64.c b/lib/crc64.c
--- a/lib/crc64.c	2025-06-19 09:32:38.000000000 -0400
+++ b/lib/crc64.c	2025-10-23 09:30:40.287462269 -0400
@@ -22,6 +22,11 @@
  * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
  * x^7 + x^4 + x + 1
  *
+ * crc64iso3309table[256] table is from the ISO-3309:1991 specification
+ * polynomial defined as,
+ *
+ * x^64 + x^4 + x^3 + x + 1
+ *
  * crc64rocksoft[256] table is from the Rocksoft specification polynomial
  * defined as,
  *
@@ -64,6 +69,28 @@
 EXPORT_SYMBOL_GPL(crc64_be);
 
 /**
+ * crc64_iso3309_generic - Calculate bitwise ISO3309 CRC64
+ * @crc: seed value for computation. 0 for a new CRC calculation, or the
+ *	 previous crc64 value if computing incrementally.
+ * @p: pointer to buffer over which CRC64 is run
+ * @len: length of buffer @p
+ */
+u64 __pure crc64_iso3309_generic(u64 crc, const void *p, size_t len)
+{
+	size_t i, t;
+
+	const unsigned char *_p = p;
+
+	for (i = 0; i < len; i++) {
+		t = ((crc >> 56) ^ (*_p++)) & 0xFF;
+		crc = crc64iso3309table[t] ^ (crc << 8);
+	}
+
+	return crc;
+}
+EXPORT_SYMBOL_GPL(crc64_iso3309_generic);
+
+/**
  * crc64_rocksoft_generic - Calculate bitwise Rocksoft CRC64
  * @crc: seed value for computation. 0 for a new CRC calculation, or the
  * 	 previous crc64 value if computing incrementally.
diff -Naur --no-dereference a/lib/gen_crc64table.c b/lib/gen_crc64table.c
--- a/lib/gen_crc64table.c	2025-06-19 09:32:38.000000000 -0400
+++ b/lib/gen_crc64table.c	2025-10-23 09:30:40.287462269 -0400
@@ -17,9 +17,11 @@
 #include <stdio.h>
 
 #define CRC64_ECMA182_POLY 0x42F0E1EBA9EA3693ULL
+#define CRC64_ISO3309_POLY 0x000000000000001BULL
 #define CRC64_ROCKSOFT_POLY 0x9A6C9329AC4BC9B5ULL
 
 static uint64_t crc64_table[256] = {0};
+static uint64_t crc64_iso3309_table[256] = {0};
 static uint64_t crc64_rocksoft_table[256] = {0};
 
 static void generate_reflected_crc64_table(uint64_t table[256], uint64_t poly)
@@ -82,6 +84,9 @@
 	printf("static const u64 ____cacheline_aligned crc64table[256] = {\n");
 	output_table(crc64_table);
 
+	printf("\nstatic const u64 ____cacheline_aligned crc64iso3309table[256] = {\n");
+	output_table(crc64_iso3309_table);
+
 	printf("\nstatic const u64 ____cacheline_aligned crc64rocksofttable[256] = {\n");
 	output_table(crc64_rocksoft_table);
 }
@@ -89,6 +94,7 @@
 int main(int argc, char *argv[])
 {
 	generate_crc64_table(crc64_table, CRC64_ECMA182_POLY);
+	generate_crc64_table(crc64_iso3309_table, CRC64_ISO3309_POLY);
 	generate_reflected_crc64_table(crc64_rocksoft_table, CRC64_ROCKSOFT_POLY);
 	print_crc64_tables();
 	return 0;
diff -Naur --no-dereference a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	2025-06-19 09:32:38.000000000 -0400
+++ b/MAINTAINERS	2025-10-23 09:30:40.281462084 -0400
@@ -7739,6 +7739,7 @@
 L:	dri-devel@lists.freedesktop.org
 S:	Maintained
 T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
+F:	Documentation/devicetree/bindings/display/ti/ti,am625-oldi.yaml
 F:	Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
 F:	Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml
 F:	Documentation/devicetree/bindings/display/ti/ti,k2g-dss.yaml
@@ -17029,6 +17030,16 @@
 T:	git git://linuxtv.org/media.git
 F:	drivers/media/i2c/ov08x40.c
 
+OMNIVISION OV1063x SENSOR DRIVER
+M:	Benoit Parrot <bparrot@ti.com>
+M:	Sukrut Bellary <sbellary@baylibre.com>
+L:	linux-media@vger.kernel.org
+S:	Maintained
+T:	git git://linuxtv.org/media_tree.git
+F:	Documentation/devicetree/bindings/media/i2c/ov1063x.yaml
+F:	drivers/media/i2c/ov1063x.c
+F:	drivers/media/i2c/ov1063x_regs.h
+
 OMNIVISION OV13858 SENSOR DRIVER
 M:	Sakari Ailus <sakari.ailus@linux.intel.com>
 L:	linux-media@vger.kernel.org
@@ -21546,6 +21557,13 @@
 F:	Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml
 F:	drivers/media/i2c/imx415.c
 
+SONY IMX728 SENSOR DRIVER
+M:	Stuart Burtner <sburtner@d3embedded.com>
+L:	linux-media@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/i2c/sony,imx728.yaml
+F:	drivers/media/i2c/imx728.c
+
 SONY MEMORYSTICK SUBSYSTEM
 M:	Maxim Levitsky <maximlevitsky@gmail.com>
 M:	Alex Dubov <oakad@yahoo.com>
@@ -23122,6 +23140,13 @@
 F:	drivers/clk/ti/
 F:	include/linux/clk/ti.h
 
+TI DATA TRANSFORM AND HASHING ENGINE (DTHE) V2 CRYPTO ACCELERATOR DRIVER
+M:	T Pratham <t-pratham@ti.com>
+L:	linux-crypto@vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/crypto/ti,dthev2.yaml
+F:	drivers/crypto/ti/
+
 TI DAVINCI MACHINE SUPPORT
 M:	Bartosz Golaszewski <brgl@bgdev.pl>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -23231,6 +23256,7 @@
 F:	Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
 F:	drivers/pmdomain/ti/omap_prm.c
 F:	drivers/soc/ti/*
+F:	include/linux/pruss_driver.h
 
 TI LM49xxx FAMILY ASoC CODEC DRIVERS
 M:	M R Swami Reddy <mr.swami.reddy@ti.com>
@@ -23248,6 +23274,13 @@
 F:	Documentation/devicetree/bindings/iio/adc/ti,lmp92064.yaml
 F:	drivers/iio/adc/ti-lmp92064.c
 
+TI MEMORY CYCLIC REDUNDANCY CHECK (MCRC64) DRIVER
+M:	Kamlesh Gurudasani <kamlesh@ti.com>
+L:	linux-crypto@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/crypto/ti,mcrc64.yaml
+F:	drivers/crypto/ti/mcrc64.c
+
 TI PCM3060 ASoC CODEC DRIVER
 M:	Kirill Marinushkin <k.marinushkin@gmail.com>
 L:	linux-sound@vger.kernel.org
@@ -23296,6 +23329,7 @@
 W:	http://linuxtv.org/
 Q:	http://patchwork.linuxtv.org/project/linux-media/list/
 F:	Documentation/devicetree/bindings/media/ti,cal.yaml
+F:	Documentation/devicetree/bindings/media/ti,vip.yaml
 F:	Documentation/devicetree/bindings/media/ti,vpe.yaml
 F:	drivers/media/platform/ti/cal/
 F:	drivers/media/platform/ti/vpe/
diff -Naur --no-dereference a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
--- a/net/core/dev_addr_lists.c	2025-06-19 09:32:38.000000000 -0400
+++ b/net/core/dev_addr_lists.c	2025-10-23 09:30:40.287462269 -0400
@@ -242,9 +242,9 @@
 	__hw_addr_del_entry(from_list, ha, false, false);
 }
 
-static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
-				   struct netdev_hw_addr_list *from_list,
-				   int addr_len)
+int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
+			    struct netdev_hw_addr_list *from_list,
+			    int addr_len)
 {
 	int err = 0;
 	struct netdev_hw_addr *ha, *tmp;
@@ -260,6 +260,7 @@
 	}
 	return err;
 }
+EXPORT_SYMBOL(__hw_addr_sync_multiple);
 
 /* This function only works where there is a strict 1-1 relationship
  * between source and destination of they synch. If you ever need to
diff -Naur --no-dereference a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
--- a/net/hsr/hsr_device.c	2025-06-19 09:32:38.000000000 -0400
+++ b/net/hsr/hsr_device.c	2025-10-23 09:30:40.287462269 -0400
@@ -522,6 +522,77 @@
 	}
 }
 
+static int hsr_ndo_vlan_rx_add_vid(struct net_device *dev,
+				   __be16 proto, u16 vid)
+{
+	bool is_slave_a_added = false;
+	bool is_slave_b_added = false;
+	struct hsr_port *port;
+	struct hsr_priv *hsr;
+	int ret = 0;
+
+	hsr = netdev_priv(dev);
+
+	hsr_for_each_port(hsr, port) {
+		if (port->type == HSR_PT_MASTER ||
+		    port->type == HSR_PT_INTERLINK)
+			continue;
+
+		ret = vlan_vid_add(port->dev, proto, vid);
+		switch (port->type) {
+		case HSR_PT_SLAVE_A:
+			if (ret) {
+				/* clean up Slave-B */
+				netdev_err(dev, "add vid failed for Slave-A\n");
+				if (is_slave_b_added)
+					vlan_vid_del(port->dev, proto, vid);
+				return ret;
+			}
+
+			is_slave_a_added = true;
+			break;
+
+		case HSR_PT_SLAVE_B:
+			if (ret) {
+				/* clean up Slave-A */
+				netdev_err(dev, "add vid failed for Slave-B\n");
+				if (is_slave_a_added)
+					vlan_vid_del(port->dev, proto, vid);
+				return ret;
+			}
+
+			is_slave_b_added = true;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int hsr_ndo_vlan_rx_kill_vid(struct net_device *dev,
+				    __be16 proto, u16 vid)
+{
+	struct hsr_port *port;
+	struct hsr_priv *hsr;
+
+	hsr = netdev_priv(dev);
+
+	hsr_for_each_port(hsr, port) {
+		switch (port->type) {
+		case HSR_PT_SLAVE_A:
+		case HSR_PT_SLAVE_B:
+			vlan_vid_del(port->dev, proto, vid);
+			break;
+		default:
+			break;
+		}
+	}
+
+	return 0;
+}
+
 static const struct net_device_ops hsr_device_ops = {
 	.ndo_change_mtu = hsr_dev_change_mtu,
 	.ndo_open = hsr_dev_open,
@@ -530,6 +601,8 @@
 	.ndo_change_rx_flags = hsr_change_rx_flags,
 	.ndo_fix_features = hsr_fix_features,
 	.ndo_set_rx_mode = hsr_set_rx_mode,
+	.ndo_vlan_rx_add_vid = hsr_ndo_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid = hsr_ndo_vlan_rx_kill_vid,
 };
 
 static const struct device_type hsr_type = {
@@ -578,14 +651,10 @@
 
 	dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
 			   NETIF_F_GSO_MASK | NETIF_F_HW_CSUM |
-			   NETIF_F_HW_VLAN_CTAG_TX;
+			   NETIF_F_HW_VLAN_CTAG_TX |
+			   NETIF_F_HW_VLAN_CTAG_FILTER;
 
 	dev->features = dev->hw_features;
-
-	/* VLAN on top of HSR needs testing and probably some work on
-	 * hsr_header_create() etc.
-	 */
-	dev->features |= NETIF_F_VLAN_CHALLENGED;
 }
 
 /* Return true if dev is a HSR master; return false otherwise.
@@ -596,6 +665,19 @@
 }
 EXPORT_SYMBOL(is_hsr_master);
 
+struct net_device *hsr_get_port_ndev(struct net_device *ndev,
+				     enum hsr_port_type pt)
+{
+	struct hsr_priv *hsr = netdev_priv(ndev);
+	struct hsr_port *port;
+
+	hsr_for_each_port(hsr, port)
+		if (port->type == pt)
+			return port->dev;
+	return NULL;
+}
+EXPORT_SYMBOL(hsr_get_port_ndev);
+
 /* Default multicast address for HSR Supervision frames */
 static const unsigned char def_multicast_addr[ETH_ALEN] __aligned(2) = {
 	0x01, 0x15, 0x4e, 0x00, 0x01, 0x00
@@ -661,6 +743,10 @@
 	    (slave[1]->features & NETIF_F_HW_HSR_FWD))
 		hsr->fwd_offloaded = true;
 
+	if ((slave[0]->features & NETIF_F_HW_VLAN_CTAG_FILTER) &&
+	    (slave[1]->features & NETIF_F_HW_VLAN_CTAG_FILTER))
+		hsr_dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+
 	res = register_netdevice(hsr_dev);
 	if (res)
 		goto err_unregister;
diff -Naur --no-dereference a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
--- a/net/hsr/hsr_forward.c	2025-06-19 09:32:38.000000000 -0400
+++ b/net/hsr/hsr_forward.c	2025-10-23 09:30:40.287462269 -0400
@@ -280,6 +280,7 @@
 				    struct hsr_port *port, u8 proto_version)
 {
 	struct hsr_ethhdr *hsr_ethhdr;
+	unsigned char *pc;
 	int lsdu_size;
 
 	/* pad to minimum packet size which is 60 + 6 (HSR tag) */
@@ -290,7 +291,18 @@
 	if (frame->is_vlan)
 		lsdu_size -= 4;
 
-	hsr_ethhdr = (struct hsr_ethhdr *)skb_mac_header(skb);
+	pc = skb_mac_header(skb);
+	if (frame->is_vlan)
+		/* This 4-byte shift (size of a vlan tag) does not
+		 * mean that the ethhdr starts there. But rather it
+		 * provides the proper environment for accessing
+		 * the fields, such as hsr_tag etc., just like
+		 * when the vlan tag is not there. This is because
+		 * the hsr tag is after the vlan tag.
+		 */
+		hsr_ethhdr = (struct hsr_ethhdr *)(pc + VLAN_HLEN);
+	else
+		hsr_ethhdr = (struct hsr_ethhdr *)pc;
 
 	hsr_set_path_id(hsr_ethhdr, port);
 	set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, lsdu_size);
@@ -368,7 +380,7 @@
 		return skb_clone(frame->skb_std, GFP_ATOMIC);
 	}
 
-	skb = skb_copy_expand(frame->skb_std, 0,
+	skb = skb_copy_expand(frame->skb_std, skb_headroom(frame->skb_std),
 			      skb_tailroom(frame->skb_std) + HSR_HLEN,
 			      GFP_ATOMIC);
 	return prp_fill_rct(skb, frame, port);
@@ -695,9 +707,6 @@
 			return -EINVAL;
 		vlan_hdr = (struct hsr_vlan_ethhdr *)skb_mac_header(skb);
 		proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto;
-		/* FIXME: */
-		netdev_warn_once(skb->dev, "VLAN not yet supported");
-		return -EINVAL;
 	}
 
 	frame->is_from_san = false;
diff -Naur --no-dereference a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
--- a/net/hsr/hsr_main.h	2025-06-19 09:32:38.000000000 -0400
+++ b/net/hsr/hsr_main.h	2025-10-23 09:30:40.287462269 -0400
@@ -121,15 +121,6 @@
 	struct hsr_sup_tag	hsr_sup;
 } __packed;
 
-enum hsr_port_type {
-	HSR_PT_NONE = 0,	/* Must be 0, used by framereg */
-	HSR_PT_SLAVE_A,
-	HSR_PT_SLAVE_B,
-	HSR_PT_INTERLINK,
-	HSR_PT_MASTER,
-	HSR_PT_PORTS,	/* This must be the last item in the enum */
-};
-
 /* PRP Redunancy Control Trailor (RCT).
  * As defined in IEC-62439-4:2012, the PRP RCT is really { sequence Nr,
  * Lan indentifier (LanId), LSDU_size and PRP_suffix = 0x88FB }.
diff -Naur --no-dereference a/README.md b/README.md
--- a/README.md	1969-12-31 19:00:00.000000000 -0500
+++ b/README.md	2025-10-23 09:30:40.281462084 -0400
@@ -0,0 +1,3 @@
+# Gitlab CI
+
+Job Status: https://openbeagle.org/beagleboard/linux/-/jobs
diff -Naur --no-dereference a/scripts/package/builddeb b/scripts/package/builddeb
--- a/scripts/package/builddeb	2025-06-19 09:32:38.000000000 -0400
+++ b/scripts/package/builddeb	2025-10-23 09:30:40.287462269 -0400
@@ -31,6 +31,7 @@
 	# Only some architectures with OF support have this target
 	if is_enabled CONFIG_OF_EARLY_FLATTREE && [ -d "${srctree}/arch/${SRCARCH}/boot/dts" ]; then
 		${MAKE} -f ${srctree}/Makefile INSTALL_DTBS_PATH="${pdir}/usr/lib/linux-image-${KERNELRELEASE}" dtbs_install
+		${MAKE} -f ${srctree}/Makefile INSTALL_DTBS_PATH="${pdir}/boot/dtbs/${KERNELRELEASE}" dtbs_install
 	fi
 
 	${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" INSTALL_MOD_STRIP=1 modules_install
diff -Naur --no-dereference a/sound/soc/ti/j721e-evm.c b/sound/soc/ti/j721e-evm.c
--- a/sound/soc/ti/j721e-evm.c	2025-06-19 09:32:38.000000000 -0400
+++ b/sound/soc/ti/j721e-evm.c	2025-10-23 09:30:40.287462269 -0400
@@ -915,8 +915,9 @@
 	mutex_init(&priv->mutex);
 	ret = devm_snd_soc_register_card(&pdev->dev, card);
 	if (ret)
-		dev_err(&pdev->dev, "devm_snd_soc_register_card() failed: %d\n",
-			ret);
+		dev_err_probe(&pdev->dev, ret,
+			      "devm_snd_soc_register_card() failed: %d\n",
+			      ret);
 
 	return ret;
 }
diff -Naur --no-dereference a/sound/soc/ti/Kconfig b/sound/soc/ti/Kconfig
--- a/sound/soc/ti/Kconfig	2025-06-19 09:32:38.000000000 -0400
+++ b/sound/soc/ti/Kconfig	2025-10-23 09:30:40.287462269 -0400
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 menu "Audio support for Texas Instruments SoCs"
-depends on DMA_OMAP || TI_EDMA || TI_K3_UDMA || COMPILE_TEST
+depends on DMA_OMAP || TI_EDMA || TI_K3_UDMA || TI_K3_UDMA_AM62L || COMPILE_TEST
 
 config SND_SOC_TI_EDMA_PCM
 	tristate
diff -Naur --no-dereference a/tools/testing/selftests/net/hsr/config b/tools/testing/selftests/net/hsr/config
--- a/tools/testing/selftests/net/hsr/config	2025-06-19 09:32:38.000000000 -0400
+++ b/tools/testing/selftests/net/hsr/config	2025-10-23 09:30:40.287462269 -0400
@@ -3,3 +3,4 @@
 CONFIG_HSR=y
 CONFIG_VETH=y
 CONFIG_BRIDGE=y
+CONFIG_VLAN_8021Q=m
diff -Naur --no-dereference a/tools/testing/selftests/net/hsr/hsr_ping.sh b/tools/testing/selftests/net/hsr/hsr_ping.sh
--- a/tools/testing/selftests/net/hsr/hsr_ping.sh	2025-06-19 09:32:38.000000000 -0400
+++ b/tools/testing/selftests/net/hsr/hsr_ping.sh	2025-10-23 09:30:40.287462269 -0400
@@ -175,6 +175,100 @@
 	ip -net "$ns3" link set hsr3 up
 }
 
+setup_vlan_interfaces() {
+	ip -net "$ns1" link add link hsr1 name hsr1.2 type vlan id 2
+	ip -net "$ns1" link add link hsr1 name hsr1.3 type vlan id 3
+	ip -net "$ns1" link add link hsr1 name hsr1.4 type vlan id 4
+	ip -net "$ns1" link add link hsr1 name hsr1.5 type vlan id 5
+
+	ip -net "$ns2" link add link hsr2 name hsr2.2 type vlan id 2
+	ip -net "$ns2" link add link hsr2 name hsr2.3 type vlan id 3
+	ip -net "$ns2" link add link hsr2 name hsr2.4 type vlan id 4
+	ip -net "$ns2" link add link hsr2 name hsr2.5 type vlan id 5
+
+	ip -net "$ns3" link add link hsr3 name hsr3.2 type vlan id 2
+	ip -net "$ns3" link add link hsr3 name hsr3.3 type vlan id 3
+	ip -net "$ns3" link add link hsr3 name hsr3.4 type vlan id 4
+	ip -net "$ns3" link add link hsr3 name hsr3.5 type vlan id 5
+
+	ip -net "$ns1" addr add 100.64.2.1/24 dev hsr1.2
+	ip -net "$ns1" addr add 100.64.3.1/24 dev hsr1.3
+	ip -net "$ns1" addr add 100.64.4.1/24 dev hsr1.4
+	ip -net "$ns1" addr add 100.64.5.1/24 dev hsr1.5
+
+	ip -net "$ns2" addr add 100.64.2.2/24 dev hsr2.2
+	ip -net "$ns2" addr add 100.64.3.2/24 dev hsr2.3
+	ip -net "$ns2" addr add 100.64.4.2/24 dev hsr2.4
+	ip -net "$ns2" addr add 100.64.5.2/24 dev hsr2.5
+
+	ip -net "$ns3" addr add 100.64.2.3/24 dev hsr3.2
+	ip -net "$ns3" addr add 100.64.3.3/24 dev hsr3.3
+	ip -net "$ns3" addr add 100.64.4.3/24 dev hsr3.4
+	ip -net "$ns3" addr add 100.64.5.3/24 dev hsr3.5
+
+	ip -net "$ns1" link set dev hsr1.2 up
+	ip -net "$ns1" link set dev hsr1.3 up
+	ip -net "$ns1" link set dev hsr1.4 up
+	ip -net "$ns1" link set dev hsr1.5 up
+
+	ip -net "$ns2" link set dev hsr2.2 up
+	ip -net "$ns2" link set dev hsr2.3 up
+	ip -net "$ns2" link set dev hsr2.4 up
+	ip -net "$ns2" link set dev hsr2.5 up
+
+	ip -net "$ns3" link set dev hsr3.2 up
+	ip -net "$ns3" link set dev hsr3.3 up
+	ip -net "$ns3" link set dev hsr3.4 up
+	ip -net "$ns3" link set dev hsr3.5 up
+
+}
+
+hsr_vlan_ping() {
+	do_ping "$ns1" 100.64.2.2
+	do_ping "$ns1" 100.64.3.2
+	do_ping "$ns1" 100.64.4.2
+	do_ping "$ns1" 100.64.5.2
+
+	do_ping "$ns1" 100.64.2.3
+	do_ping "$ns1" 100.64.3.3
+	do_ping "$ns1" 100.64.4.3
+	do_ping "$ns1" 100.64.5.3
+
+	do_ping "$ns2" 100.64.2.1
+	do_ping "$ns2" 100.64.3.1
+	do_ping "$ns2" 100.64.4.1
+	do_ping "$ns2" 100.64.5.1
+
+	do_ping "$ns2" 100.64.2.3
+	do_ping "$ns2" 100.64.3.3
+	do_ping "$ns2" 100.64.4.3
+	do_ping "$ns2" 100.64.5.3
+
+	do_ping "$ns3" 100.64.2.1
+	do_ping "$ns3" 100.64.3.1
+	do_ping "$ns3" 100.64.4.1
+	do_ping "$ns3" 100.64.5.1
+
+	do_ping "$ns3" 100.64.2.2
+	do_ping "$ns3" 100.64.3.2
+	do_ping "$ns3" 100.64.4.2
+	do_ping "$ns3" 100.64.5.2
+}
+
+run_vlan_tests() {
+	vlan_challenged_hsr1=$(ip net exec "$ns1" ethtool -k hsr1 | grep "vlan-challenged" | awk '{print $2}')
+	vlan_challenged_hsr2=$(ip net exec "$ns2" ethtool -k hsr2 | grep "vlan-challenged" | awk '{print $2}')
+	vlan_challenged_hsr3=$(ip net exec "$ns3" ethtool -k hsr3 | grep "vlan-challenged" | awk '{print $2}')
+
+	if [[ "$vlan_challenged_hsr1" = "off" || "$vlan_challenged_hsr2" = "off" || "$vlan_challenged_hsr3" = "off" ]]; then
+		echo "INFO: Running VLAN tests"
+		setup_vlan_interfaces
+		hsr_vlan_ping
+	else
+		echo "INFO: Not Running VLAN tests as the device does not support VLAN"
+	fi
+}
+
 check_prerequisites
 setup_ns ns1 ns2 ns3
 
@@ -183,9 +277,13 @@
 setup_hsr_interfaces 0
 do_complete_ping_test
 
+run_vlan_tests
+
 setup_ns ns1 ns2 ns3
 
 setup_hsr_interfaces 1
 do_complete_ping_test
 
+run_vlan_tests
+
 exit $ret
