From 435024a55a8a3f64af6ebeff596332aebd15b7e9 Mon Sep 17 00:00:00 2001 From: guowenxue <guowenxue@gmail.com> Date: Mon, 06 May 2024 17:52:06 +0800 Subject: [PATCH] Build:GauGuin-Board: Add GauGuin Board based on i.MX8MP build support --- bootloader/build.sh | 4 bootloader/patches/gauguin-imx8mp/uboot-imx-lf-5.15.71-2.2.0.patch | 7320 +++++++++++++++++++++++++++++++++++ kernel/patches/gauguin-imx8mp/linux-imx-lf-5.15.71-2.2.0.patch | 5191 ++++++++++++++++++++++++ 3 files changed, 12,515 insertions(+), 0 deletions(-) diff --git a/bootloader/build.sh b/bootloader/build.sh index 90be466..99eeba6 100755 --- a/bootloader/build.sh +++ b/bootloader/build.sh @@ -92,6 +92,10 @@ export FMW_IMX=firmware-imx-8.21 + elif [[ $BSP_VER =~ 5.15.71 ]] ; then + + export FMW_IMX=firmware-imx-8.18 + fi export FMWS="$FMW_IMX" diff --git a/bootloader/patches/gauguin-imx8mp/uboot-imx-lf-5.15.71-2.2.0.patch b/bootloader/patches/gauguin-imx8mp/uboot-imx-lf-5.15.71-2.2.0.patch new file mode 100644 index 0000000..a5696b8 --- /dev/null +++ b/bootloader/patches/gauguin-imx8mp/uboot-imx-lf-5.15.71-2.2.0.patch @@ -0,0 +1,7320 @@ +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index 709fdaec..00d6d30c 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -1002,6 +1002,7 @@ dtb-$(CONFIG_ARCH_IMX8M) += \ + imx8mp-evk.dtb \ + imx8mp-phyboard-pollux-rdk.dtb \ + imx8mp-verdin.dtb \ ++ gauguin-imx8mp.dtb \ + imx8mq-pico-pi.dtb \ + imx8mq-kontron-pitx-imx8m.dtb + +diff --git a/arch/arm/dts/gauguin-imx8mp-u-boot.dtsi b/arch/arm/dts/gauguin-imx8mp-u-boot.dtsi +new file mode 100644 +index 00000000..922b5d6d +--- /dev/null ++++ b/arch/arm/dts/gauguin-imx8mp-u-boot.dtsi +@@ -0,0 +1,234 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright 2019, 2021 NXP ++ */ ++#include "imx8mp-sec-def.h" ++ ++#include "imx8mp-u-boot.dtsi" ++ ++/ { ++ wdt-reboot { ++ compatible = "wdt-reboot"; ++ wdt = <&wdog1>; ++ u-boot,dm-spl; ++ }; ++ firmware { ++ optee { ++ compatible = "linaro,optee-tz"; ++ method = "smc"; ++ }; ++ }; ++ ++ mcu_rdc { ++ compatible = "imx8m,mcu_rdc"; ++ /* rdc config when MCU starts ++ * master ++ * SDMA3p --> domain 1 ++ * SDMA3b --> domian 1 ++ * SDMA3_SPBA2 --> domian 1 ++ * peripheral: ++ * SAI3 --> Only Domian 1 can access ++ * UART4 --> Only Domian 1 can access ++ * GPT1 --> Only Domian 1 can access ++ * SDMA3 --> Only Domian 1 can access ++ * I2C3 --> Only Domian 1 can access ++ * memory: ++ * TCM --> Only Domian 1 can access (0x7E0000~0x81FFFF) ++ * DDR --> Only Domian 1 can access (0x80000000~0x81000000) ++ * end. ++ */ ++ start-config = < ++ RDC_MDA RDC_MDA_SDMA3p DID1 0x0 0x0 ++ RDC_MDA RDC_MDA_ENET1_TX DID1 0x0 0x0 ++ RDC_MDA RDC_MDA_ENET1_RX DID1 0x0 0x0 ++ RDC_MDA RDC_MDA_SDMA3b DID1 0x0 0x0 ++ RDC_MDA RDC_MDA_SDMA3_SPBA2 DID1 0x0 0x0 ++ RDC_PDAP RDC_PDAP_ENET1 PDAP_D0D1_ACCESS 0x0 0x0 ++ RDC_PDAP RDC_PDAP_SAI3 PDAP_D1_ACCESS 0x0 0x0 ++ RDC_PDAP RDC_PDAP_UART4 PDAP_D1_ACCESS 0x0 0x0 ++ RDC_PDAP RDC_PDAP_GPT1 PDAP_D1_ACCESS 0x0 0x0 ++ RDC_PDAP RDC_PDAP_SDMA3 PDAP_D1_ACCESS 0x0 0x0 ++ RDC_PDAP RDC_PDAP_I2C3 PDAP_D1_ACCESS 0x0 0x0 ++ RDC_MEM_REGION 22 TCM_START TCM_END MEM_D1_ACCESS ++ RDC_MEM_REGION 39 M4_DDR_START M4_DDR_END MEM_D1_ACCESS ++ 0x0 0x0 0x0 0x0 0x0 ++ >; ++ /* rdc config when MCU stops ++ * memory: ++ * TCM --> domain 0/1 can access (0x7E0000~0x81FFFF) ++ * DDR --> domain 0/1 can access (0x80000000~0x81000000) ++ * end. ++ */ ++ stop-config = < ++ RDC_MEM_REGION 22 TCM_START TCM_END MEM_D0D1_ACCESS ++ RDC_MEM_REGION 39 M4_DDR_START M4_DDR_END MEM_D0D1_ACCESS ++ 0x0 0x0 0x0 0x0 0x0 ++ >; ++ }; ++}; ++ ++&pinctrl_uart2 { ++ u-boot,dm-spl; ++}; ++ ++&pinctrl_usdhc3 { ++ u-boot,dm-spl; ++}; ++ ++&gpio1 { ++ u-boot,dm-spl; ++}; ++ ++&gpio2 { ++ u-boot,dm-spl; ++}; ++ ++&gpio3 { ++ u-boot,dm-spl; ++}; ++ ++&gpio4 { ++ u-boot,dm-spl; ++}; ++ ++&gpio5 { ++ u-boot,dm-spl; ++}; ++ ++&uart2 { ++ u-boot,dm-spl; ++}; ++ ++&crypto { ++ u-boot,dm-spl; ++}; ++ ++&sec_jr0 { ++ u-boot,dm-spl; ++}; ++ ++&sec_jr1 { ++ u-boot,dm-spl; ++}; ++ ++&sec_jr2 { ++ u-boot,dm-spl; ++}; ++ ++&i2c1 { ++ u-boot,dm-spl; ++}; ++ ++&i2c2 { ++ u-boot,dm-spl; ++}; ++ ++&i2c3 { ++ u-boot,dm-spl; ++}; ++ ++&pinctrl_i2c1 { ++ u-boot,dm-spl; ++}; ++ ++&pinctrl_i2c1_gpio { ++ u-boot,dm-spl; ++}; ++ ++&usdhc1 { ++ u-boot,dm-spl; ++ assigned-clocks = <&clk IMX8MP_CLK_USDHC1>; ++ assigned-clock-rates = <400000000>; ++ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_400M>; ++}; ++ ++&usdhc2 { ++ u-boot,dm-spl; ++ sd-uhs-sdr104; ++ sd-uhs-ddr50; ++ assigned-clocks = <&clk IMX8MP_CLK_USDHC2>; ++ assigned-clock-rates = <400000000>; ++ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_400M>; ++}; ++ ++&usdhc3 { ++ u-boot,dm-spl; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ assigned-clocks = <&clk IMX8MP_CLK_USDHC3>; ++ assigned-clock-rates = <400000000>; ++ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_400M>; ++}; ++ ++&wdog1 { ++ u-boot,dm-spl; ++}; ++ ++&{/soc@0/bus@30800000/i2c@30a20000/pca9450@25} { ++ u-boot,dm-spl; ++}; ++ ++&{/soc@0/bus@30800000/i2c@30a20000/pca9450@25/regulators} { ++ u-boot,dm-spl; ++}; ++ ++&pinctrl_pmic { ++ u-boot,dm-spl; ++}; ++ ++&eqos { ++ compatible = "fsl,imx-eqos"; ++ /delete-property/ assigned-clocks; ++ /delete-property/ assigned-clock-parents; ++ /delete-property/ assigned-clock-rates; ++}; ++ ++ðphy0 { ++ reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; ++ reset-assert-us = <15000>; ++ reset-deassert-us = <100000>; ++}; ++ ++&fec { ++ phy-reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>; ++ phy-reset-duration = <15>; ++ phy-reset-post-delay = <100>; ++}; ++ ++&flexspi { ++ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_400M>; ++}; ++ ++&lcdif1 { ++ /delete-property/ assigned-clocks; ++ /delete-property/ assigned-clock-parents; ++ /delete-property/ assigned-clock-rates; ++}; ++ ++&mipi_dsi { ++ /delete-property/ assigned-clocks; ++ /delete-property/ assigned-clock-parents; ++ /delete-property/ assigned-clock-rates; ++}; ++ ++&usb3_0 { ++ /delete-property/ power-domains; ++}; ++ ++&usb3_1 { ++ /delete-property/ power-domains; ++}; ++ ++&usb_dwc3_0 { ++ compatible = "fsl,imx8mq-dwc3", "snps,dwc3"; ++ assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>; ++ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>; ++ assigned-clock-rates = <400000000>; ++}; ++ ++&usb_dwc3_1 { ++ compatible = "fsl,imx8mq-dwc3", "snps,dwc3"; ++ assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>; ++ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>; ++ assigned-clock-rates = <400000000>; ++}; +diff --git a/arch/arm/dts/gauguin-imx8mp.dts b/arch/arm/dts/gauguin-imx8mp.dts +new file mode 100644 +index 00000000..2a48b4f6 +--- /dev/null ++++ b/arch/arm/dts/gauguin-imx8mp.dts +@@ -0,0 +1,449 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright 2019 NXP ++ */ ++ ++/dts-v1/; ++ ++#include <dt-bindings/usb/pd.h> ++#include "imx8mp.dtsi" ++ ++/ { ++ model = "ZhiTu GauGuin Board - imx8mp"; ++ compatible = "fsl,imx8mp-evk", "fsl,imx8mp"; ++ ++ chosen { ++ bootargs = "console=ttymxc1,115200 earlycon=ec_imx6q,0x30890000,115200"; ++ stdout-path = &uart2; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_gpio_led>; ++ ++ led-red { ++ label = "red:status"; ++ gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ ++ led-green { ++ label = "green:status"; ++ gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ }; ++ ++ memory@40000000 { ++ device_type = "memory"; ++ reg = <0x0 0x40000000 0 0xc0000000>, ++ <0x1 0x00000000 0 0xc0000000>; ++ }; ++}; ++ ++/*eth0 T1*/ ++&eqos { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_eqos>; ++ phy-mode = "rgmii-id"; ++ phy-handle = <ðphy0>; ++ status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ethphy0: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ eee-broken-1000t; ++ }; ++ }; ++}; ++ ++/*eth1 T2*/ ++&fec { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_fec>; ++ phy-mode = "rgmii-id"; ++ phy-handle = <ðphy1>; ++ fsl,magic-packet; ++ status = "okay"; ++ ++ mdio { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ethphy1: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ eee-broken-1000t; ++ }; ++ }; ++}; ++ ++&flexspi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_flexspi0>; ++ status = "okay"; ++ ++ flash0: mt25qu256aba@0 { ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "jedec,spi-nor"; ++ spi-max-frequency = <80000000>; ++ spi-tx-bus-width = <4>; ++ spi-rx-bus-width = <4>; ++ }; ++}; ++ ++&i2c1 { ++ clock-frequency = <400000>; ++ pinctrl-names = "default", "gpio"; ++ pinctrl-0 = <&pinctrl_i2c1>; ++ pinctrl-1 = <&pinctrl_i2c1_gpio>; ++ scl-gpios = <&gpio5 14 GPIO_ACTIVE_HIGH>; ++ sda-gpios = <&gpio5 15 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ ++ pmic: pca9450@25 { ++ reg = <0x25>; ++ compatible = "nxp,pca9450c"; ++ /* PMIC PCA9450 PMIC_nINT GPIO1_IO3 */ ++ pinctrl-0 = <&pinctrl_pmic>; ++ gpio_intr = <&gpio1 3 GPIO_ACTIVE_LOW>; ++ ++ regulators { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pca9450,pmic-buck2-uses-i2c-dvs; ++ /* Run/Standby voltage */ ++ pca9450,pmic-buck2-dvs-voltage = <950000>, <850000>; ++ ++ buck1_reg: regulator@0 { ++ reg = <0>; ++ regulator-compatible = "buck1"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <2187500>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-ramp-delay = <3125>; ++ }; ++ ++ buck2_reg: regulator@1 { ++ reg = <1>; ++ regulator-compatible = "buck2"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <2187500>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-ramp-delay = <3125>; ++ }; ++ ++ buck4_reg: regulator@3 { ++ reg = <3>; ++ regulator-compatible = "buck4"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ buck5_reg: regulator@4 { ++ reg = <4>; ++ regulator-compatible = "buck5"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ buck6_reg: regulator@5 { ++ reg = <5>; ++ regulator-compatible = "buck6"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ ldo1_reg: regulator@6 { ++ reg = <6>; ++ regulator-compatible = "ldo1"; ++ regulator-min-microvolt = <1600000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ ldo2_reg: regulator@7 { ++ reg = <7>; ++ regulator-compatible = "ldo2"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ ldo3_reg: regulator@8 { ++ reg = <8>; ++ regulator-compatible = "ldo3"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ ldo4_reg: regulator@9 { ++ reg = <9>; ++ regulator-compatible = "ldo4"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ ldo5_reg: regulator@10 { ++ reg = <10>; ++ regulator-compatible = "ldo5"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ }; ++ }; ++}; ++ ++&i2c2 { ++ clock-frequency = <400000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c2>; ++ status = "okay"; ++}; ++ ++&i2c3 { ++ clock-frequency = <100000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c3>; ++ status = "okay"; ++}; ++ ++&snvs_pwrkey { ++ status = "okay"; ++}; ++ ++&uart2 { ++ /* console */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_uart2>; ++ status = "okay"; ++}; ++ ++&usb3_phy0 { ++ fsl,phy-tx-vref-tune = <0xe>; ++ fsl,phy-tx-preemp-amp-tune = <3>; ++ fsl,phy-tx-vboost-level = <5>; ++ fsl,phy-comp-dis-tune = <7>; ++ fsl,pcs-tx-deemph-3p5db = <0x21>; ++ fsl,phy-pcs-tx-swing-full = <0x7f>; ++ status = "okay"; ++}; ++ ++&usb3_0 { ++ status = "okay"; ++}; ++ ++&usb_dwc3_0 { ++ dr_mode = "otg"; ++ hnp-disable; ++ srp-disable; ++ adp-disable; ++ usb-role-switch; ++ role-switch-default-mode = "none"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_usb0_id_grp>;/*add otg control gpio*/ ++ status = "okay"; ++}; ++ ++&usdhc3 { ++ pinctrl-names = "default", "state_100mhz", "state_200mhz"; ++ pinctrl-0 = <&pinctrl_usdhc3>; ++ pinctrl-1 = <&pinctrl_usdhc3_100mhz>; ++ pinctrl-2 = <&pinctrl_usdhc3_200mhz>; ++ bus-width = <8>; ++ non-removable; ++ status = "okay"; ++}; ++ ++&wdog1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_wdog>; ++ fsl,ext-reset-output; ++ status = "okay"; ++}; ++ ++&iomuxc { ++ pinctrl-names = "default"; ++ ++ pinctrl_eqos: eqosgrp {/*T1*/ ++ fsl,pins = < ++ MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x3 ++ MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x3 ++ MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91 ++ MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91 ++ MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x91 ++ MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x91 ++ MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x91 ++ MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91 ++ MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f ++ MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f ++ MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x1f ++ MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x1f ++ MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f ++ MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1f ++ MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x19 ++ >; ++ }; ++ ++ pinctrl_fec: fecgrp {/*T2*/ ++ fsl,pins = < ++ MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x3 ++ MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x3 ++ MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x91 ++ MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x91 ++ MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x91 ++ MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x91 ++ MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x91 ++ MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x91 ++ MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x1f ++ MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x1f ++ MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x1f ++ MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x1f ++ MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x1f ++ MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x1f ++ MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02 0x19 ++ >; ++ }; ++ ++ pinctrl_flexspi0: flexspi0grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_NAND_ALE__FLEXSPI_A_SCLK 0x1c2 ++ MX8MP_IOMUXC_NAND_CE0_B__FLEXSPI_A_SS0_B 0x82 ++ MX8MP_IOMUXC_NAND_DATA00__FLEXSPI_A_DATA00 0x82 ++ MX8MP_IOMUXC_NAND_DATA01__FLEXSPI_A_DATA01 0x82 ++ MX8MP_IOMUXC_NAND_DATA02__FLEXSPI_A_DATA02 0x82 ++ MX8MP_IOMUXC_NAND_DATA03__FLEXSPI_A_DATA03 0x82 ++ >; ++ }; ++ ++ pinctrl_gpio_led: gpioledgrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_SD1_STROBE__GPIO2_IO11 0x19 ++ MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x19 ++ >; ++ }; ++ ++ pinctrl_i2c1: i2c1grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c3 ++ MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c3 ++ >; ++ }; ++ ++ pinctrl_i2c2: i2c2grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c3 ++ MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c3 ++ >; ++ }; ++ ++ pinctrl_i2c3: i2c3grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c3 ++ MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c3 ++ >; ++ }; ++ ++ pinctrl_i2c1_gpio: i2c1grp-gpio { ++ fsl,pins = < ++ MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14 0x1c3 ++ MX8MP_IOMUXC_I2C1_SDA__GPIO5_IO15 0x1c3 ++ >; ++ }; ++ ++ pinctrl_pmic: pmicirq { ++ fsl,pins = < ++ MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03 0x41 ++ >; ++ }; ++ ++ pinctrl_uart2: uart2grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140 ++ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 ++ >; ++ }; ++ ++ pinctrl_usb0_id_grp: usb0grp{ ++ fsl,pins = < ++ MX8MP_IOMUXC_SAI2_TXD0__GPIO4_IO26 0x1c4 ++ >; ++ }; ++ ++ pinctrl_usdhc3: usdhc3grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190 ++ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d0 ++ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d0 ++ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d0 ++ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d0 ++ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d0 ++ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d0 ++ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d0 ++ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d0 ++ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d0 ++ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x190 ++ >; ++ }; ++ ++ pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x194 ++ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d4 ++ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d4 ++ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d4 ++ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d4 ++ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d4 ++ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d4 ++ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d4 ++ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d4 ++ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d4 ++ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x194 ++ >; ++ }; ++ ++ pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x196 ++ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d6 ++ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d6 ++ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d6 ++ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d6 ++ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d6 ++ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d6 ++ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d6 ++ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d6 ++ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d6 ++ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x196 ++ >; ++ }; ++ ++ pinctrl_wdog: wdoggrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0xc6 ++ >; ++ }; ++}; +diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig +index a225a978..860f0003 100644 +--- a/arch/arm/mach-imx/imx8m/Kconfig ++++ b/arch/arm/mach-imx/imx8m/Kconfig +@@ -241,6 +241,16 @@ config TARGET_IMX8MP_EVK + select ARCH_MISC_INIT + select SPL_CRYPTO if SPL + ++config TARGET_GAUGUIN_IMX8MP ++ bool "ZhiTu IMX8MP LPDDR4 GauGuin Board" ++ select IMX8MP ++ select SUPPORT_SPL ++ select IMX8M_LPDDR4 ++ select FSL_CAAM ++ select FSL_BLOB ++ select ARCH_MISC_INIT ++ select SPL_CRYPTO if SPL ++ + config TARGET_IMX8MP_DDR4_EVK + bool "imx8mp DDR4 EVK board" + select IMX8MP +@@ -366,5 +376,6 @@ source "board/technexion/pico-imx8mq/Kconfig" + source "board/variscite/imx8mn_var_som/Kconfig" + source "board/toradex/verdin-imx8mm/Kconfig" + source "board/toradex/verdin-imx8mp/Kconfig" ++source "board/freescale/gauguin-imx8mp/Kconfig" + + endif +diff --git a/board/freescale/gauguin-imx8mp/Kconfig b/board/freescale/gauguin-imx8mp/Kconfig +new file mode 100644 +index 00000000..a3eb059f +--- /dev/null ++++ b/board/freescale/gauguin-imx8mp/Kconfig +@@ -0,0 +1,17 @@ ++if TARGET_GAUGUIN_IMX8MP || TARGET_IMX8MP_DDR4_EVK ++ ++config SYS_BOARD ++ default "gauguin-imx8mp" ++ ++config SYS_VENDOR ++ default "freescale" ++ ++config SYS_CONFIG_NAME ++ default "gauguin-imx8mp" ++ ++config IMX_CONFIG ++ default "board/freescale/gauguin-imx8mp/imximage-8mp-lpddr4.cfg" ++ ++source "board/freescale/common/Kconfig" ++ ++endif +diff --git a/board/freescale/gauguin-imx8mp/MAINTAINERS b/board/freescale/gauguin-imx8mp/MAINTAINERS +new file mode 100644 +index 00000000..1f793c27 +--- /dev/null ++++ b/board/freescale/gauguin-imx8mp/MAINTAINERS +@@ -0,0 +1,6 @@ ++i.MX8MP GauGuin Board ++M: Guo Wenxue <guowenxue@gmail.com> ++S: Maintained ++F: board/freescale/gauguin-imx8mp/ ++F: include/configs/gauguin-imx8mp.h ++F: configs/gauguin-imx8mp_defconfig +diff --git a/board/freescale/gauguin-imx8mp/Makefile b/board/freescale/gauguin-imx8mp/Makefile +new file mode 100644 +index 00000000..30c74f9b +--- /dev/null ++++ b/board/freescale/gauguin-imx8mp/Makefile +@@ -0,0 +1,17 @@ ++# ++# Copyright 2019 NXP ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++obj-y += gauguin-imx8mp.o ++ ++ifdef CONFIG_SPL_BUILD ++obj-y += spl.o ++ifdef CONFIG_IMX8M_LPDDR4_FREQ0_3200MTS ++obj-y += lpddr4_timing_ndm.o ++else ++obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4_timing.o ++obj-$(CONFIG_IMX8M_DDR4) += ddr4_timing.o ++endif ++endif +diff --git a/board/freescale/gauguin-imx8mp/ddr4_timing.c b/board/freescale/gauguin-imx8mp/ddr4_timing.c +new file mode 100644 +index 00000000..3e3cc01b +--- /dev/null ++++ b/board/freescale/gauguin-imx8mp/ddr4_timing.c +@@ -0,0 +1,1311 @@ ++/* ++ * Copyright 2019 NXP ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * ++ * Generated code from MX8M_DDR_tool ++ * ++ * Align with uboot version: ++ * imx_v2018.03_4.14.78_1.0.0_ga ~ imx_v2018.04_4.19.35_1.1.0_ga ++ * For imx_v2019.04_5.4.x and above version: ++ * please replace #include <asm/arch/imx8m_ddr.h> with #include <asm/arch/ddr.h> ++ */ ++ ++#include <linux/kernel.h> ++#include <asm/arch/ddr.h> ++ ++struct dram_cfg_param ddr_ddrc_cfg[] = { ++ /** Initialize DDRC registers **/ ++ { 0x3d400304, 0x1 }, ++ { 0x3d400030, 0x1 }, ++ { 0x3d400000, 0x81040010 }, ++ { 0x3d400030, 0xaa }, ++ { 0x3d400034, 0x221306 }, ++ { 0x3d400050, 0x210070 }, ++ { 0x3d400054, 0x10008 }, ++ { 0x3d400060, 0x0 }, ++ { 0x3d400064, 0xc30118 }, ++ { 0x3d4000c0, 0x0 }, ++ { 0x3d4000c4, 0x1000 }, ++#ifdef CONFIG_IMX8M_DRAM_INLINE_ECC ++ { 0x3d400070, 0x1027f54 }, ++#else ++ { 0x3d400070, 0x1027f10 }, ++#endif ++ { 0x3d400074, 0x7b0 }, ++ { 0x3d4000d0, 0xc0030188 }, ++ { 0x3d4000d4, 0x9e0000 }, ++ { 0x3d4000dc, 0xc500501 }, ++ { 0x3d4000e0, 0x280400 }, ++ { 0x3d4000e4, 0x110000 }, ++ { 0x3d4000e8, 0x2000600 }, ++ { 0x3d4000ec, 0x1010 }, ++ { 0x3d4000f0, 0x20 }, ++ { 0x3d4000f4, 0xec7 }, ++ { 0x3d400100, 0x1618361a }, ++ { 0x3d400104, 0x50626 }, ++ { 0x3d400108, 0x80b0610 }, ++ { 0x3d40010c, 0x400c }, ++ { 0x3d400110, 0xc04060d }, ++ { 0x3d400114, 0x8080504 }, ++ { 0x3d40011c, 0x808 }, ++ { 0x3d400120, 0x6060d0a }, ++ { 0x3d400124, 0x2050c }, ++ { 0x3d40012c, 0x160b010e }, ++ { 0x3d400130, 0x8 }, ++ { 0x3d40013c, 0x0 }, ++ { 0x3d400180, 0x1000040 }, ++ { 0x3d400184, 0x61a8 }, ++ { 0x3d400190, 0x391820b }, ++ { 0x3d400194, 0x2020303 }, ++ { 0x3d400198, 0x7f04011 }, ++ { 0x3d40019c, 0xb0 }, ++ { 0x3d4001a0, 0xe0400018 }, ++ { 0x3d4001a4, 0x48005a }, ++ { 0x3d4001a8, 0x80000000 }, ++ { 0x3d4001b0, 0x1 }, ++ { 0x3d4001b4, 0x110b }, ++ { 0x3d4001b8, 0x4 }, ++ { 0x3d4001c0, 0x1 }, ++ { 0x3d4001c4, 0x0 }, ++ { 0x3d400200, 0x1f }, ++#ifdef CONFIG_IMX8M_DRAM_INLINE_ECC ++ { 0x3d400204, 0x3f0505 }, ++ { 0x3d400208, 0x700 }, ++ { 0x3d40020c, 0x14141400 }, ++ { 0x3d400210, 0x1f1f }, ++ { 0x3d400214, 0x4040403 }, ++ { 0x3d400218, 0x4040404 }, ++ { 0x3d40021c, 0xf04 }, ++#else ++ { 0x3d400204, 0x3f0909 }, ++ { 0x3d400208, 0x700 }, ++ { 0x3d40020c, 0x0 }, ++ { 0x3d400210, 0x1f1f }, ++ { 0x3d400214, 0x7070707 }, ++ { 0x3d400218, 0x7070707 }, ++ { 0x3d40021c, 0xf07 }, ++#endif ++ { 0x3d400220, 0x3f01 }, ++ { 0x3d400240, 0x6000618 }, ++ { 0x3d400244, 0x1323 }, ++ { 0x3d400250, 0x00001a05 }, ++ { 0x3d400254, 0x1f }, ++ { 0x3d40025c, 0x10000010 }, ++ { 0x3d400264, 0x100000ff }, ++ { 0x3d40026c, 0x100002ff }, ++ { 0x3d40036c, 0x0 }, ++ { 0x3d400400, 0x100 }, ++ { 0x3d400404, 0x72ff }, ++ { 0x3d400408, 0x72ff }, ++ { 0x3d400494, 0x2100e07 }, ++ { 0x3d400498, 0x620096 }, ++ { 0x3d40049c, 0x1100e07 }, ++ { 0x3d4004a0, 0xc8012c }, ++ { 0x3d402050, 0x210070 }, ++ { 0x3d402064, 0x40005e }, ++ { 0x3d4020dc, 0x40501 }, ++ { 0x3d4020e0, 0x0 }, ++ { 0x3d4020e8, 0x2000600 }, ++ { 0x3d4020ec, 0x10 }, ++ { 0x3d402100, 0xb081209 }, ++ { 0x3d402104, 0x2020d }, ++ { 0x3d402108, 0x5050309 }, ++ { 0x3d40210c, 0x400c }, ++ { 0x3d402110, 0x4030205 }, ++ { 0x3d402114, 0x3030202 }, ++ { 0x3d40211c, 0x303 }, ++ { 0x3d402120, 0x3030d04 }, ++ { 0x3d402124, 0x20208 }, ++ { 0x3d40212c, 0x1005010e }, ++ { 0x3d402130, 0x8 }, ++ { 0x3d40213c, 0x0 }, ++ { 0x3d402180, 0x1000040 }, ++ { 0x3d402190, 0x3858204 }, ++ { 0x3d402194, 0x2020303 }, ++ { 0x3d4021b4, 0x504 }, ++ { 0x3d4021b8, 0x4 }, ++ { 0x3d402240, 0x6000604 }, ++ { 0x3d4020f4, 0xec7 }, ++}; ++ ++/* PHY Initialize Configuration */ ++struct dram_cfg_param ddr_ddrphy_cfg[] = { ++ { 0x1005f, 0x2df }, ++ { 0x1015f, 0x2df }, ++ { 0x1105f, 0x2df }, ++ { 0x1115f, 0x2df }, ++ { 0x1205f, 0x2df }, ++ { 0x1215f, 0x2df }, ++ { 0x1305f, 0x2df }, ++ { 0x1315f, 0x2df }, ++ { 0x11005f, 0x2df }, ++ { 0x11015f, 0x2df }, ++ { 0x11105f, 0x2df }, ++ { 0x11115f, 0x2df }, ++ { 0x11205f, 0x2df }, ++ { 0x11215f, 0x2df }, ++ { 0x11305f, 0x2df }, ++ { 0x11315f, 0x2df }, ++ { 0x55, 0x355 }, ++ { 0x1055, 0x355 }, ++ { 0x2055, 0x355 }, ++ { 0x3055, 0x355 }, ++ { 0x4055, 0x55 }, ++ { 0x5055, 0x55 }, ++ { 0x6055, 0x355 }, ++ { 0x7055, 0x355 }, ++ { 0x8055, 0x355 }, ++ { 0x9055, 0x355 }, ++ { 0x200c5, 0x19 }, ++ { 0x1200c5, 0x6 }, ++ { 0x2002e, 0x2 }, ++ { 0x12002e, 0x1 }, ++ { 0x20024, 0x8 }, ++ { 0x2003a, 0x2 }, ++ { 0x120024, 0x8 }, ++ { 0x2003a, 0x2 }, ++ { 0x20056, 0x7 }, ++ { 0x120056, 0xa }, ++ { 0x1004d, 0x1a }, ++ { 0x1014d, 0x1a }, ++ { 0x1104d, 0x1a }, ++ { 0x1114d, 0x1a }, ++ { 0x1204d, 0x1a }, ++ { 0x1214d, 0x1a }, ++ { 0x1304d, 0x1a }, ++ { 0x1314d, 0x1a }, ++ { 0x11004d, 0x1a }, ++ { 0x11014d, 0x1a }, ++ { 0x11104d, 0x1a }, ++ { 0x11114d, 0x1a }, ++ { 0x11204d, 0x1a }, ++ { 0x11214d, 0x1a }, ++ { 0x11304d, 0x1a }, ++ { 0x11314d, 0x1a }, ++ { 0x10049, 0xeba }, ++ { 0x10149, 0xeba }, ++ { 0x11049, 0xeba }, ++ { 0x11149, 0xeba }, ++ { 0x12049, 0xeba }, ++ { 0x12149, 0xeba }, ++ { 0x13049, 0xeba }, ++ { 0x13149, 0xeba }, ++ { 0x110049, 0xeba }, ++ { 0x110149, 0xeba }, ++ { 0x111049, 0xeba }, ++ { 0x111149, 0xeba }, ++ { 0x112049, 0xeba }, ++ { 0x112149, 0xeba }, ++ { 0x113049, 0xeba }, ++ { 0x113149, 0xeba }, ++ { 0x43, 0xe7 }, ++ { 0x1043, 0xe7 }, ++ { 0x2043, 0xe7 }, ++ { 0x3043, 0xe7 }, ++ { 0x4043, 0xe7 }, ++ { 0x5043, 0xe7 }, ++ { 0x6043, 0xe7 }, ++ { 0x7043, 0xe7 }, ++ { 0x8043, 0xe7 }, ++ { 0x9043, 0xe7 }, ++ { 0x20018, 0x5 }, ++ { 0x20075, 0x2 }, ++ { 0x20050, 0x0 }, ++ { 0x20008, 0x320 }, ++ { 0x120008, 0x10a }, ++ { 0x20088, 0x9 }, ++ { 0x200b2, 0x248 }, ++ { 0x10043, 0x5b1 }, ++ { 0x10143, 0x5b1 }, ++ { 0x11043, 0x5b1 }, ++ { 0x11143, 0x5b1 }, ++ { 0x12043, 0x5b1 }, ++ { 0x12143, 0x5b1 }, ++ { 0x13043, 0x5b1 }, ++ { 0x13143, 0x5b1 }, ++ { 0x1200b2, 0x248 }, ++ { 0x110043, 0x5b1 }, ++ { 0x110143, 0x5b1 }, ++ { 0x111043, 0x5b1 }, ++ { 0x111143, 0x5b1 }, ++ { 0x112043, 0x5b1 }, ++ { 0x112143, 0x5b1 }, ++ { 0x113043, 0x5b1 }, ++ { 0x113143, 0x5b1 }, ++ { 0x200fa, 0x1 }, ++ { 0x1200fa, 0x1 }, ++ { 0x20019, 0x5 }, ++ { 0x120019, 0x5 }, ++ { 0x200f0, 0x5555 }, ++ { 0x200f1, 0x5555 }, ++ { 0x200f2, 0x5555 }, ++ { 0x200f3, 0x5555 }, ++ { 0x200f4, 0x5555 }, ++ { 0x200f5, 0x5555 }, ++ { 0x200f6, 0x5555 }, ++ { 0x200f7, 0xf000 }, ++ { 0x20025, 0x0 }, ++ { 0x2002d, 0x0 }, ++ { 0x12002d, 0x0 }, ++ { 0x2007d, 0x212 }, ++ { 0x12007d, 0x212 }, ++ { 0x2007c, 0x61 }, ++ { 0x12007c, 0x61 }, ++ { 0x1004a, 0x500 }, ++ { 0x1104a, 0x500 }, ++ { 0x1204a, 0x500 }, ++ { 0x1304a, 0x500 }, ++ { 0x2002c, 0x0 }, ++}; ++ ++/* ddr phy trained csr */ ++struct dram_cfg_param ddr_ddrphy_trained_csr[] = { ++ { 0x200b2, 0x0 }, ++ { 0x1200b2, 0x0 }, ++ { 0x2200b2, 0x0 }, ++ { 0x200cb, 0x0 }, ++ { 0x10043, 0x0 }, ++ { 0x110043, 0x0 }, ++ { 0x210043, 0x0 }, ++ { 0x10143, 0x0 }, ++ { 0x110143, 0x0 }, ++ { 0x210143, 0x0 }, ++ { 0x11043, 0x0 }, ++ { 0x111043, 0x0 }, ++ { 0x211043, 0x0 }, ++ { 0x11143, 0x0 }, ++ { 0x111143, 0x0 }, ++ { 0x211143, 0x0 }, ++ { 0x12043, 0x0 }, ++ { 0x112043, 0x0 }, ++ { 0x212043, 0x0 }, ++ { 0x12143, 0x0 }, ++ { 0x112143, 0x0 }, ++ { 0x212143, 0x0 }, ++ { 0x13043, 0x0 }, ++ { 0x113043, 0x0 }, ++ { 0x213043, 0x0 }, ++ { 0x13143, 0x0 }, ++ { 0x113143, 0x0 }, ++ { 0x213143, 0x0 }, ++ { 0x80, 0x0 }, ++ { 0x100080, 0x0 }, ++ { 0x200080, 0x0 }, ++ { 0x1080, 0x0 }, ++ { 0x101080, 0x0 }, ++ { 0x201080, 0x0 }, ++ { 0x2080, 0x0 }, ++ { 0x102080, 0x0 }, ++ { 0x202080, 0x0 }, ++ { 0x3080, 0x0 }, ++ { 0x103080, 0x0 }, ++ { 0x203080, 0x0 }, ++ { 0x4080, 0x0 }, ++ { 0x104080, 0x0 }, ++ { 0x204080, 0x0 }, ++ { 0x5080, 0x0 }, ++ { 0x105080, 0x0 }, ++ { 0x205080, 0x0 }, ++ { 0x6080, 0x0 }, ++ { 0x106080, 0x0 }, ++ { 0x206080, 0x0 }, ++ { 0x7080, 0x0 }, ++ { 0x107080, 0x0 }, ++ { 0x207080, 0x0 }, ++ { 0x8080, 0x0 }, ++ { 0x108080, 0x0 }, ++ { 0x208080, 0x0 }, ++ { 0x9080, 0x0 }, ++ { 0x109080, 0x0 }, ++ { 0x209080, 0x0 }, ++ { 0x10080, 0x0 }, ++ { 0x110080, 0x0 }, ++ { 0x210080, 0x0 }, ++ { 0x10180, 0x0 }, ++ { 0x110180, 0x0 }, ++ { 0x210180, 0x0 }, ++ { 0x11080, 0x0 }, ++ { 0x111080, 0x0 }, ++ { 0x211080, 0x0 }, ++ { 0x11180, 0x0 }, ++ { 0x111180, 0x0 }, ++ { 0x211180, 0x0 }, ++ { 0x12080, 0x0 }, ++ { 0x112080, 0x0 }, ++ { 0x212080, 0x0 }, ++ { 0x12180, 0x0 }, ++ { 0x112180, 0x0 }, ++ { 0x212180, 0x0 }, ++ { 0x13080, 0x0 }, ++ { 0x113080, 0x0 }, ++ { 0x213080, 0x0 }, ++ { 0x13180, 0x0 }, ++ { 0x113180, 0x0 }, ++ { 0x213180, 0x0 }, ++ { 0x10081, 0x0 }, ++ { 0x110081, 0x0 }, ++ { 0x210081, 0x0 }, ++ { 0x10181, 0x0 }, ++ { 0x110181, 0x0 }, ++ { 0x210181, 0x0 }, ++ { 0x11081, 0x0 }, ++ { 0x111081, 0x0 }, ++ { 0x211081, 0x0 }, ++ { 0x11181, 0x0 }, ++ { 0x111181, 0x0 }, ++ { 0x211181, 0x0 }, ++ { 0x12081, 0x0 }, ++ { 0x112081, 0x0 }, ++ { 0x212081, 0x0 }, ++ { 0x12181, 0x0 }, ++ { 0x112181, 0x0 }, ++ { 0x212181, 0x0 }, ++ { 0x13081, 0x0 }, ++ { 0x113081, 0x0 }, ++ { 0x213081, 0x0 }, ++ { 0x13181, 0x0 }, ++ { 0x113181, 0x0 }, ++ { 0x213181, 0x0 }, ++ { 0x100d0, 0x0 }, ++ { 0x1100d0, 0x0 }, ++ { 0x2100d0, 0x0 }, ++ { 0x101d0, 0x0 }, ++ { 0x1101d0, 0x0 }, ++ { 0x2101d0, 0x0 }, ++ { 0x110d0, 0x0 }, ++ { 0x1110d0, 0x0 }, ++ { 0x2110d0, 0x0 }, ++ { 0x111d0, 0x0 }, ++ { 0x1111d0, 0x0 }, ++ { 0x2111d0, 0x0 }, ++ { 0x120d0, 0x0 }, ++ { 0x1120d0, 0x0 }, ++ { 0x2120d0, 0x0 }, ++ { 0x121d0, 0x0 }, ++ { 0x1121d0, 0x0 }, ++ { 0x2121d0, 0x0 }, ++ { 0x130d0, 0x0 }, ++ { 0x1130d0, 0x0 }, ++ { 0x2130d0, 0x0 }, ++ { 0x131d0, 0x0 }, ++ { 0x1131d0, 0x0 }, ++ { 0x2131d0, 0x0 }, ++ { 0x100d1, 0x0 }, ++ { 0x1100d1, 0x0 }, ++ { 0x2100d1, 0x0 }, ++ { 0x101d1, 0x0 }, ++ { 0x1101d1, 0x0 }, ++ { 0x2101d1, 0x0 }, ++ { 0x110d1, 0x0 }, ++ { 0x1110d1, 0x0 }, ++ { 0x2110d1, 0x0 }, ++ { 0x111d1, 0x0 }, ++ { 0x1111d1, 0x0 }, ++ { 0x2111d1, 0x0 }, ++ { 0x120d1, 0x0 }, ++ { 0x1120d1, 0x0 }, ++ { 0x2120d1, 0x0 }, ++ { 0x121d1, 0x0 }, ++ { 0x1121d1, 0x0 }, ++ { 0x2121d1, 0x0 }, ++ { 0x130d1, 0x0 }, ++ { 0x1130d1, 0x0 }, ++ { 0x2130d1, 0x0 }, ++ { 0x131d1, 0x0 }, ++ { 0x1131d1, 0x0 }, ++ { 0x2131d1, 0x0 }, ++ { 0x10068, 0x0 }, ++ { 0x10168, 0x0 }, ++ { 0x10268, 0x0 }, ++ { 0x10368, 0x0 }, ++ { 0x10468, 0x0 }, ++ { 0x10568, 0x0 }, ++ { 0x10668, 0x0 }, ++ { 0x10768, 0x0 }, ++ { 0x10868, 0x0 }, ++ { 0x11068, 0x0 }, ++ { 0x11168, 0x0 }, ++ { 0x11268, 0x0 }, ++ { 0x11368, 0x0 }, ++ { 0x11468, 0x0 }, ++ { 0x11568, 0x0 }, ++ { 0x11668, 0x0 }, ++ { 0x11768, 0x0 }, ++ { 0x11868, 0x0 }, ++ { 0x12068, 0x0 }, ++ { 0x12168, 0x0 }, ++ { 0x12268, 0x0 }, ++ { 0x12368, 0x0 }, ++ { 0x12468, 0x0 }, ++ { 0x12568, 0x0 }, ++ { 0x12668, 0x0 }, ++ { 0x12768, 0x0 }, ++ { 0x12868, 0x0 }, ++ { 0x13068, 0x0 }, ++ { 0x13168, 0x0 }, ++ { 0x13268, 0x0 }, ++ { 0x13368, 0x0 }, ++ { 0x13468, 0x0 }, ++ { 0x13568, 0x0 }, ++ { 0x13668, 0x0 }, ++ { 0x13768, 0x0 }, ++ { 0x13868, 0x0 }, ++ { 0x10069, 0x0 }, ++ { 0x10169, 0x0 }, ++ { 0x10269, 0x0 }, ++ { 0x10369, 0x0 }, ++ { 0x10469, 0x0 }, ++ { 0x10569, 0x0 }, ++ { 0x10669, 0x0 }, ++ { 0x10769, 0x0 }, ++ { 0x10869, 0x0 }, ++ { 0x11069, 0x0 }, ++ { 0x11169, 0x0 }, ++ { 0x11269, 0x0 }, ++ { 0x11369, 0x0 }, ++ { 0x11469, 0x0 }, ++ { 0x11569, 0x0 }, ++ { 0x11669, 0x0 }, ++ { 0x11769, 0x0 }, ++ { 0x11869, 0x0 }, ++ { 0x12069, 0x0 }, ++ { 0x12169, 0x0 }, ++ { 0x12269, 0x0 }, ++ { 0x12369, 0x0 }, ++ { 0x12469, 0x0 }, ++ { 0x12569, 0x0 }, ++ { 0x12669, 0x0 }, ++ { 0x12769, 0x0 }, ++ { 0x12869, 0x0 }, ++ { 0x13069, 0x0 }, ++ { 0x13169, 0x0 }, ++ { 0x13269, 0x0 }, ++ { 0x13369, 0x0 }, ++ { 0x13469, 0x0 }, ++ { 0x13569, 0x0 }, ++ { 0x13669, 0x0 }, ++ { 0x13769, 0x0 }, ++ { 0x13869, 0x0 }, ++ { 0x1008c, 0x0 }, ++ { 0x11008c, 0x0 }, ++ { 0x21008c, 0x0 }, ++ { 0x1018c, 0x0 }, ++ { 0x11018c, 0x0 }, ++ { 0x21018c, 0x0 }, ++ { 0x1108c, 0x0 }, ++ { 0x11108c, 0x0 }, ++ { 0x21108c, 0x0 }, ++ { 0x1118c, 0x0 }, ++ { 0x11118c, 0x0 }, ++ { 0x21118c, 0x0 }, ++ { 0x1208c, 0x0 }, ++ { 0x11208c, 0x0 }, ++ { 0x21208c, 0x0 }, ++ { 0x1218c, 0x0 }, ++ { 0x11218c, 0x0 }, ++ { 0x21218c, 0x0 }, ++ { 0x1308c, 0x0 }, ++ { 0x11308c, 0x0 }, ++ { 0x21308c, 0x0 }, ++ { 0x1318c, 0x0 }, ++ { 0x11318c, 0x0 }, ++ { 0x21318c, 0x0 }, ++ { 0x1008d, 0x0 }, ++ { 0x11008d, 0x0 }, ++ { 0x21008d, 0x0 }, ++ { 0x1018d, 0x0 }, ++ { 0x11018d, 0x0 }, ++ { 0x21018d, 0x0 }, ++ { 0x1108d, 0x0 }, ++ { 0x11108d, 0x0 }, ++ { 0x21108d, 0x0 }, ++ { 0x1118d, 0x0 }, ++ { 0x11118d, 0x0 }, ++ { 0x21118d, 0x0 }, ++ { 0x1208d, 0x0 }, ++ { 0x11208d, 0x0 }, ++ { 0x21208d, 0x0 }, ++ { 0x1218d, 0x0 }, ++ { 0x11218d, 0x0 }, ++ { 0x21218d, 0x0 }, ++ { 0x1308d, 0x0 }, ++ { 0x11308d, 0x0 }, ++ { 0x21308d, 0x0 }, ++ { 0x1318d, 0x0 }, ++ { 0x11318d, 0x0 }, ++ { 0x21318d, 0x0 }, ++ { 0x100c0, 0x0 }, ++ { 0x1100c0, 0x0 }, ++ { 0x2100c0, 0x0 }, ++ { 0x101c0, 0x0 }, ++ { 0x1101c0, 0x0 }, ++ { 0x2101c0, 0x0 }, ++ { 0x102c0, 0x0 }, ++ { 0x1102c0, 0x0 }, ++ { 0x2102c0, 0x0 }, ++ { 0x103c0, 0x0 }, ++ { 0x1103c0, 0x0 }, ++ { 0x2103c0, 0x0 }, ++ { 0x104c0, 0x0 }, ++ { 0x1104c0, 0x0 }, ++ { 0x2104c0, 0x0 }, ++ { 0x105c0, 0x0 }, ++ { 0x1105c0, 0x0 }, ++ { 0x2105c0, 0x0 }, ++ { 0x106c0, 0x0 }, ++ { 0x1106c0, 0x0 }, ++ { 0x2106c0, 0x0 }, ++ { 0x107c0, 0x0 }, ++ { 0x1107c0, 0x0 }, ++ { 0x2107c0, 0x0 }, ++ { 0x108c0, 0x0 }, ++ { 0x1108c0, 0x0 }, ++ { 0x2108c0, 0x0 }, ++ { 0x110c0, 0x0 }, ++ { 0x1110c0, 0x0 }, ++ { 0x2110c0, 0x0 }, ++ { 0x111c0, 0x0 }, ++ { 0x1111c0, 0x0 }, ++ { 0x2111c0, 0x0 }, ++ { 0x112c0, 0x0 }, ++ { 0x1112c0, 0x0 }, ++ { 0x2112c0, 0x0 }, ++ { 0x113c0, 0x0 }, ++ { 0x1113c0, 0x0 }, ++ { 0x2113c0, 0x0 }, ++ { 0x114c0, 0x0 }, ++ { 0x1114c0, 0x0 }, ++ { 0x2114c0, 0x0 }, ++ { 0x115c0, 0x0 }, ++ { 0x1115c0, 0x0 }, ++ { 0x2115c0, 0x0 }, ++ { 0x116c0, 0x0 }, ++ { 0x1116c0, 0x0 }, ++ { 0x2116c0, 0x0 }, ++ { 0x117c0, 0x0 }, ++ { 0x1117c0, 0x0 }, ++ { 0x2117c0, 0x0 }, ++ { 0x118c0, 0x0 }, ++ { 0x1118c0, 0x0 }, ++ { 0x2118c0, 0x0 }, ++ { 0x120c0, 0x0 }, ++ { 0x1120c0, 0x0 }, ++ { 0x2120c0, 0x0 }, ++ { 0x121c0, 0x0 }, ++ { 0x1121c0, 0x0 }, ++ { 0x2121c0, 0x0 }, ++ { 0x122c0, 0x0 }, ++ { 0x1122c0, 0x0 }, ++ { 0x2122c0, 0x0 }, ++ { 0x123c0, 0x0 }, ++ { 0x1123c0, 0x0 }, ++ { 0x2123c0, 0x0 }, ++ { 0x124c0, 0x0 }, ++ { 0x1124c0, 0x0 }, ++ { 0x2124c0, 0x0 }, ++ { 0x125c0, 0x0 }, ++ { 0x1125c0, 0x0 }, ++ { 0x2125c0, 0x0 }, ++ { 0x126c0, 0x0 }, ++ { 0x1126c0, 0x0 }, ++ { 0x2126c0, 0x0 }, ++ { 0x127c0, 0x0 }, ++ { 0x1127c0, 0x0 }, ++ { 0x2127c0, 0x0 }, ++ { 0x128c0, 0x0 }, ++ { 0x1128c0, 0x0 }, ++ { 0x2128c0, 0x0 }, ++ { 0x130c0, 0x0 }, ++ { 0x1130c0, 0x0 }, ++ { 0x2130c0, 0x0 }, ++ { 0x131c0, 0x0 }, ++ { 0x1131c0, 0x0 }, ++ { 0x2131c0, 0x0 }, ++ { 0x132c0, 0x0 }, ++ { 0x1132c0, 0x0 }, ++ { 0x2132c0, 0x0 }, ++ { 0x133c0, 0x0 }, ++ { 0x1133c0, 0x0 }, ++ { 0x2133c0, 0x0 }, ++ { 0x134c0, 0x0 }, ++ { 0x1134c0, 0x0 }, ++ { 0x2134c0, 0x0 }, ++ { 0x135c0, 0x0 }, ++ { 0x1135c0, 0x0 }, ++ { 0x2135c0, 0x0 }, ++ { 0x136c0, 0x0 }, ++ { 0x1136c0, 0x0 }, ++ { 0x2136c0, 0x0 }, ++ { 0x137c0, 0x0 }, ++ { 0x1137c0, 0x0 }, ++ { 0x2137c0, 0x0 }, ++ { 0x138c0, 0x0 }, ++ { 0x1138c0, 0x0 }, ++ { 0x2138c0, 0x0 }, ++ { 0x100c1, 0x0 }, ++ { 0x1100c1, 0x0 }, ++ { 0x2100c1, 0x0 }, ++ { 0x101c1, 0x0 }, ++ { 0x1101c1, 0x0 }, ++ { 0x2101c1, 0x0 }, ++ { 0x102c1, 0x0 }, ++ { 0x1102c1, 0x0 }, ++ { 0x2102c1, 0x0 }, ++ { 0x103c1, 0x0 }, ++ { 0x1103c1, 0x0 }, ++ { 0x2103c1, 0x0 }, ++ { 0x104c1, 0x0 }, ++ { 0x1104c1, 0x0 }, ++ { 0x2104c1, 0x0 }, ++ { 0x105c1, 0x0 }, ++ { 0x1105c1, 0x0 }, ++ { 0x2105c1, 0x0 }, ++ { 0x106c1, 0x0 }, ++ { 0x1106c1, 0x0 }, ++ { 0x2106c1, 0x0 }, ++ { 0x107c1, 0x0 }, ++ { 0x1107c1, 0x0 }, ++ { 0x2107c1, 0x0 }, ++ { 0x108c1, 0x0 }, ++ { 0x1108c1, 0x0 }, ++ { 0x2108c1, 0x0 }, ++ { 0x110c1, 0x0 }, ++ { 0x1110c1, 0x0 }, ++ { 0x2110c1, 0x0 }, ++ { 0x111c1, 0x0 }, ++ { 0x1111c1, 0x0 }, ++ { 0x2111c1, 0x0 }, ++ { 0x112c1, 0x0 }, ++ { 0x1112c1, 0x0 }, ++ { 0x2112c1, 0x0 }, ++ { 0x113c1, 0x0 }, ++ { 0x1113c1, 0x0 }, ++ { 0x2113c1, 0x0 }, ++ { 0x114c1, 0x0 }, ++ { 0x1114c1, 0x0 }, ++ { 0x2114c1, 0x0 }, ++ { 0x115c1, 0x0 }, ++ { 0x1115c1, 0x0 }, ++ { 0x2115c1, 0x0 }, ++ { 0x116c1, 0x0 }, ++ { 0x1116c1, 0x0 }, ++ { 0x2116c1, 0x0 }, ++ { 0x117c1, 0x0 }, ++ { 0x1117c1, 0x0 }, ++ { 0x2117c1, 0x0 }, ++ { 0x118c1, 0x0 }, ++ { 0x1118c1, 0x0 }, ++ { 0x2118c1, 0x0 }, ++ { 0x120c1, 0x0 }, ++ { 0x1120c1, 0x0 }, ++ { 0x2120c1, 0x0 }, ++ { 0x121c1, 0x0 }, ++ { 0x1121c1, 0x0 }, ++ { 0x2121c1, 0x0 }, ++ { 0x122c1, 0x0 }, ++ { 0x1122c1, 0x0 }, ++ { 0x2122c1, 0x0 }, ++ { 0x123c1, 0x0 }, ++ { 0x1123c1, 0x0 }, ++ { 0x2123c1, 0x0 }, ++ { 0x124c1, 0x0 }, ++ { 0x1124c1, 0x0 }, ++ { 0x2124c1, 0x0 }, ++ { 0x125c1, 0x0 }, ++ { 0x1125c1, 0x0 }, ++ { 0x2125c1, 0x0 }, ++ { 0x126c1, 0x0 }, ++ { 0x1126c1, 0x0 }, ++ { 0x2126c1, 0x0 }, ++ { 0x127c1, 0x0 }, ++ { 0x1127c1, 0x0 }, ++ { 0x2127c1, 0x0 }, ++ { 0x128c1, 0x0 }, ++ { 0x1128c1, 0x0 }, ++ { 0x2128c1, 0x0 }, ++ { 0x130c1, 0x0 }, ++ { 0x1130c1, 0x0 }, ++ { 0x2130c1, 0x0 }, ++ { 0x131c1, 0x0 }, ++ { 0x1131c1, 0x0 }, ++ { 0x2131c1, 0x0 }, ++ { 0x132c1, 0x0 }, ++ { 0x1132c1, 0x0 }, ++ { 0x2132c1, 0x0 }, ++ { 0x133c1, 0x0 }, ++ { 0x1133c1, 0x0 }, ++ { 0x2133c1, 0x0 }, ++ { 0x134c1, 0x0 }, ++ { 0x1134c1, 0x0 }, ++ { 0x2134c1, 0x0 }, ++ { 0x135c1, 0x0 }, ++ { 0x1135c1, 0x0 }, ++ { 0x2135c1, 0x0 }, ++ { 0x136c1, 0x0 }, ++ { 0x1136c1, 0x0 }, ++ { 0x2136c1, 0x0 }, ++ { 0x137c1, 0x0 }, ++ { 0x1137c1, 0x0 }, ++ { 0x2137c1, 0x0 }, ++ { 0x138c1, 0x0 }, ++ { 0x1138c1, 0x0 }, ++ { 0x2138c1, 0x0 }, ++ { 0x10020, 0x0 }, ++ { 0x110020, 0x0 }, ++ { 0x210020, 0x0 }, ++ { 0x11020, 0x0 }, ++ { 0x111020, 0x0 }, ++ { 0x211020, 0x0 }, ++ { 0x12020, 0x0 }, ++ { 0x112020, 0x0 }, ++ { 0x212020, 0x0 }, ++ { 0x13020, 0x0 }, ++ { 0x113020, 0x0 }, ++ { 0x213020, 0x0 }, ++ { 0x20072, 0x0 }, ++ { 0x20073, 0x0 }, ++ { 0x20074, 0x0 }, ++ { 0x100aa, 0x0 }, ++ { 0x110aa, 0x0 }, ++ { 0x120aa, 0x0 }, ++ { 0x130aa, 0x0 }, ++ { 0x20010, 0x0 }, ++ { 0x120010, 0x0 }, ++ { 0x220010, 0x0 }, ++ { 0x20011, 0x0 }, ++ { 0x120011, 0x0 }, ++ { 0x220011, 0x0 }, ++ { 0x100ae, 0x0 }, ++ { 0x1100ae, 0x0 }, ++ { 0x2100ae, 0x0 }, ++ { 0x100af, 0x0 }, ++ { 0x1100af, 0x0 }, ++ { 0x2100af, 0x0 }, ++ { 0x110ae, 0x0 }, ++ { 0x1110ae, 0x0 }, ++ { 0x2110ae, 0x0 }, ++ { 0x110af, 0x0 }, ++ { 0x1110af, 0x0 }, ++ { 0x2110af, 0x0 }, ++ { 0x120ae, 0x0 }, ++ { 0x1120ae, 0x0 }, ++ { 0x2120ae, 0x0 }, ++ { 0x120af, 0x0 }, ++ { 0x1120af, 0x0 }, ++ { 0x2120af, 0x0 }, ++ { 0x130ae, 0x0 }, ++ { 0x1130ae, 0x0 }, ++ { 0x2130ae, 0x0 }, ++ { 0x130af, 0x0 }, ++ { 0x1130af, 0x0 }, ++ { 0x2130af, 0x0 }, ++ { 0x20020, 0x0 }, ++ { 0x120020, 0x0 }, ++ { 0x220020, 0x0 }, ++ { 0x100a0, 0x0 }, ++ { 0x100a1, 0x0 }, ++ { 0x100a2, 0x0 }, ++ { 0x100a3, 0x0 }, ++ { 0x100a4, 0x0 }, ++ { 0x100a5, 0x0 }, ++ { 0x100a6, 0x0 }, ++ { 0x100a7, 0x0 }, ++ { 0x110a0, 0x0 }, ++ { 0x110a1, 0x0 }, ++ { 0x110a2, 0x0 }, ++ { 0x110a3, 0x0 }, ++ { 0x110a4, 0x0 }, ++ { 0x110a5, 0x0 }, ++ { 0x110a6, 0x0 }, ++ { 0x110a7, 0x0 }, ++ { 0x120a0, 0x0 }, ++ { 0x120a1, 0x0 }, ++ { 0x120a2, 0x0 }, ++ { 0x120a3, 0x0 }, ++ { 0x120a4, 0x0 }, ++ { 0x120a5, 0x0 }, ++ { 0x120a6, 0x0 }, ++ { 0x120a7, 0x0 }, ++ { 0x130a0, 0x0 }, ++ { 0x130a1, 0x0 }, ++ { 0x130a2, 0x0 }, ++ { 0x130a3, 0x0 }, ++ { 0x130a4, 0x0 }, ++ { 0x130a5, 0x0 }, ++ { 0x130a6, 0x0 }, ++ { 0x130a7, 0x0 }, ++ { 0x2007c, 0x0 }, ++ { 0x12007c, 0x0 }, ++ { 0x22007c, 0x0 }, ++ { 0x2007d, 0x0 }, ++ { 0x12007d, 0x0 }, ++ { 0x22007d, 0x0 }, ++ { 0x400fd, 0x0 }, ++ { 0x400c0, 0x0 }, ++ { 0x90201, 0x0 }, ++ { 0x190201, 0x0 }, ++ { 0x290201, 0x0 }, ++ { 0x90202, 0x0 }, ++ { 0x190202, 0x0 }, ++ { 0x290202, 0x0 }, ++ { 0x90203, 0x0 }, ++ { 0x190203, 0x0 }, ++ { 0x290203, 0x0 }, ++ { 0x90204, 0x0 }, ++ { 0x190204, 0x0 }, ++ { 0x290204, 0x0 }, ++ { 0x90205, 0x0 }, ++ { 0x190205, 0x0 }, ++ { 0x290205, 0x0 }, ++ { 0x90206, 0x0 }, ++ { 0x190206, 0x0 }, ++ { 0x290206, 0x0 }, ++ { 0x90207, 0x0 }, ++ { 0x190207, 0x0 }, ++ { 0x290207, 0x0 }, ++ { 0x90208, 0x0 }, ++ { 0x190208, 0x0 }, ++ { 0x290208, 0x0 }, ++ { 0x10062, 0x0 }, ++ { 0x10162, 0x0 }, ++ { 0x10262, 0x0 }, ++ { 0x10362, 0x0 }, ++ { 0x10462, 0x0 }, ++ { 0x10562, 0x0 }, ++ { 0x10662, 0x0 }, ++ { 0x10762, 0x0 }, ++ { 0x10862, 0x0 }, ++ { 0x11062, 0x0 }, ++ { 0x11162, 0x0 }, ++ { 0x11262, 0x0 }, ++ { 0x11362, 0x0 }, ++ { 0x11462, 0x0 }, ++ { 0x11562, 0x0 }, ++ { 0x11662, 0x0 }, ++ { 0x11762, 0x0 }, ++ { 0x11862, 0x0 }, ++ { 0x12062, 0x0 }, ++ { 0x12162, 0x0 }, ++ { 0x12262, 0x0 }, ++ { 0x12362, 0x0 }, ++ { 0x12462, 0x0 }, ++ { 0x12562, 0x0 }, ++ { 0x12662, 0x0 }, ++ { 0x12762, 0x0 }, ++ { 0x12862, 0x0 }, ++ { 0x13062, 0x0 }, ++ { 0x13162, 0x0 }, ++ { 0x13262, 0x0 }, ++ { 0x13362, 0x0 }, ++ { 0x13462, 0x0 }, ++ { 0x13562, 0x0 }, ++ { 0x13662, 0x0 }, ++ { 0x13762, 0x0 }, ++ { 0x13862, 0x0 }, ++ { 0x20077, 0x0 }, ++ { 0x10001, 0x0 }, ++ { 0x11001, 0x0 }, ++ { 0x12001, 0x0 }, ++ { 0x13001, 0x0 }, ++ { 0x10040, 0x0 }, ++ { 0x10140, 0x0 }, ++ { 0x10240, 0x0 }, ++ { 0x10340, 0x0 }, ++ { 0x10440, 0x0 }, ++ { 0x10540, 0x0 }, ++ { 0x10640, 0x0 }, ++ { 0x10740, 0x0 }, ++ { 0x10840, 0x0 }, ++ { 0x10030, 0x0 }, ++ { 0x10130, 0x0 }, ++ { 0x10230, 0x0 }, ++ { 0x10330, 0x0 }, ++ { 0x10430, 0x0 }, ++ { 0x10530, 0x0 }, ++ { 0x10630, 0x0 }, ++ { 0x10730, 0x0 }, ++ { 0x10830, 0x0 }, ++ { 0x11040, 0x0 }, ++ { 0x11140, 0x0 }, ++ { 0x11240, 0x0 }, ++ { 0x11340, 0x0 }, ++ { 0x11440, 0x0 }, ++ { 0x11540, 0x0 }, ++ { 0x11640, 0x0 }, ++ { 0x11740, 0x0 }, ++ { 0x11840, 0x0 }, ++ { 0x11030, 0x0 }, ++ { 0x11130, 0x0 }, ++ { 0x11230, 0x0 }, ++ { 0x11330, 0x0 }, ++ { 0x11430, 0x0 }, ++ { 0x11530, 0x0 }, ++ { 0x11630, 0x0 }, ++ { 0x11730, 0x0 }, ++ { 0x11830, 0x0 }, ++ { 0x12040, 0x0 }, ++ { 0x12140, 0x0 }, ++ { 0x12240, 0x0 }, ++ { 0x12340, 0x0 }, ++ { 0x12440, 0x0 }, ++ { 0x12540, 0x0 }, ++ { 0x12640, 0x0 }, ++ { 0x12740, 0x0 }, ++ { 0x12840, 0x0 }, ++ { 0x12030, 0x0 }, ++ { 0x12130, 0x0 }, ++ { 0x12230, 0x0 }, ++ { 0x12330, 0x0 }, ++ { 0x12430, 0x0 }, ++ { 0x12530, 0x0 }, ++ { 0x12630, 0x0 }, ++ { 0x12730, 0x0 }, ++ { 0x12830, 0x0 }, ++ { 0x13040, 0x0 }, ++ { 0x13140, 0x0 }, ++ { 0x13240, 0x0 }, ++ { 0x13340, 0x0 }, ++ { 0x13440, 0x0 }, ++ { 0x13540, 0x0 }, ++ { 0x13640, 0x0 }, ++ { 0x13740, 0x0 }, ++ { 0x13840, 0x0 }, ++ { 0x13030, 0x0 }, ++ { 0x13130, 0x0 }, ++ { 0x13230, 0x0 }, ++ { 0x13330, 0x0 }, ++ { 0x13430, 0x0 }, ++ { 0x13530, 0x0 }, ++ { 0x13630, 0x0 }, ++ { 0x13730, 0x0 }, ++ { 0x13830, 0x0 }, ++}; ++/* P0 message block paremeter for training firmware */ ++struct dram_cfg_param ddr_fsp0_cfg[] = { ++ { 0xd0000, 0x0 }, ++ { 0x54003, 0xc80 }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2230 }, ++ { 0x54006, 0x25b }, ++ { 0x54007, 0x2000 }, ++ { 0x54008, 0x101 }, ++ { 0x5400b, 0x31f }, ++ { 0x5400c, 0xc8 }, ++ { 0x5400d, 0x100 }, ++ { 0x54012, 0x1 }, ++ { 0x5402f, 0xc50 }, ++ { 0x54030, 0x501 }, ++ { 0x54031, 0x28 }, ++ { 0x54032, 0x400 }, ++ { 0x54033, 0x200 }, ++ { 0x54034, 0x600 }, ++ { 0x54035, 0x1010 }, ++ { 0x54036, 0x101 }, ++ { 0x5403f, 0x1221 }, ++ { 0x541fc, 0x100 }, ++ { 0xd0000, 0x1 }, ++}; ++ ++ ++/* P1 message block paremeter for training firmware */ ++struct dram_cfg_param ddr_fsp1_cfg[] = { ++ { 0xd0000, 0x0 }, ++ { 0x54002, 0x1 }, ++ { 0x54003, 0x42a }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2230 }, ++ { 0x54006, 0x25b }, ++ { 0x54007, 0x2000 }, ++ { 0x54008, 0x101 }, ++ { 0x5400b, 0x21f }, ++ { 0x5400c, 0xc8 }, ++ { 0x5400d, 0x100 }, ++ { 0x54012, 0x1 }, ++ { 0x5402f, 0x4 }, ++ { 0x54030, 0x501 }, ++ { 0x54033, 0x200 }, ++ { 0x54034, 0x600 }, ++ { 0x54035, 0x10 }, ++ { 0x54036, 0x101 }, ++ { 0x5403f, 0x1221 }, ++ { 0x541fc, 0x100 }, ++ { 0xd0000, 0x1 }, ++}; ++ ++ ++/* P0 2D message block paremeter for training firmware */ ++struct dram_cfg_param ddr_fsp0_2d_cfg[] = { ++ { 0xd0000, 0x0 }, ++ { 0x54003, 0xc80 }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2230 }, ++ { 0x54006, 0x25b }, ++ { 0x54007, 0x2000 }, ++ { 0x54008, 0x101 }, ++ { 0x5400b, 0x61 }, ++ { 0x5400c, 0xc8 }, ++ { 0x5400d, 0x100 }, ++ { 0x5400e, 0x1f7f }, ++ { 0x54012, 0x1 }, ++ { 0x5402f, 0xc50 }, ++ { 0x54030, 0x501 }, ++ { 0x54031, 0x28 }, ++ { 0x54032, 0x400 }, ++ { 0x54033, 0x200 }, ++ { 0x54034, 0x600 }, ++ { 0x54035, 0x1010 }, ++ { 0x54036, 0x101 }, ++ { 0x5403f, 0x1221 }, ++ { 0x541fc, 0x100 }, ++ { 0xd0000, 0x1 }, ++}; ++ ++/* DRAM PHY init engine image */ ++struct dram_cfg_param ddr_phy_pie[] = { ++ { 0xd0000, 0x0 }, ++ { 0x90000, 0x10 }, ++ { 0x90001, 0x400 }, ++ { 0x90002, 0x10e }, ++ { 0x90003, 0x0 }, ++ { 0x90004, 0x0 }, ++ { 0x90005, 0x8 }, ++ { 0x90029, 0xb }, ++ { 0x9002a, 0x480 }, ++ { 0x9002b, 0x109 }, ++ { 0x9002c, 0x8 }, ++ { 0x9002d, 0x448 }, ++ { 0x9002e, 0x139 }, ++ { 0x9002f, 0x8 }, ++ { 0x90030, 0x478 }, ++ { 0x90031, 0x109 }, ++ { 0x90032, 0x2 }, ++ { 0x90033, 0x10 }, ++ { 0x90034, 0x139 }, ++ { 0x90035, 0xb }, ++ { 0x90036, 0x7c0 }, ++ { 0x90037, 0x139 }, ++ { 0x90038, 0x44 }, ++ { 0x90039, 0x633 }, ++ { 0x9003a, 0x159 }, ++ { 0x9003b, 0x14f }, ++ { 0x9003c, 0x630 }, ++ { 0x9003d, 0x159 }, ++ { 0x9003e, 0x47 }, ++ { 0x9003f, 0x633 }, ++ { 0x90040, 0x149 }, ++ { 0x90041, 0x4f }, ++ { 0x90042, 0x633 }, ++ { 0x90043, 0x179 }, ++ { 0x90044, 0x8 }, ++ { 0x90045, 0xe0 }, ++ { 0x90046, 0x109 }, ++ { 0x90047, 0x0 }, ++ { 0x90048, 0x7c8 }, ++ { 0x90049, 0x109 }, ++ { 0x9004a, 0x0 }, ++ { 0x9004b, 0x1 }, ++ { 0x9004c, 0x8 }, ++ { 0x9004d, 0x0 }, ++ { 0x9004e, 0x45a }, ++ { 0x9004f, 0x9 }, ++ { 0x90050, 0x0 }, ++ { 0x90051, 0x448 }, ++ { 0x90052, 0x109 }, ++ { 0x90053, 0x40 }, ++ { 0x90054, 0x633 }, ++ { 0x90055, 0x179 }, ++ { 0x90056, 0x1 }, ++ { 0x90057, 0x618 }, ++ { 0x90058, 0x109 }, ++ { 0x90059, 0x40c0 }, ++ { 0x9005a, 0x633 }, ++ { 0x9005b, 0x149 }, ++ { 0x9005c, 0x8 }, ++ { 0x9005d, 0x4 }, ++ { 0x9005e, 0x48 }, ++ { 0x9005f, 0x4040 }, ++ { 0x90060, 0x633 }, ++ { 0x90061, 0x149 }, ++ { 0x90062, 0x0 }, ++ { 0x90063, 0x4 }, ++ { 0x90064, 0x48 }, ++ { 0x90065, 0x40 }, ++ { 0x90066, 0x633 }, ++ { 0x90067, 0x149 }, ++ { 0x90068, 0x10 }, ++ { 0x90069, 0x4 }, ++ { 0x9006a, 0x18 }, ++ { 0x9006b, 0x0 }, ++ { 0x9006c, 0x4 }, ++ { 0x9006d, 0x78 }, ++ { 0x9006e, 0x549 }, ++ { 0x9006f, 0x633 }, ++ { 0x90070, 0x159 }, ++ { 0x90071, 0xd49 }, ++ { 0x90072, 0x633 }, ++ { 0x90073, 0x159 }, ++ { 0x90074, 0x94a }, ++ { 0x90075, 0x633 }, ++ { 0x90076, 0x159 }, ++ { 0x90077, 0x441 }, ++ { 0x90078, 0x633 }, ++ { 0x90079, 0x149 }, ++ { 0x9007a, 0x42 }, ++ { 0x9007b, 0x633 }, ++ { 0x9007c, 0x149 }, ++ { 0x9007d, 0x1 }, ++ { 0x9007e, 0x633 }, ++ { 0x9007f, 0x149 }, ++ { 0x90080, 0x0 }, ++ { 0x90081, 0xe0 }, ++ { 0x90082, 0x109 }, ++ { 0x90083, 0xa }, ++ { 0x90084, 0x10 }, ++ { 0x90085, 0x109 }, ++ { 0x90086, 0x9 }, ++ { 0x90087, 0x3c0 }, ++ { 0x90088, 0x149 }, ++ { 0x90089, 0x9 }, ++ { 0x9008a, 0x3c0 }, ++ { 0x9008b, 0x159 }, ++ { 0x9008c, 0x18 }, ++ { 0x9008d, 0x10 }, ++ { 0x9008e, 0x109 }, ++ { 0x9008f, 0x0 }, ++ { 0x90090, 0x3c0 }, ++ { 0x90091, 0x109 }, ++ { 0x90092, 0x18 }, ++ { 0x90093, 0x4 }, ++ { 0x90094, 0x48 }, ++ { 0x90095, 0x18 }, ++ { 0x90096, 0x4 }, ++ { 0x90097, 0x58 }, ++ { 0x90098, 0xb }, ++ { 0x90099, 0x10 }, ++ { 0x9009a, 0x109 }, ++ { 0x9009b, 0x1 }, ++ { 0x9009c, 0x10 }, ++ { 0x9009d, 0x109 }, ++ { 0x9009e, 0x5 }, ++ { 0x9009f, 0x7c0 }, ++ { 0x900a0, 0x109 }, ++ { 0x900a1, 0x0 }, ++ { 0x900a2, 0x8140 }, ++ { 0x900a3, 0x10c }, ++ { 0x900a4, 0x10 }, ++ { 0x900a5, 0x8138 }, ++ { 0x900a6, 0x104 }, ++ { 0x900a7, 0x8 }, ++ { 0x900a8, 0x448 }, ++ { 0x900a9, 0x109 }, ++ { 0x900aa, 0xf }, ++ { 0x900ab, 0x7c0 }, ++ { 0x900ac, 0x109 }, ++ { 0x900ad, 0x47 }, ++ { 0x900ae, 0x630 }, ++ { 0x900af, 0x109 }, ++ { 0x900b0, 0x8 }, ++ { 0x900b1, 0x618 }, ++ { 0x900b2, 0x109 }, ++ { 0x900b3, 0x8 }, ++ { 0x900b4, 0xe0 }, ++ { 0x900b5, 0x109 }, ++ { 0x900b6, 0x0 }, ++ { 0x900b7, 0x7c8 }, ++ { 0x900b8, 0x109 }, ++ { 0x900b9, 0x8 }, ++ { 0x900ba, 0x8140 }, ++ { 0x900bb, 0x10c }, ++ { 0x900bc, 0x0 }, ++ { 0x900bd, 0x478 }, ++ { 0x900be, 0x109 }, ++ { 0x900bf, 0x0 }, ++ { 0x900c0, 0x1 }, ++ { 0x900c1, 0x8 }, ++ { 0x900c2, 0x8 }, ++ { 0x900c3, 0x4 }, ++ { 0x900c4, 0x0 }, ++ { 0x90006, 0x8 }, ++ { 0x90007, 0x7c8 }, ++ { 0x90008, 0x109 }, ++ { 0x90009, 0x0 }, ++ { 0x9000a, 0x400 }, ++ { 0x9000b, 0x106 }, ++ { 0xd00e7, 0x400 }, ++ { 0x90017, 0x0 }, ++ { 0x90026, 0x2a }, ++ { 0x2000b, 0x64 }, ++ { 0x2000c, 0xc8 }, ++ { 0x2000d, 0x7d0 }, ++ { 0x2000e, 0x2c }, ++ { 0x12000b, 0x21 }, ++ { 0x12000c, 0x42 }, ++ { 0x12000d, 0x29a }, ++ { 0x12000e, 0x21 }, ++ { 0x9000c, 0x0 }, ++ { 0x9000d, 0x173 }, ++ { 0x9000e, 0x60 }, ++ { 0x9000f, 0x6110 }, ++ { 0x90010, 0x2152 }, ++ { 0x90011, 0xdfbd }, ++ { 0x90012, 0xffff }, ++ { 0x90013, 0x6152 }, ++ { 0x20089, 0x1 }, ++ { 0x20088, 0x19 }, ++ { 0xc0080, 0x0 }, ++ { 0xd0000, 0x1 } ++}; ++ ++struct dram_fsp_msg ddr_dram_fsp_msg[] = { ++ { ++ /* P0 3200mts 1D */ ++ .drate = 3200, ++ .fw_type = FW_1D_IMAGE, ++ .fsp_cfg = ddr_fsp0_cfg, ++ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg), ++ }, ++ { ++ /* P1 1066mts 1D */ ++ .drate = 1066, ++ .fw_type = FW_1D_IMAGE, ++ .fsp_cfg = ddr_fsp1_cfg, ++ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg), ++ }, ++ { ++ /* P0 3200mts 2D */ ++ .drate = 3200, ++ .fw_type = FW_2D_IMAGE, ++ .fsp_cfg = ddr_fsp0_2d_cfg, ++ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_2d_cfg), ++ }, ++}; ++ ++/* ddr timing config params */ ++struct dram_timing_info dram_timing = { ++ .ddrc_cfg = ddr_ddrc_cfg, ++ .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg), ++ .ddrphy_cfg = ddr_ddrphy_cfg, ++ .ddrphy_cfg_num = ARRAY_SIZE(ddr_ddrphy_cfg), ++ .fsp_msg = ddr_dram_fsp_msg, ++ .fsp_msg_num = ARRAY_SIZE(ddr_dram_fsp_msg), ++ .ddrphy_trained_csr = ddr_ddrphy_trained_csr, ++ .ddrphy_trained_csr_num = ARRAY_SIZE(ddr_ddrphy_trained_csr), ++ .ddrphy_pie = ddr_phy_pie, ++ .ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie), ++ .fsp_table = { 3200, 1066, }, ++}; ++ ++#ifdef CONFIG_IMX8M_DRAM_INLINE_ECC ++void board_dram_ecc_scrub(void) ++{ ++ ddrc_inline_ecc_scrub(0x0,0x7ffffff); ++ ddrc_inline_ecc_scrub(0x8000000,0xfffffff); ++ ddrc_inline_ecc_scrub(0x10000000,0x17ffffff); ++ ddrc_inline_ecc_scrub(0x18000000,0x1fffffff); ++ ddrc_inline_ecc_scrub(0x20000000,0x27ffffff); ++ ddrc_inline_ecc_scrub(0x28000000,0x2fffffff); ++ ddrc_inline_ecc_scrub(0x30000000,0x37ffffff); ++ ddrc_inline_ecc_scrub_end(0x0,0x3fffffff); ++} ++#endif +diff --git a/board/freescale/gauguin-imx8mp/gauguin-imx8mp.c b/board/freescale/gauguin-imx8mp/gauguin-imx8mp.c +new file mode 100644 +index 00000000..5f5667b0 +--- /dev/null ++++ b/board/freescale/gauguin-imx8mp/gauguin-imx8mp.c +@@ -0,0 +1,531 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright 2019 NXP ++ */ ++ ++#include <common.h> ++#include <efi_loader.h> ++#include <env.h> ++#include <errno.h> ++#include <init.h> ++#include <miiphy.h> ++#include <netdev.h> ++#include <linux/delay.h> ++#include <asm/global_data.h> ++#include <asm/io.h> ++#include <asm/mach-imx/iomux-v3.h> ++#include <asm-generic/gpio.h> ++#include <asm/arch/imx8mp_pins.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/sys_proto.h> ++#include <asm/mach-imx/gpio.h> ++#include <asm/mach-imx/mxc_i2c.h> ++#include <spl.h> ++#include <asm/mach-imx/dma.h> ++#include <power/pmic.h> ++#include "../common/tcpc.h" ++#include <usb.h> ++#include <dwc3-uboot.h> ++#include <imx_sip.h> ++#include <linux/arm-smccc.h> ++#include <mmc.h> ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1) ++#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE) ++ ++static iomux_v3_cfg_t const uart_pads[] = { ++ MX8MP_PAD_UART2_RXD__UART2_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), ++ MX8MP_PAD_UART2_TXD__UART2_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), ++}; ++ ++static iomux_v3_cfg_t const wdog_pads[] = { ++ MX8MP_PAD_GPIO1_IO02__WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL), ++}; ++ ++#ifdef CONFIG_NAND_MXS ++ ++static void setup_gpmi_nand(void) ++{ ++ init_nand_clk(); ++} ++#endif ++ ++#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) ++struct efi_fw_image fw_images[] = { ++ { ++ .image_type_id = IMX_BOOT_IMAGE_GUID, ++ .fw_name = u"IMX8MP-EVK-RAW", ++ .image_index = 1, ++ }, ++}; ++ ++struct efi_capsule_update_info update_info = { ++ .dfu_string = "mmc 2=flash-bin raw 0 0x2000 mmcpart 1", ++ .images = fw_images, ++}; ++ ++u8 num_image_type_guids = ARRAY_SIZE(fw_images); ++#endif /* EFI_HAVE_CAPSULE_SUPPORT */ ++ ++int board_early_init_f(void) ++{ ++ struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; ++ ++ imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads)); ++ ++ set_wdog_reset(wdog); ++ ++ imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); ++ ++ init_uart_clk(1); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_OF_BOARD_SETUP ++int ft_board_setup(void *blob, struct bd_info *bd) ++{ ++#ifdef CONFIG_IMX8M_DRAM_INLINE_ECC ++#ifdef CONFIG_TARGET_IMX8MP_DDR4_EVK ++ int rc; ++ phys_addr_t ecc_start = 0x120000000; ++ size_t ecc_size = 0x20000000; ++ ++ rc = add_res_mem_dt_node(blob, "ecc", ecc_start, ecc_size); ++ if (rc < 0) { ++ printf("Could not create ecc reserved-memory node.\n"); ++ return rc; ++ } ++#else ++ int rc; ++ phys_addr_t ecc0_start = 0xb0000000; ++ phys_addr_t ecc1_start = 0x130000000; ++ phys_addr_t ecc2_start = 0x1b0000000; ++ size_t ecc_size = 0x10000000; ++ ++ rc = add_res_mem_dt_node(blob, "ecc", ecc0_start, ecc_size); ++ if (rc < 0) { ++ printf("Could not create ecc0 reserved-memory node.\n"); ++ return rc; ++ } ++ ++ rc = add_res_mem_dt_node(blob, "ecc", ecc1_start, ecc_size); ++ if (rc < 0) { ++ printf("Could not create ecc1 reserved-memory node.\n"); ++ return rc; ++ } ++ ++ rc = add_res_mem_dt_node(blob, "ecc", ecc2_start, ecc_size); ++ if (rc < 0) { ++ printf("Could not create ecc2 reserved-memory node.\n"); ++ return rc; ++ } ++#endif ++#endif ++ ++ return 0; ++} ++#endif ++ ++#ifdef CONFIG_USB_TCPC ++struct tcpc_port port1; ++struct tcpc_port port2; ++ ++static int setup_pd_switch(uint8_t i2c_bus, uint8_t addr) ++{ ++ struct udevice *bus; ++ struct udevice *i2c_dev = NULL; ++ int ret; ++ uint8_t valb; ++ ++ ret = uclass_get_device_by_seq(UCLASS_I2C, i2c_bus, &bus); ++ if (ret) { ++ printf("%s: Can't find bus\n", __func__); ++ return -EINVAL; ++ } ++ ++ ret = dm_i2c_probe(bus, addr, 0, &i2c_dev); ++ if (ret) { ++ printf("%s: Can't find device id=0x%x\n", ++ __func__, addr); ++ return -ENODEV; ++ } ++ ++ ret = dm_i2c_read(i2c_dev, 0xB, &valb, 1); ++ if (ret) { ++ printf("%s dm_i2c_read failed, err %d\n", __func__, ret); ++ return -EIO; ++ } ++ valb |= 0x4; /* Set DB_EXIT to exit dead battery mode */ ++ ret = dm_i2c_write(i2c_dev, 0xB, (const uint8_t *)&valb, 1); ++ if (ret) { ++ printf("%s dm_i2c_write failed, err %d\n", __func__, ret); ++ return -EIO; ++ } ++ ++ /* Set OVP threshold to 23V */ ++ valb = 0x6; ++ ret = dm_i2c_write(i2c_dev, 0x8, (const uint8_t *)&valb, 1); ++ if (ret) { ++ printf("%s dm_i2c_write failed, err %d\n", __func__, ret); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++int pd_switch_snk_enable(struct tcpc_port *port) ++{ ++ if (port == &port1) { ++ debug("Setup pd switch on port 1\n"); ++ return setup_pd_switch(1, 0x72); ++ } else ++ return -EINVAL; ++} ++ ++/* Port2 is the power supply, port 1 does not support power */ ++struct tcpc_port_config port1_config = { ++ .i2c_bus = 1, /*i2c2*/ ++ .addr = 0x50, ++ .port_type = TYPEC_PORT_UFP, ++ .max_snk_mv = 20000, ++ .max_snk_ma = 3000, ++ .max_snk_mw = 45000, ++ .op_snk_mv = 15000, ++ .switch_setup_func = &pd_switch_snk_enable, ++ .disable_pd = true, ++}; ++ ++struct tcpc_port_config port2_config = { ++ .i2c_bus = 2, /*i2c3*/ ++ .addr = 0x50, ++ .port_type = TYPEC_PORT_UFP, ++ .max_snk_mv = 20000, ++ .max_snk_ma = 3000, ++ .max_snk_mw = 45000, ++ .op_snk_mv = 15000, ++}; ++ ++#define USB_TYPEC_SEL IMX_GPIO_NR(4, 20) ++#define USB_TYPEC_EN IMX_GPIO_NR(2, 20) ++ ++static iomux_v3_cfg_t ss_mux_gpio[] = { ++ MX8MP_PAD_SAI1_MCLK__GPIO4_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL), ++ MX8MP_PAD_SD2_WP__GPIO2_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL), ++}; ++ ++void ss_mux_select(enum typec_cc_polarity pol) ++{ ++ if (pol == TYPEC_POLARITY_CC1) ++ gpio_direction_output(USB_TYPEC_SEL, 0); ++ else ++ gpio_direction_output(USB_TYPEC_SEL, 1); ++} ++ ++static int setup_typec(void) ++{ ++ int ret; ++ struct gpio_desc per_12v_desc; ++ ++ debug("tcpc_init port 2\n"); ++ ret = tcpc_init(&port2, port2_config, NULL); ++ if (ret) { ++ printf("%s: tcpc port2 init failed, err=%d\n", ++ __func__, ret); ++ } else if (tcpc_pd_sink_check_charging(&port2)) { ++ printf("Power supply on USB2\n"); ++ ++ /* Enable PER 12V, any check before it? */ ++ ret = dm_gpio_lookup_name("gpio@20_1", &per_12v_desc); ++ if (ret) { ++ printf("%s lookup gpio@20_1 failed ret = %d\n", __func__, ret); ++ return -ENODEV; ++ } ++ ++ ret = dm_gpio_request(&per_12v_desc, "per_12v_en"); ++ if (ret) { ++ printf("%s request per_12v failed ret = %d\n", __func__, ret); ++ return -EIO; ++ } ++ ++ /* Enable PER 12V regulator */ ++ dm_gpio_set_dir_flags(&per_12v_desc, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); ++ } ++ ++ debug("tcpc_init port 1\n"); ++ imx_iomux_v3_setup_multiple_pads(ss_mux_gpio, ARRAY_SIZE(ss_mux_gpio)); ++ gpio_request(USB_TYPEC_SEL, "typec_sel"); ++ gpio_request(USB_TYPEC_EN, "typec_en"); ++ gpio_direction_output(USB_TYPEC_EN, 0); ++ ++ ret = tcpc_init(&port1, port1_config, &ss_mux_select); ++ if (ret) { ++ printf("%s: tcpc port1 init failed, err=%d\n", ++ __func__, ret); ++ } else { ++ return ret; ++ } ++ ++ return ret; ++} ++#endif ++ ++#ifdef CONFIG_USB_DWC3 ++ ++#define USB_PHY_CTRL0 0xF0040 ++#define USB_PHY_CTRL0_REF_SSP_EN BIT(2) ++ ++#define USB_PHY_CTRL1 0xF0044 ++#define USB_PHY_CTRL1_RESET BIT(0) ++#define USB_PHY_CTRL1_COMMONONN BIT(1) ++#define USB_PHY_CTRL1_ATERESET BIT(3) ++#define USB_PHY_CTRL1_VDATSRCENB0 BIT(19) ++#define USB_PHY_CTRL1_VDATDETENB0 BIT(20) ++ ++#define USB_PHY_CTRL2 0xF0048 ++#define USB_PHY_CTRL2_TXENABLEN0 BIT(8) ++ ++#define USB_PHY_CTRL6 0xF0058 ++ ++#define HSIO_GPR_BASE (0x32F10000U) ++#define HSIO_GPR_REG_0 (HSIO_GPR_BASE) ++#define HSIO_GPR_REG_0_USB_CLOCK_MODULE_EN_SHIFT (1) ++#define HSIO_GPR_REG_0_USB_CLOCK_MODULE_EN (0x1U << HSIO_GPR_REG_0_USB_CLOCK_MODULE_EN_SHIFT) ++ ++ ++static struct dwc3_device dwc3_device_data = { ++#ifdef CONFIG_SPL_BUILD ++ .maximum_speed = USB_SPEED_HIGH, ++#else ++ .maximum_speed = USB_SPEED_SUPER, ++#endif ++ .base = USB1_BASE_ADDR, ++ .dr_mode = USB_DR_MODE_PERIPHERAL, ++ .index = 0, ++ .power_down_scale = 2, ++}; ++ ++int usb_gadget_handle_interrupts(int index) ++{ ++ dwc3_uboot_handle_interrupt(index); ++ return 0; ++} ++ ++static void dwc3_nxp_usb_phy_init(struct dwc3_device *dwc3) ++{ ++ u32 RegData; ++ ++ /* enable usb clock via hsio gpr */ ++ RegData = readl(HSIO_GPR_REG_0); ++ RegData |= HSIO_GPR_REG_0_USB_CLOCK_MODULE_EN; ++ writel(RegData, HSIO_GPR_REG_0); ++ ++ /* USB3.0 PHY signal fsel for 100M ref */ ++ RegData = readl(dwc3->base + USB_PHY_CTRL0); ++ RegData = (RegData & 0xfffff81f) | (0x2a<<5); ++ writel(RegData, dwc3->base + USB_PHY_CTRL0); ++ ++ RegData = readl(dwc3->base + USB_PHY_CTRL6); ++ RegData &=~0x1; ++ writel(RegData, dwc3->base + USB_PHY_CTRL6); ++ ++ RegData = readl(dwc3->base + USB_PHY_CTRL1); ++ RegData &= ~(USB_PHY_CTRL1_VDATSRCENB0 | USB_PHY_CTRL1_VDATDETENB0 | ++ USB_PHY_CTRL1_COMMONONN); ++ RegData |= USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET; ++ writel(RegData, dwc3->base + USB_PHY_CTRL1); ++ ++ RegData = readl(dwc3->base + USB_PHY_CTRL0); ++ RegData |= USB_PHY_CTRL0_REF_SSP_EN; ++ writel(RegData, dwc3->base + USB_PHY_CTRL0); ++ ++ RegData = readl(dwc3->base + USB_PHY_CTRL2); ++ RegData |= USB_PHY_CTRL2_TXENABLEN0; ++ writel(RegData, dwc3->base + USB_PHY_CTRL2); ++ ++ RegData = readl(dwc3->base + USB_PHY_CTRL1); ++ RegData &= ~(USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET); ++ writel(RegData, dwc3->base + USB_PHY_CTRL1); ++} ++#endif ++ ++#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_IMX8M) ++#define USB2_PWR_EN IMX_GPIO_NR(1, 14) ++int board_usb_init(int index, enum usb_init_type init) ++{ ++ int ret = 0; ++ imx8m_usb_power(index, true); ++ ++ if (index == 0 && init == USB_INIT_DEVICE) { ++#ifdef CONFIG_USB_TCPC ++ ret = tcpc_setup_ufp_mode(&port1); ++ if (ret) ++ return ret; ++#endif ++ dwc3_nxp_usb_phy_init(&dwc3_device_data); ++ return dwc3_uboot_init(&dwc3_device_data); ++ } else if (index == 0 && init == USB_INIT_HOST) { ++#ifdef CONFIG_USB_TCPC ++ ret = tcpc_setup_dfp_mode(&port1); ++#endif ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int board_usb_cleanup(int index, enum usb_init_type init) ++{ ++ int ret = 0; ++ if (index == 0 && init == USB_INIT_DEVICE) { ++ dwc3_uboot_exit(index); ++ } else if (index == 0 && init == USB_INIT_HOST) { ++#ifdef CONFIG_USB_TCPC ++ ret = tcpc_disable_src_vbus(&port1); ++#endif ++ } ++ ++ imx8m_usb_power(index, false); ++ ++ return ret; ++} ++ ++#ifdef CONFIG_USB_TCPC ++/* Not used so far */ ++int board_typec_get_mode(int index) ++{ ++ int ret = 0; ++ enum typec_cc_polarity pol; ++ enum typec_cc_state state; ++ ++ if (index == 0) { ++ tcpc_setup_ufp_mode(&port1); ++ ++ ret = tcpc_get_cc_status(&port1, &pol, &state); ++ if (!ret) { ++ if (state == TYPEC_STATE_SRC_RD_RA || state == TYPEC_STATE_SRC_RD) ++ return USB_INIT_HOST; ++ } ++ ++ return USB_INIT_DEVICE; ++ } else { ++ return USB_INIT_HOST; ++ } ++} ++#endif ++#endif ++ ++static void setup_fec(void) ++{ ++ struct iomuxc_gpr_base_regs *gpr = ++ (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; ++ ++ /* Enable RGMII TX clk output */ ++ setbits_le32(&gpr->gpr[1], BIT(22)); ++} ++ ++static int setup_eqos(void) ++{ ++ struct iomuxc_gpr_base_regs *gpr = ++ (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; ++ ++ /* set INTF as RGMII, enable RGMII TXC clock */ ++ clrsetbits_le32(&gpr->gpr[1], ++ IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MASK, BIT(16)); ++ setbits_le32(&gpr->gpr[1], BIT(19) | BIT(21)); ++ ++ return set_clk_eqos(ENET_125MHZ); ++} ++ ++#if CONFIG_IS_ENABLED(NET) ++int board_phy_config(struct phy_device *phydev) ++{ ++ if (phydev->drv->config) ++ phydev->drv->config(phydev); ++ return 0; ++} ++#endif ++ ++#define DISPMIX 13 ++#define MIPI 15 ++ ++int board_init(void) ++{ ++ struct arm_smccc_res res; ++ ++#ifdef CONFIG_USB_TCPC ++ setup_typec(); ++ ++ /* Enable USB power default */ ++ imx8m_usb_power(0, true); ++ imx8m_usb_power(1, true); ++#endif ++ ++ if (CONFIG_IS_ENABLED(FEC_MXC)) { ++ setup_fec(); ++ } ++ ++ if (CONFIG_IS_ENABLED(DWC_ETH_QOS)) { ++ setup_eqos(); ++ } ++ ++#ifdef CONFIG_NAND_MXS ++ setup_gpmi_nand(); ++#endif ++ ++#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_IMX8M) ++ init_usb_clk(); ++#endif ++ ++ /* enable the dispmix & mipi phy power domain */ ++ arm_smccc_smc(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, ++ DISPMIX, true, 0, 0, 0, 0, &res); ++ arm_smccc_smc(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, ++ MIPI, true, 0, 0, 0, 0, &res); ++ ++ return 0; ++} ++ ++int board_late_init(void) ++{ ++#ifdef CONFIG_ENV_IS_IN_MMC ++ board_late_mmc_env_init(); ++#endif ++#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG ++ env_set("board_name", "IGKBoard"); ++ env_set("board_rev", "iMX8MP"); ++#endif ++ ++ return 0; ++} ++ ++#ifdef CONFIG_ANDROID_SUPPORT ++bool is_power_key_pressed(void) { ++ return (bool)(!!(readl(SNVS_HPSR) & (0x1 << 6))); ++} ++#endif ++ ++#ifdef CONFIG_SPL_MMC ++#define UBOOT_RAW_SECTOR_OFFSET 0x40 ++unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc) ++{ ++ u32 boot_dev = spl_boot_device(); ++ switch (boot_dev) { ++ case BOOT_DEVICE_MMC2: ++ return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR - UBOOT_RAW_SECTOR_OFFSET; ++ default: ++ return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR; ++ } ++} ++#endif ++ ++#ifdef CONFIG_FSL_FASTBOOT ++#ifdef CONFIG_ANDROID_RECOVERY ++int is_recovery_key_pressing(void) ++{ ++ return 0; /* TODO */ ++} ++#endif /* CONFIG_ANDROID_RECOVERY */ ++#endif /* CONFIG_FSL_FASTBOOT */ +diff --git a/board/freescale/gauguin-imx8mp/imximage-8mp-lpddr4.cfg b/board/freescale/gauguin-imx8mp/imximage-8mp-lpddr4.cfg +new file mode 100644 +index 00000000..6dedf172 +--- /dev/null ++++ b/board/freescale/gauguin-imx8mp/imximage-8mp-lpddr4.cfg +@@ -0,0 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright 2021 NXP ++ */ ++ ++ ++ROM_VERSION v2 ++BOOT_FROM sd ++LOADER u-boot-spl-ddr.bin 0x920000 +diff --git a/board/freescale/gauguin-imx8mp/lpddr4_timing.c b/board/freescale/gauguin-imx8mp/lpddr4_timing.c +new file mode 100644 +index 00000000..8c5306d5 +--- /dev/null ++++ b/board/freescale/gauguin-imx8mp/lpddr4_timing.c +@@ -0,0 +1,2048 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright 2019 NXP ++ */ ++ ++#include <linux/kernel.h> ++#include <asm/arch/ddr.h> ++ ++struct dram_cfg_param ddr_ddrc_cfg[] = { ++ /** Initialize DDRC registers **/ ++ { 0x3d400304, 0x1 }, ++ { 0x3d400030, 0x1 }, ++ { 0x3d400000, 0xa3080020 }, ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ { 0x3d400020, 0x223 }, ++ { 0x3d400024, 0x124f800 }, ++ { 0x3d400064, 0x4900a8 }, ++ { 0x3d400070, 0x1027f90 }, ++ { 0x3d400074, 0x790 }, ++ { 0x3d4000d0, 0xc0030495 }, ++ { 0x3d4000d4, 0x770000 }, ++ { 0x3d4000dc, 0xc40024 }, ++#else ++ { 0x3d400020, 0x1323 }, ++ { 0x3d400024, 0x1e84800 }, ++ { 0x3d400064, 0x7a017c }, ++#ifdef CONFIG_IMX8M_DRAM_INLINE_ECC ++ { 0x3d400070, 0x1027f54 }, ++#else ++ { 0x3d400070, 0x1027f10 }, ++#endif ++ { 0x3d400074, 0x7b0 }, ++ { 0x3d4000d0, 0xc00307a3 }, ++ { 0x3d4000d4, 0xc50000 }, ++ { 0x3d4000dc, 0xf4003f }, ++#endif ++ { 0x3d4000e0, 0x330000 }, ++ { 0x3d4000e8, 0x660048 }, ++ { 0x3d4000ec, 0x160048 }, ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ { 0x3d400100, 0x1618141a }, ++ { 0x3d400104, 0x504a6 }, ++ { 0x3d40010c, 0x909000 }, ++ { 0x3d400110, 0xb04060b }, ++ { 0x3d400114, 0x2030909 }, ++ { 0x3d400118, 0x1010006 }, ++ { 0x3d40011c, 0x301 }, ++ { 0x3d400130, 0x20500 }, ++ { 0x3d400134, 0xb100002 }, ++ { 0x3d400138, 0xad }, ++ { 0x3d400144, 0x78003c }, ++ { 0x3d400180, 0x2580012 }, ++ { 0x3d400184, 0x1e0493e }, ++ { 0x3d400188, 0x0 }, ++ { 0x3d400190, 0x4938208 }, ++ { 0x3d400194, 0x80303 }, ++ { 0x3d4001b4, 0x1308 }, ++#else ++ { 0x3d400100, 0x2028222a }, ++ { 0x3d400104, 0x807bf }, ++ { 0x3d40010c, 0xe0e000 }, ++ { 0x3d400110, 0x12040a12 }, ++ { 0x3d400114, 0x2050f0f }, ++ { 0x3d400118, 0x1010009 }, ++ { 0x3d40011c, 0x501 }, ++ { 0x3d400130, 0x20800 }, ++ { 0x3d400134, 0xe100002 }, ++ { 0x3d400138, 0x184 }, ++ { 0x3d400144, 0xc80064 }, ++ { 0x3d400180, 0x3e8001e }, ++ { 0x3d400184, 0x3207a12 }, ++ { 0x3d400188, 0x0 }, ++ { 0x3d400190, 0x49f820e }, ++ { 0x3d400194, 0x80303 }, ++ { 0x3d4001b4, 0x1f0e }, ++#endif ++ { 0x3d4001a0, 0xe0400018 }, ++ { 0x3d4001a4, 0xdf00e4 }, ++ { 0x3d4001a8, 0x80000000 }, ++ { 0x3d4001b0, 0x11 }, ++ { 0x3d4001c0, 0x1 }, ++ { 0x3d4001c4, 0x1 }, ++ { 0x3d4000f4, 0xc99 }, ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ { 0x3d400108, 0x60c1514 }, ++ { 0x3d400200, 0x16 }, ++ { 0x3d40020c, 0x0 }, ++ { 0x3d400210, 0x1f1f }, ++ { 0x3d400204, 0x80808 }, ++ { 0x3d400214, 0x7070707 }, ++ { 0x3d400218, 0x68070707 }, ++ { 0x3d40021c, 0xf08 }, ++ { 0x3d400250, 0x1f05 }, ++ { 0x3d400254, 0x1f }, ++ { 0x3d400264, 0x90003ff }, ++ { 0x3d40026c, 0x20003ff }, ++ { 0x3d400400, 0x111 }, ++ { 0x3d400408, 0x72ff }, ++ { 0x3d400494, 0x1000e00 }, ++ { 0x3d400498, 0x3ff0000 }, ++ { 0x3d40049c, 0x1000e00 }, ++ { 0x3d4004a0, 0x3ff0000 }, ++ { 0x3d402020, 0x21 }, ++ { 0x3d402024, 0x30d400 }, ++ { 0x3d402050, 0x20d000 }, ++ { 0x3d402064, 0xc001c }, ++#else ++ { 0x3d400108, 0x9121c1c }, ++#ifdef CONFIG_IMX8M_DRAM_INLINE_ECC ++ { 0x3d400200, 0x13 }, ++ { 0x3d40020c, 0x13131300 }, ++ { 0x3d400210, 0x1f1f }, ++ { 0x3d400204, 0x50505 }, ++ { 0x3d400214, 0x4040404 }, ++ { 0x3d400218, 0x68040404 }, ++#else ++ { 0x3d400200, 0x16 }, ++ { 0x3d40020c, 0x0 }, ++ { 0x3d400210, 0x1f1f }, ++ { 0x3d400204, 0x80808 }, ++ { 0x3d400214, 0x7070707 }, ++ { 0x3d400218, 0x68070707 }, ++#endif ++ { 0x3d40021c, 0xf08 }, ++ { 0x3d400250, 0x1705 }, ++ { 0x3d400254, 0x2c }, ++ { 0x3d40025c, 0x4000030 }, ++ { 0x3d400264, 0x900093e7 }, ++ { 0x3d40026c, 0x2005574 }, ++ { 0x3d400400, 0x111 }, ++ { 0x3d400404, 0x72ff }, ++ { 0x3d400408, 0x72ff }, ++ { 0x3d400494, 0x2100e07 }, ++ { 0x3d400498, 0x620096 }, ++ { 0x3d40049c, 0x1100e07 }, ++ { 0x3d4004a0, 0xc8012c }, ++ { 0x3d402020, 0x1021 }, ++ { 0x3d402024, 0x30d400 }, ++ { 0x3d402050, 0x20d000 }, ++ { 0x3d402064, 0xc0026 }, ++#endif ++ { 0x3d4020dc, 0x840000 }, ++ { 0x3d4020e0, 0x330000 }, ++ { 0x3d4020e8, 0x660048 }, ++ { 0x3d4020ec, 0x160048 }, ++ { 0x3d402100, 0xa040305 }, ++ { 0x3d402104, 0x30407 }, ++ { 0x3d402108, 0x203060b }, ++ { 0x3d40210c, 0x505000 }, ++ { 0x3d402110, 0x2040202 }, ++ { 0x3d402114, 0x2030202 }, ++ { 0x3d402118, 0x1010004 }, ++ { 0x3d40211c, 0x301 }, ++ { 0x3d402130, 0x20300 }, ++ { 0x3d402134, 0xa100002 }, ++ { 0x3d402138, 0x27 }, ++ { 0x3d402144, 0x14000a }, ++ { 0x3d402180, 0x640004 }, ++ { 0x3d402190, 0x3818200 }, ++ { 0x3d402194, 0x80303 }, ++ { 0x3d4021b4, 0x100 }, ++ { 0x3d4020f4, 0xc99 }, ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ { 0x3d403020, 0x21 }, ++ { 0x3d403024, 0xc3500 }, ++ { 0x3d403050, 0x20d000 }, ++ { 0x3d403064, 0x30007 }, ++#else ++ { 0x3d403020, 0x1021 }, ++ { 0x3d403024, 0xc3500 }, ++ { 0x3d403050, 0x20d000 }, ++ { 0x3d403064, 0x3000a }, ++#endif ++ { 0x3d4030dc, 0x840000 }, ++ { 0x3d4030e0, 0x330000 }, ++ { 0x3d4030e8, 0x660048 }, ++ { 0x3d4030ec, 0x160048 }, ++ { 0x3d403100, 0xa010102 }, ++ { 0x3d403104, 0x30404 }, ++ { 0x3d403108, 0x203060b }, ++ { 0x3d40310c, 0x505000 }, ++ { 0x3d403110, 0x2040202 }, ++ { 0x3d403114, 0x2030202 }, ++ { 0x3d403118, 0x1010004 }, ++ { 0x3d40311c, 0x301 }, ++ { 0x3d403130, 0x20300 }, ++ { 0x3d403134, 0xa100002 }, ++ { 0x3d403138, 0xa }, ++ { 0x3d403144, 0x50003 }, ++ { 0x3d403180, 0x190004 }, ++ { 0x3d403190, 0x3818200 }, ++ { 0x3d403194, 0x80303 }, ++ { 0x3d4031b4, 0x100 }, ++ { 0x3d4030f4, 0xc99 }, ++ { 0x3d400028, 0x0 }, ++}; ++ ++/* PHY Initialize Configuration */ ++struct dram_cfg_param ddr_ddrphy_cfg[] = { ++ { 0x100a0, 0x0 }, ++ { 0x100a1, 0x1 }, ++ { 0x100a2, 0x2 }, ++ { 0x100a3, 0x3 }, ++ { 0x100a4, 0x4 }, ++ { 0x100a5, 0x5 }, ++ { 0x100a6, 0x6 }, ++ { 0x100a7, 0x7 }, ++ { 0x110a0, 0x0 }, ++ { 0x110a1, 0x1 }, ++ { 0x110a2, 0x3 }, ++ { 0x110a3, 0x4 }, ++ { 0x110a4, 0x5 }, ++ { 0x110a5, 0x2 }, ++ { 0x110a6, 0x7 }, ++ { 0x110a7, 0x6 }, ++ { 0x120a0, 0x0 }, ++ { 0x120a1, 0x1 }, ++ { 0x120a2, 0x3 }, ++ { 0x120a3, 0x2 }, ++ { 0x120a4, 0x5 }, ++ { 0x120a5, 0x4 }, ++ { 0x120a6, 0x7 }, ++ { 0x120a7, 0x6 }, ++ { 0x130a0, 0x0 }, ++ { 0x130a1, 0x1 }, ++ { 0x130a2, 0x2 }, ++ { 0x130a3, 0x3 }, ++ { 0x130a4, 0x4 }, ++ { 0x130a5, 0x5 }, ++ { 0x130a6, 0x6 }, ++ { 0x130a7, 0x7 }, ++ { 0x1005f, 0x1ff }, ++ { 0x1015f, 0x1ff }, ++ { 0x1105f, 0x1ff }, ++ { 0x1115f, 0x1ff }, ++ { 0x1205f, 0x1ff }, ++ { 0x1215f, 0x1ff }, ++ { 0x1305f, 0x1ff }, ++ { 0x1315f, 0x1ff }, ++ { 0x11005f, 0x1ff }, ++ { 0x11015f, 0x1ff }, ++ { 0x11105f, 0x1ff }, ++ { 0x11115f, 0x1ff }, ++ { 0x11205f, 0x1ff }, ++ { 0x11215f, 0x1ff }, ++ { 0x11305f, 0x1ff }, ++ { 0x11315f, 0x1ff }, ++ { 0x21005f, 0x1ff }, ++ { 0x21015f, 0x1ff }, ++ { 0x21105f, 0x1ff }, ++ { 0x21115f, 0x1ff }, ++ { 0x21205f, 0x1ff }, ++ { 0x21215f, 0x1ff }, ++ { 0x21305f, 0x1ff }, ++ { 0x21315f, 0x1ff }, ++ { 0x55, 0x1ff }, ++ { 0x1055, 0x1ff }, ++ { 0x2055, 0x1ff }, ++ { 0x3055, 0x1ff }, ++ { 0x4055, 0x1ff }, ++ { 0x5055, 0x1ff }, ++ { 0x6055, 0x1ff }, ++ { 0x7055, 0x1ff }, ++ { 0x8055, 0x1ff }, ++ { 0x9055, 0x1ff }, ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ { 0x200c5, 0xa }, ++#else ++ { 0x200c5, 0x18 }, ++#endif ++ { 0x1200c5, 0x7 }, ++ { 0x2200c5, 0x7 }, ++ { 0x2002e, 0x2 }, ++ { 0x12002e, 0x2 }, ++ { 0x22002e, 0x2 }, ++ { 0x90204, 0x0 }, ++ { 0x190204, 0x0 }, ++ { 0x290204, 0x0 }, ++ { 0x20024, 0x1e3 }, ++ { 0x2003a, 0x2 }, ++ { 0x120024, 0x1e3 }, ++ { 0x2003a, 0x2 }, ++ { 0x220024, 0x1e3 }, ++ { 0x2003a, 0x2 }, ++ { 0x20056, 0x3 }, ++ { 0x120056, 0x3 }, ++ { 0x220056, 0x3 }, ++ { 0x1004d, 0xe00 }, ++ { 0x1014d, 0xe00 }, ++ { 0x1104d, 0xe00 }, ++ { 0x1114d, 0xe00 }, ++ { 0x1204d, 0xe00 }, ++ { 0x1214d, 0xe00 }, ++ { 0x1304d, 0xe00 }, ++ { 0x1314d, 0xe00 }, ++ { 0x11004d, 0xe00 }, ++ { 0x11014d, 0xe00 }, ++ { 0x11104d, 0xe00 }, ++ { 0x11114d, 0xe00 }, ++ { 0x11204d, 0xe00 }, ++ { 0x11214d, 0xe00 }, ++ { 0x11304d, 0xe00 }, ++ { 0x11314d, 0xe00 }, ++ { 0x21004d, 0xe00 }, ++ { 0x21014d, 0xe00 }, ++ { 0x21104d, 0xe00 }, ++ { 0x21114d, 0xe00 }, ++ { 0x21204d, 0xe00 }, ++ { 0x21214d, 0xe00 }, ++ { 0x21304d, 0xe00 }, ++ { 0x21314d, 0xe00 }, ++ { 0x10049, 0xeba }, ++ { 0x10149, 0xeba }, ++ { 0x11049, 0xeba }, ++ { 0x11149, 0xeba }, ++ { 0x12049, 0xeba }, ++ { 0x12149, 0xeba }, ++ { 0x13049, 0xeba }, ++ { 0x13149, 0xeba }, ++ { 0x110049, 0xeba }, ++ { 0x110149, 0xeba }, ++ { 0x111049, 0xeba }, ++ { 0x111149, 0xeba }, ++ { 0x112049, 0xeba }, ++ { 0x112149, 0xeba }, ++ { 0x113049, 0xeba }, ++ { 0x113149, 0xeba }, ++ { 0x210049, 0xeba }, ++ { 0x210149, 0xeba }, ++ { 0x211049, 0xeba }, ++ { 0x211149, 0xeba }, ++ { 0x212049, 0xeba }, ++ { 0x212149, 0xeba }, ++ { 0x213049, 0xeba }, ++ { 0x213149, 0xeba }, ++ { 0x43, 0x63 }, ++ { 0x1043, 0x63 }, ++ { 0x2043, 0x63 }, ++ { 0x3043, 0x63 }, ++ { 0x4043, 0x63 }, ++ { 0x5043, 0x63 }, ++ { 0x6043, 0x63 }, ++ { 0x7043, 0x63 }, ++ { 0x8043, 0x63 }, ++ { 0x9043, 0x63 }, ++ { 0x20018, 0x3 }, ++ { 0x20075, 0x4 }, ++ { 0x20050, 0x0 }, ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ { 0x20008, 0x258 }, ++#else ++ { 0x20008, 0x3e8 }, ++#endif ++ { 0x120008, 0x64 }, ++ { 0x220008, 0x19 }, ++ { 0x20088, 0x9 }, ++ { 0x200b2, 0x104 }, ++ { 0x10043, 0x5a1 }, ++ { 0x10143, 0x5a1 }, ++ { 0x11043, 0x5a1 }, ++ { 0x11143, 0x5a1 }, ++ { 0x12043, 0x5a1 }, ++ { 0x12143, 0x5a1 }, ++ { 0x13043, 0x5a1 }, ++ { 0x13143, 0x5a1 }, ++ { 0x1200b2, 0x104 }, ++ { 0x110043, 0x5a1 }, ++ { 0x110143, 0x5a1 }, ++ { 0x111043, 0x5a1 }, ++ { 0x111143, 0x5a1 }, ++ { 0x112043, 0x5a1 }, ++ { 0x112143, 0x5a1 }, ++ { 0x113043, 0x5a1 }, ++ { 0x113143, 0x5a1 }, ++ { 0x2200b2, 0x104 }, ++ { 0x210043, 0x5a1 }, ++ { 0x210143, 0x5a1 }, ++ { 0x211043, 0x5a1 }, ++ { 0x211143, 0x5a1 }, ++ { 0x212043, 0x5a1 }, ++ { 0x212143, 0x5a1 }, ++ { 0x213043, 0x5a1 }, ++ { 0x213143, 0x5a1 }, ++ { 0x200fa, 0x1 }, ++ { 0x1200fa, 0x1 }, ++ { 0x2200fa, 0x1 }, ++ { 0x20019, 0x1 }, ++ { 0x120019, 0x1 }, ++ { 0x220019, 0x1 }, ++ { 0x200f0, 0x660 }, ++ { 0x200f1, 0x0 }, ++ { 0x200f2, 0x4444 }, ++ { 0x200f3, 0x8888 }, ++ { 0x200f4, 0x5665 }, ++ { 0x200f5, 0x0 }, ++ { 0x200f6, 0x0 }, ++ { 0x200f7, 0xf000 }, ++ { 0x20025, 0x0 }, ++ { 0x2002d, 0x0 }, ++ { 0x12002d, 0x0 }, ++ { 0x22002d, 0x0 }, ++ { 0x2007d, 0x212 }, ++ { 0x12007d, 0x212 }, ++ { 0x22007d, 0x212 }, ++ { 0x2007c, 0x61 }, ++ { 0x12007c, 0x61 }, ++ { 0x22007c, 0x61 }, ++ { 0x1004a, 0x500 }, ++ { 0x1104a, 0x500 }, ++ { 0x1204a, 0x500 }, ++ { 0x1304a, 0x500 }, ++ { 0x2002c, 0x0 }, ++}; ++ ++/* ddr phy trained csr */ ++struct dram_cfg_param ddr_ddrphy_trained_csr[] = { ++ { 0x200b2, 0x0 }, ++ { 0x1200b2, 0x0 }, ++ { 0x2200b2, 0x0 }, ++ { 0x200cb, 0x0 }, ++ { 0x10043, 0x0 }, ++ { 0x110043, 0x0 }, ++ { 0x210043, 0x0 }, ++ { 0x10143, 0x0 }, ++ { 0x110143, 0x0 }, ++ { 0x210143, 0x0 }, ++ { 0x11043, 0x0 }, ++ { 0x111043, 0x0 }, ++ { 0x211043, 0x0 }, ++ { 0x11143, 0x0 }, ++ { 0x111143, 0x0 }, ++ { 0x211143, 0x0 }, ++ { 0x12043, 0x0 }, ++ { 0x112043, 0x0 }, ++ { 0x212043, 0x0 }, ++ { 0x12143, 0x0 }, ++ { 0x112143, 0x0 }, ++ { 0x212143, 0x0 }, ++ { 0x13043, 0x0 }, ++ { 0x113043, 0x0 }, ++ { 0x213043, 0x0 }, ++ { 0x13143, 0x0 }, ++ { 0x113143, 0x0 }, ++ { 0x213143, 0x0 }, ++ { 0x80, 0x0 }, ++ { 0x100080, 0x0 }, ++ { 0x200080, 0x0 }, ++ { 0x1080, 0x0 }, ++ { 0x101080, 0x0 }, ++ { 0x201080, 0x0 }, ++ { 0x2080, 0x0 }, ++ { 0x102080, 0x0 }, ++ { 0x202080, 0x0 }, ++ { 0x3080, 0x0 }, ++ { 0x103080, 0x0 }, ++ { 0x203080, 0x0 }, ++ { 0x4080, 0x0 }, ++ { 0x104080, 0x0 }, ++ { 0x204080, 0x0 }, ++ { 0x5080, 0x0 }, ++ { 0x105080, 0x0 }, ++ { 0x205080, 0x0 }, ++ { 0x6080, 0x0 }, ++ { 0x106080, 0x0 }, ++ { 0x206080, 0x0 }, ++ { 0x7080, 0x0 }, ++ { 0x107080, 0x0 }, ++ { 0x207080, 0x0 }, ++ { 0x8080, 0x0 }, ++ { 0x108080, 0x0 }, ++ { 0x208080, 0x0 }, ++ { 0x9080, 0x0 }, ++ { 0x109080, 0x0 }, ++ { 0x209080, 0x0 }, ++ { 0x10080, 0x0 }, ++ { 0x110080, 0x0 }, ++ { 0x210080, 0x0 }, ++ { 0x10180, 0x0 }, ++ { 0x110180, 0x0 }, ++ { 0x210180, 0x0 }, ++ { 0x11080, 0x0 }, ++ { 0x111080, 0x0 }, ++ { 0x211080, 0x0 }, ++ { 0x11180, 0x0 }, ++ { 0x111180, 0x0 }, ++ { 0x211180, 0x0 }, ++ { 0x12080, 0x0 }, ++ { 0x112080, 0x0 }, ++ { 0x212080, 0x0 }, ++ { 0x12180, 0x0 }, ++ { 0x112180, 0x0 }, ++ { 0x212180, 0x0 }, ++ { 0x13080, 0x0 }, ++ { 0x113080, 0x0 }, ++ { 0x213080, 0x0 }, ++ { 0x13180, 0x0 }, ++ { 0x113180, 0x0 }, ++ { 0x213180, 0x0 }, ++ { 0x10081, 0x0 }, ++ { 0x110081, 0x0 }, ++ { 0x210081, 0x0 }, ++ { 0x10181, 0x0 }, ++ { 0x110181, 0x0 }, ++ { 0x210181, 0x0 }, ++ { 0x11081, 0x0 }, ++ { 0x111081, 0x0 }, ++ { 0x211081, 0x0 }, ++ { 0x11181, 0x0 }, ++ { 0x111181, 0x0 }, ++ { 0x211181, 0x0 }, ++ { 0x12081, 0x0 }, ++ { 0x112081, 0x0 }, ++ { 0x212081, 0x0 }, ++ { 0x12181, 0x0 }, ++ { 0x112181, 0x0 }, ++ { 0x212181, 0x0 }, ++ { 0x13081, 0x0 }, ++ { 0x113081, 0x0 }, ++ { 0x213081, 0x0 }, ++ { 0x13181, 0x0 }, ++ { 0x113181, 0x0 }, ++ { 0x213181, 0x0 }, ++ { 0x100d0, 0x0 }, ++ { 0x1100d0, 0x0 }, ++ { 0x2100d0, 0x0 }, ++ { 0x101d0, 0x0 }, ++ { 0x1101d0, 0x0 }, ++ { 0x2101d0, 0x0 }, ++ { 0x110d0, 0x0 }, ++ { 0x1110d0, 0x0 }, ++ { 0x2110d0, 0x0 }, ++ { 0x111d0, 0x0 }, ++ { 0x1111d0, 0x0 }, ++ { 0x2111d0, 0x0 }, ++ { 0x120d0, 0x0 }, ++ { 0x1120d0, 0x0 }, ++ { 0x2120d0, 0x0 }, ++ { 0x121d0, 0x0 }, ++ { 0x1121d0, 0x0 }, ++ { 0x2121d0, 0x0 }, ++ { 0x130d0, 0x0 }, ++ { 0x1130d0, 0x0 }, ++ { 0x2130d0, 0x0 }, ++ { 0x131d0, 0x0 }, ++ { 0x1131d0, 0x0 }, ++ { 0x2131d0, 0x0 }, ++ { 0x100d1, 0x0 }, ++ { 0x1100d1, 0x0 }, ++ { 0x2100d1, 0x0 }, ++ { 0x101d1, 0x0 }, ++ { 0x1101d1, 0x0 }, ++ { 0x2101d1, 0x0 }, ++ { 0x110d1, 0x0 }, ++ { 0x1110d1, 0x0 }, ++ { 0x2110d1, 0x0 }, ++ { 0x111d1, 0x0 }, ++ { 0x1111d1, 0x0 }, ++ { 0x2111d1, 0x0 }, ++ { 0x120d1, 0x0 }, ++ { 0x1120d1, 0x0 }, ++ { 0x2120d1, 0x0 }, ++ { 0x121d1, 0x0 }, ++ { 0x1121d1, 0x0 }, ++ { 0x2121d1, 0x0 }, ++ { 0x130d1, 0x0 }, ++ { 0x1130d1, 0x0 }, ++ { 0x2130d1, 0x0 }, ++ { 0x131d1, 0x0 }, ++ { 0x1131d1, 0x0 }, ++ { 0x2131d1, 0x0 }, ++ { 0x10068, 0x0 }, ++ { 0x10168, 0x0 }, ++ { 0x10268, 0x0 }, ++ { 0x10368, 0x0 }, ++ { 0x10468, 0x0 }, ++ { 0x10568, 0x0 }, ++ { 0x10668, 0x0 }, ++ { 0x10768, 0x0 }, ++ { 0x10868, 0x0 }, ++ { 0x11068, 0x0 }, ++ { 0x11168, 0x0 }, ++ { 0x11268, 0x0 }, ++ { 0x11368, 0x0 }, ++ { 0x11468, 0x0 }, ++ { 0x11568, 0x0 }, ++ { 0x11668, 0x0 }, ++ { 0x11768, 0x0 }, ++ { 0x11868, 0x0 }, ++ { 0x12068, 0x0 }, ++ { 0x12168, 0x0 }, ++ { 0x12268, 0x0 }, ++ { 0x12368, 0x0 }, ++ { 0x12468, 0x0 }, ++ { 0x12568, 0x0 }, ++ { 0x12668, 0x0 }, ++ { 0x12768, 0x0 }, ++ { 0x12868, 0x0 }, ++ { 0x13068, 0x0 }, ++ { 0x13168, 0x0 }, ++ { 0x13268, 0x0 }, ++ { 0x13368, 0x0 }, ++ { 0x13468, 0x0 }, ++ { 0x13568, 0x0 }, ++ { 0x13668, 0x0 }, ++ { 0x13768, 0x0 }, ++ { 0x13868, 0x0 }, ++ { 0x10069, 0x0 }, ++ { 0x10169, 0x0 }, ++ { 0x10269, 0x0 }, ++ { 0x10369, 0x0 }, ++ { 0x10469, 0x0 }, ++ { 0x10569, 0x0 }, ++ { 0x10669, 0x0 }, ++ { 0x10769, 0x0 }, ++ { 0x10869, 0x0 }, ++ { 0x11069, 0x0 }, ++ { 0x11169, 0x0 }, ++ { 0x11269, 0x0 }, ++ { 0x11369, 0x0 }, ++ { 0x11469, 0x0 }, ++ { 0x11569, 0x0 }, ++ { 0x11669, 0x0 }, ++ { 0x11769, 0x0 }, ++ { 0x11869, 0x0 }, ++ { 0x12069, 0x0 }, ++ { 0x12169, 0x0 }, ++ { 0x12269, 0x0 }, ++ { 0x12369, 0x0 }, ++ { 0x12469, 0x0 }, ++ { 0x12569, 0x0 }, ++ { 0x12669, 0x0 }, ++ { 0x12769, 0x0 }, ++ { 0x12869, 0x0 }, ++ { 0x13069, 0x0 }, ++ { 0x13169, 0x0 }, ++ { 0x13269, 0x0 }, ++ { 0x13369, 0x0 }, ++ { 0x13469, 0x0 }, ++ { 0x13569, 0x0 }, ++ { 0x13669, 0x0 }, ++ { 0x13769, 0x0 }, ++ { 0x13869, 0x0 }, ++ { 0x1008c, 0x0 }, ++ { 0x11008c, 0x0 }, ++ { 0x21008c, 0x0 }, ++ { 0x1018c, 0x0 }, ++ { 0x11018c, 0x0 }, ++ { 0x21018c, 0x0 }, ++ { 0x1108c, 0x0 }, ++ { 0x11108c, 0x0 }, ++ { 0x21108c, 0x0 }, ++ { 0x1118c, 0x0 }, ++ { 0x11118c, 0x0 }, ++ { 0x21118c, 0x0 }, ++ { 0x1208c, 0x0 }, ++ { 0x11208c, 0x0 }, ++ { 0x21208c, 0x0 }, ++ { 0x1218c, 0x0 }, ++ { 0x11218c, 0x0 }, ++ { 0x21218c, 0x0 }, ++ { 0x1308c, 0x0 }, ++ { 0x11308c, 0x0 }, ++ { 0x21308c, 0x0 }, ++ { 0x1318c, 0x0 }, ++ { 0x11318c, 0x0 }, ++ { 0x21318c, 0x0 }, ++ { 0x1008d, 0x0 }, ++ { 0x11008d, 0x0 }, ++ { 0x21008d, 0x0 }, ++ { 0x1018d, 0x0 }, ++ { 0x11018d, 0x0 }, ++ { 0x21018d, 0x0 }, ++ { 0x1108d, 0x0 }, ++ { 0x11108d, 0x0 }, ++ { 0x21108d, 0x0 }, ++ { 0x1118d, 0x0 }, ++ { 0x11118d, 0x0 }, ++ { 0x21118d, 0x0 }, ++ { 0x1208d, 0x0 }, ++ { 0x11208d, 0x0 }, ++ { 0x21208d, 0x0 }, ++ { 0x1218d, 0x0 }, ++ { 0x11218d, 0x0 }, ++ { 0x21218d, 0x0 }, ++ { 0x1308d, 0x0 }, ++ { 0x11308d, 0x0 }, ++ { 0x21308d, 0x0 }, ++ { 0x1318d, 0x0 }, ++ { 0x11318d, 0x0 }, ++ { 0x21318d, 0x0 }, ++ { 0x100c0, 0x0 }, ++ { 0x1100c0, 0x0 }, ++ { 0x2100c0, 0x0 }, ++ { 0x101c0, 0x0 }, ++ { 0x1101c0, 0x0 }, ++ { 0x2101c0, 0x0 }, ++ { 0x102c0, 0x0 }, ++ { 0x1102c0, 0x0 }, ++ { 0x2102c0, 0x0 }, ++ { 0x103c0, 0x0 }, ++ { 0x1103c0, 0x0 }, ++ { 0x2103c0, 0x0 }, ++ { 0x104c0, 0x0 }, ++ { 0x1104c0, 0x0 }, ++ { 0x2104c0, 0x0 }, ++ { 0x105c0, 0x0 }, ++ { 0x1105c0, 0x0 }, ++ { 0x2105c0, 0x0 }, ++ { 0x106c0, 0x0 }, ++ { 0x1106c0, 0x0 }, ++ { 0x2106c0, 0x0 }, ++ { 0x107c0, 0x0 }, ++ { 0x1107c0, 0x0 }, ++ { 0x2107c0, 0x0 }, ++ { 0x108c0, 0x0 }, ++ { 0x1108c0, 0x0 }, ++ { 0x2108c0, 0x0 }, ++ { 0x110c0, 0x0 }, ++ { 0x1110c0, 0x0 }, ++ { 0x2110c0, 0x0 }, ++ { 0x111c0, 0x0 }, ++ { 0x1111c0, 0x0 }, ++ { 0x2111c0, 0x0 }, ++ { 0x112c0, 0x0 }, ++ { 0x1112c0, 0x0 }, ++ { 0x2112c0, 0x0 }, ++ { 0x113c0, 0x0 }, ++ { 0x1113c0, 0x0 }, ++ { 0x2113c0, 0x0 }, ++ { 0x114c0, 0x0 }, ++ { 0x1114c0, 0x0 }, ++ { 0x2114c0, 0x0 }, ++ { 0x115c0, 0x0 }, ++ { 0x1115c0, 0x0 }, ++ { 0x2115c0, 0x0 }, ++ { 0x116c0, 0x0 }, ++ { 0x1116c0, 0x0 }, ++ { 0x2116c0, 0x0 }, ++ { 0x117c0, 0x0 }, ++ { 0x1117c0, 0x0 }, ++ { 0x2117c0, 0x0 }, ++ { 0x118c0, 0x0 }, ++ { 0x1118c0, 0x0 }, ++ { 0x2118c0, 0x0 }, ++ { 0x120c0, 0x0 }, ++ { 0x1120c0, 0x0 }, ++ { 0x2120c0, 0x0 }, ++ { 0x121c0, 0x0 }, ++ { 0x1121c0, 0x0 }, ++ { 0x2121c0, 0x0 }, ++ { 0x122c0, 0x0 }, ++ { 0x1122c0, 0x0 }, ++ { 0x2122c0, 0x0 }, ++ { 0x123c0, 0x0 }, ++ { 0x1123c0, 0x0 }, ++ { 0x2123c0, 0x0 }, ++ { 0x124c0, 0x0 }, ++ { 0x1124c0, 0x0 }, ++ { 0x2124c0, 0x0 }, ++ { 0x125c0, 0x0 }, ++ { 0x1125c0, 0x0 }, ++ { 0x2125c0, 0x0 }, ++ { 0x126c0, 0x0 }, ++ { 0x1126c0, 0x0 }, ++ { 0x2126c0, 0x0 }, ++ { 0x127c0, 0x0 }, ++ { 0x1127c0, 0x0 }, ++ { 0x2127c0, 0x0 }, ++ { 0x128c0, 0x0 }, ++ { 0x1128c0, 0x0 }, ++ { 0x2128c0, 0x0 }, ++ { 0x130c0, 0x0 }, ++ { 0x1130c0, 0x0 }, ++ { 0x2130c0, 0x0 }, ++ { 0x131c0, 0x0 }, ++ { 0x1131c0, 0x0 }, ++ { 0x2131c0, 0x0 }, ++ { 0x132c0, 0x0 }, ++ { 0x1132c0, 0x0 }, ++ { 0x2132c0, 0x0 }, ++ { 0x133c0, 0x0 }, ++ { 0x1133c0, 0x0 }, ++ { 0x2133c0, 0x0 }, ++ { 0x134c0, 0x0 }, ++ { 0x1134c0, 0x0 }, ++ { 0x2134c0, 0x0 }, ++ { 0x135c0, 0x0 }, ++ { 0x1135c0, 0x0 }, ++ { 0x2135c0, 0x0 }, ++ { 0x136c0, 0x0 }, ++ { 0x1136c0, 0x0 }, ++ { 0x2136c0, 0x0 }, ++ { 0x137c0, 0x0 }, ++ { 0x1137c0, 0x0 }, ++ { 0x2137c0, 0x0 }, ++ { 0x138c0, 0x0 }, ++ { 0x1138c0, 0x0 }, ++ { 0x2138c0, 0x0 }, ++ { 0x100c1, 0x0 }, ++ { 0x1100c1, 0x0 }, ++ { 0x2100c1, 0x0 }, ++ { 0x101c1, 0x0 }, ++ { 0x1101c1, 0x0 }, ++ { 0x2101c1, 0x0 }, ++ { 0x102c1, 0x0 }, ++ { 0x1102c1, 0x0 }, ++ { 0x2102c1, 0x0 }, ++ { 0x103c1, 0x0 }, ++ { 0x1103c1, 0x0 }, ++ { 0x2103c1, 0x0 }, ++ { 0x104c1, 0x0 }, ++ { 0x1104c1, 0x0 }, ++ { 0x2104c1, 0x0 }, ++ { 0x105c1, 0x0 }, ++ { 0x1105c1, 0x0 }, ++ { 0x2105c1, 0x0 }, ++ { 0x106c1, 0x0 }, ++ { 0x1106c1, 0x0 }, ++ { 0x2106c1, 0x0 }, ++ { 0x107c1, 0x0 }, ++ { 0x1107c1, 0x0 }, ++ { 0x2107c1, 0x0 }, ++ { 0x108c1, 0x0 }, ++ { 0x1108c1, 0x0 }, ++ { 0x2108c1, 0x0 }, ++ { 0x110c1, 0x0 }, ++ { 0x1110c1, 0x0 }, ++ { 0x2110c1, 0x0 }, ++ { 0x111c1, 0x0 }, ++ { 0x1111c1, 0x0 }, ++ { 0x2111c1, 0x0 }, ++ { 0x112c1, 0x0 }, ++ { 0x1112c1, 0x0 }, ++ { 0x2112c1, 0x0 }, ++ { 0x113c1, 0x0 }, ++ { 0x1113c1, 0x0 }, ++ { 0x2113c1, 0x0 }, ++ { 0x114c1, 0x0 }, ++ { 0x1114c1, 0x0 }, ++ { 0x2114c1, 0x0 }, ++ { 0x115c1, 0x0 }, ++ { 0x1115c1, 0x0 }, ++ { 0x2115c1, 0x0 }, ++ { 0x116c1, 0x0 }, ++ { 0x1116c1, 0x0 }, ++ { 0x2116c1, 0x0 }, ++ { 0x117c1, 0x0 }, ++ { 0x1117c1, 0x0 }, ++ { 0x2117c1, 0x0 }, ++ { 0x118c1, 0x0 }, ++ { 0x1118c1, 0x0 }, ++ { 0x2118c1, 0x0 }, ++ { 0x120c1, 0x0 }, ++ { 0x1120c1, 0x0 }, ++ { 0x2120c1, 0x0 }, ++ { 0x121c1, 0x0 }, ++ { 0x1121c1, 0x0 }, ++ { 0x2121c1, 0x0 }, ++ { 0x122c1, 0x0 }, ++ { 0x1122c1, 0x0 }, ++ { 0x2122c1, 0x0 }, ++ { 0x123c1, 0x0 }, ++ { 0x1123c1, 0x0 }, ++ { 0x2123c1, 0x0 }, ++ { 0x124c1, 0x0 }, ++ { 0x1124c1, 0x0 }, ++ { 0x2124c1, 0x0 }, ++ { 0x125c1, 0x0 }, ++ { 0x1125c1, 0x0 }, ++ { 0x2125c1, 0x0 }, ++ { 0x126c1, 0x0 }, ++ { 0x1126c1, 0x0 }, ++ { 0x2126c1, 0x0 }, ++ { 0x127c1, 0x0 }, ++ { 0x1127c1, 0x0 }, ++ { 0x2127c1, 0x0 }, ++ { 0x128c1, 0x0 }, ++ { 0x1128c1, 0x0 }, ++ { 0x2128c1, 0x0 }, ++ { 0x130c1, 0x0 }, ++ { 0x1130c1, 0x0 }, ++ { 0x2130c1, 0x0 }, ++ { 0x131c1, 0x0 }, ++ { 0x1131c1, 0x0 }, ++ { 0x2131c1, 0x0 }, ++ { 0x132c1, 0x0 }, ++ { 0x1132c1, 0x0 }, ++ { 0x2132c1, 0x0 }, ++ { 0x133c1, 0x0 }, ++ { 0x1133c1, 0x0 }, ++ { 0x2133c1, 0x0 }, ++ { 0x134c1, 0x0 }, ++ { 0x1134c1, 0x0 }, ++ { 0x2134c1, 0x0 }, ++ { 0x135c1, 0x0 }, ++ { 0x1135c1, 0x0 }, ++ { 0x2135c1, 0x0 }, ++ { 0x136c1, 0x0 }, ++ { 0x1136c1, 0x0 }, ++ { 0x2136c1, 0x0 }, ++ { 0x137c1, 0x0 }, ++ { 0x1137c1, 0x0 }, ++ { 0x2137c1, 0x0 }, ++ { 0x138c1, 0x0 }, ++ { 0x1138c1, 0x0 }, ++ { 0x2138c1, 0x0 }, ++ { 0x10020, 0x0 }, ++ { 0x110020, 0x0 }, ++ { 0x210020, 0x0 }, ++ { 0x11020, 0x0 }, ++ { 0x111020, 0x0 }, ++ { 0x211020, 0x0 }, ++ { 0x12020, 0x0 }, ++ { 0x112020, 0x0 }, ++ { 0x212020, 0x0 }, ++ { 0x13020, 0x0 }, ++ { 0x113020, 0x0 }, ++ { 0x213020, 0x0 }, ++ { 0x20072, 0x0 }, ++ { 0x20073, 0x0 }, ++ { 0x20074, 0x0 }, ++ { 0x100aa, 0x0 }, ++ { 0x110aa, 0x0 }, ++ { 0x120aa, 0x0 }, ++ { 0x130aa, 0x0 }, ++ { 0x20010, 0x0 }, ++ { 0x120010, 0x0 }, ++ { 0x220010, 0x0 }, ++ { 0x20011, 0x0 }, ++ { 0x120011, 0x0 }, ++ { 0x220011, 0x0 }, ++ { 0x100ae, 0x0 }, ++ { 0x1100ae, 0x0 }, ++ { 0x2100ae, 0x0 }, ++ { 0x100af, 0x0 }, ++ { 0x1100af, 0x0 }, ++ { 0x2100af, 0x0 }, ++ { 0x110ae, 0x0 }, ++ { 0x1110ae, 0x0 }, ++ { 0x2110ae, 0x0 }, ++ { 0x110af, 0x0 }, ++ { 0x1110af, 0x0 }, ++ { 0x2110af, 0x0 }, ++ { 0x120ae, 0x0 }, ++ { 0x1120ae, 0x0 }, ++ { 0x2120ae, 0x0 }, ++ { 0x120af, 0x0 }, ++ { 0x1120af, 0x0 }, ++ { 0x2120af, 0x0 }, ++ { 0x130ae, 0x0 }, ++ { 0x1130ae, 0x0 }, ++ { 0x2130ae, 0x0 }, ++ { 0x130af, 0x0 }, ++ { 0x1130af, 0x0 }, ++ { 0x2130af, 0x0 }, ++ { 0x20020, 0x0 }, ++ { 0x120020, 0x0 }, ++ { 0x220020, 0x0 }, ++ { 0x100a0, 0x0 }, ++ { 0x100a1, 0x0 }, ++ { 0x100a2, 0x0 }, ++ { 0x100a3, 0x0 }, ++ { 0x100a4, 0x0 }, ++ { 0x100a5, 0x0 }, ++ { 0x100a6, 0x0 }, ++ { 0x100a7, 0x0 }, ++ { 0x110a0, 0x0 }, ++ { 0x110a1, 0x0 }, ++ { 0x110a2, 0x0 }, ++ { 0x110a3, 0x0 }, ++ { 0x110a4, 0x0 }, ++ { 0x110a5, 0x0 }, ++ { 0x110a6, 0x0 }, ++ { 0x110a7, 0x0 }, ++ { 0x120a0, 0x0 }, ++ { 0x120a1, 0x0 }, ++ { 0x120a2, 0x0 }, ++ { 0x120a3, 0x0 }, ++ { 0x120a4, 0x0 }, ++ { 0x120a5, 0x0 }, ++ { 0x120a6, 0x0 }, ++ { 0x120a7, 0x0 }, ++ { 0x130a0, 0x0 }, ++ { 0x130a1, 0x0 }, ++ { 0x130a2, 0x0 }, ++ { 0x130a3, 0x0 }, ++ { 0x130a4, 0x0 }, ++ { 0x130a5, 0x0 }, ++ { 0x130a6, 0x0 }, ++ { 0x130a7, 0x0 }, ++ { 0x2007c, 0x0 }, ++ { 0x12007c, 0x0 }, ++ { 0x22007c, 0x0 }, ++ { 0x2007d, 0x0 }, ++ { 0x12007d, 0x0 }, ++ { 0x22007d, 0x0 }, ++ { 0x400fd, 0x0 }, ++ { 0x400c0, 0x0 }, ++ { 0x90201, 0x0 }, ++ { 0x190201, 0x0 }, ++ { 0x290201, 0x0 }, ++ { 0x90202, 0x0 }, ++ { 0x190202, 0x0 }, ++ { 0x290202, 0x0 }, ++ { 0x90203, 0x0 }, ++ { 0x190203, 0x0 }, ++ { 0x290203, 0x0 }, ++ { 0x90204, 0x0 }, ++ { 0x190204, 0x0 }, ++ { 0x290204, 0x0 }, ++ { 0x90205, 0x0 }, ++ { 0x190205, 0x0 }, ++ { 0x290205, 0x0 }, ++ { 0x90206, 0x0 }, ++ { 0x190206, 0x0 }, ++ { 0x290206, 0x0 }, ++ { 0x90207, 0x0 }, ++ { 0x190207, 0x0 }, ++ { 0x290207, 0x0 }, ++ { 0x90208, 0x0 }, ++ { 0x190208, 0x0 }, ++ { 0x290208, 0x0 }, ++ { 0x10062, 0x0 }, ++ { 0x10162, 0x0 }, ++ { 0x10262, 0x0 }, ++ { 0x10362, 0x0 }, ++ { 0x10462, 0x0 }, ++ { 0x10562, 0x0 }, ++ { 0x10662, 0x0 }, ++ { 0x10762, 0x0 }, ++ { 0x10862, 0x0 }, ++ { 0x11062, 0x0 }, ++ { 0x11162, 0x0 }, ++ { 0x11262, 0x0 }, ++ { 0x11362, 0x0 }, ++ { 0x11462, 0x0 }, ++ { 0x11562, 0x0 }, ++ { 0x11662, 0x0 }, ++ { 0x11762, 0x0 }, ++ { 0x11862, 0x0 }, ++ { 0x12062, 0x0 }, ++ { 0x12162, 0x0 }, ++ { 0x12262, 0x0 }, ++ { 0x12362, 0x0 }, ++ { 0x12462, 0x0 }, ++ { 0x12562, 0x0 }, ++ { 0x12662, 0x0 }, ++ { 0x12762, 0x0 }, ++ { 0x12862, 0x0 }, ++ { 0x13062, 0x0 }, ++ { 0x13162, 0x0 }, ++ { 0x13262, 0x0 }, ++ { 0x13362, 0x0 }, ++ { 0x13462, 0x0 }, ++ { 0x13562, 0x0 }, ++ { 0x13662, 0x0 }, ++ { 0x13762, 0x0 }, ++ { 0x13862, 0x0 }, ++ { 0x20077, 0x0 }, ++ { 0x10001, 0x0 }, ++ { 0x11001, 0x0 }, ++ { 0x12001, 0x0 }, ++ { 0x13001, 0x0 }, ++ { 0x10040, 0x0 }, ++ { 0x10140, 0x0 }, ++ { 0x10240, 0x0 }, ++ { 0x10340, 0x0 }, ++ { 0x10440, 0x0 }, ++ { 0x10540, 0x0 }, ++ { 0x10640, 0x0 }, ++ { 0x10740, 0x0 }, ++ { 0x10840, 0x0 }, ++ { 0x10030, 0x0 }, ++ { 0x10130, 0x0 }, ++ { 0x10230, 0x0 }, ++ { 0x10330, 0x0 }, ++ { 0x10430, 0x0 }, ++ { 0x10530, 0x0 }, ++ { 0x10630, 0x0 }, ++ { 0x10730, 0x0 }, ++ { 0x10830, 0x0 }, ++ { 0x11040, 0x0 }, ++ { 0x11140, 0x0 }, ++ { 0x11240, 0x0 }, ++ { 0x11340, 0x0 }, ++ { 0x11440, 0x0 }, ++ { 0x11540, 0x0 }, ++ { 0x11640, 0x0 }, ++ { 0x11740, 0x0 }, ++ { 0x11840, 0x0 }, ++ { 0x11030, 0x0 }, ++ { 0x11130, 0x0 }, ++ { 0x11230, 0x0 }, ++ { 0x11330, 0x0 }, ++ { 0x11430, 0x0 }, ++ { 0x11530, 0x0 }, ++ { 0x11630, 0x0 }, ++ { 0x11730, 0x0 }, ++ { 0x11830, 0x0 }, ++ { 0x12040, 0x0 }, ++ { 0x12140, 0x0 }, ++ { 0x12240, 0x0 }, ++ { 0x12340, 0x0 }, ++ { 0x12440, 0x0 }, ++ { 0x12540, 0x0 }, ++ { 0x12640, 0x0 }, ++ { 0x12740, 0x0 }, ++ { 0x12840, 0x0 }, ++ { 0x12030, 0x0 }, ++ { 0x12130, 0x0 }, ++ { 0x12230, 0x0 }, ++ { 0x12330, 0x0 }, ++ { 0x12430, 0x0 }, ++ { 0x12530, 0x0 }, ++ { 0x12630, 0x0 }, ++ { 0x12730, 0x0 }, ++ { 0x12830, 0x0 }, ++ { 0x13040, 0x0 }, ++ { 0x13140, 0x0 }, ++ { 0x13240, 0x0 }, ++ { 0x13340, 0x0 }, ++ { 0x13440, 0x0 }, ++ { 0x13540, 0x0 }, ++ { 0x13640, 0x0 }, ++ { 0x13740, 0x0 }, ++ { 0x13840, 0x0 }, ++ { 0x13030, 0x0 }, ++ { 0x13130, 0x0 }, ++ { 0x13230, 0x0 }, ++ { 0x13330, 0x0 }, ++ { 0x13430, 0x0 }, ++ { 0x13530, 0x0 }, ++ { 0x13630, 0x0 }, ++ { 0x13730, 0x0 }, ++ { 0x13830, 0x0 }, ++}; ++ ++/* P0 message block paremeter for training firmware */ ++struct dram_cfg_param ddr_fsp0_cfg[] = { ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ { 0xd0000, 0x0 }, ++ { 0x54003, 0x960 }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2228 }, ++ { 0x54006, 0x14 }, ++ { 0x54008, 0x131f }, ++ { 0x54009, 0xc8 }, ++ { 0x5400b, 0x2 }, ++ { 0x5400f, 0x100 }, ++ { 0x54012, 0x310 }, ++ { 0x54019, 0x24c4 }, ++ { 0x5401a, 0x33 }, ++ { 0x5401b, 0x4866 }, ++ { 0x5401c, 0x4800 }, ++ { 0x5401e, 0x16 }, ++ { 0x5401f, 0x24c4 }, ++ { 0x54020, 0x33 }, ++ { 0x54021, 0x4866 }, ++ { 0x54022, 0x4800 }, ++ { 0x54024, 0x16 }, ++ { 0x5402b, 0x1000 }, ++ { 0x5402c, 0x3 }, ++ { 0x54032, 0xc400 }, ++ { 0x54033, 0x3324 }, ++ { 0x54034, 0x6600 }, ++ { 0x54035, 0x48 }, ++ { 0x54036, 0x48 }, ++ { 0x54037, 0x1600 }, ++ { 0x54038, 0xc400 }, ++ { 0x54039, 0x3324 }, ++#else ++ { 0xd0000, 0x0 }, ++ { 0x54003, 0xfa0 }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2228 }, ++ { 0x54006, 0x14 }, ++ { 0x54008, 0x131f }, ++ { 0x54009, 0xc8 }, ++ { 0x5400b, 0x2 }, ++ { 0x5400f, 0x100 }, ++ { 0x54012, 0x310 }, ++ { 0x54019, 0x3ff4 }, ++ { 0x5401a, 0x33 }, ++ { 0x5401b, 0x4866 }, ++ { 0x5401c, 0x4800 }, ++ { 0x5401e, 0x16 }, ++ { 0x5401f, 0x3ff4 }, ++ { 0x54020, 0x33 }, ++ { 0x54021, 0x4866 }, ++ { 0x54022, 0x4800 }, ++ { 0x54024, 0x16 }, ++ { 0x5402b, 0x1000 }, ++ { 0x5402c, 0x3 }, ++ { 0x54032, 0xf400 }, ++ { 0x54033, 0x333f }, ++ { 0x54034, 0x6600 }, ++ { 0x54035, 0x48 }, ++ { 0x54036, 0x48 }, ++ { 0x54037, 0x1600 }, ++ { 0x54038, 0xf400 }, ++ { 0x54039, 0x333f }, ++#endif ++ { 0x5403a, 0x6600 }, ++ { 0x5403b, 0x48 }, ++ { 0x5403c, 0x48 }, ++ { 0x5403d, 0x1600 }, ++ { 0xd0000, 0x1 }, ++}; ++ ++/* P1 message block paremeter for training firmware */ ++struct dram_cfg_param ddr_fsp1_cfg[] = { ++ { 0xd0000, 0x0 }, ++ { 0x54002, 0x101 }, ++ { 0x54003, 0x190 }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2228 }, ++ { 0x54006, 0x14 }, ++ { 0x54008, 0x121f }, ++ { 0x54009, 0xc8 }, ++ { 0x5400b, 0x2 }, ++ { 0x5400f, 0x100 }, ++ { 0x54012, 0x310 }, ++ { 0x54019, 0x84 }, ++ { 0x5401a, 0x33 }, ++ { 0x5401b, 0x4866 }, ++ { 0x5401c, 0x4800 }, ++ { 0x5401e, 0x16 }, ++ { 0x5401f, 0x84 }, ++ { 0x54020, 0x33 }, ++ { 0x54021, 0x4866 }, ++ { 0x54022, 0x4800 }, ++ { 0x54024, 0x16 }, ++ { 0x5402b, 0x1000 }, ++ { 0x5402c, 0x3 }, ++ { 0x54032, 0x8400 }, ++ { 0x54033, 0x3300 }, ++ { 0x54034, 0x6600 }, ++ { 0x54035, 0x48 }, ++ { 0x54036, 0x48 }, ++ { 0x54037, 0x1600 }, ++ { 0x54038, 0x8400 }, ++ { 0x54039, 0x3300 }, ++ { 0x5403a, 0x6600 }, ++ { 0x5403b, 0x48 }, ++ { 0x5403c, 0x48 }, ++ { 0x5403d, 0x1600 }, ++ { 0xd0000, 0x1 }, ++}; ++ ++/* P2 message block paremeter for training firmware */ ++struct dram_cfg_param ddr_fsp2_cfg[] = { ++ { 0xd0000, 0x0 }, ++ { 0x54002, 0x102 }, ++ { 0x54003, 0x64 }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2228 }, ++ { 0x54006, 0x14 }, ++ { 0x54008, 0x121f }, ++ { 0x54009, 0xc8 }, ++ { 0x5400b, 0x2 }, ++ { 0x5400f, 0x100 }, ++ { 0x54012, 0x310 }, ++ { 0x54019, 0x84 }, ++ { 0x5401a, 0x33 }, ++ { 0x5401b, 0x4866 }, ++ { 0x5401c, 0x4800 }, ++ { 0x5401e, 0x16 }, ++ { 0x5401f, 0x84 }, ++ { 0x54020, 0x33 }, ++ { 0x54021, 0x4866 }, ++ { 0x54022, 0x4800 }, ++ { 0x54024, 0x16 }, ++ { 0x5402b, 0x1000 }, ++ { 0x5402c, 0x3 }, ++ { 0x54032, 0x8400 }, ++ { 0x54033, 0x3300 }, ++ { 0x54034, 0x6600 }, ++ { 0x54035, 0x48 }, ++ { 0x54036, 0x48 }, ++ { 0x54037, 0x1600 }, ++ { 0x54038, 0x8400 }, ++ { 0x54039, 0x3300 }, ++ { 0x5403a, 0x6600 }, ++ { 0x5403b, 0x48 }, ++ { 0x5403c, 0x48 }, ++ { 0x5403d, 0x1600 }, ++ { 0xd0000, 0x1 }, ++}; ++ ++/* P0 2D message block paremeter for training firmware */ ++struct dram_cfg_param ddr_fsp0_2d_cfg[] = { ++ { 0xd0000, 0x0 }, ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ { 0x54003, 0x960 }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2228 }, ++ { 0x54006, 0x14 }, ++ { 0x54008, 0x61 }, ++ { 0x54009, 0xc8 }, ++ { 0x5400b, 0x2 }, ++ { 0x5400f, 0x100 }, ++ { 0x54010, 0x1f7f }, ++ { 0x54012, 0x310 }, ++ { 0x54019, 0x24c4 }, ++ { 0x5401a, 0x33 }, ++ { 0x5401b, 0x4866 }, ++ { 0x5401c, 0x4800 }, ++ { 0x5401e, 0x16 }, ++ { 0x5401f, 0x24c4 }, ++ { 0x54020, 0x33 }, ++ { 0x54021, 0x4866 }, ++ { 0x54022, 0x4800 }, ++ { 0x54024, 0x16 }, ++ { 0x5402b, 0x1000 }, ++ { 0x5402c, 0x3 }, ++ { 0x54032, 0xc400 }, ++ { 0x54033, 0x3324 }, ++ { 0x54034, 0x6600 }, ++ { 0x54035, 0x48 }, ++ { 0x54036, 0x48 }, ++ { 0x54037, 0x1600 }, ++ { 0x54038, 0xc400 }, ++ { 0x54039, 0x3324 }, ++#else ++ { 0x54003, 0xfa0 }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2228 }, ++ { 0x54006, 0x14 }, ++ { 0x54008, 0x61 }, ++ { 0x54009, 0xc8 }, ++ { 0x5400b, 0x2 }, ++ { 0x5400f, 0x100 }, ++ { 0x54010, 0x1f7f }, ++ { 0x54012, 0x310 }, ++ { 0x54019, 0x3ff4 }, ++ { 0x5401a, 0x33 }, ++ { 0x5401b, 0x4866 }, ++ { 0x5401c, 0x4800 }, ++ { 0x5401e, 0x16 }, ++ { 0x5401f, 0x3ff4 }, ++ { 0x54020, 0x33 }, ++ { 0x54021, 0x4866 }, ++ { 0x54022, 0x4800 }, ++ { 0x54024, 0x16 }, ++ { 0x5402b, 0x1000 }, ++ { 0x5402c, 0x3 }, ++ { 0x54032, 0xf400 }, ++ { 0x54033, 0x333f }, ++ { 0x54034, 0x6600 }, ++ { 0x54035, 0x48 }, ++ { 0x54036, 0x48 }, ++ { 0x54037, 0x1600 }, ++ { 0x54038, 0xf400 }, ++ { 0x54039, 0x333f }, ++#endif ++ { 0x5403a, 0x6600 }, ++ { 0x5403b, 0x48 }, ++ { 0x5403c, 0x48 }, ++ { 0x5403d, 0x1600 }, ++ { 0xd0000, 0x1 }, ++}; ++ ++/* DRAM PHY init engine image */ ++struct dram_cfg_param ddr_phy_pie[] = { ++ { 0xd0000, 0x0 }, ++ { 0x90000, 0x10 }, ++ { 0x90001, 0x400 }, ++ { 0x90002, 0x10e }, ++ { 0x90003, 0x0 }, ++ { 0x90004, 0x0 }, ++ { 0x90005, 0x8 }, ++ { 0x90029, 0xb }, ++ { 0x9002a, 0x480 }, ++ { 0x9002b, 0x109 }, ++ { 0x9002c, 0x8 }, ++ { 0x9002d, 0x448 }, ++ { 0x9002e, 0x139 }, ++ { 0x9002f, 0x8 }, ++ { 0x90030, 0x478 }, ++ { 0x90031, 0x109 }, ++ { 0x90032, 0x0 }, ++ { 0x90033, 0xe8 }, ++ { 0x90034, 0x109 }, ++ { 0x90035, 0x2 }, ++ { 0x90036, 0x10 }, ++ { 0x90037, 0x139 }, ++ { 0x90038, 0xb }, ++ { 0x90039, 0x7c0 }, ++ { 0x9003a, 0x139 }, ++ { 0x9003b, 0x44 }, ++ { 0x9003c, 0x633 }, ++ { 0x9003d, 0x159 }, ++ { 0x9003e, 0x14f }, ++ { 0x9003f, 0x630 }, ++ { 0x90040, 0x159 }, ++ { 0x90041, 0x47 }, ++ { 0x90042, 0x633 }, ++ { 0x90043, 0x149 }, ++ { 0x90044, 0x4f }, ++ { 0x90045, 0x633 }, ++ { 0x90046, 0x179 }, ++ { 0x90047, 0x8 }, ++ { 0x90048, 0xe0 }, ++ { 0x90049, 0x109 }, ++ { 0x9004a, 0x0 }, ++ { 0x9004b, 0x7c8 }, ++ { 0x9004c, 0x109 }, ++ { 0x9004d, 0x0 }, ++ { 0x9004e, 0x1 }, ++ { 0x9004f, 0x8 }, ++ { 0x90050, 0x0 }, ++ { 0x90051, 0x45a }, ++ { 0x90052, 0x9 }, ++ { 0x90053, 0x0 }, ++ { 0x90054, 0x448 }, ++ { 0x90055, 0x109 }, ++ { 0x90056, 0x40 }, ++ { 0x90057, 0x633 }, ++ { 0x90058, 0x179 }, ++ { 0x90059, 0x1 }, ++ { 0x9005a, 0x618 }, ++ { 0x9005b, 0x109 }, ++ { 0x9005c, 0x40c0 }, ++ { 0x9005d, 0x633 }, ++ { 0x9005e, 0x149 }, ++ { 0x9005f, 0x8 }, ++ { 0x90060, 0x4 }, ++ { 0x90061, 0x48 }, ++ { 0x90062, 0x4040 }, ++ { 0x90063, 0x633 }, ++ { 0x90064, 0x149 }, ++ { 0x90065, 0x0 }, ++ { 0x90066, 0x4 }, ++ { 0x90067, 0x48 }, ++ { 0x90068, 0x40 }, ++ { 0x90069, 0x633 }, ++ { 0x9006a, 0x149 }, ++ { 0x9006b, 0x10 }, ++ { 0x9006c, 0x4 }, ++ { 0x9006d, 0x18 }, ++ { 0x9006e, 0x0 }, ++ { 0x9006f, 0x4 }, ++ { 0x90070, 0x78 }, ++ { 0x90071, 0x549 }, ++ { 0x90072, 0x633 }, ++ { 0x90073, 0x159 }, ++ { 0x90074, 0xd49 }, ++ { 0x90075, 0x633 }, ++ { 0x90076, 0x159 }, ++ { 0x90077, 0x94a }, ++ { 0x90078, 0x633 }, ++ { 0x90079, 0x159 }, ++ { 0x9007a, 0x441 }, ++ { 0x9007b, 0x633 }, ++ { 0x9007c, 0x149 }, ++ { 0x9007d, 0x42 }, ++ { 0x9007e, 0x633 }, ++ { 0x9007f, 0x149 }, ++ { 0x90080, 0x1 }, ++ { 0x90081, 0x633 }, ++ { 0x90082, 0x149 }, ++ { 0x90083, 0x0 }, ++ { 0x90084, 0xe0 }, ++ { 0x90085, 0x109 }, ++ { 0x90086, 0xa }, ++ { 0x90087, 0x10 }, ++ { 0x90088, 0x109 }, ++ { 0x90089, 0x9 }, ++ { 0x9008a, 0x3c0 }, ++ { 0x9008b, 0x149 }, ++ { 0x9008c, 0x9 }, ++ { 0x9008d, 0x3c0 }, ++ { 0x9008e, 0x159 }, ++ { 0x9008f, 0x18 }, ++ { 0x90090, 0x10 }, ++ { 0x90091, 0x109 }, ++ { 0x90092, 0x0 }, ++ { 0x90093, 0x3c0 }, ++ { 0x90094, 0x109 }, ++ { 0x90095, 0x18 }, ++ { 0x90096, 0x4 }, ++ { 0x90097, 0x48 }, ++ { 0x90098, 0x18 }, ++ { 0x90099, 0x4 }, ++ { 0x9009a, 0x58 }, ++ { 0x9009b, 0xb }, ++ { 0x9009c, 0x10 }, ++ { 0x9009d, 0x109 }, ++ { 0x9009e, 0x1 }, ++ { 0x9009f, 0x10 }, ++ { 0x900a0, 0x109 }, ++ { 0x900a1, 0x5 }, ++ { 0x900a2, 0x7c0 }, ++ { 0x900a3, 0x109 }, ++ { 0x40000, 0x811 }, ++ { 0x40020, 0x880 }, ++ { 0x40040, 0x0 }, ++ { 0x40060, 0x0 }, ++ { 0x40001, 0x4008 }, ++ { 0x40021, 0x83 }, ++ { 0x40041, 0x4f }, ++ { 0x40061, 0x0 }, ++ { 0x40002, 0x4040 }, ++ { 0x40022, 0x83 }, ++ { 0x40042, 0x51 }, ++ { 0x40062, 0x0 }, ++ { 0x40003, 0x811 }, ++ { 0x40023, 0x880 }, ++ { 0x40043, 0x0 }, ++ { 0x40063, 0x0 }, ++ { 0x40004, 0x720 }, ++ { 0x40024, 0xf }, ++ { 0x40044, 0x1740 }, ++ { 0x40064, 0x0 }, ++ { 0x40005, 0x16 }, ++ { 0x40025, 0x83 }, ++ { 0x40045, 0x4b }, ++ { 0x40065, 0x0 }, ++ { 0x40006, 0x716 }, ++ { 0x40026, 0xf }, ++ { 0x40046, 0x2001 }, ++ { 0x40066, 0x0 }, ++ { 0x40007, 0x716 }, ++ { 0x40027, 0xf }, ++ { 0x40047, 0x2800 }, ++ { 0x40067, 0x0 }, ++ { 0x40008, 0x716 }, ++ { 0x40028, 0xf }, ++ { 0x40048, 0xf00 }, ++ { 0x40068, 0x0 }, ++ { 0x40009, 0x720 }, ++ { 0x40029, 0xf }, ++ { 0x40049, 0x1400 }, ++ { 0x40069, 0x0 }, ++ { 0x4000a, 0xe08 }, ++ { 0x4002a, 0xc15 }, ++ { 0x4004a, 0x0 }, ++ { 0x4006a, 0x0 }, ++ { 0x4000b, 0x625 }, ++ { 0x4002b, 0x15 }, ++ { 0x4004b, 0x0 }, ++ { 0x4006b, 0x0 }, ++ { 0x4000c, 0x4028 }, ++ { 0x4002c, 0x80 }, ++ { 0x4004c, 0x0 }, ++ { 0x4006c, 0x0 }, ++ { 0x4000d, 0xe08 }, ++ { 0x4002d, 0xc1a }, ++ { 0x4004d, 0x0 }, ++ { 0x4006d, 0x0 }, ++ { 0x4000e, 0x625 }, ++ { 0x4002e, 0x1a }, ++ { 0x4004e, 0x0 }, ++ { 0x4006e, 0x0 }, ++ { 0x4000f, 0x4040 }, ++ { 0x4002f, 0x80 }, ++ { 0x4004f, 0x0 }, ++ { 0x4006f, 0x0 }, ++ { 0x40010, 0x2604 }, ++ { 0x40030, 0x15 }, ++ { 0x40050, 0x0 }, ++ { 0x40070, 0x0 }, ++ { 0x40011, 0x708 }, ++ { 0x40031, 0x5 }, ++ { 0x40051, 0x0 }, ++ { 0x40071, 0x2002 }, ++ { 0x40012, 0x8 }, ++ { 0x40032, 0x80 }, ++ { 0x40052, 0x0 }, ++ { 0x40072, 0x0 }, ++ { 0x40013, 0x2604 }, ++ { 0x40033, 0x1a }, ++ { 0x40053, 0x0 }, ++ { 0x40073, 0x0 }, ++ { 0x40014, 0x708 }, ++ { 0x40034, 0xa }, ++ { 0x40054, 0x0 }, ++ { 0x40074, 0x2002 }, ++ { 0x40015, 0x4040 }, ++ { 0x40035, 0x80 }, ++ { 0x40055, 0x0 }, ++ { 0x40075, 0x0 }, ++ { 0x40016, 0x60a }, ++ { 0x40036, 0x15 }, ++ { 0x40056, 0x1200 }, ++ { 0x40076, 0x0 }, ++ { 0x40017, 0x61a }, ++ { 0x40037, 0x15 }, ++ { 0x40057, 0x1300 }, ++ { 0x40077, 0x0 }, ++ { 0x40018, 0x60a }, ++ { 0x40038, 0x1a }, ++ { 0x40058, 0x1200 }, ++ { 0x40078, 0x0 }, ++ { 0x40019, 0x642 }, ++ { 0x40039, 0x1a }, ++ { 0x40059, 0x1300 }, ++ { 0x40079, 0x0 }, ++ { 0x4001a, 0x4808 }, ++ { 0x4003a, 0x880 }, ++ { 0x4005a, 0x0 }, ++ { 0x4007a, 0x0 }, ++ { 0x900a4, 0x0 }, ++ { 0x900a5, 0x790 }, ++ { 0x900a6, 0x11a }, ++ { 0x900a7, 0x8 }, ++ { 0x900a8, 0x7aa }, ++ { 0x900a9, 0x2a }, ++ { 0x900aa, 0x10 }, ++ { 0x900ab, 0x7b2 }, ++ { 0x900ac, 0x2a }, ++ { 0x900ad, 0x0 }, ++ { 0x900ae, 0x7c8 }, ++ { 0x900af, 0x109 }, ++ { 0x900b0, 0x10 }, ++ { 0x900b1, 0x10 }, ++ { 0x900b2, 0x109 }, ++ { 0x900b3, 0x10 }, ++ { 0x900b4, 0x2a8 }, ++ { 0x900b5, 0x129 }, ++ { 0x900b6, 0x8 }, ++ { 0x900b7, 0x370 }, ++ { 0x900b8, 0x129 }, ++ { 0x900b9, 0xa }, ++ { 0x900ba, 0x3c8 }, ++ { 0x900bb, 0x1a9 }, ++ { 0x900bc, 0xc }, ++ { 0x900bd, 0x408 }, ++ { 0x900be, 0x199 }, ++ { 0x900bf, 0x14 }, ++ { 0x900c0, 0x790 }, ++ { 0x900c1, 0x11a }, ++ { 0x900c2, 0x8 }, ++ { 0x900c3, 0x4 }, ++ { 0x900c4, 0x18 }, ++ { 0x900c5, 0xe }, ++ { 0x900c6, 0x408 }, ++ { 0x900c7, 0x199 }, ++ { 0x900c8, 0x8 }, ++ { 0x900c9, 0x8568 }, ++ { 0x900ca, 0x108 }, ++ { 0x900cb, 0x18 }, ++ { 0x900cc, 0x790 }, ++ { 0x900cd, 0x16a }, ++ { 0x900ce, 0x8 }, ++ { 0x900cf, 0x1d8 }, ++ { 0x900d0, 0x169 }, ++ { 0x900d1, 0x10 }, ++ { 0x900d2, 0x8558 }, ++ { 0x900d3, 0x168 }, ++ { 0x900d4, 0x70 }, ++ { 0x900d5, 0x788 }, ++ { 0x900d6, 0x16a }, ++ { 0x900d7, 0x1ff8 }, ++ { 0x900d8, 0x85a8 }, ++ { 0x900d9, 0x1e8 }, ++ { 0x900da, 0x50 }, ++ { 0x900db, 0x798 }, ++ { 0x900dc, 0x16a }, ++ { 0x900dd, 0x60 }, ++ { 0x900de, 0x7a0 }, ++ { 0x900df, 0x16a }, ++ { 0x900e0, 0x8 }, ++ { 0x900e1, 0x8310 }, ++ { 0x900e2, 0x168 }, ++ { 0x900e3, 0x8 }, ++ { 0x900e4, 0xa310 }, ++ { 0x900e5, 0x168 }, ++ { 0x900e6, 0xa }, ++ { 0x900e7, 0x408 }, ++ { 0x900e8, 0x169 }, ++ { 0x900e9, 0x6e }, ++ { 0x900ea, 0x0 }, ++ { 0x900eb, 0x68 }, ++ { 0x900ec, 0x0 }, ++ { 0x900ed, 0x408 }, ++ { 0x900ee, 0x169 }, ++ { 0x900ef, 0x0 }, ++ { 0x900f0, 0x8310 }, ++ { 0x900f1, 0x168 }, ++ { 0x900f2, 0x0 }, ++ { 0x900f3, 0xa310 }, ++ { 0x900f4, 0x168 }, ++ { 0x900f5, 0x1ff8 }, ++ { 0x900f6, 0x85a8 }, ++ { 0x900f7, 0x1e8 }, ++ { 0x900f8, 0x68 }, ++ { 0x900f9, 0x798 }, ++ { 0x900fa, 0x16a }, ++ { 0x900fb, 0x78 }, ++ { 0x900fc, 0x7a0 }, ++ { 0x900fd, 0x16a }, ++ { 0x900fe, 0x68 }, ++ { 0x900ff, 0x790 }, ++ { 0x90100, 0x16a }, ++ { 0x90101, 0x8 }, ++ { 0x90102, 0x8b10 }, ++ { 0x90103, 0x168 }, ++ { 0x90104, 0x8 }, ++ { 0x90105, 0xab10 }, ++ { 0x90106, 0x168 }, ++ { 0x90107, 0xa }, ++ { 0x90108, 0x408 }, ++ { 0x90109, 0x169 }, ++ { 0x9010a, 0x58 }, ++ { 0x9010b, 0x0 }, ++ { 0x9010c, 0x68 }, ++ { 0x9010d, 0x0 }, ++ { 0x9010e, 0x408 }, ++ { 0x9010f, 0x169 }, ++ { 0x90110, 0x0 }, ++ { 0x90111, 0x8b10 }, ++ { 0x90112, 0x168 }, ++ { 0x90113, 0x1 }, ++ { 0x90114, 0xab10 }, ++ { 0x90115, 0x168 }, ++ { 0x90116, 0x0 }, ++ { 0x90117, 0x1d8 }, ++ { 0x90118, 0x169 }, ++ { 0x90119, 0x80 }, ++ { 0x9011a, 0x790 }, ++ { 0x9011b, 0x16a }, ++ { 0x9011c, 0x18 }, ++ { 0x9011d, 0x7aa }, ++ { 0x9011e, 0x6a }, ++ { 0x9011f, 0xa }, ++ { 0x90120, 0x0 }, ++ { 0x90121, 0x1e9 }, ++ { 0x90122, 0x8 }, ++ { 0x90123, 0x8080 }, ++ { 0x90124, 0x108 }, ++ { 0x90125, 0xf }, ++ { 0x90126, 0x408 }, ++ { 0x90127, 0x169 }, ++ { 0x90128, 0xc }, ++ { 0x90129, 0x0 }, ++ { 0x9012a, 0x68 }, ++ { 0x9012b, 0x9 }, ++ { 0x9012c, 0x0 }, ++ { 0x9012d, 0x1a9 }, ++ { 0x9012e, 0x0 }, ++ { 0x9012f, 0x408 }, ++ { 0x90130, 0x169 }, ++ { 0x90131, 0x0 }, ++ { 0x90132, 0x8080 }, ++ { 0x90133, 0x108 }, ++ { 0x90134, 0x8 }, ++ { 0x90135, 0x7aa }, ++ { 0x90136, 0x6a }, ++ { 0x90137, 0x0 }, ++ { 0x90138, 0x8568 }, ++ { 0x90139, 0x108 }, ++ { 0x9013a, 0xb7 }, ++ { 0x9013b, 0x790 }, ++ { 0x9013c, 0x16a }, ++ { 0x9013d, 0x1f }, ++ { 0x9013e, 0x0 }, ++ { 0x9013f, 0x68 }, ++ { 0x90140, 0x8 }, ++ { 0x90141, 0x8558 }, ++ { 0x90142, 0x168 }, ++ { 0x90143, 0xf }, ++ { 0x90144, 0x408 }, ++ { 0x90145, 0x169 }, ++ { 0x90146, 0xd }, ++ { 0x90147, 0x0 }, ++ { 0x90148, 0x68 }, ++ { 0x90149, 0x0 }, ++ { 0x9014a, 0x408 }, ++ { 0x9014b, 0x169 }, ++ { 0x9014c, 0x0 }, ++ { 0x9014d, 0x8558 }, ++ { 0x9014e, 0x168 }, ++ { 0x9014f, 0x8 }, ++ { 0x90150, 0x3c8 }, ++ { 0x90151, 0x1a9 }, ++ { 0x90152, 0x3 }, ++ { 0x90153, 0x370 }, ++ { 0x90154, 0x129 }, ++ { 0x90155, 0x20 }, ++ { 0x90156, 0x2aa }, ++ { 0x90157, 0x9 }, ++ { 0x90158, 0x8 }, ++ { 0x90159, 0xe8 }, ++ { 0x9015a, 0x109 }, ++ { 0x9015b, 0x0 }, ++ { 0x9015c, 0x8140 }, ++ { 0x9015d, 0x10c }, ++ { 0x9015e, 0x10 }, ++ { 0x9015f, 0x8138 }, ++ { 0x90160, 0x104 }, ++ { 0x90161, 0x8 }, ++ { 0x90162, 0x448 }, ++ { 0x90163, 0x109 }, ++ { 0x90164, 0xf }, ++ { 0x90165, 0x7c0 }, ++ { 0x90166, 0x109 }, ++ { 0x90167, 0x0 }, ++ { 0x90168, 0xe8 }, ++ { 0x90169, 0x109 }, ++ { 0x9016a, 0x47 }, ++ { 0x9016b, 0x630 }, ++ { 0x9016c, 0x109 }, ++ { 0x9016d, 0x8 }, ++ { 0x9016e, 0x618 }, ++ { 0x9016f, 0x109 }, ++ { 0x90170, 0x8 }, ++ { 0x90171, 0xe0 }, ++ { 0x90172, 0x109 }, ++ { 0x90173, 0x0 }, ++ { 0x90174, 0x7c8 }, ++ { 0x90175, 0x109 }, ++ { 0x90176, 0x8 }, ++ { 0x90177, 0x8140 }, ++ { 0x90178, 0x10c }, ++ { 0x90179, 0x0 }, ++ { 0x9017a, 0x478 }, ++ { 0x9017b, 0x109 }, ++ { 0x9017c, 0x0 }, ++ { 0x9017d, 0x1 }, ++ { 0x9017e, 0x8 }, ++ { 0x9017f, 0x8 }, ++ { 0x90180, 0x4 }, ++ { 0x90181, 0x0 }, ++ { 0x90006, 0x8 }, ++ { 0x90007, 0x7c8 }, ++ { 0x90008, 0x109 }, ++ { 0x90009, 0x0 }, ++ { 0x9000a, 0x400 }, ++ { 0x9000b, 0x106 }, ++ { 0xd00e7, 0x400 }, ++ { 0x90017, 0x0 }, ++ { 0x9001f, 0x29 }, ++ { 0x90026, 0x68 }, ++ { 0x400d0, 0x0 }, ++ { 0x400d1, 0x101 }, ++ { 0x400d2, 0x105 }, ++ { 0x400d3, 0x107 }, ++ { 0x400d4, 0x10f }, ++ { 0x400d5, 0x202 }, ++ { 0x400d6, 0x20a }, ++ { 0x400d7, 0x20b }, ++ { 0x2003a, 0x2 }, ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ { 0x2000b, 0x4b }, ++ { 0x2000c, 0x96 }, ++ { 0x2000d, 0x5dc }, ++#else ++ { 0x200be, 0x3 }, ++ { 0x2000b, 0x7d }, ++ { 0x2000c, 0xfa }, ++ { 0x2000d, 0x9c4 }, ++#endif ++ { 0x2000e, 0x2c }, ++ { 0x12000b, 0xc }, ++ { 0x12000c, 0x19 }, ++ { 0x12000d, 0xfa }, ++ { 0x12000e, 0x10 }, ++ { 0x22000b, 0x3 }, ++ { 0x22000c, 0x6 }, ++ { 0x22000d, 0x3e }, ++ { 0x22000e, 0x10 }, ++ { 0x9000c, 0x0 }, ++ { 0x9000d, 0x173 }, ++ { 0x9000e, 0x60 }, ++ { 0x9000f, 0x6110 }, ++ { 0x90010, 0x2152 }, ++ { 0x90011, 0xdfbd }, ++ { 0x90012, 0x2060 }, ++ { 0x90013, 0x6152 }, ++ { 0x20010, 0x5a }, ++ { 0x20011, 0x3 }, ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ { 0x120010, 0x5a }, ++ { 0x120011, 0x3 }, ++ { 0x220010, 0x5a }, ++ { 0x220011, 0x3 }, ++#endif ++ { 0x40080, 0xe0 }, ++ { 0x40081, 0x12 }, ++ { 0x40082, 0xe0 }, ++ { 0x40083, 0x12 }, ++ { 0x40084, 0xe0 }, ++ { 0x40085, 0x12 }, ++ { 0x140080, 0xe0 }, ++ { 0x140081, 0x12 }, ++ { 0x140082, 0xe0 }, ++ { 0x140083, 0x12 }, ++ { 0x140084, 0xe0 }, ++ { 0x140085, 0x12 }, ++ { 0x240080, 0xe0 }, ++ { 0x240081, 0x12 }, ++ { 0x240082, 0xe0 }, ++ { 0x240083, 0x12 }, ++ { 0x240084, 0xe0 }, ++ { 0x240085, 0x12 }, ++ { 0x400fd, 0xf }, ++ { 0x10011, 0x1 }, ++ { 0x10012, 0x1 }, ++ { 0x10013, 0x180 }, ++ { 0x10018, 0x1 }, ++ { 0x10002, 0x6209 }, ++ { 0x100b2, 0x1 }, ++ { 0x101b4, 0x1 }, ++ { 0x102b4, 0x1 }, ++ { 0x103b4, 0x1 }, ++ { 0x104b4, 0x1 }, ++ { 0x105b4, 0x1 }, ++ { 0x106b4, 0x1 }, ++ { 0x107b4, 0x1 }, ++ { 0x108b4, 0x1 }, ++ { 0x11011, 0x1 }, ++ { 0x11012, 0x1 }, ++ { 0x11013, 0x180 }, ++ { 0x11018, 0x1 }, ++ { 0x11002, 0x6209 }, ++ { 0x110b2, 0x1 }, ++ { 0x111b4, 0x1 }, ++ { 0x112b4, 0x1 }, ++ { 0x113b4, 0x1 }, ++ { 0x114b4, 0x1 }, ++ { 0x115b4, 0x1 }, ++ { 0x116b4, 0x1 }, ++ { 0x117b4, 0x1 }, ++ { 0x118b4, 0x1 }, ++ { 0x12011, 0x1 }, ++ { 0x12012, 0x1 }, ++ { 0x12013, 0x180 }, ++ { 0x12018, 0x1 }, ++ { 0x12002, 0x6209 }, ++ { 0x120b2, 0x1 }, ++ { 0x121b4, 0x1 }, ++ { 0x122b4, 0x1 }, ++ { 0x123b4, 0x1 }, ++ { 0x124b4, 0x1 }, ++ { 0x125b4, 0x1 }, ++ { 0x126b4, 0x1 }, ++ { 0x127b4, 0x1 }, ++ { 0x128b4, 0x1 }, ++ { 0x13011, 0x1 }, ++ { 0x13012, 0x1 }, ++ { 0x13013, 0x180 }, ++ { 0x13018, 0x1 }, ++ { 0x13002, 0x6209 }, ++ { 0x130b2, 0x1 }, ++ { 0x131b4, 0x1 }, ++ { 0x132b4, 0x1 }, ++ { 0x133b4, 0x1 }, ++ { 0x134b4, 0x1 }, ++ { 0x135b4, 0x1 }, ++ { 0x136b4, 0x1 }, ++ { 0x137b4, 0x1 }, ++ { 0x138b4, 0x1 }, ++ { 0x20089, 0x1 }, ++ { 0x20088, 0x19 }, ++ { 0xc0080, 0x2 }, ++ { 0xd0000, 0x1 } ++}; ++ ++struct dram_fsp_msg ddr_dram_fsp_msg[] = { ++ { ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ /* P0 2400mts 1D */ ++ .drate = 2400, ++#else ++ /* P0 4000mts 1D */ ++ .drate = 4000, ++#endif ++ .fw_type = FW_1D_IMAGE, ++ .fsp_cfg = ddr_fsp0_cfg, ++ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg), ++ }, ++ { ++ /* P1 400mts 1D */ ++ .drate = 400, ++ .fw_type = FW_1D_IMAGE, ++ .fsp_cfg = ddr_fsp1_cfg, ++ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg), ++ }, ++ { ++ /* P2 100mts 1D */ ++ .drate = 100, ++ .fw_type = FW_1D_IMAGE, ++ .fsp_cfg = ddr_fsp2_cfg, ++ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp2_cfg), ++ }, ++ { ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ /* P0 2400mts 2D */ ++ .drate = 2400, ++#else ++ /* P0 4000mts 2D */ ++ .drate = 4000, ++#endif ++ .fw_type = FW_2D_IMAGE, ++ .fsp_cfg = ddr_fsp0_2d_cfg, ++ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_2d_cfg), ++ }, ++}; ++ ++/* ddr timing config params */ ++struct dram_timing_info dram_timing = { ++ .ddrc_cfg = ddr_ddrc_cfg, ++ .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg), ++ .ddrphy_cfg = ddr_ddrphy_cfg, ++ .ddrphy_cfg_num = ARRAY_SIZE(ddr_ddrphy_cfg), ++ .fsp_msg = ddr_dram_fsp_msg, ++ .fsp_msg_num = ARRAY_SIZE(ddr_dram_fsp_msg), ++ .ddrphy_trained_csr = ddr_ddrphy_trained_csr, ++ .ddrphy_trained_csr_num = ARRAY_SIZE(ddr_ddrphy_trained_csr), ++ .ddrphy_pie = ddr_phy_pie, ++ .ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie), ++#ifdef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++ .fsp_table = { 2400, 400, 100, }, ++#else ++ .fsp_table = { 4000, 400, 100, }, ++#endif ++}; ++ ++#ifndef CONFIG_IMX8M_LPDDR4_FREQ0_2400MTS ++#ifdef CONFIG_IMX8M_DRAM_INLINE_ECC ++void board_dram_ecc_scrub(void) ++{ ++ ddrc_inline_ecc_scrub(0x0, 0x3ffffff); ++ ddrc_inline_ecc_scrub(0x20000000, 0x23ffffff); ++ ddrc_inline_ecc_scrub(0x40000000, 0x43ffffff); ++ ddrc_inline_ecc_scrub(0x4000000, 0x7ffffff); ++ ddrc_inline_ecc_scrub(0x24000000, 0x27ffffff); ++ ddrc_inline_ecc_scrub(0x44000000, 0x47ffffff); ++ ddrc_inline_ecc_scrub(0x8000000, 0xbffffff); ++ ddrc_inline_ecc_scrub(0x28000000, 0x2bffffff); ++ ddrc_inline_ecc_scrub(0x48000000, 0x4bffffff); ++ ddrc_inline_ecc_scrub(0xc000000, 0xfffffff); ++ ddrc_inline_ecc_scrub(0x2c000000, 0x2fffffff); ++ ddrc_inline_ecc_scrub(0x4c000000, 0x4fffffff); ++ ddrc_inline_ecc_scrub(0x10000000, 0x13ffffff); ++ ddrc_inline_ecc_scrub(0x30000000, 0x33ffffff); ++ ddrc_inline_ecc_scrub(0x50000000, 0x53ffffff); ++ ddrc_inline_ecc_scrub(0x14000000, 0x17ffffff); ++ ddrc_inline_ecc_scrub(0x34000000, 0x37ffffff); ++ ddrc_inline_ecc_scrub(0x54000000, 0x57ffffff); ++ ddrc_inline_ecc_scrub(0x18000000, 0x1bffffff); ++ ddrc_inline_ecc_scrub(0x38000000, 0x3bffffff); ++ ddrc_inline_ecc_scrub(0x58000000, 0x5bffffff); ++ ddrc_inline_ecc_scrub_end(0x0, 0x5fffffff); ++} ++#endif ++#endif +diff --git a/board/freescale/gauguin-imx8mp/lpddr4_timing_ndm.c b/board/freescale/gauguin-imx8mp/lpddr4_timing_ndm.c +new file mode 100644 +index 00000000..4765618a +--- /dev/null ++++ b/board/freescale/gauguin-imx8mp/lpddr4_timing_ndm.c +@@ -0,0 +1,1853 @@ ++/* ++ * Copyright 2021 NXP ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * ++ * Generated code from MX8M_DDR_tool ++ * ++ * Align with uboot version: ++ * imx_v2019.04_5.4.x and above version ++ * For imx_v2018.03_4.14.78_1.0.0_ga ~ imx_v2018.04_4.19.35_1.1.0_ga: ++ * please replace #include <asm/arch/ddr.h> with #include <asm/arch/imx8m_ddr.h> ++ */ ++ ++#include <linux/kernel.h> ++#include <asm/arch/ddr.h> ++ ++struct dram_cfg_param ddr_ddrc_cfg[] = { ++ /** Initialize DDRC registers **/ ++ { 0x3d400304, 0x1 }, ++ { 0x3d400030, 0x1 }, ++ { 0x3d400000, 0xa3080020 }, ++ { 0x3d400020, 0x1223 }, ++ { 0x3d400024, 0x186a000 }, ++ { 0x3d400064, 0x610130 }, ++ { 0x3d400070, 0x1027f10 }, ++ { 0x3d400074, 0x7b0 }, ++ { 0x3d4000d0, 0xc003061c }, ++ { 0x3d4000d4, 0x9e0000 }, ++ { 0x3d4000dc, 0xd4002d }, ++ { 0x3d4000e0, 0x330000 }, ++ { 0x3d4000e8, 0x660048 }, ++ { 0x3d4000ec, 0x160048 }, ++ { 0x3d400100, 0x1a201b22 }, ++ { 0x3d400104, 0x60633 }, ++ { 0x3d40010c, 0xc0c000 }, ++ { 0x3d400110, 0xf04080f }, ++ { 0x3d400114, 0x2040c0c }, ++ { 0x3d400118, 0x1010007 }, ++ { 0x3d40011c, 0x401 }, ++ { 0x3d400130, 0x20600 }, ++ { 0x3d400134, 0xe100002 }, ++ { 0x3d400138, 0x136 }, ++ { 0x3d400144, 0xa00050 }, ++ { 0x3d400180, 0x3200018 }, ++ { 0x3d400184, 0x28061a8 }, ++ { 0x3d400188, 0x0 }, ++ { 0x3d400190, 0x497820a }, ++ { 0x3d400194, 0x80303 }, ++ { 0x3d4001b4, 0x170a }, ++ { 0x3d4001a0, 0xe0400018 }, ++ { 0x3d4001a4, 0xdf00e4 }, ++ { 0x3d4001a8, 0x80000000 }, ++ { 0x3d4001b0, 0x11 }, ++ { 0x3d4001c0, 0x1 }, ++ { 0x3d4001c4, 0x1 }, ++ { 0x3d4000f4, 0xc99 }, ++ { 0x3d400108, 0x70e1617 }, ++ { 0x3d400200, 0x16 }, ++ { 0x3d40020c, 0x0 }, ++ { 0x3d400210, 0x1f1f }, ++ { 0x3d400204, 0x80808 }, ++ { 0x3d400214, 0x7070707 }, ++ { 0x3d400218, 0x68070707 }, ++ { 0x3d40021c, 0xf08 }, ++ { 0x3d400250, 0x1705 }, ++ { 0x3d400254, 0x2c }, ++ { 0x3d40025c, 0x4000030 }, ++ { 0x3d400264, 0x900093e7 }, ++ { 0x3d40026c, 0x2005574 }, ++ { 0x3d400400, 0x111 }, ++ { 0x3d400404, 0x72ff }, ++ { 0x3d400408, 0x72ff }, ++ { 0x3d400494, 0x2100e07 }, ++ { 0x3d400498, 0x620096 }, ++ { 0x3d40049c, 0x1100e07 }, ++ { 0x3d4004a0, 0xc8012c }, ++ { 0x3d402020, 0x1021 }, ++ { 0x3d402024, 0x30d400 }, ++ { 0x3d402050, 0x20d000 }, ++ { 0x3d402064, 0xc0026 }, ++ { 0x3d4020dc, 0x840000 }, ++ { 0x3d4020e0, 0x330000 }, ++ { 0x3d4020e8, 0x660048 }, ++ { 0x3d4020ec, 0x160048 }, ++ { 0x3d402100, 0xa040305 }, ++ { 0x3d402104, 0x30407 }, ++ { 0x3d402108, 0x203060b }, ++ { 0x3d40210c, 0x505000 }, ++ { 0x3d402110, 0x2040202 }, ++ { 0x3d402114, 0x2030202 }, ++ { 0x3d402118, 0x1010004 }, ++ { 0x3d40211c, 0x301 }, ++ { 0x3d402130, 0x20300 }, ++ { 0x3d402134, 0xa100002 }, ++ { 0x3d402138, 0x27 }, ++ { 0x3d402144, 0x14000a }, ++ { 0x3d402180, 0x640004 }, ++ { 0x3d402190, 0x3818200 }, ++ { 0x3d402194, 0x80303 }, ++ { 0x3d4021b4, 0x100 }, ++ { 0x3d4020f4, 0xc99 }, ++ { 0x3d403020, 0x1021 }, ++ { 0x3d403024, 0xc3500 }, ++ { 0x3d403050, 0x20d000 }, ++ { 0x3d403064, 0x3000a }, ++ { 0x3d4030dc, 0x840000 }, ++ { 0x3d4030e0, 0x330000 }, ++ { 0x3d4030e8, 0x660048 }, ++ { 0x3d4030ec, 0x160048 }, ++ { 0x3d403100, 0xa010102 }, ++ { 0x3d403104, 0x30404 }, ++ { 0x3d403108, 0x203060b }, ++ { 0x3d40310c, 0x505000 }, ++ { 0x3d403110, 0x2040202 }, ++ { 0x3d403114, 0x2030202 }, ++ { 0x3d403118, 0x1010004 }, ++ { 0x3d40311c, 0x301 }, ++ { 0x3d403130, 0x20300 }, ++ { 0x3d403134, 0xa100002 }, ++ { 0x3d403138, 0xa }, ++ { 0x3d403144, 0x50003 }, ++ { 0x3d403180, 0x190004 }, ++ { 0x3d403190, 0x3818200 }, ++ { 0x3d403194, 0x80303 }, ++ { 0x3d4031b4, 0x100 }, ++ { 0x3d4030f4, 0xc99 }, ++ { 0x3d400028, 0x0 }, ++}; ++ ++/* PHY Initialize Configuration */ ++struct dram_cfg_param ddr_ddrphy_cfg[] = { ++ { 0x100a0, 0x0 }, ++ { 0x100a1, 0x1 }, ++ { 0x100a2, 0x2 }, ++ { 0x100a3, 0x3 }, ++ { 0x100a4, 0x4 }, ++ { 0x100a5, 0x5 }, ++ { 0x100a6, 0x6 }, ++ { 0x100a7, 0x7 }, ++ { 0x110a0, 0x0 }, ++ { 0x110a1, 0x1 }, ++ { 0x110a2, 0x3 }, ++ { 0x110a3, 0x4 }, ++ { 0x110a4, 0x5 }, ++ { 0x110a5, 0x2 }, ++ { 0x110a6, 0x7 }, ++ { 0x110a7, 0x6 }, ++ { 0x120a0, 0x0 }, ++ { 0x120a1, 0x1 }, ++ { 0x120a2, 0x3 }, ++ { 0x120a3, 0x2 }, ++ { 0x120a4, 0x5 }, ++ { 0x120a5, 0x4 }, ++ { 0x120a6, 0x7 }, ++ { 0x120a7, 0x6 }, ++ { 0x130a0, 0x0 }, ++ { 0x130a1, 0x1 }, ++ { 0x130a2, 0x2 }, ++ { 0x130a3, 0x3 }, ++ { 0x130a4, 0x4 }, ++ { 0x130a5, 0x5 }, ++ { 0x130a6, 0x6 }, ++ { 0x130a7, 0x7 }, ++ { 0x1005f, 0x1ff }, ++ { 0x1015f, 0x1ff }, ++ { 0x1105f, 0x1ff }, ++ { 0x1115f, 0x1ff }, ++ { 0x1205f, 0x1ff }, ++ { 0x1215f, 0x1ff }, ++ { 0x1305f, 0x1ff }, ++ { 0x1315f, 0x1ff }, ++ { 0x11005f, 0x1ff }, ++ { 0x11015f, 0x1ff }, ++ { 0x11105f, 0x1ff }, ++ { 0x11115f, 0x1ff }, ++ { 0x11205f, 0x1ff }, ++ { 0x11215f, 0x1ff }, ++ { 0x11305f, 0x1ff }, ++ { 0x11315f, 0x1ff }, ++ { 0x21005f, 0x1ff }, ++ { 0x21015f, 0x1ff }, ++ { 0x21105f, 0x1ff }, ++ { 0x21115f, 0x1ff }, ++ { 0x21205f, 0x1ff }, ++ { 0x21215f, 0x1ff }, ++ { 0x21305f, 0x1ff }, ++ { 0x21315f, 0x1ff }, ++ { 0x55, 0x1ff }, ++ { 0x1055, 0x1ff }, ++ { 0x2055, 0x1ff }, ++ { 0x3055, 0x1ff }, ++ { 0x4055, 0x1ff }, ++ { 0x5055, 0x1ff }, ++ { 0x6055, 0x1ff }, ++ { 0x7055, 0x1ff }, ++ { 0x8055, 0x1ff }, ++ { 0x9055, 0x1ff }, ++ { 0x200c5, 0x19 }, ++ { 0x1200c5, 0x7 }, ++ { 0x2200c5, 0x7 }, ++ { 0x2002e, 0x2 }, ++ { 0x12002e, 0x2 }, ++ { 0x22002e, 0x2 }, ++ { 0x90204, 0x0 }, ++ { 0x190204, 0x0 }, ++ { 0x290204, 0x0 }, ++ { 0x20024, 0x1e3 }, ++ { 0x2003a, 0x2 }, ++ { 0x120024, 0x1e3 }, ++ { 0x2003a, 0x2 }, ++ { 0x220024, 0x1e3 }, ++ { 0x2003a, 0x2 }, ++ { 0x20056, 0x3 }, ++ { 0x120056, 0x3 }, ++ { 0x220056, 0x3 }, ++ { 0x1004d, 0xe00 }, ++ { 0x1014d, 0xe00 }, ++ { 0x1104d, 0xe00 }, ++ { 0x1114d, 0xe00 }, ++ { 0x1204d, 0xe00 }, ++ { 0x1214d, 0xe00 }, ++ { 0x1304d, 0xe00 }, ++ { 0x1314d, 0xe00 }, ++ { 0x11004d, 0xe00 }, ++ { 0x11014d, 0xe00 }, ++ { 0x11104d, 0xe00 }, ++ { 0x11114d, 0xe00 }, ++ { 0x11204d, 0xe00 }, ++ { 0x11214d, 0xe00 }, ++ { 0x11304d, 0xe00 }, ++ { 0x11314d, 0xe00 }, ++ { 0x21004d, 0xe00 }, ++ { 0x21014d, 0xe00 }, ++ { 0x21104d, 0xe00 }, ++ { 0x21114d, 0xe00 }, ++ { 0x21204d, 0xe00 }, ++ { 0x21214d, 0xe00 }, ++ { 0x21304d, 0xe00 }, ++ { 0x21314d, 0xe00 }, ++ { 0x10049, 0xeba }, ++ { 0x10149, 0xeba }, ++ { 0x11049, 0xeba }, ++ { 0x11149, 0xeba }, ++ { 0x12049, 0xeba }, ++ { 0x12149, 0xeba }, ++ { 0x13049, 0xeba }, ++ { 0x13149, 0xeba }, ++ { 0x110049, 0xeba }, ++ { 0x110149, 0xeba }, ++ { 0x111049, 0xeba }, ++ { 0x111149, 0xeba }, ++ { 0x112049, 0xeba }, ++ { 0x112149, 0xeba }, ++ { 0x113049, 0xeba }, ++ { 0x113149, 0xeba }, ++ { 0x210049, 0xeba }, ++ { 0x210149, 0xeba }, ++ { 0x211049, 0xeba }, ++ { 0x211149, 0xeba }, ++ { 0x212049, 0xeba }, ++ { 0x212149, 0xeba }, ++ { 0x213049, 0xeba }, ++ { 0x213149, 0xeba }, ++ { 0x43, 0x63 }, ++ { 0x1043, 0x63 }, ++ { 0x2043, 0x63 }, ++ { 0x3043, 0x63 }, ++ { 0x4043, 0x63 }, ++ { 0x5043, 0x63 }, ++ { 0x6043, 0x63 }, ++ { 0x7043, 0x63 }, ++ { 0x8043, 0x63 }, ++ { 0x9043, 0x63 }, ++ { 0x20018, 0x3 }, ++ { 0x20075, 0x4 }, ++ { 0x20050, 0x0 }, ++ { 0x20008, 0x320 }, ++ { 0x120008, 0x64 }, ++ { 0x220008, 0x19 }, ++ { 0x20088, 0x9 }, ++ { 0x200b2, 0x104 }, ++ { 0x10043, 0x5a1 }, ++ { 0x10143, 0x5a1 }, ++ { 0x11043, 0x5a1 }, ++ { 0x11143, 0x5a1 }, ++ { 0x12043, 0x5a1 }, ++ { 0x12143, 0x5a1 }, ++ { 0x13043, 0x5a1 }, ++ { 0x13143, 0x5a1 }, ++ { 0x1200b2, 0x104 }, ++ { 0x110043, 0x5a1 }, ++ { 0x110143, 0x5a1 }, ++ { 0x111043, 0x5a1 }, ++ { 0x111143, 0x5a1 }, ++ { 0x112043, 0x5a1 }, ++ { 0x112143, 0x5a1 }, ++ { 0x113043, 0x5a1 }, ++ { 0x113143, 0x5a1 }, ++ { 0x2200b2, 0x104 }, ++ { 0x210043, 0x5a1 }, ++ { 0x210143, 0x5a1 }, ++ { 0x211043, 0x5a1 }, ++ { 0x211143, 0x5a1 }, ++ { 0x212043, 0x5a1 }, ++ { 0x212143, 0x5a1 }, ++ { 0x213043, 0x5a1 }, ++ { 0x213143, 0x5a1 }, ++ { 0x200fa, 0x1 }, ++ { 0x1200fa, 0x1 }, ++ { 0x2200fa, 0x1 }, ++ { 0x20019, 0x1 }, ++ { 0x120019, 0x1 }, ++ { 0x220019, 0x1 }, ++ { 0x200f0, 0x660 }, ++ { 0x200f1, 0x0 }, ++ { 0x200f2, 0x4444 }, ++ { 0x200f3, 0x8888 }, ++ { 0x200f4, 0x5665 }, ++ { 0x200f5, 0x0 }, ++ { 0x200f6, 0x0 }, ++ { 0x200f7, 0xf000 }, ++ { 0x20025, 0x0 }, ++ { 0x2002d, 0x0 }, ++ { 0x12002d, 0x0 }, ++ { 0x22002d, 0x0 }, ++ { 0x2007d, 0x212 }, ++ { 0x12007d, 0x212 }, ++ { 0x22007d, 0x212 }, ++ { 0x2007c, 0x61 }, ++ { 0x12007c, 0x61 }, ++ { 0x22007c, 0x61 }, ++ { 0x1004a, 0x500 }, ++ { 0x1104a, 0x500 }, ++ { 0x1204a, 0x500 }, ++ { 0x1304a, 0x500 }, ++ { 0x2002c, 0x0 }, ++}; ++ ++/* ddr phy trained csr */ ++struct dram_cfg_param ddr_ddrphy_trained_csr[] = { ++ { 0x200b2, 0x0 }, ++ { 0x1200b2, 0x0 }, ++ { 0x2200b2, 0x0 }, ++ { 0x200cb, 0x0 }, ++ { 0x10043, 0x0 }, ++ { 0x110043, 0x0 }, ++ { 0x210043, 0x0 }, ++ { 0x10143, 0x0 }, ++ { 0x110143, 0x0 }, ++ { 0x210143, 0x0 }, ++ { 0x11043, 0x0 }, ++ { 0x111043, 0x0 }, ++ { 0x211043, 0x0 }, ++ { 0x11143, 0x0 }, ++ { 0x111143, 0x0 }, ++ { 0x211143, 0x0 }, ++ { 0x12043, 0x0 }, ++ { 0x112043, 0x0 }, ++ { 0x212043, 0x0 }, ++ { 0x12143, 0x0 }, ++ { 0x112143, 0x0 }, ++ { 0x212143, 0x0 }, ++ { 0x13043, 0x0 }, ++ { 0x113043, 0x0 }, ++ { 0x213043, 0x0 }, ++ { 0x13143, 0x0 }, ++ { 0x113143, 0x0 }, ++ { 0x213143, 0x0 }, ++ { 0x80, 0x0 }, ++ { 0x100080, 0x0 }, ++ { 0x200080, 0x0 }, ++ { 0x1080, 0x0 }, ++ { 0x101080, 0x0 }, ++ { 0x201080, 0x0 }, ++ { 0x2080, 0x0 }, ++ { 0x102080, 0x0 }, ++ { 0x202080, 0x0 }, ++ { 0x3080, 0x0 }, ++ { 0x103080, 0x0 }, ++ { 0x203080, 0x0 }, ++ { 0x4080, 0x0 }, ++ { 0x104080, 0x0 }, ++ { 0x204080, 0x0 }, ++ { 0x5080, 0x0 }, ++ { 0x105080, 0x0 }, ++ { 0x205080, 0x0 }, ++ { 0x6080, 0x0 }, ++ { 0x106080, 0x0 }, ++ { 0x206080, 0x0 }, ++ { 0x7080, 0x0 }, ++ { 0x107080, 0x0 }, ++ { 0x207080, 0x0 }, ++ { 0x8080, 0x0 }, ++ { 0x108080, 0x0 }, ++ { 0x208080, 0x0 }, ++ { 0x9080, 0x0 }, ++ { 0x109080, 0x0 }, ++ { 0x209080, 0x0 }, ++ { 0x10080, 0x0 }, ++ { 0x110080, 0x0 }, ++ { 0x210080, 0x0 }, ++ { 0x10180, 0x0 }, ++ { 0x110180, 0x0 }, ++ { 0x210180, 0x0 }, ++ { 0x11080, 0x0 }, ++ { 0x111080, 0x0 }, ++ { 0x211080, 0x0 }, ++ { 0x11180, 0x0 }, ++ { 0x111180, 0x0 }, ++ { 0x211180, 0x0 }, ++ { 0x12080, 0x0 }, ++ { 0x112080, 0x0 }, ++ { 0x212080, 0x0 }, ++ { 0x12180, 0x0 }, ++ { 0x112180, 0x0 }, ++ { 0x212180, 0x0 }, ++ { 0x13080, 0x0 }, ++ { 0x113080, 0x0 }, ++ { 0x213080, 0x0 }, ++ { 0x13180, 0x0 }, ++ { 0x113180, 0x0 }, ++ { 0x213180, 0x0 }, ++ { 0x10081, 0x0 }, ++ { 0x110081, 0x0 }, ++ { 0x210081, 0x0 }, ++ { 0x10181, 0x0 }, ++ { 0x110181, 0x0 }, ++ { 0x210181, 0x0 }, ++ { 0x11081, 0x0 }, ++ { 0x111081, 0x0 }, ++ { 0x211081, 0x0 }, ++ { 0x11181, 0x0 }, ++ { 0x111181, 0x0 }, ++ { 0x211181, 0x0 }, ++ { 0x12081, 0x0 }, ++ { 0x112081, 0x0 }, ++ { 0x212081, 0x0 }, ++ { 0x12181, 0x0 }, ++ { 0x112181, 0x0 }, ++ { 0x212181, 0x0 }, ++ { 0x13081, 0x0 }, ++ { 0x113081, 0x0 }, ++ { 0x213081, 0x0 }, ++ { 0x13181, 0x0 }, ++ { 0x113181, 0x0 }, ++ { 0x213181, 0x0 }, ++ { 0x100d0, 0x0 }, ++ { 0x1100d0, 0x0 }, ++ { 0x2100d0, 0x0 }, ++ { 0x101d0, 0x0 }, ++ { 0x1101d0, 0x0 }, ++ { 0x2101d0, 0x0 }, ++ { 0x110d0, 0x0 }, ++ { 0x1110d0, 0x0 }, ++ { 0x2110d0, 0x0 }, ++ { 0x111d0, 0x0 }, ++ { 0x1111d0, 0x0 }, ++ { 0x2111d0, 0x0 }, ++ { 0x120d0, 0x0 }, ++ { 0x1120d0, 0x0 }, ++ { 0x2120d0, 0x0 }, ++ { 0x121d0, 0x0 }, ++ { 0x1121d0, 0x0 }, ++ { 0x2121d0, 0x0 }, ++ { 0x130d0, 0x0 }, ++ { 0x1130d0, 0x0 }, ++ { 0x2130d0, 0x0 }, ++ { 0x131d0, 0x0 }, ++ { 0x1131d0, 0x0 }, ++ { 0x2131d0, 0x0 }, ++ { 0x100d1, 0x0 }, ++ { 0x1100d1, 0x0 }, ++ { 0x2100d1, 0x0 }, ++ { 0x101d1, 0x0 }, ++ { 0x1101d1, 0x0 }, ++ { 0x2101d1, 0x0 }, ++ { 0x110d1, 0x0 }, ++ { 0x1110d1, 0x0 }, ++ { 0x2110d1, 0x0 }, ++ { 0x111d1, 0x0 }, ++ { 0x1111d1, 0x0 }, ++ { 0x2111d1, 0x0 }, ++ { 0x120d1, 0x0 }, ++ { 0x1120d1, 0x0 }, ++ { 0x2120d1, 0x0 }, ++ { 0x121d1, 0x0 }, ++ { 0x1121d1, 0x0 }, ++ { 0x2121d1, 0x0 }, ++ { 0x130d1, 0x0 }, ++ { 0x1130d1, 0x0 }, ++ { 0x2130d1, 0x0 }, ++ { 0x131d1, 0x0 }, ++ { 0x1131d1, 0x0 }, ++ { 0x2131d1, 0x0 }, ++ { 0x10068, 0x0 }, ++ { 0x10168, 0x0 }, ++ { 0x10268, 0x0 }, ++ { 0x10368, 0x0 }, ++ { 0x10468, 0x0 }, ++ { 0x10568, 0x0 }, ++ { 0x10668, 0x0 }, ++ { 0x10768, 0x0 }, ++ { 0x10868, 0x0 }, ++ { 0x11068, 0x0 }, ++ { 0x11168, 0x0 }, ++ { 0x11268, 0x0 }, ++ { 0x11368, 0x0 }, ++ { 0x11468, 0x0 }, ++ { 0x11568, 0x0 }, ++ { 0x11668, 0x0 }, ++ { 0x11768, 0x0 }, ++ { 0x11868, 0x0 }, ++ { 0x12068, 0x0 }, ++ { 0x12168, 0x0 }, ++ { 0x12268, 0x0 }, ++ { 0x12368, 0x0 }, ++ { 0x12468, 0x0 }, ++ { 0x12568, 0x0 }, ++ { 0x12668, 0x0 }, ++ { 0x12768, 0x0 }, ++ { 0x12868, 0x0 }, ++ { 0x13068, 0x0 }, ++ { 0x13168, 0x0 }, ++ { 0x13268, 0x0 }, ++ { 0x13368, 0x0 }, ++ { 0x13468, 0x0 }, ++ { 0x13568, 0x0 }, ++ { 0x13668, 0x0 }, ++ { 0x13768, 0x0 }, ++ { 0x13868, 0x0 }, ++ { 0x10069, 0x0 }, ++ { 0x10169, 0x0 }, ++ { 0x10269, 0x0 }, ++ { 0x10369, 0x0 }, ++ { 0x10469, 0x0 }, ++ { 0x10569, 0x0 }, ++ { 0x10669, 0x0 }, ++ { 0x10769, 0x0 }, ++ { 0x10869, 0x0 }, ++ { 0x11069, 0x0 }, ++ { 0x11169, 0x0 }, ++ { 0x11269, 0x0 }, ++ { 0x11369, 0x0 }, ++ { 0x11469, 0x0 }, ++ { 0x11569, 0x0 }, ++ { 0x11669, 0x0 }, ++ { 0x11769, 0x0 }, ++ { 0x11869, 0x0 }, ++ { 0x12069, 0x0 }, ++ { 0x12169, 0x0 }, ++ { 0x12269, 0x0 }, ++ { 0x12369, 0x0 }, ++ { 0x12469, 0x0 }, ++ { 0x12569, 0x0 }, ++ { 0x12669, 0x0 }, ++ { 0x12769, 0x0 }, ++ { 0x12869, 0x0 }, ++ { 0x13069, 0x0 }, ++ { 0x13169, 0x0 }, ++ { 0x13269, 0x0 }, ++ { 0x13369, 0x0 }, ++ { 0x13469, 0x0 }, ++ { 0x13569, 0x0 }, ++ { 0x13669, 0x0 }, ++ { 0x13769, 0x0 }, ++ { 0x13869, 0x0 }, ++ { 0x1008c, 0x0 }, ++ { 0x11008c, 0x0 }, ++ { 0x21008c, 0x0 }, ++ { 0x1018c, 0x0 }, ++ { 0x11018c, 0x0 }, ++ { 0x21018c, 0x0 }, ++ { 0x1108c, 0x0 }, ++ { 0x11108c, 0x0 }, ++ { 0x21108c, 0x0 }, ++ { 0x1118c, 0x0 }, ++ { 0x11118c, 0x0 }, ++ { 0x21118c, 0x0 }, ++ { 0x1208c, 0x0 }, ++ { 0x11208c, 0x0 }, ++ { 0x21208c, 0x0 }, ++ { 0x1218c, 0x0 }, ++ { 0x11218c, 0x0 }, ++ { 0x21218c, 0x0 }, ++ { 0x1308c, 0x0 }, ++ { 0x11308c, 0x0 }, ++ { 0x21308c, 0x0 }, ++ { 0x1318c, 0x0 }, ++ { 0x11318c, 0x0 }, ++ { 0x21318c, 0x0 }, ++ { 0x1008d, 0x0 }, ++ { 0x11008d, 0x0 }, ++ { 0x21008d, 0x0 }, ++ { 0x1018d, 0x0 }, ++ { 0x11018d, 0x0 }, ++ { 0x21018d, 0x0 }, ++ { 0x1108d, 0x0 }, ++ { 0x11108d, 0x0 }, ++ { 0x21108d, 0x0 }, ++ { 0x1118d, 0x0 }, ++ { 0x11118d, 0x0 }, ++ { 0x21118d, 0x0 }, ++ { 0x1208d, 0x0 }, ++ { 0x11208d, 0x0 }, ++ { 0x21208d, 0x0 }, ++ { 0x1218d, 0x0 }, ++ { 0x11218d, 0x0 }, ++ { 0x21218d, 0x0 }, ++ { 0x1308d, 0x0 }, ++ { 0x11308d, 0x0 }, ++ { 0x21308d, 0x0 }, ++ { 0x1318d, 0x0 }, ++ { 0x11318d, 0x0 }, ++ { 0x21318d, 0x0 }, ++ { 0x100c0, 0x0 }, ++ { 0x1100c0, 0x0 }, ++ { 0x2100c0, 0x0 }, ++ { 0x101c0, 0x0 }, ++ { 0x1101c0, 0x0 }, ++ { 0x2101c0, 0x0 }, ++ { 0x102c0, 0x0 }, ++ { 0x1102c0, 0x0 }, ++ { 0x2102c0, 0x0 }, ++ { 0x103c0, 0x0 }, ++ { 0x1103c0, 0x0 }, ++ { 0x2103c0, 0x0 }, ++ { 0x104c0, 0x0 }, ++ { 0x1104c0, 0x0 }, ++ { 0x2104c0, 0x0 }, ++ { 0x105c0, 0x0 }, ++ { 0x1105c0, 0x0 }, ++ { 0x2105c0, 0x0 }, ++ { 0x106c0, 0x0 }, ++ { 0x1106c0, 0x0 }, ++ { 0x2106c0, 0x0 }, ++ { 0x107c0, 0x0 }, ++ { 0x1107c0, 0x0 }, ++ { 0x2107c0, 0x0 }, ++ { 0x108c0, 0x0 }, ++ { 0x1108c0, 0x0 }, ++ { 0x2108c0, 0x0 }, ++ { 0x110c0, 0x0 }, ++ { 0x1110c0, 0x0 }, ++ { 0x2110c0, 0x0 }, ++ { 0x111c0, 0x0 }, ++ { 0x1111c0, 0x0 }, ++ { 0x2111c0, 0x0 }, ++ { 0x112c0, 0x0 }, ++ { 0x1112c0, 0x0 }, ++ { 0x2112c0, 0x0 }, ++ { 0x113c0, 0x0 }, ++ { 0x1113c0, 0x0 }, ++ { 0x2113c0, 0x0 }, ++ { 0x114c0, 0x0 }, ++ { 0x1114c0, 0x0 }, ++ { 0x2114c0, 0x0 }, ++ { 0x115c0, 0x0 }, ++ { 0x1115c0, 0x0 }, ++ { 0x2115c0, 0x0 }, ++ { 0x116c0, 0x0 }, ++ { 0x1116c0, 0x0 }, ++ { 0x2116c0, 0x0 }, ++ { 0x117c0, 0x0 }, ++ { 0x1117c0, 0x0 }, ++ { 0x2117c0, 0x0 }, ++ { 0x118c0, 0x0 }, ++ { 0x1118c0, 0x0 }, ++ { 0x2118c0, 0x0 }, ++ { 0x120c0, 0x0 }, ++ { 0x1120c0, 0x0 }, ++ { 0x2120c0, 0x0 }, ++ { 0x121c0, 0x0 }, ++ { 0x1121c0, 0x0 }, ++ { 0x2121c0, 0x0 }, ++ { 0x122c0, 0x0 }, ++ { 0x1122c0, 0x0 }, ++ { 0x2122c0, 0x0 }, ++ { 0x123c0, 0x0 }, ++ { 0x1123c0, 0x0 }, ++ { 0x2123c0, 0x0 }, ++ { 0x124c0, 0x0 }, ++ { 0x1124c0, 0x0 }, ++ { 0x2124c0, 0x0 }, ++ { 0x125c0, 0x0 }, ++ { 0x1125c0, 0x0 }, ++ { 0x2125c0, 0x0 }, ++ { 0x126c0, 0x0 }, ++ { 0x1126c0, 0x0 }, ++ { 0x2126c0, 0x0 }, ++ { 0x127c0, 0x0 }, ++ { 0x1127c0, 0x0 }, ++ { 0x2127c0, 0x0 }, ++ { 0x128c0, 0x0 }, ++ { 0x1128c0, 0x0 }, ++ { 0x2128c0, 0x0 }, ++ { 0x130c0, 0x0 }, ++ { 0x1130c0, 0x0 }, ++ { 0x2130c0, 0x0 }, ++ { 0x131c0, 0x0 }, ++ { 0x1131c0, 0x0 }, ++ { 0x2131c0, 0x0 }, ++ { 0x132c0, 0x0 }, ++ { 0x1132c0, 0x0 }, ++ { 0x2132c0, 0x0 }, ++ { 0x133c0, 0x0 }, ++ { 0x1133c0, 0x0 }, ++ { 0x2133c0, 0x0 }, ++ { 0x134c0, 0x0 }, ++ { 0x1134c0, 0x0 }, ++ { 0x2134c0, 0x0 }, ++ { 0x135c0, 0x0 }, ++ { 0x1135c0, 0x0 }, ++ { 0x2135c0, 0x0 }, ++ { 0x136c0, 0x0 }, ++ { 0x1136c0, 0x0 }, ++ { 0x2136c0, 0x0 }, ++ { 0x137c0, 0x0 }, ++ { 0x1137c0, 0x0 }, ++ { 0x2137c0, 0x0 }, ++ { 0x138c0, 0x0 }, ++ { 0x1138c0, 0x0 }, ++ { 0x2138c0, 0x0 }, ++ { 0x100c1, 0x0 }, ++ { 0x1100c1, 0x0 }, ++ { 0x2100c1, 0x0 }, ++ { 0x101c1, 0x0 }, ++ { 0x1101c1, 0x0 }, ++ { 0x2101c1, 0x0 }, ++ { 0x102c1, 0x0 }, ++ { 0x1102c1, 0x0 }, ++ { 0x2102c1, 0x0 }, ++ { 0x103c1, 0x0 }, ++ { 0x1103c1, 0x0 }, ++ { 0x2103c1, 0x0 }, ++ { 0x104c1, 0x0 }, ++ { 0x1104c1, 0x0 }, ++ { 0x2104c1, 0x0 }, ++ { 0x105c1, 0x0 }, ++ { 0x1105c1, 0x0 }, ++ { 0x2105c1, 0x0 }, ++ { 0x106c1, 0x0 }, ++ { 0x1106c1, 0x0 }, ++ { 0x2106c1, 0x0 }, ++ { 0x107c1, 0x0 }, ++ { 0x1107c1, 0x0 }, ++ { 0x2107c1, 0x0 }, ++ { 0x108c1, 0x0 }, ++ { 0x1108c1, 0x0 }, ++ { 0x2108c1, 0x0 }, ++ { 0x110c1, 0x0 }, ++ { 0x1110c1, 0x0 }, ++ { 0x2110c1, 0x0 }, ++ { 0x111c1, 0x0 }, ++ { 0x1111c1, 0x0 }, ++ { 0x2111c1, 0x0 }, ++ { 0x112c1, 0x0 }, ++ { 0x1112c1, 0x0 }, ++ { 0x2112c1, 0x0 }, ++ { 0x113c1, 0x0 }, ++ { 0x1113c1, 0x0 }, ++ { 0x2113c1, 0x0 }, ++ { 0x114c1, 0x0 }, ++ { 0x1114c1, 0x0 }, ++ { 0x2114c1, 0x0 }, ++ { 0x115c1, 0x0 }, ++ { 0x1115c1, 0x0 }, ++ { 0x2115c1, 0x0 }, ++ { 0x116c1, 0x0 }, ++ { 0x1116c1, 0x0 }, ++ { 0x2116c1, 0x0 }, ++ { 0x117c1, 0x0 }, ++ { 0x1117c1, 0x0 }, ++ { 0x2117c1, 0x0 }, ++ { 0x118c1, 0x0 }, ++ { 0x1118c1, 0x0 }, ++ { 0x2118c1, 0x0 }, ++ { 0x120c1, 0x0 }, ++ { 0x1120c1, 0x0 }, ++ { 0x2120c1, 0x0 }, ++ { 0x121c1, 0x0 }, ++ { 0x1121c1, 0x0 }, ++ { 0x2121c1, 0x0 }, ++ { 0x122c1, 0x0 }, ++ { 0x1122c1, 0x0 }, ++ { 0x2122c1, 0x0 }, ++ { 0x123c1, 0x0 }, ++ { 0x1123c1, 0x0 }, ++ { 0x2123c1, 0x0 }, ++ { 0x124c1, 0x0 }, ++ { 0x1124c1, 0x0 }, ++ { 0x2124c1, 0x0 }, ++ { 0x125c1, 0x0 }, ++ { 0x1125c1, 0x0 }, ++ { 0x2125c1, 0x0 }, ++ { 0x126c1, 0x0 }, ++ { 0x1126c1, 0x0 }, ++ { 0x2126c1, 0x0 }, ++ { 0x127c1, 0x0 }, ++ { 0x1127c1, 0x0 }, ++ { 0x2127c1, 0x0 }, ++ { 0x128c1, 0x0 }, ++ { 0x1128c1, 0x0 }, ++ { 0x2128c1, 0x0 }, ++ { 0x130c1, 0x0 }, ++ { 0x1130c1, 0x0 }, ++ { 0x2130c1, 0x0 }, ++ { 0x131c1, 0x0 }, ++ { 0x1131c1, 0x0 }, ++ { 0x2131c1, 0x0 }, ++ { 0x132c1, 0x0 }, ++ { 0x1132c1, 0x0 }, ++ { 0x2132c1, 0x0 }, ++ { 0x133c1, 0x0 }, ++ { 0x1133c1, 0x0 }, ++ { 0x2133c1, 0x0 }, ++ { 0x134c1, 0x0 }, ++ { 0x1134c1, 0x0 }, ++ { 0x2134c1, 0x0 }, ++ { 0x135c1, 0x0 }, ++ { 0x1135c1, 0x0 }, ++ { 0x2135c1, 0x0 }, ++ { 0x136c1, 0x0 }, ++ { 0x1136c1, 0x0 }, ++ { 0x2136c1, 0x0 }, ++ { 0x137c1, 0x0 }, ++ { 0x1137c1, 0x0 }, ++ { 0x2137c1, 0x0 }, ++ { 0x138c1, 0x0 }, ++ { 0x1138c1, 0x0 }, ++ { 0x2138c1, 0x0 }, ++ { 0x10020, 0x0 }, ++ { 0x110020, 0x0 }, ++ { 0x210020, 0x0 }, ++ { 0x11020, 0x0 }, ++ { 0x111020, 0x0 }, ++ { 0x211020, 0x0 }, ++ { 0x12020, 0x0 }, ++ { 0x112020, 0x0 }, ++ { 0x212020, 0x0 }, ++ { 0x13020, 0x0 }, ++ { 0x113020, 0x0 }, ++ { 0x213020, 0x0 }, ++ { 0x20072, 0x0 }, ++ { 0x20073, 0x0 }, ++ { 0x20074, 0x0 }, ++ { 0x100aa, 0x0 }, ++ { 0x110aa, 0x0 }, ++ { 0x120aa, 0x0 }, ++ { 0x130aa, 0x0 }, ++ { 0x20010, 0x0 }, ++ { 0x120010, 0x0 }, ++ { 0x220010, 0x0 }, ++ { 0x20011, 0x0 }, ++ { 0x120011, 0x0 }, ++ { 0x220011, 0x0 }, ++ { 0x100ae, 0x0 }, ++ { 0x1100ae, 0x0 }, ++ { 0x2100ae, 0x0 }, ++ { 0x100af, 0x0 }, ++ { 0x1100af, 0x0 }, ++ { 0x2100af, 0x0 }, ++ { 0x110ae, 0x0 }, ++ { 0x1110ae, 0x0 }, ++ { 0x2110ae, 0x0 }, ++ { 0x110af, 0x0 }, ++ { 0x1110af, 0x0 }, ++ { 0x2110af, 0x0 }, ++ { 0x120ae, 0x0 }, ++ { 0x1120ae, 0x0 }, ++ { 0x2120ae, 0x0 }, ++ { 0x120af, 0x0 }, ++ { 0x1120af, 0x0 }, ++ { 0x2120af, 0x0 }, ++ { 0x130ae, 0x0 }, ++ { 0x1130ae, 0x0 }, ++ { 0x2130ae, 0x0 }, ++ { 0x130af, 0x0 }, ++ { 0x1130af, 0x0 }, ++ { 0x2130af, 0x0 }, ++ { 0x20020, 0x0 }, ++ { 0x120020, 0x0 }, ++ { 0x220020, 0x0 }, ++ { 0x100a0, 0x0 }, ++ { 0x100a1, 0x0 }, ++ { 0x100a2, 0x0 }, ++ { 0x100a3, 0x0 }, ++ { 0x100a4, 0x0 }, ++ { 0x100a5, 0x0 }, ++ { 0x100a6, 0x0 }, ++ { 0x100a7, 0x0 }, ++ { 0x110a0, 0x0 }, ++ { 0x110a1, 0x0 }, ++ { 0x110a2, 0x0 }, ++ { 0x110a3, 0x0 }, ++ { 0x110a4, 0x0 }, ++ { 0x110a5, 0x0 }, ++ { 0x110a6, 0x0 }, ++ { 0x110a7, 0x0 }, ++ { 0x120a0, 0x0 }, ++ { 0x120a1, 0x0 }, ++ { 0x120a2, 0x0 }, ++ { 0x120a3, 0x0 }, ++ { 0x120a4, 0x0 }, ++ { 0x120a5, 0x0 }, ++ { 0x120a6, 0x0 }, ++ { 0x120a7, 0x0 }, ++ { 0x130a0, 0x0 }, ++ { 0x130a1, 0x0 }, ++ { 0x130a2, 0x0 }, ++ { 0x130a3, 0x0 }, ++ { 0x130a4, 0x0 }, ++ { 0x130a5, 0x0 }, ++ { 0x130a6, 0x0 }, ++ { 0x130a7, 0x0 }, ++ { 0x2007c, 0x0 }, ++ { 0x12007c, 0x0 }, ++ { 0x22007c, 0x0 }, ++ { 0x2007d, 0x0 }, ++ { 0x12007d, 0x0 }, ++ { 0x22007d, 0x0 }, ++ { 0x400fd, 0x0 }, ++ { 0x400c0, 0x0 }, ++ { 0x90201, 0x0 }, ++ { 0x190201, 0x0 }, ++ { 0x290201, 0x0 }, ++ { 0x90202, 0x0 }, ++ { 0x190202, 0x0 }, ++ { 0x290202, 0x0 }, ++ { 0x90203, 0x0 }, ++ { 0x190203, 0x0 }, ++ { 0x290203, 0x0 }, ++ { 0x90204, 0x0 }, ++ { 0x190204, 0x0 }, ++ { 0x290204, 0x0 }, ++ { 0x90205, 0x0 }, ++ { 0x190205, 0x0 }, ++ { 0x290205, 0x0 }, ++ { 0x90206, 0x0 }, ++ { 0x190206, 0x0 }, ++ { 0x290206, 0x0 }, ++ { 0x90207, 0x0 }, ++ { 0x190207, 0x0 }, ++ { 0x290207, 0x0 }, ++ { 0x90208, 0x0 }, ++ { 0x190208, 0x0 }, ++ { 0x290208, 0x0 }, ++ { 0x10062, 0x0 }, ++ { 0x10162, 0x0 }, ++ { 0x10262, 0x0 }, ++ { 0x10362, 0x0 }, ++ { 0x10462, 0x0 }, ++ { 0x10562, 0x0 }, ++ { 0x10662, 0x0 }, ++ { 0x10762, 0x0 }, ++ { 0x10862, 0x0 }, ++ { 0x11062, 0x0 }, ++ { 0x11162, 0x0 }, ++ { 0x11262, 0x0 }, ++ { 0x11362, 0x0 }, ++ { 0x11462, 0x0 }, ++ { 0x11562, 0x0 }, ++ { 0x11662, 0x0 }, ++ { 0x11762, 0x0 }, ++ { 0x11862, 0x0 }, ++ { 0x12062, 0x0 }, ++ { 0x12162, 0x0 }, ++ { 0x12262, 0x0 }, ++ { 0x12362, 0x0 }, ++ { 0x12462, 0x0 }, ++ { 0x12562, 0x0 }, ++ { 0x12662, 0x0 }, ++ { 0x12762, 0x0 }, ++ { 0x12862, 0x0 }, ++ { 0x13062, 0x0 }, ++ { 0x13162, 0x0 }, ++ { 0x13262, 0x0 }, ++ { 0x13362, 0x0 }, ++ { 0x13462, 0x0 }, ++ { 0x13562, 0x0 }, ++ { 0x13662, 0x0 }, ++ { 0x13762, 0x0 }, ++ { 0x13862, 0x0 }, ++ { 0x20077, 0x0 }, ++ { 0x10001, 0x0 }, ++ { 0x11001, 0x0 }, ++ { 0x12001, 0x0 }, ++ { 0x13001, 0x0 }, ++ { 0x10040, 0x0 }, ++ { 0x10140, 0x0 }, ++ { 0x10240, 0x0 }, ++ { 0x10340, 0x0 }, ++ { 0x10440, 0x0 }, ++ { 0x10540, 0x0 }, ++ { 0x10640, 0x0 }, ++ { 0x10740, 0x0 }, ++ { 0x10840, 0x0 }, ++ { 0x10030, 0x0 }, ++ { 0x10130, 0x0 }, ++ { 0x10230, 0x0 }, ++ { 0x10330, 0x0 }, ++ { 0x10430, 0x0 }, ++ { 0x10530, 0x0 }, ++ { 0x10630, 0x0 }, ++ { 0x10730, 0x0 }, ++ { 0x10830, 0x0 }, ++ { 0x11040, 0x0 }, ++ { 0x11140, 0x0 }, ++ { 0x11240, 0x0 }, ++ { 0x11340, 0x0 }, ++ { 0x11440, 0x0 }, ++ { 0x11540, 0x0 }, ++ { 0x11640, 0x0 }, ++ { 0x11740, 0x0 }, ++ { 0x11840, 0x0 }, ++ { 0x11030, 0x0 }, ++ { 0x11130, 0x0 }, ++ { 0x11230, 0x0 }, ++ { 0x11330, 0x0 }, ++ { 0x11430, 0x0 }, ++ { 0x11530, 0x0 }, ++ { 0x11630, 0x0 }, ++ { 0x11730, 0x0 }, ++ { 0x11830, 0x0 }, ++ { 0x12040, 0x0 }, ++ { 0x12140, 0x0 }, ++ { 0x12240, 0x0 }, ++ { 0x12340, 0x0 }, ++ { 0x12440, 0x0 }, ++ { 0x12540, 0x0 }, ++ { 0x12640, 0x0 }, ++ { 0x12740, 0x0 }, ++ { 0x12840, 0x0 }, ++ { 0x12030, 0x0 }, ++ { 0x12130, 0x0 }, ++ { 0x12230, 0x0 }, ++ { 0x12330, 0x0 }, ++ { 0x12430, 0x0 }, ++ { 0x12530, 0x0 }, ++ { 0x12630, 0x0 }, ++ { 0x12730, 0x0 }, ++ { 0x12830, 0x0 }, ++ { 0x13040, 0x0 }, ++ { 0x13140, 0x0 }, ++ { 0x13240, 0x0 }, ++ { 0x13340, 0x0 }, ++ { 0x13440, 0x0 }, ++ { 0x13540, 0x0 }, ++ { 0x13640, 0x0 }, ++ { 0x13740, 0x0 }, ++ { 0x13840, 0x0 }, ++ { 0x13030, 0x0 }, ++ { 0x13130, 0x0 }, ++ { 0x13230, 0x0 }, ++ { 0x13330, 0x0 }, ++ { 0x13430, 0x0 }, ++ { 0x13530, 0x0 }, ++ { 0x13630, 0x0 }, ++ { 0x13730, 0x0 }, ++ { 0x13830, 0x0 }, ++}; ++/* P0 message block paremeter for training firmware */ ++struct dram_cfg_param ddr_fsp0_cfg[] = { ++ { 0xd0000, 0x0 }, ++ { 0x54003, 0xc80 }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2228 }, ++ { 0x54006, 0x14 }, ++ { 0x54008, 0x131f }, ++ { 0x54009, 0xc8 }, ++ { 0x5400b, 0x2 }, ++ { 0x5400f, 0x100 }, ++ { 0x54012, 0x310 }, ++ { 0x54019, 0x2dd4 }, ++ { 0x5401a, 0x33 }, ++ { 0x5401b, 0x4866 }, ++ { 0x5401c, 0x4800 }, ++ { 0x5401e, 0x16 }, ++ { 0x5401f, 0x2dd4 }, ++ { 0x54020, 0x33 }, ++ { 0x54021, 0x4866 }, ++ { 0x54022, 0x4800 }, ++ { 0x54024, 0x16 }, ++ { 0x5402b, 0x1000 }, ++ { 0x5402c, 0x3 }, ++ { 0x54032, 0xd400 }, ++ { 0x54033, 0x332d }, ++ { 0x54034, 0x6600 }, ++ { 0x54035, 0x48 }, ++ { 0x54036, 0x48 }, ++ { 0x54037, 0x1600 }, ++ { 0x54038, 0xd400 }, ++ { 0x54039, 0x332d }, ++ { 0x5403a, 0x6600 }, ++ { 0x5403b, 0x48 }, ++ { 0x5403c, 0x48 }, ++ { 0x5403d, 0x1600 }, ++ { 0xd0000, 0x1 }, ++}; ++ ++ ++/* P1 message block paremeter for training firmware */ ++struct dram_cfg_param ddr_fsp1_cfg[] = { ++ { 0xd0000, 0x0 }, ++ { 0x54002, 0x101 }, ++ { 0x54003, 0x190 }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2228 }, ++ { 0x54006, 0x14 }, ++ { 0x54008, 0x121f }, ++ { 0x54009, 0xc8 }, ++ { 0x5400b, 0x2 }, ++ { 0x5400f, 0x100 }, ++ { 0x54012, 0x310 }, ++ { 0x54019, 0x84 }, ++ { 0x5401a, 0x33 }, ++ { 0x5401b, 0x4866 }, ++ { 0x5401c, 0x4800 }, ++ { 0x5401e, 0x16 }, ++ { 0x5401f, 0x84 }, ++ { 0x54020, 0x33 }, ++ { 0x54021, 0x4866 }, ++ { 0x54022, 0x4800 }, ++ { 0x54024, 0x16 }, ++ { 0x5402b, 0x1000 }, ++ { 0x5402c, 0x3 }, ++ { 0x54032, 0x8400 }, ++ { 0x54033, 0x3300 }, ++ { 0x54034, 0x6600 }, ++ { 0x54035, 0x48 }, ++ { 0x54036, 0x48 }, ++ { 0x54037, 0x1600 }, ++ { 0x54038, 0x8400 }, ++ { 0x54039, 0x3300 }, ++ { 0x5403a, 0x6600 }, ++ { 0x5403b, 0x48 }, ++ { 0x5403c, 0x48 }, ++ { 0x5403d, 0x1600 }, ++ { 0xd0000, 0x1 }, ++}; ++ ++ ++/* P2 message block paremeter for training firmware */ ++struct dram_cfg_param ddr_fsp2_cfg[] = { ++ { 0xd0000, 0x0 }, ++ { 0x54002, 0x102 }, ++ { 0x54003, 0x64 }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2228 }, ++ { 0x54006, 0x14 }, ++ { 0x54008, 0x121f }, ++ { 0x54009, 0xc8 }, ++ { 0x5400b, 0x2 }, ++ { 0x5400f, 0x100 }, ++ { 0x54012, 0x310 }, ++ { 0x54019, 0x84 }, ++ { 0x5401a, 0x33 }, ++ { 0x5401b, 0x4866 }, ++ { 0x5401c, 0x4800 }, ++ { 0x5401e, 0x16 }, ++ { 0x5401f, 0x84 }, ++ { 0x54020, 0x33 }, ++ { 0x54021, 0x4866 }, ++ { 0x54022, 0x4800 }, ++ { 0x54024, 0x16 }, ++ { 0x5402b, 0x1000 }, ++ { 0x5402c, 0x3 }, ++ { 0x54032, 0x8400 }, ++ { 0x54033, 0x3300 }, ++ { 0x54034, 0x6600 }, ++ { 0x54035, 0x48 }, ++ { 0x54036, 0x48 }, ++ { 0x54037, 0x1600 }, ++ { 0x54038, 0x8400 }, ++ { 0x54039, 0x3300 }, ++ { 0x5403a, 0x6600 }, ++ { 0x5403b, 0x48 }, ++ { 0x5403c, 0x48 }, ++ { 0x5403d, 0x1600 }, ++ { 0xd0000, 0x1 }, ++}; ++ ++ ++/* P0 2D message block paremeter for training firmware */ ++struct dram_cfg_param ddr_fsp0_2d_cfg[] = { ++ { 0xd0000, 0x0 }, ++ { 0x54003, 0xc80 }, ++ { 0x54004, 0x2 }, ++ { 0x54005, 0x2228 }, ++ { 0x54006, 0x14 }, ++ { 0x54008, 0x61 }, ++ { 0x54009, 0xc8 }, ++ { 0x5400b, 0x2 }, ++ { 0x5400d, 0x100 }, ++ { 0x5400f, 0x100 }, ++ { 0x54010, 0x1f7f }, ++ { 0x54012, 0x310 }, ++ { 0x54019, 0x2dd4 }, ++ { 0x5401a, 0x33 }, ++ { 0x5401b, 0x4866 }, ++ { 0x5401c, 0x4800 }, ++ { 0x5401e, 0x16 }, ++ { 0x5401f, 0x2dd4 }, ++ { 0x54020, 0x33 }, ++ { 0x54021, 0x4866 }, ++ { 0x54022, 0x4800 }, ++ { 0x54024, 0x16 }, ++ { 0x5402b, 0x1000 }, ++ { 0x5402c, 0x3 }, ++ { 0x54032, 0xd400 }, ++ { 0x54033, 0x332d }, ++ { 0x54034, 0x6600 }, ++ { 0x54035, 0x48 }, ++ { 0x54036, 0x48 }, ++ { 0x54037, 0x1600 }, ++ { 0x54038, 0xd400 }, ++ { 0x54039, 0x332d }, ++ { 0x5403a, 0x6600 }, ++ { 0x5403b, 0x48 }, ++ { 0x5403c, 0x48 }, ++ { 0x5403d, 0x1600 }, ++ { 0xd0000, 0x1 }, ++}; ++ ++/* DRAM PHY init engine image */ ++struct dram_cfg_param ddr_phy_pie[] = { ++ { 0xd0000, 0x0 }, ++ { 0x90000, 0x10 }, ++ { 0x90001, 0x400 }, ++ { 0x90002, 0x10e }, ++ { 0x90003, 0x0 }, ++ { 0x90004, 0x0 }, ++ { 0x90005, 0x8 }, ++ { 0x90029, 0xb }, ++ { 0x9002a, 0x480 }, ++ { 0x9002b, 0x109 }, ++ { 0x9002c, 0x8 }, ++ { 0x9002d, 0x448 }, ++ { 0x9002e, 0x139 }, ++ { 0x9002f, 0x8 }, ++ { 0x90030, 0x478 }, ++ { 0x90031, 0x109 }, ++ { 0x90032, 0x0 }, ++ { 0x90033, 0xe8 }, ++ { 0x90034, 0x109 }, ++ { 0x90035, 0x2 }, ++ { 0x90036, 0x10 }, ++ { 0x90037, 0x139 }, ++ { 0x90038, 0xb }, ++ { 0x90039, 0x7c0 }, ++ { 0x9003a, 0x139 }, ++ { 0x9003b, 0x44 }, ++ { 0x9003c, 0x633 }, ++ { 0x9003d, 0x159 }, ++ { 0x9003e, 0x14f }, ++ { 0x9003f, 0x630 }, ++ { 0x90040, 0x159 }, ++ { 0x90041, 0x47 }, ++ { 0x90042, 0x633 }, ++ { 0x90043, 0x149 }, ++ { 0x90044, 0x4f }, ++ { 0x90045, 0x633 }, ++ { 0x90046, 0x179 }, ++ { 0x90047, 0x8 }, ++ { 0x90048, 0xe0 }, ++ { 0x90049, 0x109 }, ++ { 0x9004a, 0x0 }, ++ { 0x9004b, 0x7c8 }, ++ { 0x9004c, 0x109 }, ++ { 0x9004d, 0x0 }, ++ { 0x9004e, 0x1 }, ++ { 0x9004f, 0x8 }, ++ { 0x90050, 0x0 }, ++ { 0x90051, 0x45a }, ++ { 0x90052, 0x9 }, ++ { 0x90053, 0x0 }, ++ { 0x90054, 0x448 }, ++ { 0x90055, 0x109 }, ++ { 0x90056, 0x40 }, ++ { 0x90057, 0x633 }, ++ { 0x90058, 0x179 }, ++ { 0x90059, 0x1 }, ++ { 0x9005a, 0x618 }, ++ { 0x9005b, 0x109 }, ++ { 0x9005c, 0x40c0 }, ++ { 0x9005d, 0x633 }, ++ { 0x9005e, 0x149 }, ++ { 0x9005f, 0x8 }, ++ { 0x90060, 0x4 }, ++ { 0x90061, 0x48 }, ++ { 0x90062, 0x4040 }, ++ { 0x90063, 0x633 }, ++ { 0x90064, 0x149 }, ++ { 0x90065, 0x0 }, ++ { 0x90066, 0x4 }, ++ { 0x90067, 0x48 }, ++ { 0x90068, 0x40 }, ++ { 0x90069, 0x633 }, ++ { 0x9006a, 0x149 }, ++ { 0x9006b, 0x10 }, ++ { 0x9006c, 0x4 }, ++ { 0x9006d, 0x18 }, ++ { 0x9006e, 0x0 }, ++ { 0x9006f, 0x4 }, ++ { 0x90070, 0x78 }, ++ { 0x90071, 0x549 }, ++ { 0x90072, 0x633 }, ++ { 0x90073, 0x159 }, ++ { 0x90074, 0xd49 }, ++ { 0x90075, 0x633 }, ++ { 0x90076, 0x159 }, ++ { 0x90077, 0x94a }, ++ { 0x90078, 0x633 }, ++ { 0x90079, 0x159 }, ++ { 0x9007a, 0x441 }, ++ { 0x9007b, 0x633 }, ++ { 0x9007c, 0x149 }, ++ { 0x9007d, 0x42 }, ++ { 0x9007e, 0x633 }, ++ { 0x9007f, 0x149 }, ++ { 0x90080, 0x1 }, ++ { 0x90081, 0x633 }, ++ { 0x90082, 0x149 }, ++ { 0x90083, 0x0 }, ++ { 0x90084, 0xe0 }, ++ { 0x90085, 0x109 }, ++ { 0x90086, 0xa }, ++ { 0x90087, 0x10 }, ++ { 0x90088, 0x109 }, ++ { 0x90089, 0x9 }, ++ { 0x9008a, 0x3c0 }, ++ { 0x9008b, 0x149 }, ++ { 0x9008c, 0x9 }, ++ { 0x9008d, 0x3c0 }, ++ { 0x9008e, 0x159 }, ++ { 0x9008f, 0x18 }, ++ { 0x90090, 0x10 }, ++ { 0x90091, 0x109 }, ++ { 0x90092, 0x0 }, ++ { 0x90093, 0x3c0 }, ++ { 0x90094, 0x109 }, ++ { 0x90095, 0x18 }, ++ { 0x90096, 0x4 }, ++ { 0x90097, 0x48 }, ++ { 0x90098, 0x18 }, ++ { 0x90099, 0x4 }, ++ { 0x9009a, 0x58 }, ++ { 0x9009b, 0xb }, ++ { 0x9009c, 0x10 }, ++ { 0x9009d, 0x109 }, ++ { 0x9009e, 0x1 }, ++ { 0x9009f, 0x10 }, ++ { 0x900a0, 0x109 }, ++ { 0x900a1, 0x5 }, ++ { 0x900a2, 0x7c0 }, ++ { 0x900a3, 0x109 }, ++ { 0x40000, 0x811 }, ++ { 0x40020, 0x880 }, ++ { 0x40040, 0x0 }, ++ { 0x40060, 0x0 }, ++ { 0x40001, 0x4008 }, ++ { 0x40021, 0x83 }, ++ { 0x40041, 0x4f }, ++ { 0x40061, 0x0 }, ++ { 0x40002, 0x4040 }, ++ { 0x40022, 0x83 }, ++ { 0x40042, 0x51 }, ++ { 0x40062, 0x0 }, ++ { 0x40003, 0x811 }, ++ { 0x40023, 0x880 }, ++ { 0x40043, 0x0 }, ++ { 0x40063, 0x0 }, ++ { 0x40004, 0x720 }, ++ { 0x40024, 0xf }, ++ { 0x40044, 0x1740 }, ++ { 0x40064, 0x0 }, ++ { 0x40005, 0x16 }, ++ { 0x40025, 0x83 }, ++ { 0x40045, 0x4b }, ++ { 0x40065, 0x0 }, ++ { 0x40006, 0x716 }, ++ { 0x40026, 0xf }, ++ { 0x40046, 0x2001 }, ++ { 0x40066, 0x0 }, ++ { 0x40007, 0x716 }, ++ { 0x40027, 0xf }, ++ { 0x40047, 0x2800 }, ++ { 0x40067, 0x0 }, ++ { 0x40008, 0x716 }, ++ { 0x40028, 0xf }, ++ { 0x40048, 0xf00 }, ++ { 0x40068, 0x0 }, ++ { 0x40009, 0x720 }, ++ { 0x40029, 0xf }, ++ { 0x40049, 0x1400 }, ++ { 0x40069, 0x0 }, ++ { 0x4000a, 0xe08 }, ++ { 0x4002a, 0xc15 }, ++ { 0x4004a, 0x0 }, ++ { 0x4006a, 0x0 }, ++ { 0x4000b, 0x625 }, ++ { 0x4002b, 0x15 }, ++ { 0x4004b, 0x0 }, ++ { 0x4006b, 0x0 }, ++ { 0x4000c, 0x4028 }, ++ { 0x4002c, 0x80 }, ++ { 0x4004c, 0x0 }, ++ { 0x4006c, 0x0 }, ++ { 0x4000d, 0xe08 }, ++ { 0x4002d, 0xc1a }, ++ { 0x4004d, 0x0 }, ++ { 0x4006d, 0x0 }, ++ { 0x4000e, 0x625 }, ++ { 0x4002e, 0x1a }, ++ { 0x4004e, 0x0 }, ++ { 0x4006e, 0x0 }, ++ { 0x4000f, 0x4040 }, ++ { 0x4002f, 0x80 }, ++ { 0x4004f, 0x0 }, ++ { 0x4006f, 0x0 }, ++ { 0x40010, 0x2604 }, ++ { 0x40030, 0x15 }, ++ { 0x40050, 0x0 }, ++ { 0x40070, 0x0 }, ++ { 0x40011, 0x708 }, ++ { 0x40031, 0x5 }, ++ { 0x40051, 0x0 }, ++ { 0x40071, 0x2002 }, ++ { 0x40012, 0x8 }, ++ { 0x40032, 0x80 }, ++ { 0x40052, 0x0 }, ++ { 0x40072, 0x0 }, ++ { 0x40013, 0x2604 }, ++ { 0x40033, 0x1a }, ++ { 0x40053, 0x0 }, ++ { 0x40073, 0x0 }, ++ { 0x40014, 0x708 }, ++ { 0x40034, 0xa }, ++ { 0x40054, 0x0 }, ++ { 0x40074, 0x2002 }, ++ { 0x40015, 0x4040 }, ++ { 0x40035, 0x80 }, ++ { 0x40055, 0x0 }, ++ { 0x40075, 0x0 }, ++ { 0x40016, 0x60a }, ++ { 0x40036, 0x15 }, ++ { 0x40056, 0x1200 }, ++ { 0x40076, 0x0 }, ++ { 0x40017, 0x61a }, ++ { 0x40037, 0x15 }, ++ { 0x40057, 0x1300 }, ++ { 0x40077, 0x0 }, ++ { 0x40018, 0x60a }, ++ { 0x40038, 0x1a }, ++ { 0x40058, 0x1200 }, ++ { 0x40078, 0x0 }, ++ { 0x40019, 0x642 }, ++ { 0x40039, 0x1a }, ++ { 0x40059, 0x1300 }, ++ { 0x40079, 0x0 }, ++ { 0x4001a, 0x4808 }, ++ { 0x4003a, 0x880 }, ++ { 0x4005a, 0x0 }, ++ { 0x4007a, 0x0 }, ++ { 0x900a4, 0x0 }, ++ { 0x900a5, 0x790 }, ++ { 0x900a6, 0x11a }, ++ { 0x900a7, 0x8 }, ++ { 0x900a8, 0x7aa }, ++ { 0x900a9, 0x2a }, ++ { 0x900aa, 0x10 }, ++ { 0x900ab, 0x7b2 }, ++ { 0x900ac, 0x2a }, ++ { 0x900ad, 0x0 }, ++ { 0x900ae, 0x7c8 }, ++ { 0x900af, 0x109 }, ++ { 0x900b0, 0x10 }, ++ { 0x900b1, 0x10 }, ++ { 0x900b2, 0x109 }, ++ { 0x900b3, 0x10 }, ++ { 0x900b4, 0x2a8 }, ++ { 0x900b5, 0x129 }, ++ { 0x900b6, 0x8 }, ++ { 0x900b7, 0x370 }, ++ { 0x900b8, 0x129 }, ++ { 0x900b9, 0xa }, ++ { 0x900ba, 0x3c8 }, ++ { 0x900bb, 0x1a9 }, ++ { 0x900bc, 0xc }, ++ { 0x900bd, 0x408 }, ++ { 0x900be, 0x199 }, ++ { 0x900bf, 0x14 }, ++ { 0x900c0, 0x790 }, ++ { 0x900c1, 0x11a }, ++ { 0x900c2, 0x8 }, ++ { 0x900c3, 0x4 }, ++ { 0x900c4, 0x18 }, ++ { 0x900c5, 0xe }, ++ { 0x900c6, 0x408 }, ++ { 0x900c7, 0x199 }, ++ { 0x900c8, 0x8 }, ++ { 0x900c9, 0x8568 }, ++ { 0x900ca, 0x108 }, ++ { 0x900cb, 0x18 }, ++ { 0x900cc, 0x790 }, ++ { 0x900cd, 0x16a }, ++ { 0x900ce, 0x8 }, ++ { 0x900cf, 0x1d8 }, ++ { 0x900d0, 0x169 }, ++ { 0x900d1, 0x10 }, ++ { 0x900d2, 0x8558 }, ++ { 0x900d3, 0x168 }, ++ { 0x900d4, 0x70 }, ++ { 0x900d5, 0x788 }, ++ { 0x900d6, 0x16a }, ++ { 0x900d7, 0x1ff8 }, ++ { 0x900d8, 0x85a8 }, ++ { 0x900d9, 0x1e8 }, ++ { 0x900da, 0x50 }, ++ { 0x900db, 0x798 }, ++ { 0x900dc, 0x16a }, ++ { 0x900dd, 0x60 }, ++ { 0x900de, 0x7a0 }, ++ { 0x900df, 0x16a }, ++ { 0x900e0, 0x8 }, ++ { 0x900e1, 0x8310 }, ++ { 0x900e2, 0x168 }, ++ { 0x900e3, 0x8 }, ++ { 0x900e4, 0xa310 }, ++ { 0x900e5, 0x168 }, ++ { 0x900e6, 0xa }, ++ { 0x900e7, 0x408 }, ++ { 0x900e8, 0x169 }, ++ { 0x900e9, 0x6e }, ++ { 0x900ea, 0x0 }, ++ { 0x900eb, 0x68 }, ++ { 0x900ec, 0x0 }, ++ { 0x900ed, 0x408 }, ++ { 0x900ee, 0x169 }, ++ { 0x900ef, 0x0 }, ++ { 0x900f0, 0x8310 }, ++ { 0x900f1, 0x168 }, ++ { 0x900f2, 0x0 }, ++ { 0x900f3, 0xa310 }, ++ { 0x900f4, 0x168 }, ++ { 0x900f5, 0x1ff8 }, ++ { 0x900f6, 0x85a8 }, ++ { 0x900f7, 0x1e8 }, ++ { 0x900f8, 0x68 }, ++ { 0x900f9, 0x798 }, ++ { 0x900fa, 0x16a }, ++ { 0x900fb, 0x78 }, ++ { 0x900fc, 0x7a0 }, ++ { 0x900fd, 0x16a }, ++ { 0x900fe, 0x68 }, ++ { 0x900ff, 0x790 }, ++ { 0x90100, 0x16a }, ++ { 0x90101, 0x8 }, ++ { 0x90102, 0x8b10 }, ++ { 0x90103, 0x168 }, ++ { 0x90104, 0x8 }, ++ { 0x90105, 0xab10 }, ++ { 0x90106, 0x168 }, ++ { 0x90107, 0xa }, ++ { 0x90108, 0x408 }, ++ { 0x90109, 0x169 }, ++ { 0x9010a, 0x58 }, ++ { 0x9010b, 0x0 }, ++ { 0x9010c, 0x68 }, ++ { 0x9010d, 0x0 }, ++ { 0x9010e, 0x408 }, ++ { 0x9010f, 0x169 }, ++ { 0x90110, 0x0 }, ++ { 0x90111, 0x8b10 }, ++ { 0x90112, 0x168 }, ++ { 0x90113, 0x1 }, ++ { 0x90114, 0xab10 }, ++ { 0x90115, 0x168 }, ++ { 0x90116, 0x0 }, ++ { 0x90117, 0x1d8 }, ++ { 0x90118, 0x169 }, ++ { 0x90119, 0x80 }, ++ { 0x9011a, 0x790 }, ++ { 0x9011b, 0x16a }, ++ { 0x9011c, 0x18 }, ++ { 0x9011d, 0x7aa }, ++ { 0x9011e, 0x6a }, ++ { 0x9011f, 0xa }, ++ { 0x90120, 0x0 }, ++ { 0x90121, 0x1e9 }, ++ { 0x90122, 0x8 }, ++ { 0x90123, 0x8080 }, ++ { 0x90124, 0x108 }, ++ { 0x90125, 0xf }, ++ { 0x90126, 0x408 }, ++ { 0x90127, 0x169 }, ++ { 0x90128, 0xc }, ++ { 0x90129, 0x0 }, ++ { 0x9012a, 0x68 }, ++ { 0x9012b, 0x9 }, ++ { 0x9012c, 0x0 }, ++ { 0x9012d, 0x1a9 }, ++ { 0x9012e, 0x0 }, ++ { 0x9012f, 0x408 }, ++ { 0x90130, 0x169 }, ++ { 0x90131, 0x0 }, ++ { 0x90132, 0x8080 }, ++ { 0x90133, 0x108 }, ++ { 0x90134, 0x8 }, ++ { 0x90135, 0x7aa }, ++ { 0x90136, 0x6a }, ++ { 0x90137, 0x0 }, ++ { 0x90138, 0x8568 }, ++ { 0x90139, 0x108 }, ++ { 0x9013a, 0xb7 }, ++ { 0x9013b, 0x790 }, ++ { 0x9013c, 0x16a }, ++ { 0x9013d, 0x1f }, ++ { 0x9013e, 0x0 }, ++ { 0x9013f, 0x68 }, ++ { 0x90140, 0x8 }, ++ { 0x90141, 0x8558 }, ++ { 0x90142, 0x168 }, ++ { 0x90143, 0xf }, ++ { 0x90144, 0x408 }, ++ { 0x90145, 0x169 }, ++ { 0x90146, 0xd }, ++ { 0x90147, 0x0 }, ++ { 0x90148, 0x68 }, ++ { 0x90149, 0x0 }, ++ { 0x9014a, 0x408 }, ++ { 0x9014b, 0x169 }, ++ { 0x9014c, 0x0 }, ++ { 0x9014d, 0x8558 }, ++ { 0x9014e, 0x168 }, ++ { 0x9014f, 0x8 }, ++ { 0x90150, 0x3c8 }, ++ { 0x90151, 0x1a9 }, ++ { 0x90152, 0x3 }, ++ { 0x90153, 0x370 }, ++ { 0x90154, 0x129 }, ++ { 0x90155, 0x20 }, ++ { 0x90156, 0x2aa }, ++ { 0x90157, 0x9 }, ++ { 0x90158, 0x8 }, ++ { 0x90159, 0xe8 }, ++ { 0x9015a, 0x109 }, ++ { 0x9015b, 0x0 }, ++ { 0x9015c, 0x8140 }, ++ { 0x9015d, 0x10c }, ++ { 0x9015e, 0x10 }, ++ { 0x9015f, 0x8138 }, ++ { 0x90160, 0x104 }, ++ { 0x90161, 0x8 }, ++ { 0x90162, 0x448 }, ++ { 0x90163, 0x109 }, ++ { 0x90164, 0xf }, ++ { 0x90165, 0x7c0 }, ++ { 0x90166, 0x109 }, ++ { 0x90167, 0x0 }, ++ { 0x90168, 0xe8 }, ++ { 0x90169, 0x109 }, ++ { 0x9016a, 0x47 }, ++ { 0x9016b, 0x630 }, ++ { 0x9016c, 0x109 }, ++ { 0x9016d, 0x8 }, ++ { 0x9016e, 0x618 }, ++ { 0x9016f, 0x109 }, ++ { 0x90170, 0x8 }, ++ { 0x90171, 0xe0 }, ++ { 0x90172, 0x109 }, ++ { 0x90173, 0x0 }, ++ { 0x90174, 0x7c8 }, ++ { 0x90175, 0x109 }, ++ { 0x90176, 0x8 }, ++ { 0x90177, 0x8140 }, ++ { 0x90178, 0x10c }, ++ { 0x90179, 0x0 }, ++ { 0x9017a, 0x478 }, ++ { 0x9017b, 0x109 }, ++ { 0x9017c, 0x0 }, ++ { 0x9017d, 0x1 }, ++ { 0x9017e, 0x8 }, ++ { 0x9017f, 0x8 }, ++ { 0x90180, 0x4 }, ++ { 0x90181, 0x0 }, ++ { 0x90006, 0x8 }, ++ { 0x90007, 0x7c8 }, ++ { 0x90008, 0x109 }, ++ { 0x90009, 0x0 }, ++ { 0x9000a, 0x400 }, ++ { 0x9000b, 0x106 }, ++ { 0xd00e7, 0x400 }, ++ { 0x90017, 0x0 }, ++ { 0x9001f, 0x29 }, ++ { 0x90026, 0x68 }, ++ { 0x400d0, 0x0 }, ++ { 0x400d1, 0x101 }, ++ { 0x400d2, 0x105 }, ++ { 0x400d3, 0x107 }, ++ { 0x400d4, 0x10f }, ++ { 0x400d5, 0x202 }, ++ { 0x400d6, 0x20a }, ++ { 0x400d7, 0x20b }, ++ { 0x2003a, 0x2 }, ++ { 0x200be, 0x3 }, ++ { 0x2000b, 0x64 }, ++ { 0x2000c, 0xc8 }, ++ { 0x2000d, 0x7d0 }, ++ { 0x2000e, 0x2c }, ++ { 0x12000b, 0xc }, ++ { 0x12000c, 0x19 }, ++ { 0x12000d, 0xfa }, ++ { 0x12000e, 0x10 }, ++ { 0x22000b, 0x3 }, ++ { 0x22000c, 0x6 }, ++ { 0x22000d, 0x3e }, ++ { 0x22000e, 0x10 }, ++ { 0x9000c, 0x0 }, ++ { 0x9000d, 0x173 }, ++ { 0x9000e, 0x60 }, ++ { 0x9000f, 0x6110 }, ++ { 0x90010, 0x2152 }, ++ { 0x90011, 0xdfbd }, ++ { 0x90012, 0x2060 }, ++ { 0x90013, 0x6152 }, ++ { 0x20010, 0x5a }, ++ { 0x20011, 0x3 }, ++ { 0x40080, 0xe0 }, ++ { 0x40081, 0x12 }, ++ { 0x40082, 0xe0 }, ++ { 0x40083, 0x12 }, ++ { 0x40084, 0xe0 }, ++ { 0x40085, 0x12 }, ++ { 0x140080, 0xe0 }, ++ { 0x140081, 0x12 }, ++ { 0x140082, 0xe0 }, ++ { 0x140083, 0x12 }, ++ { 0x140084, 0xe0 }, ++ { 0x140085, 0x12 }, ++ { 0x240080, 0xe0 }, ++ { 0x240081, 0x12 }, ++ { 0x240082, 0xe0 }, ++ { 0x240083, 0x12 }, ++ { 0x240084, 0xe0 }, ++ { 0x240085, 0x12 }, ++ { 0x400fd, 0xf }, ++ { 0x10011, 0x1 }, ++ { 0x10012, 0x1 }, ++ { 0x10013, 0x180 }, ++ { 0x10018, 0x1 }, ++ { 0x10002, 0x6209 }, ++ { 0x100b2, 0x1 }, ++ { 0x101b4, 0x1 }, ++ { 0x102b4, 0x1 }, ++ { 0x103b4, 0x1 }, ++ { 0x104b4, 0x1 }, ++ { 0x105b4, 0x1 }, ++ { 0x106b4, 0x1 }, ++ { 0x107b4, 0x1 }, ++ { 0x108b4, 0x1 }, ++ { 0x11011, 0x1 }, ++ { 0x11012, 0x1 }, ++ { 0x11013, 0x180 }, ++ { 0x11018, 0x1 }, ++ { 0x11002, 0x6209 }, ++ { 0x110b2, 0x1 }, ++ { 0x111b4, 0x1 }, ++ { 0x112b4, 0x1 }, ++ { 0x113b4, 0x1 }, ++ { 0x114b4, 0x1 }, ++ { 0x115b4, 0x1 }, ++ { 0x116b4, 0x1 }, ++ { 0x117b4, 0x1 }, ++ { 0x118b4, 0x1 }, ++ { 0x12011, 0x1 }, ++ { 0x12012, 0x1 }, ++ { 0x12013, 0x180 }, ++ { 0x12018, 0x1 }, ++ { 0x12002, 0x6209 }, ++ { 0x120b2, 0x1 }, ++ { 0x121b4, 0x1 }, ++ { 0x122b4, 0x1 }, ++ { 0x123b4, 0x1 }, ++ { 0x124b4, 0x1 }, ++ { 0x125b4, 0x1 }, ++ { 0x126b4, 0x1 }, ++ { 0x127b4, 0x1 }, ++ { 0x128b4, 0x1 }, ++ { 0x13011, 0x1 }, ++ { 0x13012, 0x1 }, ++ { 0x13013, 0x180 }, ++ { 0x13018, 0x1 }, ++ { 0x13002, 0x6209 }, ++ { 0x130b2, 0x1 }, ++ { 0x131b4, 0x1 }, ++ { 0x132b4, 0x1 }, ++ { 0x133b4, 0x1 }, ++ { 0x134b4, 0x1 }, ++ { 0x135b4, 0x1 }, ++ { 0x136b4, 0x1 }, ++ { 0x137b4, 0x1 }, ++ { 0x138b4, 0x1 }, ++ { 0x20089, 0x1 }, ++ { 0x20088, 0x19 }, ++ { 0xc0080, 0x2 }, ++ { 0xd0000, 0x1 } ++}; ++ ++struct dram_fsp_msg ddr_dram_fsp_msg[] = { ++ { ++ /* P0 3200mts 1D */ ++ .drate = 3200, ++ .fw_type = FW_1D_IMAGE, ++ .fsp_cfg = ddr_fsp0_cfg, ++ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg), ++ }, ++ { ++ /* P1 400mts 1D */ ++ .drate = 400, ++ .fw_type = FW_1D_IMAGE, ++ .fsp_cfg = ddr_fsp1_cfg, ++ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg), ++ }, ++ { ++ /* P2 100mts 1D */ ++ .drate = 100, ++ .fw_type = FW_1D_IMAGE, ++ .fsp_cfg = ddr_fsp2_cfg, ++ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp2_cfg), ++ }, ++ { ++ /* P0 3200mts 2D */ ++ .drate = 3200, ++ .fw_type = FW_2D_IMAGE, ++ .fsp_cfg = ddr_fsp0_2d_cfg, ++ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_2d_cfg), ++ }, ++}; ++ ++/* ddr timing config params */ ++struct dram_timing_info dram_timing = { ++ .ddrc_cfg = ddr_ddrc_cfg, ++ .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg), ++ .ddrphy_cfg = ddr_ddrphy_cfg, ++ .ddrphy_cfg_num = ARRAY_SIZE(ddr_ddrphy_cfg), ++ .fsp_msg = ddr_dram_fsp_msg, ++ .fsp_msg_num = ARRAY_SIZE(ddr_dram_fsp_msg), ++ .ddrphy_trained_csr = ddr_ddrphy_trained_csr, ++ .ddrphy_trained_csr_num = ARRAY_SIZE(ddr_ddrphy_trained_csr), ++ .ddrphy_pie = ddr_phy_pie, ++ .ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie), ++ .fsp_table = { 3200, 400, 100, }, ++}; +diff --git a/board/freescale/gauguin-imx8mp/spl.c b/board/freescale/gauguin-imx8mp/spl.c +new file mode 100644 +index 00000000..913e2868 +--- /dev/null ++++ b/board/freescale/gauguin-imx8mp/spl.c +@@ -0,0 +1,188 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright 2018-2019, 2021 NXP ++ * ++ */ ++ ++#include <common.h> ++#include <hang.h> ++#include <init.h> ++#include <log.h> ++#include <spl.h> ++#include <asm/global_data.h> ++#include <asm/arch/imx8mp_pins.h> ++#include <asm/arch/sys_proto.h> ++#include <asm/mach-imx/boot_mode.h> ++#include <power/pmic.h> ++ ++#include <power/pca9450.h> ++#include <asm/arch/clock.h> ++#include <dm/uclass.h> ++#include <dm/device.h> ++#include <dm/uclass-internal.h> ++#include <dm/device-internal.h> ++#include <asm/mach-imx/gpio.h> ++#include <asm/mach-imx/iomux-v3.h> ++#include <asm/mach-imx/mxc_i2c.h> ++#include <fsl_esdhc_imx.h> ++#include <mmc.h> ++#include <asm/arch/ddr.h> ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++int spl_board_boot_device(enum boot_device boot_dev_spl) ++{ ++#ifdef CONFIG_SPL_BOOTROM_SUPPORT ++ return BOOT_DEVICE_BOOTROM; ++#else ++ switch (boot_dev_spl) { ++ case SD1_BOOT: ++ case MMC1_BOOT: ++ case SD2_BOOT: ++ case MMC2_BOOT: ++ return BOOT_DEVICE_MMC1; ++ case SD3_BOOT: ++ case MMC3_BOOT: ++ return BOOT_DEVICE_MMC2; ++ case QSPI_BOOT: ++ return BOOT_DEVICE_NOR; ++ case NAND_BOOT: ++ return BOOT_DEVICE_NAND; ++ case USB_BOOT: ++ return BOOT_DEVICE_BOARD; ++ default: ++ return BOOT_DEVICE_NONE; ++ } ++#endif ++} ++ ++void spl_dram_init(void) ++{ ++ ddr_init(&dram_timing); ++} ++ ++void spl_board_init(void) ++{ ++ if (IS_ENABLED(CONFIG_FSL_CAAM)) { ++ struct udevice *dev; ++ int ret; ++ ++ ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev); ++ if (ret) ++ printf("Failed to initialize caam_jr: %d\n", ret); ++ } ++ /* ++ * Set GIC clock to 500Mhz for OD VDD_SOC. Kernel driver does ++ * not allow to change it. Should set the clock after PMIC ++ * setting done. Default is 400Mhz (system_pll1_800m with div = 2) ++ * set by ROM for ND VDD_SOC ++ */ ++#if defined(CONFIG_IMX8M_LPDDR4) && !defined(CONFIG_IMX8M_VDD_SOC_850MV) ++ clock_enable(CCGR_GIC, 0); ++ clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(5)); ++ clock_enable(CCGR_GIC, 1); ++ ++ puts("Normal Boot\n"); ++#endif ++} ++ ++#if CONFIG_IS_ENABLED(DM_PMIC_PCA9450) ++int power_init_board(void) ++{ ++ struct udevice *dev; ++ int ret; ++ ++ ret = pmic_get("pca9450@25", &dev); ++ if (ret == -ENODEV) { ++ puts("No pca9450@25\n"); ++ return 0; ++ } ++ if (ret != 0) ++ return ret; ++ ++ /* BUCKxOUT_DVS0/1 control BUCK123 output */ ++ pmic_reg_write(dev, PCA9450_BUCK123_DVS, 0x29); ++ ++#ifdef CONFIG_IMX8M_LPDDR4 ++ /* ++ * increase VDD_SOC to typical value 0.95V before first ++ * DRAM access, set DVS1 to 0.85v for suspend. ++ * Enable DVS control through PMIC_STBY_REQ and ++ * set B1_ENMODE=1 (ON by PMIC_ON_REQ=H) ++ */ ++#ifdef CONFIG_IMX8M_VDD_SOC_850MV ++ /* set DVS0 to 0.85v for special case*/ ++ pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS0, 0x14); ++#else ++ pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS0, 0x1C); ++#endif ++ pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS1, 0x14); ++ pmic_reg_write(dev, PCA9450_BUCK1CTRL, 0x59); ++ ++ /* Kernel uses OD/OD freq for SOC */ ++ /* To avoid timing risk from SOC to ARM,increase VDD_ARM to OD voltage 0.95v */ ++ pmic_reg_write(dev, PCA9450_BUCK2OUT_DVS0, 0x1C); ++#elif defined(CONFIG_IMX8M_DDR4) ++ /* DDR4 runs at 3200MTS, uses default ND 0.85v for VDD_SOC and VDD_ARM */ ++ pmic_reg_write(dev, PCA9450_BUCK1CTRL, 0x59); ++ ++ /* Set NVCC_DRAM to 1.2v for DDR4 */ ++ pmic_reg_write(dev, PCA9450_BUCK6OUT, 0x18); ++#endif ++ ++ /* set WDOG_B_CFG to cold reset */ ++ pmic_reg_write(dev, PCA9450_RESET_CTRL, 0xA1); ++ ++ return 0; ++} ++#endif ++ ++#ifdef CONFIG_SPL_LOAD_FIT ++int board_fit_config_name_match(const char *name) ++{ ++ /* Just empty function now - can't decide what to choose */ ++ debug("%s: %s\n", __func__, name); ++ ++ return 0; ++} ++#endif ++ ++void board_init_f(ulong dummy) ++{ ++ struct udevice *dev; ++ int ret; ++ ++ /* Clear the BSS. */ ++ memset(__bss_start, 0, __bss_end - __bss_start); ++ ++ arch_cpu_init(); ++ ++ board_early_init_f(); ++ ++ timer_init(); ++ ++ preloader_console_init(); ++ ++ ret = spl_early_init(); ++ if (ret) { ++ debug("spl_early_init() failed: %d\n", ret); ++ hang(); ++ } ++ ++ ret = uclass_get_device_by_name(UCLASS_CLK, ++ "clock-controller@30380000", ++ &dev); ++ if (ret < 0) { ++ printf("Failed to find clock node. Check device tree\n"); ++ hang(); ++ } ++ ++ enable_tzc380(); ++ ++ power_init_board(); ++ ++ /* DDR initialization */ ++ spl_dram_init(); ++ ++ board_init_r(NULL, 0); ++} +diff --git a/configs/gauguin-imx8mp_defconfig b/configs/gauguin-imx8mp_defconfig +new file mode 100644 +index 00000000..2ffd5329 +--- /dev/null ++++ b/configs/gauguin-imx8mp_defconfig +@@ -0,0 +1,178 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_IMX8M=y ++CONFIG_SYS_TEXT_BASE=0x40200000 ++CONFIG_SYS_MALLOC_LEN=0x2000000 ++CONFIG_SYS_MALLOC_F_LEN=0x10000 ++CONFIG_SPL_GPIO=y ++CONFIG_SPL_LIBCOMMON_SUPPORT=y ++CONFIG_SPL_LIBGENERIC_SUPPORT=y ++CONFIG_NR_DRAM_BANKS=3 ++CONFIG_SYS_MEMTEST_START=0x60000000 ++CONFIG_SYS_MEMTEST_END=0xC0000000 ++CONFIG_ENV_SIZE=0x4000 ++CONFIG_ENV_OFFSET=0x400000 ++CONFIG_ENV_SECT_SIZE=0x10000 ++CONFIG_DM_GPIO=y ++CONFIG_DEFAULT_DEVICE_TREE="gauguin-imx8mp" ++CONFIG_SPL_TEXT_BASE=0x920000 ++CONFIG_TARGET_GAUGUIN_IMX8MP=y ++CONFIG_SPL_SERIAL=y ++CONFIG_SPL_DRIVERS_MISC=y ++CONFIG_SPL=y ++CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 ++CONFIG_OF_BOARD_FIXUP=y ++CONFIG_DISTRO_DEFAULTS=y ++CONFIG_SYS_LOAD_ADDR=0x40400000 ++CONFIG_FIT=y ++CONFIG_FIT_EXTERNAL_OFFSET=0x3000 ++CONFIG_FIT_SIGNATURE=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_LEGACY_IMAGE_FORMAT=y ++CONFIG_OF_BOARD_SETUP=y ++CONFIG_OF_SYSTEM_SETUP=y ++CONFIG_BOOTCOMMAND="run distro_bootcmd;run bsp_bootcmd" ++CONFIG_DEFAULT_FDT_FILE="gauguin-imx8mp.dtb" ++CONFIG_BOARD_EARLY_INIT_F=y ++CONFIG_BOARD_LATE_INIT=y ++CONFIG_SPL_BOARD_INIT=y ++CONFIG_SPL_BOOTROM_SUPPORT=y ++CONFIG_SPL_SEPARATE_BSS=y ++CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y ++CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x300 ++CONFIG_SPL_I2C=y ++CONFIG_SPL_POWER=y ++CONFIG_SPL_WATCHDOG=y ++CONFIG_SYS_PROMPT="[u-boot@IGKBoard]# " ++# CONFIG_BOOTM_NETBSD is not set ++# CONFIG_CMD_EXPORTENV is not set ++# CONFIG_CMD_IMPORTENV is not set ++CONFIG_CMD_ERASEENV=y ++CONFIG_CMD_NVEDIT_EFI=y ++CONFIG_CRC32_VERIFY=y ++CONFIG_CMD_MEMTEST=y ++CONFIG_CMD_CLK=y ++CONFIG_CMD_DFU=y ++CONFIG_CMD_FUSE=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_I2C=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_OPTEE_RPMB=y ++CONFIG_CMD_POWEROFF=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_USB_MASS_STORAGE=y ++CONFIG_CMD_SNTP=y ++CONFIG_CMD_BMP=y ++CONFIG_CMD_CACHE=y ++CONFIG_CMD_EFIDEBUG=y ++CONFIG_CMD_RTC=y ++CONFIG_CMD_TIME=y ++CONFIG_CMD_GETTIME=y ++CONFIG_CMD_TIMER=y ++CONFIG_CMD_REGULATOR=y ++CONFIG_CMD_EXT4_WRITE=y ++CONFIG_OF_CONTROL=y ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_NOWHERE=y ++CONFIG_ENV_IS_IN_MMC=y ++CONFIG_ENV_IS_IN_SPI_FLASH=y ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_SYS_MMC_ENV_DEV=1 ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_SPL_DM=y ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_SPL_CLK_COMPOSITE_CCF=y ++CONFIG_CLK_COMPOSITE_CCF=y ++CONFIG_SPL_CLK_IMX8MP=y ++CONFIG_CLK_IMX8MP=y ++CONFIG_DFU_TFTP=y ++CONFIG_DFU_MMC=y ++CONFIG_DFU_RAM=y ++CONFIG_USB_FUNCTION_FASTBOOT=y ++CONFIG_UDP_FUNCTION_FASTBOOT=y ++CONFIG_FASTBOOT_BUF_ADDR=0x42800000 ++CONFIG_FASTBOOT_BUF_SIZE=0x40000000 ++CONFIG_FASTBOOT_FLASH=y ++CONFIG_MXC_GPIO=y ++CONFIG_DM_PCA953X=y ++CONFIG_DM_I2C=y ++CONFIG_LED=y ++CONFIG_LED_GPIO=y ++CONFIG_SUPPORT_EMMC_RPMB=y ++CONFIG_SUPPORT_EMMC_BOOT=y ++CONFIG_MMC_IO_VOLTAGE=y ++CONFIG_MMC_UHS_SUPPORT=y ++CONFIG_MMC_HS400_ES_SUPPORT=y ++CONFIG_MMC_HS400_SUPPORT=y ++CONFIG_FSL_USDHC=y ++CONFIG_DM_SPI_FLASH=y ++CONFIG_SF_DEFAULT_MODE=0 ++CONFIG_SF_DEFAULT_SPEED=40000000 ++CONFIG_SPI_FLASH_BAR=y ++CONFIG_SPI_FLASH_STMICRO=y ++CONFIG_PHY_REALTEK=y ++CONFIG_DM_ETH=y ++CONFIG_DM_ETH_PHY=y ++CONFIG_PHY_GIGE=y ++CONFIG_DWC_ETH_QOS=y ++CONFIG_DWC_ETH_QOS_IMX=y ++CONFIG_FEC_MXC=y ++CONFIG_MII=y ++CONFIG_PHY=y ++CONFIG_PHY_IMX8MQ_USB=y ++CONFIG_PINCTRL=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_PINCTRL_IMX8M=y ++CONFIG_DM_PMIC=y ++CONFIG_SPL_DM_PMIC_PCA9450=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_DM_RTC=y ++CONFIG_RTC_EMULATION=y ++CONFIG_MXC_UART=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_NXP_FSPI=y ++CONFIG_SYSRESET=y ++CONFIG_SYSRESET_PSCI=y ++CONFIG_TEE=y ++CONFIG_OPTEE=y ++CONFIG_DM_THERMAL=y ++CONFIG_IMX_TMU=y ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_DWC3=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_MANUFACTURER="FSL" ++CONFIG_USB_GADGET_VENDOR_NUM=0x1fc9 ++CONFIG_USB_GADGET_PRODUCT_NUM=0x0152 ++CONFIG_DM_VIDEO=y ++CONFIG_VIDEO_LOGO=y ++CONFIG_SYS_WHITE_ON_BLACK=y ++CONFIG_VIDEO_LCD_RAYDIUM_RM67191=y ++CONFIG_VIDEO_IMX_SEC_DSI=y ++CONFIG_VIDEO_IMX_LCDIFV3=y ++CONFIG_SPLASH_SCREEN=y ++CONFIG_SPLASH_SCREEN_ALIGN=y ++CONFIG_BMP_16BPP=y ++CONFIG_BMP_24BPP=y ++CONFIG_BMP_32BPP=y ++CONFIG_VIDEO_ADV7535=y ++CONFIG_SPL_RSA=y ++CONFIG_SHA384=y ++CONFIG_LZO=y ++CONFIG_BZIP2=y ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_EFI_MM_COMM_TEE=y ++CONFIG_EFI_VAR_BUF_SIZE=139264 ++CONFIG_EFI_SET_TIME=y ++CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y ++CONFIG_EFI_CAPSULE_ON_DISK=y ++CONFIG_EFI_IGNORE_OSINDICATIONS=y ++CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y ++CONFIG_EFI_CAPSULE_AUTHENTICATE=y ++CONFIG_EFI_SECURE_BOOT=y +diff --git a/drivers/video/u_boot_logo.S b/drivers/video/u_boot_logo.S +new file mode 100644 +index 00000000..80551a33 +--- /dev/null ++++ b/drivers/video/u_boot_logo.S +@@ -0,0 +1,8 @@ ++.section .rodata.splash.init,"a" ++.balign 16 ++.global __splash_u_boot_logo_begin ++__splash_u_boot_logo_begin: ++.incbin "drivers/video/u_boot_logo.bmp" ++__splash_u_boot_logo_end: ++.global __splash_u_boot_logo_end ++.balign 16 +diff --git a/include/configs/gauguin-imx8mp.h b/include/configs/gauguin-imx8mp.h +new file mode 100644 +index 00000000..0f5f3368 +--- /dev/null ++++ b/include/configs/gauguin-imx8mp.h +@@ -0,0 +1,246 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright 2019 NXP ++ */ ++ ++#ifndef __GAUGUIN_IMX8MP_H ++#define __GAUGUIN_IMX8MP_H ++ ++#include <linux/sizes.h> ++#include <linux/stringify.h> ++#include <asm/arch/imx-regs.h> ++#include "imx_env.h" ++ ++#define CONFIG_SYS_BOOTM_LEN (32 * SZ_1M) ++ ++#define CONFIG_SPL_MAX_SIZE (176 * 1024) ++#define CONFIG_SYS_MONITOR_LEN (512 * 1024) ++#define CONFIG_SYS_UBOOT_BASE (QSPI0_AMBA_BASE + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512) ++ ++#ifdef CONFIG_SPL_BUILD ++#define CONFIG_SPL_STACK 0x96dff0 ++#define CONFIG_SPL_BSS_START_ADDR 0x96e000 ++#define CONFIG_SPL_BSS_MAX_SIZE SZ_8K /* 8 KB */ ++#define CONFIG_SYS_SPL_MALLOC_START 0x42200000 ++#define CONFIG_SYS_SPL_MALLOC_SIZE SZ_512K /* 512 KB */ ++ ++/* For RAW image gives a error info not panic */ ++#define CONFIG_SPL_ABORT_ON_RAW_IMAGE ++ ++#if defined(CONFIG_NAND_BOOT) ++#define CONFIG_SPL_NAND_BASE ++#define CONFIG_SPL_NAND_IDENT ++#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x4000000 /* Put the FIT out of first 64MB boot area */ ++ ++/* Set a redundant offset in nand FIT mtdpart. The new uuu will burn full boot image (not only FIT part) to the mtdpart, so we check both two offsets */ ++#define CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND \ ++ (CONFIG_SYS_NAND_U_BOOT_OFFS + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512 - 0x8400) ++#endif ++ ++#endif ++ ++#define CONFIG_CMD_READ ++#define CONFIG_SERIAL_TAG ++#define CONFIG_FASTBOOT_USB_DEV 0 ++ ++#define CONFIG_REMAKE_ELF ++/* ENET Config */ ++/* ENET1 */ ++ ++#if defined(CONFIG_CMD_NET) ++#define CONFIG_ETHPRIME "eth1" /* Set eqos to primary since we use its MDIO */ ++ ++#define CONFIG_FEC_XCV_TYPE RGMII ++#define CONFIG_FEC_MXC_PHYADDR 1 ++ ++#define DWC_NET_PHYADDR 1 ++ ++#define PHY_ANEG_TIMEOUT 20000 ++ ++#endif ++ ++#ifdef CONFIG_DISTRO_DEFAULTS ++#define BOOT_TARGET_DEVICES(func) \ ++ func(USB, usb, 0) \ ++ func(MMC, mmc, 1) \ ++ func(MMC, mmc, 2) ++ ++#include <config_distro_bootcmd.h> ++#else ++#define BOOTENV ++#endif ++ ++#define JH_ROOT_DTB "gauguin-imx8mp-root.dtb" ++ ++#define JAILHOUSE_ENV \ ++ "jh_clk= \0 " \ ++ "jh_root_dtb=" JH_ROOT_DTB "\0" \ ++ "jh_mmcboot=setenv fdtfile ${jh_root_dtb};" \ ++ "setenv jh_clk clk_ignore_unused mem=1920MB; " \ ++ "if run loadimage; then " \ ++ "run mmcboot; " \ ++ "else run jh_netboot; fi; \0" \ ++ "jh_netboot=setenv fdtfile ${jh_root_dtb}; setenv jh_clk clk_ignore_unused mem=1920MB; run netboot; \0 " ++ ++#define CONFIG_MFG_ENV_SETTINGS \ ++ CONFIG_MFG_ENV_SETTINGS_DEFAULT \ ++ "initrd_addr=0x43800000\0" \ ++ "initrd_high=0xffffffffffffffff\0" \ ++ "emmc_dev=2\0"\ ++ "sd_dev=1\0" ++ ++ ++#ifdef CONFIG_NAND_BOOT ++#define MFG_NAND_PARTITION "mtdparts=gpmi-nand:64m(nandboot),16m(nandfit),32m(nandkernel),16m(nanddtb),8m(nandtee),-(nandrootfs)" ++#endif ++ ++/* Initial environment variables */ ++#if defined(CONFIG_NAND_BOOT) ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_MFG_ENV_SETTINGS \ ++ "splashimage=0x50000000\0" \ ++ "fdt_addr_r=0x43000000\0" \ ++ "fdt_addr=0x43000000\0" \ ++ "fdt_high=0xffffffffffffffff\0" \ ++ "mtdparts=" MFG_NAND_PARTITION "\0" \ ++ "console=ttymxc1,115200 earlycon=ec_imx6q,0x30890000,115200\0" \ ++ "bootargs=console=ttymxc1,115200 earlycon=ec_imx6q,0x30890000,115200 ubi.mtd=nandrootfs " \ ++ "root=ubi0:nandrootfs rootfstype=ubifs " \ ++ MFG_NAND_PARTITION \ ++ "\0" \ ++ "bootcmd=nand read ${loadaddr} 0x5000000 0x2000000;"\ ++ "nand read ${fdt_addr_r} 0x7000000 0x100000;"\ ++ "booti ${loadaddr} - ${fdt_addr_r}" ++ ++#else ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_MFG_ENV_SETTINGS \ ++ JAILHOUSE_ENV \ ++ BOOTENV \ ++ "scriptaddr=0x43500000\0" \ ++ "kernel_addr_r=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \ ++ "bsp_script=boot.scr\0" \ ++ "image=Image\0" \ ++ "splashimage=0x50000000\0" \ ++ "console=ttymxc1,115200\0" \ ++ "fdt_addr_r=0x43000000\0" \ ++ "fdt_addr=0x43000000\0" \ ++ "boot_fdt=try\0" \ ++ "fdt_high=0xffffffffffffffff\0" \ ++ "boot_fit=no\0" \ ++ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ ++ "bootm_size=0x10000000\0" \ ++ "mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \ ++ "mmcpart=1\0" \ ++ "mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \ ++ "mmcautodetect=yes\0" \ ++ "mmcargs=setenv bootargs ${jh_clk} console=${console} root=${mmcroot}\0 " \ ++ "loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${bsp_script};\0" \ ++ "bootscript=echo Running bootscript from mmc ...; " \ ++ "source\0" \ ++ "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ ++ "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr_r} ${fdtfile}\0" \ ++ "ipaddr=192.168.3.10\0" \ ++ "serverip=192.168.3.239\0" \ ++ "nfspath=/srv/nfs/rootfs\0" \ ++ "mmcboot=echo Booting from mmc ...; " \ ++ "run mmcargs; " \ ++ "if test ${boot_fit} = yes || test ${boot_fit} = try; then " \ ++ "bootm ${loadaddr}; " \ ++ "else " \ ++ "if run loadfdt; then " \ ++ "booti ${loadaddr} - ${fdt_addr_r}; " \ ++ "else " \ ++ "echo WARN: Cannot load the DT; " \ ++ "fi; " \ ++ "fi;\0" \ ++ "netargs=setenv bootargs ${jh_clk} console=${console} " \ ++ "root=/dev/nfs " \ ++ "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \ ++ "netargs_nfs=setenv bootargs console=${console} " \ ++ "root=/dev/nfs " \ ++ "nfsroot=${serverip}:${nfspath},proto=tcp rw ip=${ipaddr}:${serverip}:255.255.255.0::eth1:off\0" \ ++ "netboot=echo Booting from net ...; " \ ++ "tftp $loadaddr $image; tftp $fdt_addr ${fdtfile}; " \ ++ "run mmcargs; " \ ++ "booti ${loadaddr} - ${fdt_addr_r}\0" \ ++ "netboot_nfs=echo Booting from net ... rootfs from nfs; " \ ++ "tftp $loadaddr $image; tftp $fdt_addr ${fdtfile}; " \ ++ "run netargs_nfs; " \ ++ "booti ${loadaddr} - ${fdt_addr_r}\0" \ ++ "bsp_bootcmd=echo Running BSP bootcmd ...; " \ ++ "mmc dev ${mmcdev}; if mmc rescan; then " \ ++ "if run loadbootscript; then " \ ++ "run bootscript; " \ ++ "else " \ ++ "if run loadimage; then " \ ++ "run mmcboot; " \ ++ "else run netboot; " \ ++ "fi; " \ ++ "fi; " \ ++ "fi;\0" \ ++ "" ++#endif ++ ++/* Link Definitions */ ++ ++#define CONFIG_SYS_INIT_RAM_ADDR 0x40000000 ++#define CONFIG_SYS_INIT_RAM_SIZE 0x80000 ++#define CONFIG_SYS_INIT_SP_OFFSET \ ++ (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) ++#define CONFIG_SYS_INIT_SP_ADDR \ ++ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) ++ ++#define CONFIG_MMCROOT "/dev/mmcblk1p2" /* USDHC2 */ ++ ++/* Totally 6GB DDR */ ++#define CONFIG_SYS_SDRAM_BASE 0x40000000 ++#define PHYS_SDRAM 0x40000000 ++#define PHYS_SDRAM_SIZE 0xC0000000 /* 3 GB */ ++#define PHYS_SDRAM_2 0x100000000 ++#ifdef CONFIG_TARGET_IMX8MP_DDR4_EVK ++#define PHYS_SDRAM_2_SIZE 0x40000000 /* 1 GB */ ++#else ++#define PHYS_SDRAM_2_SIZE 0xC0000000 /* 3 GB */ ++#endif ++ ++#define CONFIG_MXC_UART_BASE UART2_BASE_ADDR ++ ++/* Monitor Command Prompt */ ++#define CONFIG_SYS_CBSIZE 2048 ++#define CONFIG_SYS_MAXARGS 64 ++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE ++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ ++ sizeof(CONFIG_SYS_PROMPT) + 16) ++ ++#define CONFIG_IMX_BOOTAUX ++ ++#ifdef CONFIG_TARGET_IMX8MP_DDR4_EVK ++#define CONFIG_SYS_FSL_USDHC_NUM 1 ++#else ++#define CONFIG_SYS_FSL_USDHC_NUM 2 ++#endif ++#define CONFIG_SYS_FSL_ESDHC_ADDR 0 ++ ++#ifdef CONFIG_NAND_MXS ++#define CONFIG_CMD_NAND_TRIMFFS ++ ++/* NAND stuff */ ++#define CONFIG_SYS_MAX_NAND_DEVICE 1 ++#define CONFIG_SYS_NAND_BASE 0x20000000 ++#define CONFIG_SYS_NAND_USE_FLASH_BBT ++#endif /* CONFIG_NAND_MXS */ ++ ++#define CONFIG_SYS_I2C_SPEED 100000 ++ ++/* USB configs */ ++ ++#define CONFIG_USB_MAX_CONTROLLER_COUNT 2 ++#define CONFIG_USBD_HS ++#define CONFIG_USB_GADGET_VBUS_DRAW 2 ++ ++#ifdef CONFIG_ANDROID_SUPPORT ++#include "imx8mp_evk_android.h" ++#endif ++ ++#endif +diff --git a/include/configs/gauguin-imx8mp_android.h b/include/configs/gauguin-imx8mp_android.h +new file mode 100644 +index 00000000..4896ce11 +--- /dev/null ++++ b/include/configs/gauguin-imx8mp_android.h +@@ -0,0 +1,46 @@ ++/* ++ * Copyright 2021 NXP ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef GAUGUIN_IMX8MP_ANDROID_H ++#define GAUGUIN_IMX8MP_ANDROID_H ++ ++#define FSL_FASTBOOT_FB_DEV "mmc" ++ ++#undef CONFIG_EXTRA_ENV_SETTINGS ++#undef CONFIG_BOOTCOMMAND ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ "splashpos=m,m\0" \ ++ "splashimage=0x50000000\0" \ ++ "fdt_high=0xffffffffffffffff\0" \ ++ "initrd_high=0xffffffffffffffff\0" \ ++ ++/* Enable mcu firmware flash */ ++#ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT ++#define ANDROID_MCU_FRIMWARE_DEV_TYPE DEV_MMC ++#define ANDROID_MCU_FIRMWARE_START 0x500000 ++#define ANDROID_MCU_OS_PARTITION_SIZE 0x40000 ++#define ANDROID_MCU_FIRMWARE_SIZE 0x20000 ++#define ANDROID_MCU_FIRMWARE_HEADER_STACK 0x20020000 ++#endif ++ ++#define CONFIG_SYS_SPL_PTE_RAM_BASE 0x41580000 ++ ++#ifdef CONFIG_IMX_TRUSTY_OS ++#define BOOTLOADER_RBIDX_OFFSET 0x3FE000 ++#define BOOTLOADER_RBIDX_START 0x3FF000 ++#define BOOTLOADER_RBIDX_LEN 0x08 ++#define BOOTLOADER_RBIDX_INITVAL 0 ++#endif ++ ++#ifdef CONFIG_IMX_TRUSTY_OS ++#define AVB_RPMB ++#define KEYSLOT_HWPARTITION_ID 2 ++#define KEYSLOT_BLKS 0x1FFF ++#define NS_ARCH_ARM64 1 ++#endif ++ ++#endif /* GAUGUIN_IMX8MP_ANDROID_H */ +diff --git a/tools/boot/bootm.c b/tools/boot/bootm.c +new file mode 100644 +index 00000000..31ddd95f +--- /dev/null ++++ b/tools/boot/bootm.c +@@ -0,0 +1 @@ ++#include <../boot/bootm.c> +diff --git a/tools/boot/fdt_region.c b/tools/boot/fdt_region.c +new file mode 100644 +index 00000000..1bb9c886 +--- /dev/null ++++ b/tools/boot/fdt_region.c +@@ -0,0 +1 @@ ++#include <../boot/fdt_region.c> +diff --git a/tools/boot/image-cipher.c b/tools/boot/image-cipher.c +new file mode 100644 +index 00000000..5013afee +--- /dev/null ++++ b/tools/boot/image-cipher.c +@@ -0,0 +1 @@ ++#include <../boot/image-cipher.c> +diff --git a/tools/boot/image-fit-sig.c b/tools/boot/image-fit-sig.c +new file mode 100644 +index 00000000..9da06c71 +--- /dev/null ++++ b/tools/boot/image-fit-sig.c +@@ -0,0 +1 @@ ++#include <../boot/image-fit-sig.c> +diff --git a/tools/boot/image-fit.c b/tools/boot/image-fit.c +new file mode 100644 +index 00000000..9168e119 +--- /dev/null ++++ b/tools/boot/image-fit.c +@@ -0,0 +1 @@ ++#include <../boot/image-fit.c> +diff --git a/tools/boot/image-host.c b/tools/boot/image-host.c +new file mode 100644 +index 00000000..fb0ad568 +--- /dev/null ++++ b/tools/boot/image-host.c +@@ -0,0 +1 @@ ++#include <../boot/image-host.c> +diff --git a/tools/boot/image.c b/tools/boot/image.c +new file mode 100644 +index 00000000..48a2e765 +--- /dev/null ++++ b/tools/boot/image.c +@@ -0,0 +1 @@ ++#include <../boot/image.c> diff --git a/kernel/patches/gauguin-imx8mp/linux-imx-lf-5.15.71-2.2.0.patch b/kernel/patches/gauguin-imx8mp/linux-imx-lf-5.15.71-2.2.0.patch new file mode 100644 index 0000000..f50b16d --- /dev/null +++ b/kernel/patches/gauguin-imx8mp/linux-imx-lf-5.15.71-2.2.0.patch @@ -0,0 +1,5191 @@ +diff --git a/Makefile b/Makefile +index 4c06cbe89..3dbf9430a 100644 +--- a/Makefile ++++ b/Makefile +@@ -383,6 +383,9 @@ include $(srctree)/scripts/subarch.include + # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile + ARCH ?= $(SUBARCH) + ++ARCH = arm64 ++CROSS_COMPILE ?= aarch64-linux-gnu- ++ + # Architecture as present in compile.h + UTS_MACHINE := $(ARCH) + SRCARCH := $(ARCH) +diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile +index 9a7319c6b..23cb09c85 100644 +--- a/arch/arm64/boot/dts/freescale/Makefile ++++ b/arch/arm64/boot/dts/freescale/Makefile +@@ -119,6 +119,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-rdk.dtb + dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb imx8mq-evk-rpmsg.dtb imx8mp-ab2.dtb + dtb-$(CONFIG_ARCH_MXC) += imx8mp-ddr4-evk.dtb + dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk-ndm.dtb ++dtb-$(CONFIG_ARCH_MXC) += gauguin-imx8mp.dtb + dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb imx8mq-evk-rpmsg.dtb imx8mq-evk-pcie1-m2.dtb imx8mq-evk-usd-wifi.dtb \ + imx8mq-evk-usdhc2-m2.dtb + dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk-ak4497.dtb imx8mq-evk-audio-tdm.dtb imx8mq-evk-pdm.dtb +diff --git a/arch/arm64/boot/dts/freescale/gauguin-imx8mp.dts b/arch/arm64/boot/dts/freescale/gauguin-imx8mp.dts +new file mode 100644 +index 000000000..f48c97c78 +--- /dev/null ++++ b/arch/arm64/boot/dts/freescale/gauguin-imx8mp.dts +@@ -0,0 +1,1000 @@ ++/* ++ * Device Tree Source for ZhiTu GauGuin Board - i.MX8MP ++ * Based on imx8mp-evk.dts/imx8mp-evk.dtsi ++ * ++ * Copyright (C) 2023 LingYun IoT System Studio. ++ * Author: Guo Wenxue<guowenxue@gmail.com> ++ */ ++ ++/dts-v1/; ++ ++#include <dt-bindings/usb/pd.h> ++#include "imx8mp.dtsi" ++ ++// #define SIMPLE_CARD /*simple_card support */ ++ ++/ { ++ model = "ZhiTu GauGuin Board - i.MX8MP"; ++ compatible = "fsl,imx8mp-evk", "fsl,imx8mp"; ++ ++ chosen { ++ stdout-path = &uart2; ++ }; ++ ++ gpio-devs-ctrl { ++ compatible = "gpio-leds"; ++ pinctrl-names = "devs-group"; ++ pinctrl-0 = <&pinctrl_gpio_devs_group>; ++ ++ uart-switch { ++ label = "uart-switch"; ++ gpios = <&gpio4 27 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ usb1-vbus { ++ label = "usb1-vbus-en"; ++ gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ wwan-power-on { ++ label = "wwan-power-on"; ++ gpios = <&gpio2 16 GPIO_ACTIVE_LOW>; ++ default-state = "on"; ++ }; ++ ++ wwan-reset { ++ label = "wwan-reset"; ++ gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_gpio_leds_group>; ++ ++ sys-status { ++ label = "sys-status"; ++ gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>; ++ // linux,default-trigger = "heartbeat"; ++ default-state = "on"; ++ }; ++ ++ rgb-led-red { ++ label = "red"; ++ gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ rgb-led-green { ++ label = "green"; ++ gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ ++ rgb-led-blue { ++ label = "blue"; ++ gpios = <&gpio2 17 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ ++ rgb-led-ext-red { ++ label = "ext-red"; ++ gpios = <&gpio3 25 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ rgb-led-ext-green { ++ label = "ext-green"; ++ gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ rgb-led-ext-blue { ++ label = "ext-blue"; ++ gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ }; ++ ++ memory@40000000 { ++ device_type = "memory"; ++ reg = <0x0 0x40000000 0 0xc0000000>, ++ <0x1 0x00000000 0 0xc0000000>; ++ }; ++ /*+--------------+ ++ | Regulator | ++ +--------------+*/ ++ /*4G power_en # low-->en*/ ++ regulator-wwan-prower-en { ++ compatible = "regulator-fixed"; ++ regulator-name = "wwan-prower-en"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_wwan_reg>; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ gpios = <&gpio5 10 GPIO_ACTIVE_LOW>; ++ enable-active-low; ++ regulator-always-on; ++ }; ++ ++ /*usb host vbus en # low-->en*/ ++ regulator-usb-host-vbus-en { ++ compatible = "regulator-fixed"; ++ regulator-name = "usb-host-vbus-en"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_usb_host_reg>; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ gpios = <&gpio5 12 GPIO_ACTIVE_LOW>; ++ enable-active-low; ++ regulator-always-on; ++ }; ++ ++ /*lcd reset : 硬件已经拉高*/ ++ regulator-lcd-reset { ++ compatible = "regulator-fixed"; ++ regulator-name = "lcd-reset"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ gpios = <&gpio5 7 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ /delete-node/ regulator-lcd-reset; ++ ++ /*audio ap shotdown low-->en*/ ++ reg_audio_pwr: regulator-audio-pwr { ++ compatible = "regulator-fixed"; ++ regulator-name = "audio-pwr"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ gpios = <&gpio4 28 GPIO_ACTIVE_LOW>; ++ enable-active-low; ++ regulator-always-on; ++ }; ++ ++ /*+---------------+ ++ | Sound Card | ++ +--------------+*/ ++#ifndef SIMPLE_CARD ++ sound-nau8822 { ++ compatible = "fsl,imx-audio-nau8822"; ++ model = "nau8822-audio";/*声卡名字*/ ++ audio-cpu = <&sai3>; /*cpu-dai*/ ++ audio-codec = <&codec>;/*codec-dai*/ ++ audio-asrc = <&easrc>; /*增强型异步采样器*/ ++ audio-routing = //sink + source 需使用 源码已有的组件 ++ "Headphone Jack", "LHP", ++ "Headphone Jack", "RHP", ++ "Ext Spk", "LSPK", ++ "Ext Spk", "RSPK", ++ "Line Out Jack", "AUXOUT1", ++ "Line Out Jack", "AUXOUT2", ++ "LAUX", "Line In Jack", ++ "RAUX", "Line In Jack", ++ "LMICN", "Mic Jack", ++ "LMICP", "Mic Jack", ++ "RMICN", "Mic Jack", ++ "RMICP", "Mic Jack"; ++ }; ++#else ++ sound_card: sound-card ++ { ++ compatible = "simple-audio-card"; ++ simple-audio-card,bitclock-master = <&dailink_master>;/*master 时钟 */ ++ simple-audio-card,format = "i2s";/*传输格式*/ ++ simple-audio-card,frame-master = <&dailink_master>;/*master 帧*/ ++ simple-audio-card,name = "imx8mp-nau8822"; /*aplay -l 出现的声卡名字*/ ++ simple-audio-card,widgets = /*声卡组件 board组件*/ ++ "Headphones", "Headphones", ++ "Line Out", "Line Out", ++ "Speaker", "Speaker", ++ "Microphone", "Mic In", ++ "Line", "Line In"; ++ simple-audio-card,routing = /*音频路由 sink + source*/ ++ "Headphones", "LHP", ++ "Headphones", "RHP", ++ "Speaker", "LSPK", ++ "Speaker", "RSPK", ++ "Line Out", "AUXOUT1", ++ "Line Out", "AUXOUT2", ++ "LAUX", "Line In", ++ "RAUX", "Line In", ++ "LMICP", "Mic In", ++ "RMICP", "Mic In"; ++ dailink_master: simple-audio-card,codec {/* 确定codec-dai */ ++ sound-dai = <&codec>; ++ clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_MCLK1>; /*mclk 时钟*/ ++ }; ++ ++ simple-audio-card,cpu {/* 确定cpu-dai */ ++ sound-dai = <&sai3>; /*cpu dai*/ ++ }; ++ }; ++#endif ++ ++ // sound-xcvr { //音频收发器 ++ // compatible = "fsl,imx-audio-card"; ++ // model = "imx-audio-xcvr"; ++ // pri-dai-link { ++ // link-name = "XCVR PCM"; ++ // cpu { ++ // sound-dai = <&xcvr>; ++ // }; ++ // }; ++ // }; ++ ++ /*+---------------+ ++ | Lvds Panel | ++ +--------------+*/ ++ lvds0_panel { ++ compatible = "auo,g101ean02"; ++ backlight = <&lvds_backlight>; ++ status = "okay"; ++ ++ port { ++ panel_lvds_in: endpoint { ++ remote-endpoint = <&lvds_out>; ++ }; ++ }; ++ }; ++ ++ lvds_backlight: lvds_backlight { ++ compatible = "pwm-backlight"; ++ pwms = <&pwm2 0 100000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_backlight>; ++ enable-gpios = <&gpio5 6 GPIO_ACTIVE_LOW>; ++ status = "okay"; ++ ++ 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 = <20>; ++ }; ++ ++ /*+---------------+ ++ | Extcon gpio | ++ +--------------+*/ ++ extcon_dwc3: extcon_dwc3 { ++ compatible = "linux,extcon-usb-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_usb0_id_grp>; ++ id-gpio = <&gpio4 26 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++/*+--------------+ ++ | Misc Modules | ++ +--------------+*/ ++&snvs_pwrkey { ++ status = "okay"; ++}; ++ ++&sdma2 { ++ status = "okay"; ++}; ++ ++&pwm2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_pwm2>; ++ status = "okay"; ++}; ++ ++&A53_0 { ++ cpu-supply = <&buck2>; ++}; ++ ++&A53_1 { ++ cpu-supply = <&buck2>; ++}; ++ ++&A53_2 { ++ cpu-supply = <&buck2>; ++}; ++ ++&A53_3 { ++ cpu-supply = <&buck2>; ++}; ++ ++&wdog1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_wdog>; ++ fsl,ext-reset-output; ++ status = "okay"; ++}; ++ ++/*+------------------------+ ++ | Uart and can interface | ++ +------------------------+*/ ++&uart1 { ++ /* RS485 */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_uart1>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ /* console */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_uart2>; ++ status = "okay"; ++}; ++ ++&flexcan1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_flexcan1>; ++ status = "okay"; ++}; ++ ++/*+--------------+ ++ | Lvds Modules | ++ +--------------+*/ ++&lcdif2 { ++ status = "okay"; ++}; ++ ++&ldb { ++ status = "okay"; ++ ++ lvds-channel@0 { ++ fsl,data-mapping = "spwg"; ++ fsl,data-width = <24>; ++ status = "okay"; ++ ++ port@1 { ++ reg = <1>; ++ ++ lvds_out: endpoint { ++ remote-endpoint = <&panel_lvds_in>; ++ }; ++ }; ++ }; ++}; ++ ++&ldb_phy { ++ status = "okay"; ++}; ++ ++/*+--------------+ ++ | Spi Modules | ++ +--------------+*/ ++&flexspi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_flexspi0>; ++ status = "okay"; ++ ++ flash0: mt25qu256aba@0 { ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "jedec,spi-nor"; ++ spi-max-frequency = <80000000>; ++ spi-tx-bus-width = <1>; ++ spi-rx-bus-width = <4>; ++ }; ++}; ++ ++/*+------------------+ ++ | Ethernet Modules | ++ +------------------+*/ ++&eqos { //T1 eth1 ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_eqos>; ++ phy-mode = "rgmii-id"; ++ phy-handle = <ðphy1>; ++ // snps,force_thresh_dma_mode; ++ // snps,mtl-tx-config = <&mtl_tx_setup>; /*TODO: dma相关*/ ++ // snps,mtl-rx-config = <&mtl_rx_setup>; ++ status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ethphy1: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ eee-broken-1000t; ++ realtek,clkout-disable; ++ }; ++ }; ++}; ++ ++&fec {//T2 eth0 ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_fec>; ++ phy-mode = "rgmii-id"; ++ phy-handle = <ðphy2>; ++ fsl,magic-packet; ++ status = "okay"; ++ ++ mdio { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ethphy2: ethernet-phy@2 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <2>; ++ eee-broken-1000t; ++ reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>; ++ reset-assert-us = <10000>; ++ reset-deassert-us = <80000>; ++ realtek,clkout-disable; ++ }; ++ }; ++}; ++ ++/*+---------------+ ++ | I2C Module | ++ +---------------+*/ ++&i2c1 { ++ clock-frequency = <400000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c1>; ++ status = "okay"; ++ ++ pmic@25 { ++ compatible = "nxp,pca9450c"; ++ reg = <0x25>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_pmic>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <3 IRQ_TYPE_LEVEL_LOW>; ++ ++ regulators { ++ buck1: BUCK1 { ++ regulator-name = "BUCK1"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <2187500>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-ramp-delay = <3125>; ++ }; ++ ++ buck2: BUCK2 { ++ regulator-name = "BUCK2"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <2187500>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-ramp-delay = <3125>; ++ nxp,dvs-run-voltage = <950000>; ++ nxp,dvs-standby-voltage = <850000>; ++ }; ++ ++ buck4: BUCK4{ ++ regulator-name = "BUCK4"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ buck5: BUCK5{ ++ regulator-name = "BUCK5"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ buck6: BUCK6 { ++ regulator-name = "BUCK6"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <3400000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ ldo1: LDO1 { ++ regulator-name = "LDO1"; ++ regulator-min-microvolt = <1600000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ ldo2: LDO2 { ++ regulator-name = "LDO2"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ ldo3: LDO3 { ++ regulator-name = "LDO3"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ ldo4: LDO4 { ++ regulator-name = "LDO4"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ ldo5: LDO5 { ++ regulator-name = "LDO5"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ }; ++ }; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c2>; ++ status = "okay"; ++ ++ gt9xx@5d { ++ compatible = "goodix,gt928"; ++ reg = <0x5d>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_ts_pins>; ++ ++ reset-gpios = <&gpio5 8 GPIO_ACTIVE_HIGH>; ++ irq-gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>; ++ interrupt-parent = <&gpio5>; ++ interrupts = <9 IRQ_TYPE_EDGE_FALLING>; ++ ++ status = "okay"; /* Enable in LCD overlay */ ++ }; ++}; ++ ++&i2c3 { ++ clock-frequency = <400000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c3>; ++ status = "okay"; ++#ifndef SIMPLE_CARD ++ codec: nau8822@1a { ++ compatible = "nuvoton,nau8822"; ++ reg = <0x1a>; ++ clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_MCLK1>; /*mclk时钟*/ ++ clock-names = "mclk"; ++ }; ++#else ++ codec: nau8822@1a { ++ compatible = "nuvoton,nau8822"; ++ reg = <0x1a>; ++ #sound-dai-cells = <0>; ++ }; ++#endif ++}; ++ ++/*+--------------+ ++ | Audio Module | ++ +--------------+*/ ++&dsp { ++ status = "okay"; ++}; ++ ++&aud2htx { ++ status = "okay"; ++}; ++ ++&easrc { ++ fsl,asrc-rate = <48000>; ++ status = "okay"; ++}; ++#ifndef SIMPLE_CARD ++&sai3 { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_sai3>; ++ assigned-clocks = <&clk IMX8MP_CLK_SAI3>; ++ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>; ++ assigned-clock-rates = <12288000>; ++ fsl,sai-mclk-direction-output; ++ status = "okay"; ++}; ++#else ++&sai3 { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_sai3>; ++ assigned-clocks = <&clk IMX8MP_CLK_SAI3>; ++ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>; ++ // assigned-clock-rates = <24576000>; ++ assigned-clock-rates = <12288000>; /*48000*256 是 44100 * 2 * 16 的 2^n 倍数*/ ++ fsl,sai-mclk-direction-output; ++ status = "okay"; ++}; ++#endif ++ ++// &xcvr { ++// #sound-dai-cells = <0>; ++// status = "okay"; ++// }; ++ ++/*+---------------+ ++ | USB interface | ++ +---------------+*/ ++//USB1 ++&usb3_phy0 { ++ fsl,phy-tx-vref-tune = <0xe>; ++ fsl,phy-tx-preemp-amp-tune = <3>; ++ fsl,phy-tx-vboost-level = <5>; ++ fsl,phy-comp-dis-tune = <7>; ++ fsl,pcs-tx-deemph-3p5db = <0x21>; ++ fsl,phy-pcs-tx-swing-full = <0x7f>; ++ status = "okay"; ++}; ++ ++&usb3_0 { ++ status = "okay"; ++}; ++ ++#if 0 ++&usb_dwc3_0 { ++ dr_mode = "host";//应该otg,TODO:otg id未解决 ++ hnp-disable; ++ srp-disable; ++ adp-disable; ++ snps,usb2-lpm-disable; ++ // usb-role-switch; ++ // role-switch-default-mode = "none"; ++ // snps,dis-u1-entry-quirk; ++ // snps,dis-u2-entry-quirk; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_usb0_id_grp>; ++ // interrupts = <&gpio4 26 IRQ_TYPE_EDGE_BOTH>, ++ // <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;// interrupt 需增加修改 ++ // interrupt-names = "otg",""; ++ power-polarity-active-high;// ++ disable-over-current;// ++ status = "okay"; ++}; ++#else ++&usb_dwc3_0 { ++ dr_mode = "otg"; ++ hnp-disable; ++ srp-disable; ++ adp-disable; ++ status = "okay"; ++ extcon = <&extcon_dwc3>; ++}; ++#endif ++ ++/* USB2 for 4G or 5G module*/ ++&usb3_phy1 { ++ fsl,phy-tx-preemp-amp-tune = <3>; ++ fsl,phy-tx-vref-tune = <0xb>; ++ status = "okay"; ++}; ++ ++&usb3_1 { ++ status = "okay"; ++}; ++ ++&usb_dwc3_1 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++/*+------------------+ ++ | USDCHC interface | ++ +------------------+*/ ++&usdhc3 { ++ assigned-clocks = <&clk IMX8MP_CLK_USDHC3>; ++ assigned-clock-rates = <400000000>; ++ pinctrl-names = "default", "state_100mhz", "state_200mhz"; ++ pinctrl-0 = <&pinctrl_usdhc3>; ++ pinctrl-1 = <&pinctrl_usdhc3_100mhz>; ++ pinctrl-2 = <&pinctrl_usdhc3_200mhz>; ++ bus-width = <8>; ++ non-removable; ++ status = "okay"; ++}; ++ ++/*+----------------------+ ++ | Basic pinctrl iomuxc | ++ +----------------------+*/ ++&iomuxc { ++ pinctrl-names = "default"; ++ ++ pinctrl_backlight: backlightgrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_ECSPI1_SCLK__GPIO5_IO06 0x19 ++ >; ++ }; ++ ++ pinctrl_ts_pins: tsgrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_ECSPI1_MISO__GPIO5_IO08 0x17059 /* TouchScreen RST */ ++ MX8MP_IOMUXC_ECSPI1_SS0__GPIO5_IO09 0x17059 /* TouchScreen IRQ */ ++ >; ++ }; ++ ++ pinctrl_pwm2: pwm2grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_GPIO1_IO11__PWM2_OUT 0x116 ++ >; ++ }; ++ ++ pinctrl_eqos: eqosgrp { //T1 TODO: 和evk不一致 ++ fsl,pins = < ++ MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x3 ++ MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x3 ++ MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91 ++ MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91 ++ MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x91 ++ MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x91 ++ MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x91 ++ MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91 ++ MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f ++ MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f ++ MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x1f ++ MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x1f ++ MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f ++ MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1f ++ MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x19 ++ >; ++ }; ++ ++ pinctrl_fec: fecgrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x3 ++ MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x3 ++ MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x91 ++ MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x91 ++ MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x91 ++ MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x91 ++ MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x91 ++ MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x91 ++ MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x1f ++ MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x1f ++ MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x1f ++ MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x1f ++ MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x1f ++ MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x1f ++ MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02 0x19 ++ >; ++ }; ++ ++ pinctrl_flexspi0: flexspi0grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_NAND_ALE__FLEXSPI_A_SCLK 0x1c2 ++ MX8MP_IOMUXC_NAND_CE0_B__FLEXSPI_A_SS0_B 0x82 ++ MX8MP_IOMUXC_NAND_DATA00__FLEXSPI_A_DATA00 0x82 ++ MX8MP_IOMUXC_NAND_DATA01__FLEXSPI_A_DATA01 0x82 ++ MX8MP_IOMUXC_NAND_DATA02__FLEXSPI_A_DATA02 0x82 ++ MX8MP_IOMUXC_NAND_DATA03__FLEXSPI_A_DATA03 0x82 ++ >; ++ }; ++ ++ pinctrl_flexcan1: flexcan1grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_SPDIF_RX__CAN1_RX 0x154 ++ MX8MP_IOMUXC_SPDIF_TX__CAN1_TX 0x154 ++ >; ++ }; ++ ++ pinctrl_gpio_leds_group: gpioledsgrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x140 ++ MX8MP_IOMUXC_SD1_STROBE__GPIO2_IO11 0x140 ++ MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x140 ++ MX8MP_IOMUXC_SD2_DATA2__GPIO2_IO17 0x140 ++ MX8MP_IOMUXC_SAI5_MCLK__GPIO3_IO25 0x140 ++ MX8MP_IOMUXC_SAI5_RXFS__GPIO3_IO19 0x140 ++ >; ++ }; ++ ++ pinctrl_gpio_devs_group: gpiodevsgrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27 0x140 ++ MX8MP_IOMUXC_SAI2_TXC__GPIO4_IO25 0x154 ++ MX8MP_IOMUXC_SD2_DATA1__GPIO2_IO16 0x140 ++ MX8MP_IOMUXC_SD1_CMD__GPIO2_IO01 0x154 ++ >; ++ }; ++ ++ pinctrl_wwan_reg: wwanprowergrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_ECSPI2_SCLK__GPIO5_IO10 0x140 ++ >; ++ }; ++ ++ pinctrl_usb_host_reg: usbvbusgrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_ECSPI2_MISO__GPIO5_IO12 0x140 ++ >; ++ }; ++ ++ pinctrl_i2c1: i2c1grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c2 ++ MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c2 ++ >; ++ }; ++ ++ pinctrl_i2c2: i2c2grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c2 ++ MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c2 ++ >; ++ }; ++ ++ pinctrl_i2c3: i2c3grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c2 ++ MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c2 ++ >; ++ }; ++ ++ pinctrl_pmic: pmicgrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03 0x000001c0 ++ >; ++ }; ++ ++ pinctrl_sai3: sai3grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC 0xd6 ++ MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI3_TX_BCLK 0xd6 ++ MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI3_RX_DATA00 0xd6 ++ MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI3_TX_DATA00 0xd6 ++ MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SAI3_MCLK 0xd6 ++ MX8MP_IOMUXC_SAI3_RXFS__GPIO4_IO28 0xd6 ++ MX8MP_IOMUXC_SAI3_RXC__GPIO4_IO29 0xd6 ++ >; ++ }; ++ ++ pinctrl_uart2: uart2grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140 ++ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 ++ >; ++ }; ++ ++ pinctrl_uart1: uart1grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x140 ++ MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x140 ++ >; ++ }; ++ ++ pinctrl_usb0_id_grp: usb0grp{ ++ fsl,pins = < ++ MX8MP_IOMUXC_SAI2_TXD0__GPIO4_IO26 0x19 ++ >; ++ }; ++ ++ pinctrl_usdhc3: usdhc3grp { ++ fsl,pins = < ++ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190 ++ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d0 ++ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d0 ++ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d0 ++ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d0 ++ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d0 ++ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d0 ++ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d0 ++ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d0 ++ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d0 ++ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x190 ++ >; ++ }; ++ ++ pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x194 ++ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d4 ++ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d4 ++ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d4 ++ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d4 ++ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d4 ++ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d4 ++ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d4 ++ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d4 ++ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d4 ++ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x194 ++ >; ++ }; ++ ++ pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x196 ++ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d6 ++ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d6 ++ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d6 ++ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d6 ++ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d6 ++ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d6 ++ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d6 ++ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d6 ++ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d6 ++ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x196 ++ >; ++ }; ++ ++ pinctrl_wdog: wdoggrp { ++ fsl,pins = < ++ MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0x166 ++ >; ++ }; ++}; ++ ++/*+---------------+ ++ | Other Modules | ++ +---------------+*/ ++&vpu_g1 { ++ status = "okay"; ++}; ++ ++&vpu_g2 { ++ status = "okay"; ++}; ++ ++&vpu_vc8000e { ++ status = "okay"; ++}; ++ ++&vpu_v4l2 { ++ status = "okay"; ++}; ++ ++&gpu_3d { ++ status = "okay"; ++}; ++ ++&gpu_2d { ++ status = "okay"; ++}; ++ ++&ml_vipsi { ++ status = "okay"; ++}; ++ ++&mix_gpu_ml { ++ status = "okay"; ++}; ++ ++&cameradev { ++ status = "okay"; ++}; ++ ++&isi_0 { ++ status = "okay"; ++ ++ cap_device { ++ status = "okay"; ++ }; ++ ++ m2m_device { ++ status = "okay"; ++ }; ++}; ++ ++&isi_1 { ++ status = "disabled"; ++ ++ cap_device { ++ status = "okay"; ++ }; ++}; +diff --git a/arch/arm64/configs/gauguin-imx8mp_defconfig b/arch/arm64/configs/gauguin-imx8mp_defconfig +new file mode 100644 +index 000000000..d5f67800e +--- /dev/null ++++ b/arch/arm64/configs/gauguin-imx8mp_defconfig +@@ -0,0 +1,1034 @@ ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_AUDIT=y ++CONFIG_NO_HZ_IDLE=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_BPF_JIT=y ++CONFIG_PREEMPT=y ++CONFIG_IRQ_TIME_ACCOUNTING=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_NUMA_BALANCING=y ++CONFIG_MEMCG=y ++CONFIG_BLK_CGROUP=y ++CONFIG_CGROUP_PIDS=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CGROUP_HUGETLB=y ++CONFIG_CPUSETS=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_PERF=y ++CONFIG_NAMESPACES=y ++CONFIG_USER_NS=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_SYSFS_DEPRECATED=y ++CONFIG_SYSFS_DEPRECATED_V2=y ++CONFIG_RELAY=y ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_KALLSYMS_ALL=y ++CONFIG_EMBEDDED=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_PROFILING=y ++CONFIG_ARCH_LAYERSCAPE=y ++CONFIG_ARCH_KEEMBAY=y ++CONFIG_ARCH_MXC=y ++CONFIG_ARCH_S32=y ++CONFIG_SOC_S32V234=y ++CONFIG_ARM64_VA_BITS_48=y ++CONFIG_SCHED_MC=y ++CONFIG_SCHED_SMT=y ++CONFIG_NUMA=y ++CONFIG_KEXEC=y ++CONFIG_KEXEC_FILE=y ++CONFIG_CRASH_DUMP=y ++CONFIG_XEN=y ++CONFIG_FORCE_MAX_ZONEORDER=14 ++CONFIG_COMPAT=y ++CONFIG_RANDOMIZE_BASE=y ++CONFIG_PM_DEBUG=y ++CONFIG_PM_TEST_SUSPEND=y ++CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y ++CONFIG_ENERGY_MODEL=y ++CONFIG_ARM_CPUIDLE=y ++CONFIG_ARM_PSCI_CPUIDLE=y ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_STAT=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y ++CONFIG_CPUFREQ_DT=y ++CONFIG_ACPI_CPPC_CPUFREQ=m ++CONFIG_ARM_SCPI_CPUFREQ=y ++CONFIG_ARM_IMX_CPUFREQ_DT=y ++CONFIG_ARM_SCMI_CPUFREQ=y ++CONFIG_QORIQ_CPUFREQ=y ++CONFIG_ACPI=y ++CONFIG_ACPI_APEI=y ++CONFIG_ACPI_APEI_GHES=y ++CONFIG_ACPI_APEI_MEMORY_FAILURE=y ++CONFIG_ACPI_APEI_EINJ=y ++CONFIG_VIRTUALIZATION=y ++CONFIG_KVM=y ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM64_CE=y ++CONFIG_CRYPTO_SHA2_ARM64_CE=y ++CONFIG_CRYPTO_SHA512_ARM64_CE=m ++CONFIG_CRYPTO_SHA3_ARM64=m ++CONFIG_CRYPTO_SM3_ARM64_CE=m ++CONFIG_CRYPTO_GHASH_ARM64_CE=y ++CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m ++CONFIG_CRYPTO_AES_ARM64_CE_CCM=y ++CONFIG_CRYPTO_AES_ARM64_CE_BLK=y ++CONFIG_CRYPTO_CHACHA20_NEON=m ++CONFIG_CRYPTO_AES_ARM64_BS=m ++CONFIG_JUMP_LABEL=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++CONFIG_KSM=y ++CONFIG_MEMORY_FAILURE=y ++CONFIG_TRANSPARENT_HUGEPAGE=y ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_TLS=y ++CONFIG_TLS_DEVICE=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++CONFIG_IPV6_SIT=m ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK_EVENTS=y ++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_IP_NF_IPTABLES=m ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP6_NF_NAT=m ++CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_BRIDGE=y ++CONFIG_BRIDGE_VLAN_FILTERING=y ++CONFIG_NET_DSA=m ++CONFIG_NET_DSA_TAG_OCELOT=m ++CONFIG_NET_DSA_TAG_OCELOT_8021Q=m ++CONFIG_VLAN_8021Q_GVRP=y ++CONFIG_VLAN_8021Q_MVRP=y ++CONFIG_LLC2=y ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_MULTIQ=m ++CONFIG_NET_SCH_CBS=m ++CONFIG_NET_SCH_ETF=m ++CONFIG_NET_SCH_TAPRIO=m ++CONFIG_NET_SCH_MQPRIO=m ++CONFIG_NET_SCH_INGRESS=m ++CONFIG_NET_CLS_BASIC=m ++CONFIG_NET_CLS_TCINDEX=m ++CONFIG_NET_CLS_FLOWER=m ++CONFIG_NET_CLS_ACT=y ++CONFIG_NET_ACT_GACT=m ++CONFIG_NET_ACT_MIRRED=m ++CONFIG_NET_ACT_GATE=m ++CONFIG_TSN=y ++CONFIG_QRTR=m ++CONFIG_QRTR_SMD=m ++CONFIG_QRTR_TUN=m ++CONFIG_NET_PKTGEN=m ++CONFIG_CAN=m ++CONFIG_CAN_FLEXCAN=m ++CONFIG_BT=y ++CONFIG_BT_RFCOMM=y ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=y ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=y ++CONFIG_BT_LEDS=y ++# CONFIG_BT_DEBUGFS is not set ++CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIUART=y ++CONFIG_BT_HCIUART_BCSP=y ++CONFIG_BT_HCIUART_ATH3K=y ++CONFIG_BT_HCIUART_LL=y ++CONFIG_BT_HCIUART_3WIRE=y ++CONFIG_BT_HCIUART_BCM=y ++CONFIG_BT_HCIUART_QCA=y ++CONFIG_BT_HCIVHCI=y ++CONFIG_CFG80211=y ++CONFIG_NL80211_TESTMODE=y ++CONFIG_CFG80211_WEXT=y ++CONFIG_MAC80211=y ++CONFIG_MAC80211_LEDS=y ++CONFIG_NET_9P=y ++CONFIG_NET_9P_VIRTIO=y ++CONFIG_NFC=m ++CONFIG_NFC_NCI=m ++CONFIG_NFC_S3FWRN5_I2C=m ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_FW_LOADER_USER_HELPER=y ++CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y ++CONFIG_BRCMSTB_GISB_ARB=y ++CONFIG_VEXPRESS_CONFIG=y ++CONFIG_FSL_MC_UAPI_SUPPORT=y ++CONFIG_ARM_SCMI_PROTOCOL=y ++CONFIG_ARM_SCPI_PROTOCOL=y ++CONFIG_EFI_CAPSULE_LOADER=y ++CONFIG_IMX_DSP=y ++CONFIG_IMX_SCU=y ++CONFIG_IMX_SCU_PD=y ++CONFIG_GNSS=m ++CONFIG_GNSS_MTK_SERIAL=m ++CONFIG_MTD=y ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_CFI_ADV_OPTIONS=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_PHYSMAP=y ++CONFIG_MTD_PHYSMAP_OF=y ++CONFIG_MTD_DATAFLASH=y ++CONFIG_MTD_SST25L=y ++CONFIG_MTD_RAW_NAND=y ++CONFIG_MTD_NAND_DENALI_DT=y ++CONFIG_MTD_NAND_GPMI_NAND=y ++CONFIG_MTD_NAND_FSL_IFC=y ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++CONFIG_MTD_UBI=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_NBD=m ++CONFIG_XEN_BLKDEV_BACKEND=m ++CONFIG_VIRTIO_BLK=y ++CONFIG_SRAM=y ++CONFIG_EEPROM_AT24=m ++CONFIG_EEPROM_AT25=m ++CONFIG_UACCE=m ++CONFIG_RAID_ATTRS=m ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_SCSI_SAS_ATA=y ++CONFIG_SCSI_HISI_SAS=y ++CONFIG_SCSI_UFSHCD=y ++CONFIG_SCSI_UFSHCD_PLATFORM=y ++CONFIG_ATA=y ++CONFIG_SATA_AHCI_PLATFORM=y ++CONFIG_AHCI_IMX=y ++CONFIG_AHCI_CEVA=y ++CONFIG_AHCI_XGENE=y ++CONFIG_AHCI_QORIQ=y ++CONFIG_PATA_PLATFORM=y ++CONFIG_PATA_OF_PLATFORM=y ++CONFIG_MD=y ++CONFIG_BLK_DEV_MD=m ++CONFIG_BLK_DEV_DM=m ++CONFIG_DM_CRYPT=m ++CONFIG_DM_MIRROR=m ++CONFIG_DM_ZERO=m ++CONFIG_NETDEVICES=y ++CONFIG_MACVLAN=m ++CONFIG_MACVTAP=m ++CONFIG_TUN=y ++CONFIG_VETH=m ++CONFIG_VIRTIO_NET=y ++CONFIG_AMD_XGBE=y ++CONFIG_BCMGENET=m ++CONFIG_MACB=y ++CONFIG_FEC=y ++CONFIG_FEC_UIO=y ++CONFIG_FSL_FMAN=y ++CONFIG_FSL_DPAA_ETH=y ++CONFIG_FSL_DPAA2_ETH=y ++CONFIG_FSL_DPAA2_MAC=y ++CONFIG_FSL_DPAA2_SWITCH=y ++CONFIG_FSL_ENETC_IERB=y ++CONFIG_HIX5HD2_GMAC=y ++CONFIG_HNS_DSAF=y ++CONFIG_HNS_ENET=y ++CONFIG_MVMDIO=y ++CONFIG_MSCC_OCELOT_SWITCH=y ++CONFIG_QCOM_EMAC=m ++CONFIG_RMNET=m ++CONFIG_SMC91X=y ++CONFIG_SMSC911X=y ++CONFIG_STMMAC_ETH=y ++CONFIG_DWMAC_GENERIC=m ++CONFIG_AQUANTIA_PHY=y ++CONFIG_BROADCOM_PHY=m ++CONFIG_BCM54140_PHY=m ++CONFIG_INPHI_PHY=y ++CONFIG_MARVELL_PHY=m ++CONFIG_MARVELL_10G_PHY=m ++CONFIG_MICREL_PHY=y ++CONFIG_MICROSEMI_PHY=y ++CONFIG_NXP_TJA11XX_PHY=y ++CONFIG_AT803X_PHY=y ++CONFIG_REALTEK_PHY=y ++CONFIG_ROCKCHIP_PHY=y ++CONFIG_VITESSE_PHY=y ++CONFIG_MDIO_BITBANG=y ++CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y ++CONFIG_MDIO_BUS_MUX_MMIOREG=y ++CONFIG_PPP=y ++CONFIG_PPP_BSDCOMP=y ++CONFIG_PPP_DEFLATE=y ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_MPPE=y ++CONFIG_PPP_MULTILINK=y ++CONFIG_PPPOE=y ++CONFIG_PPP_ASYNC=y ++CONFIG_PPP_SYNC_TTY=y ++CONFIG_SLIP=y ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_RTL8152=y ++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_NCM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SR9800=m ++CONFIG_USB_NET_SMSC75XX=m ++CONFIG_USB_NET_SMSC95XX=m ++CONFIG_USB_NET_NET1080=m ++CONFIG_USB_NET_PLUSB=m ++CONFIG_USB_NET_MCS7830=m ++CONFIG_USB_NET_CDC_SUBSET=m ++CONFIG_USB_NET_ZAURUS=m ++CONFIG_USB_NET_QMI_WWAN=y ++CONFIG_HOSTAP=y ++CONFIG_WL18XX=m ++CONFIG_WLCORE_SDIO=m ++CONFIG_XEN_NETDEV_BACKEND=m ++CONFIG_INPUT_EVDEV=y ++CONFIG_KEYBOARD_ADC=m ++CONFIG_KEYBOARD_GPIO=y ++CONFIG_KEYBOARD_RPMSG=y ++CONFIG_KEYBOARD_SNVS_PWRKEY=y ++CONFIG_KEYBOARD_BBNSM_PWRKEY=y ++CONFIG_KEYBOARD_IMX_SC_PWRKEY=y ++CONFIG_KEYBOARD_CROS_EC=y ++CONFIG_INPUT_TOUCHSCREEN=y ++CONFIG_TOUCHSCREEN_ATMEL_MXT=m ++CONFIG_TOUCHSCREEN_EXC3000=m ++CONFIG_TOUCHSCREEN_GOODIX=m ++CONFIG_TOUCHSCREEN_EDT_FT5X06=m ++CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_I2C=m ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_PWM_VIBRA=m ++# CONFIG_SERIO_SERPORT is not set ++CONFIG_SERIO_AMBAKMI=y ++CONFIG_LEGACY_PTY_COUNT=16 ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_SERIAL_IMX=y ++CONFIG_SERIAL_IMX_CONSOLE=y ++CONFIG_SERIAL_XILINX_PS_UART=y ++CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y ++CONFIG_SERIAL_FSL_LPUART=y ++CONFIG_SERIAL_FSL_LPUART_CONSOLE=y ++CONFIG_SERIAL_FSL_LINFLEXUART=y ++CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y ++CONFIG_SERIAL_DEV_BUS=y ++CONFIG_VIRTIO_CONSOLE=y ++CONFIG_IPMI_HANDLER=m ++CONFIG_IPMI_DEVICE_INTERFACE=m ++CONFIG_IPMI_SI=m ++CONFIG_TCG_TPM=y ++CONFIG_TCG_TIS_I2C_INFINEON=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++CONFIG_I2C_MUX_PCA954x=y ++CONFIG_I2C_DESIGNWARE_PLATFORM=y ++CONFIG_I2C_GPIO=m ++CONFIG_I2C_IMX=y ++CONFIG_I2C_IMX_LPI2C=y ++CONFIG_I2C_RK3X=y ++CONFIG_I2C_RPBUS=y ++CONFIG_I2C_CROS_EC_TUNNEL=y ++CONFIG_XEN_I2C_BACKEND=y ++CONFIG_I3C=y ++CONFIG_SVC_I3C_MASTER=y ++CONFIG_SPI=y ++CONFIG_SPI_CADENCE_QUADSPI=y ++CONFIG_SPI_DESIGNWARE=m ++CONFIG_SPI_DW_DMA=y ++CONFIG_SPI_DW_MMIO=m ++CONFIG_SPI_FSL_LPSPI=y ++CONFIG_SPI_FSL_QUADSPI=y ++CONFIG_SPI_NXP_FLEXSPI=y ++CONFIG_SPI_IMX=y ++CONFIG_SPI_FSL_DSPI=y ++CONFIG_SPI_PL022=y ++CONFIG_SPI_ROCKCHIP=y ++CONFIG_SPI_SPIDEV=y ++CONFIG_SPI_SLAVE=y ++CONFIG_SPI_SLAVE_TIME=y ++CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y ++CONFIG_SPMI=y ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_PINCTRL_MAX77620=y ++CONFIG_PINCTRL_IMX8MM=y ++CONFIG_PINCTRL_IMX8MN=y ++CONFIG_PINCTRL_IMX8MP=y ++CONFIG_PINCTRL_IMX8MQ=y ++CONFIG_PINCTRL_IMX8QM=y ++CONFIG_PINCTRL_IMX8QXP=y ++CONFIG_PINCTRL_IMX8DXL=y ++CONFIG_PINCTRL_IMX8ULP=y ++CONFIG_PINCTRL_IMX93=y ++CONFIG_PINCTRL_S32V234=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_ALTERA=m ++CONFIG_GPIO_DWAPB=y ++CONFIG_GPIO_MB86S7X=y ++CONFIG_GPIO_MPC8XXX=y ++CONFIG_GPIO_PL061=y ++CONFIG_GPIO_IMX_RPMSG=y ++CONFIG_GPIO_WCD934X=m ++CONFIG_GPIO_XGENE=y ++CONFIG_GPIO_MAX732X=y ++CONFIG_GPIO_PCA953X=y ++CONFIG_GPIO_PCA953X_IRQ=y ++CONFIG_GPIO_ADP5585=y ++CONFIG_GPIO_BD9571MWV=m ++CONFIG_GPIO_MAX77620=y ++CONFIG_GPIO_SL28CPLD=m ++CONFIG_POWER_RESET_BRCMSTB=y ++CONFIG_POWER_RESET_XGENE=y ++CONFIG_POWER_RESET_SYSCON=y ++CONFIG_SYSCON_REBOOT_MODE=y ++CONFIG_BATTERY_SBS=m ++CONFIG_BATTERY_BQ27XXX=y ++CONFIG_BATTERY_MAX17042=m ++CONFIG_CHARGER_BQ25890=m ++CONFIG_CHARGER_BQ25980=m ++CONFIG_SENSORS_ARM_SCMI=y ++CONFIG_SENSORS_ARM_SCPI=y ++CONFIG_SENSORS_FP9931=y ++CONFIG_SENSORS_LM90=m ++CONFIG_SENSORS_PWM_FAN=m ++CONFIG_SENSORS_SL28CPLD=m ++CONFIG_SENSORS_INA2XX=m ++CONFIG_SENSORS_INA3221=m ++CONFIG_THERMAL_WRITABLE_TRIPS=y ++CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y ++CONFIG_CPU_THERMAL=y ++CONFIG_THERMAL_EMULATION=y ++CONFIG_IMX_SC_THERMAL=y ++CONFIG_IMX8MM_THERMAL=y ++CONFIG_DEVICE_THERMAL=y ++CONFIG_QORIQ_THERMAL=y ++CONFIG_WATCHDOG=y ++CONFIG_SL28CPLD_WATCHDOG=m ++CONFIG_ARM_SP805_WATCHDOG=y ++CONFIG_ARM_SBSA_WATCHDOG=y ++CONFIG_DW_WATCHDOG=y ++CONFIG_IMX2_WDT=y ++CONFIG_IMX_SC_WDT=y ++CONFIG_IMX7ULP_WDT=y ++CONFIG_ARM_SMC_WATCHDOG=y ++CONFIG_XEN_WDT=y ++CONFIG_MFD_ADP5585=y ++CONFIG_MFD_BD9571MWV=y ++CONFIG_MFD_AXP20X_I2C=y ++CONFIG_MFD_IMX_MIX=y ++CONFIG_MFD_HI6421_PMIC=y ++CONFIG_MFD_FP9931=y ++CONFIG_MFD_MAX77620=y ++CONFIG_MFD_MT6397=y ++CONFIG_MFD_RK808=y ++CONFIG_MFD_SEC_CORE=y ++CONFIG_MFD_SL28CPLD=y ++CONFIG_MFD_ROHM_BD718XX=y ++CONFIG_MFD_WCD934X=m ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++CONFIG_REGULATOR_AXP20X=y ++CONFIG_REGULATOR_BD718XX=y ++CONFIG_REGULATOR_BD9571MWV=y ++CONFIG_REGULATOR_FAN53555=y ++CONFIG_REGULATOR_GPIO=y ++CONFIG_REGULATOR_HI6421V530=y ++CONFIG_REGULATOR_MAX77620=y ++CONFIG_REGULATOR_MAX8973=y ++CONFIG_REGULATOR_FP9931=y ++CONFIG_REGULATOR_MP8859=y ++CONFIG_REGULATOR_MT6358=y ++CONFIG_REGULATOR_MT6397=y ++CONFIG_REGULATOR_PCA9450=y ++CONFIG_REGULATOR_PF8X00=y ++CONFIG_REGULATOR_PFUZE100=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_REGULATOR_QCOM_SPMI=y ++CONFIG_REGULATOR_RK808=y ++CONFIG_REGULATOR_S2MPS11=y ++CONFIG_REGULATOR_TPS65132=m ++CONFIG_REGULATOR_VCTRL=m ++CONFIG_RC_CORE=m ++CONFIG_RC_DECODERS=y ++CONFIG_IR_NEC_DECODER=m ++CONFIG_IR_RC5_DECODER=m ++CONFIG_IR_RC6_DECODER=m ++CONFIG_IR_JVC_DECODER=m ++CONFIG_IR_SONY_DECODER=m ++CONFIG_IR_SANYO_DECODER=m ++CONFIG_IR_SHARP_DECODER=m ++CONFIG_IR_MCE_KBD_DECODER=m ++CONFIG_IR_XMP_DECODER=m ++CONFIG_IR_IMON_DECODER=m ++CONFIG_IR_RCMM_DECODER=m ++CONFIG_RC_DEVICES=y ++CONFIG_IR_GPIO_CIR=m ++CONFIG_MEDIA_SUPPORT=y ++CONFIG_MEDIA_SUPPORT_FILTER=y ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_MEDIA_ANALOG_TV_SUPPORT=y ++CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y ++CONFIG_MEDIA_SDR_SUPPORT=y ++CONFIG_MEDIA_PLATFORM_SUPPORT=y ++# CONFIG_DVB_NET is not set ++CONFIG_MEDIA_USB_SUPPORT=y ++CONFIG_USB_VIDEO_CLASS=m ++CONFIG_V4L_PLATFORM_DRIVERS=y ++CONFIG_VIDEO_IMX8_JPEG=m ++CONFIG_VIDEO_AMPHION_VPU=y ++CONFIG_VIDEO_MXC_CAPTURE=y ++CONFIG_VIDEO_MX8_CAPTURE=y ++CONFIG_VIDEO_MXC_CSI_CAMERA=y ++CONFIG_MXC_MIPI_CSI=y ++CONFIG_MXC_CAMERA_OV5640_MIPI_V2=y ++CONFIG_V4L_MEM2MEM_DRIVERS=y ++CONFIG_SDR_PLATFORM_DRIVERS=y ++CONFIG_VIDEO_IMX219=m ++CONFIG_VIDEO_OV5640=y ++CONFIG_VIDEO_OV5645=m ++CONFIG_VIDEO_MT9M114=y ++CONFIG_VIDEO_AP1302=y ++CONFIG_IMX_DPU_CORE=y ++CONFIG_IMX_LCDIF_CORE=y ++CONFIG_IMX_LCDIFV3_CORE=y ++CONFIG_DRM=y ++CONFIG_DRM_I2C_CH7006=m ++CONFIG_DRM_I2C_SIL164=m ++CONFIG_DRM_I2C_NXP_TDA998X=m ++CONFIG_DRM_MALI_DISPLAY=m ++CONFIG_DRM_RCAR_DW_HDMI=m ++CONFIG_DRM_RCAR_LVDS=m ++CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m ++CONFIG_DRM_PANEL_LVDS=m ++CONFIG_DRM_PANEL_SIMPLE=y ++CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m ++CONFIG_DRM_PANEL_ONTAT_KD50G21_40NT_A1=y ++CONFIG_DRM_PANEL_RAYDIUM_RM67191=y ++CONFIG_DRM_PANEL_RAYDIUM_RM68200=y ++CONFIG_DRM_PANEL_ROCKTECK_HIMAX8394F=y ++CONFIG_DRM_PANEL_SEIKO_43WVF1G=y ++CONFIG_DRM_PANEL_SITRONIX_ST7703=m ++CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m ++CONFIG_DRM_PANEL_WKS_101WX001=y ++CONFIG_DRM_DISPLAY_CONNECTOR=m ++CONFIG_DRM_LONTIUM_LT8912B=m ++CONFIG_DRM_LONTIUM_LT9611=m ++CONFIG_DRM_LONTIUM_LT9611UXC=m ++CONFIG_DRM_FSL_IMX_LVDS_BRIDGE=y ++CONFIG_DRM_NWL_MIPI_DSI=y ++CONFIG_DRM_NXP_SEIKO_43WVFIG=y ++CONFIG_DRM_PARADE_PS8640=m ++CONFIG_DRM_SII902X=m ++CONFIG_DRM_SIMPLE_BRIDGE=m ++CONFIG_DRM_THINE_THC63LVD1024=m ++CONFIG_DRM_TI_SN65DSI86=m ++CONFIG_DRM_I2C_ADV7511=y ++CONFIG_DRM_I2C_ADV7511_AUDIO=y ++CONFIG_DRM_CDNS_HDCP=y ++CONFIG_DRM_DW_HDMI_AHB_AUDIO=m ++CONFIG_DRM_DW_HDMI_I2S_AUDIO=m ++CONFIG_DRM_DW_HDMI_GP_AUDIO=y ++CONFIG_DRM_DW_HDMI_CEC=m ++CONFIG_DRM_ITE_IT6263=y ++CONFIG_DRM_ITE_IT6161=y ++CONFIG_DRM_IMX=y ++CONFIG_DRM_IMX_LCDIF_MUX_DISPLAY=y ++CONFIG_DRM_IMX_PARALLEL_DISPLAY=y ++CONFIG_DRM_IMX_TVE=y ++CONFIG_DRM_IMX_LDB=y ++CONFIG_DRM_IMX8QM_LDB=y ++CONFIG_DRM_IMX8QXP_LDB=y ++CONFIG_DRM_IMX8MP_LDB=y ++CONFIG_DRM_IMX93_LDB=y ++CONFIG_DRM_IMX93_PARALLEL_DISPLAY_FORMAT=y ++CONFIG_DRM_IMX_DW_MIPI_DSI=y ++CONFIG_DRM_IMX_HDMI=y ++CONFIG_DRM_IMX_SEC_DSIM=y ++CONFIG_DRM_IMX_DCNANO=y ++CONFIG_DRM_IMX_DCSS=y ++CONFIG_DRM_IMX_CDNS_MHDP=y ++CONFIG_DRM_ETNAVIV=m ++CONFIG_DRM_HISI_KIRIN=m ++CONFIG_DRM_MXSFB=y ++CONFIG_DRM_PL111=m ++CONFIG_DRM_LIMA=m ++CONFIG_DRM_PANFROST=m ++CONFIG_DRM_LEGACY=y ++CONFIG_FB=y ++CONFIG_FB_ARMCLCD=y ++CONFIG_FB_EFI=y ++CONFIG_FB_MXC_EINK_V2_PANEL=y ++CONFIG_BACKLIGHT_PWM=y ++CONFIG_BACKLIGHT_LP855X=m ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++# CONFIG_LOGO_LINUX_MONO is not set ++# CONFIG_LOGO_LINUX_VGA16 is not set ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_SND_ALOOP=m ++CONFIG_SND_USB_AUDIO=m ++CONFIG_SND_SOC=y ++CONFIG_SND_SOC_FSL_ASRC=m ++CONFIG_SND_SOC_FSL_MQS=m ++CONFIG_SND_SOC_FSL_MICFIL=m ++CONFIG_SND_SOC_FSL_EASRC=m ++CONFIG_SND_SOC_FSL_XCVR=m ++CONFIG_SND_SOC_FSL_ESAI_CLIENT=y ++CONFIG_SND_SOC_FSL_RPMSG=m ++CONFIG_SND_IMX_SOC=m ++CONFIG_SND_SOC_IMX_SGTL5000=m ++CONFIG_SND_SOC_IMX_SPDIF=m ++CONFIG_SND_SOC_FSL_ASOC_CARD=m ++CONFIG_SND_SOC_IMX_AUDMIX=m ++CONFIG_SND_SOC_IMX_HDMI=m ++CONFIG_SND_SOC_IMX_CARD=m ++CONFIG_SND_SOC_IMX_PDM_MIC=m ++CONFIG_SND_SOC_IMX_PCM512X=m ++CONFIG_SND_SOC_SOF_TOPLEVEL=y ++CONFIG_SND_SOC_SOF_OF=m ++CONFIG_SND_SOC_SOF_IMX_TOPLEVEL=y ++CONFIG_SND_SOC_SOF_IMX8=m ++CONFIG_SND_SOC_SOF_IMX8M=m ++CONFIG_SND_SOC_SOF_IMX8ULP=m ++CONFIG_SND_SOC_AK4613=m ++CONFIG_SND_SOC_BT_SCO=y ++CONFIG_SND_SOC_CROS_EC_CODEC=m ++CONFIG_SND_SOC_CS42XX8_I2C=y ++CONFIG_SND_SOC_DMIC=m ++CONFIG_SND_SOC_ES7134=m ++CONFIG_SND_SOC_ES7241=m ++CONFIG_SND_SOC_GTM601=m ++CONFIG_SND_SOC_MAX98357A=m ++CONFIG_SND_SOC_MAX98927=m ++CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m ++CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m ++CONFIG_SND_SOC_PCM3168A_I2C=m ++CONFIG_SND_SOC_RT5659=m ++CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m ++CONFIG_SND_SOC_SIMPLE_MUX=m ++CONFIG_SND_SOC_SPDIF=m ++CONFIG_SND_SOC_TAS571X=m ++CONFIG_SND_SOC_WCD934X=m ++CONFIG_SND_SOC_WM8524=y ++CONFIG_SND_SOC_WM8904=m ++CONFIG_SND_SOC_WM8960=m ++CONFIG_SND_SOC_WM8962=m ++CONFIG_SND_SOC_WSA881X=m ++CONFIG_SND_SOC_RPMSG_WM8960=m ++CONFIG_SND_SOC_RPMSG_AK4497=m ++CONFIG_SND_SOC_NAU8810=m ++CONFIG_SND_SOC_NAU8822=m ++CONFIG_SND_SOC_LPASS_WSA_MACRO=m ++CONFIG_SND_SOC_LPASS_VA_MACRO=m ++CONFIG_SND_SIMPLE_CARD=y ++CONFIG_SND_AUDIO_GRAPH_CARD=y ++CONFIG_HID_A4TECH=y ++CONFIG_HID_APPLE=y ++CONFIG_HID_BELKIN=y ++CONFIG_HID_CHERRY=y ++CONFIG_HID_CHICONY=y ++CONFIG_HID_CYPRESS=y ++CONFIG_HID_EZKEY=y ++CONFIG_HID_ITE=y ++CONFIG_HID_KENSINGTON=y ++CONFIG_HID_LOGITECH=y ++CONFIG_HID_REDRAGON=y ++CONFIG_HID_MICROSOFT=y ++CONFIG_HID_MONTEREY=y ++CONFIG_HID_MULTITOUCH=m ++CONFIG_I2C_HID_ACPI=m ++CONFIG_I2C_HID_OF=m ++CONFIG_USB_CONN_GPIO=y ++CONFIG_USB=y ++CONFIG_USB_OTG=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PCI_RENESAS=m ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_HCD_PLATFORM=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_HCD_PLATFORM=y ++CONFIG_USB_HCD_TEST_MODE=y ++CONFIG_USB_ACM=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_UAS=y ++CONFIG_USB_CDNS_SUPPORT=y ++CONFIG_USB_CDNS3=y ++CONFIG_USB_CDNS3_GADGET=y ++CONFIG_USB_CDNS3_HOST=y ++CONFIG_USB_MUSB_HDRC=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC2=y ++CONFIG_USB_CHIPIDEA=y ++CONFIG_USB_CHIPIDEA_UDC=y ++CONFIG_USB_CHIPIDEA_HOST=y ++CONFIG_USB_ISP1760=y ++CONFIG_USB_SERIAL=y ++CONFIG_USB_SERIAL_CONSOLE=y ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_SIMPLE=y ++CONFIG_USB_SERIAL_CP210X=m ++CONFIG_USB_SERIAL_FTDI_SIO=y ++CONFIG_USB_SERIAL_QUALCOMM=y ++CONFIG_USB_SERIAL_OPTION=y ++CONFIG_USB_TEST=m ++CONFIG_USB_EHSET_TEST_FIXTURE=y ++CONFIG_USB_HSIC_USB3503=y ++CONFIG_NOP_USB_XCEIV=y ++CONFIG_USB_MXS_PHY=y ++CONFIG_USB_ULPI=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_SNP_UDC_PLAT=y ++CONFIG_USB_BDC_UDC=y ++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_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_UAC1_LEGACY=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_ZERO=m ++CONFIG_USB_AUDIO=m ++CONFIG_USB_ETH=m ++CONFIG_USB_MASS_STORAGE=m ++CONFIG_USB_G_SERIAL=m ++CONFIG_TYPEC=y ++CONFIG_TYPEC_TCPM=y ++CONFIG_TYPEC_TCPCI=y ++CONFIG_TYPEC_FUSB302=m ++CONFIG_TYPEC_TPS6598X=m ++CONFIG_TYPEC_HD3SS3220=m ++CONFIG_TYPEC_SWITCH_GPIO=y ++CONFIG_MMC=y ++CONFIG_MMC_BLOCK_MINORS=32 ++CONFIG_MMC_ARMMMCI=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_OF_ARASAN=y ++CONFIG_MMC_SDHCI_OF_ESDHC=y ++CONFIG_MMC_SDHCI_CADENCE=y ++CONFIG_MMC_SDHCI_ESDHC_IMX=y ++CONFIG_MMC_SDHCI_F_SDH30=y ++CONFIG_MMC_SPI=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_EXYNOS=y ++CONFIG_MMC_DW_HI3798CV200=y ++CONFIG_MMC_DW_K3=y ++CONFIG_MMC_MTK=y ++CONFIG_MMC_SDHCI_XENON=y ++CONFIG_MMC_SDHCI_AM654=y ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_LM3692X=m ++CONFIG_LEDS_PCA9532=m ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_PCA995X=m ++CONFIG_LEDS_PWM=y ++CONFIG_LEDS_SYSCON=y ++CONFIG_LEDS_TRIGGER_TIMER=y ++CONFIG_LEDS_TRIGGER_DISK=y ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++CONFIG_LEDS_TRIGGER_CPU=y ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++CONFIG_LEDS_TRIGGER_PANIC=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_DRV_DS1307=m ++CONFIG_RTC_DRV_HYM8563=m ++CONFIG_RTC_DRV_MAX77686=y ++CONFIG_RTC_DRV_RK808=m ++CONFIG_RTC_DRV_PCF85363=m ++CONFIG_RTC_DRV_M41T80=m ++CONFIG_RTC_DRV_RX8581=m ++CONFIG_RTC_DRV_RV3028=m ++CONFIG_RTC_DRV_RV8803=m ++CONFIG_RTC_DRV_S5M=y ++CONFIG_RTC_DRV_DS3232=y ++CONFIG_RTC_DRV_PCF2127=m ++CONFIG_RTC_DRV_EFI=y ++CONFIG_RTC_DRV_CROS_EC=y ++CONFIG_RTC_DRV_FSL_FTM_ALARM=m ++CONFIG_RTC_DRV_PL031=y ++CONFIG_RTC_DRV_SNVS=y ++CONFIG_RTC_DRV_BBNSM=y ++CONFIG_RTC_DRV_IMX_SC=y ++CONFIG_RTC_DRV_IMX_RPMSG=y ++CONFIG_DMADEVICES=y ++CONFIG_BCM_SBA_RAID=m ++CONFIG_FSL_EDMA=y ++CONFIG_FSL_QDMA=m ++CONFIG_FSL_EDMA_V3=y ++CONFIG_IMX_SDMA=y ++CONFIG_MV_XOR_V2=y ++CONFIG_MXS_DMA=y ++CONFIG_MXC_PXP_V3=y ++CONFIG_PL330_DMA=y ++CONFIG_QCOM_HIDMA_MGMT=y ++CONFIG_QCOM_HIDMA=y ++CONFIG_FSL_DPAA2_QDMA=m ++CONFIG_DMATEST=y ++CONFIG_DMABUF_HEAPS=y ++CONFIG_DMABUF_HEAPS_SYSTEM=y ++CONFIG_DMABUF_HEAPS_CMA=y ++CONFIG_DMABUF_HEAPS_DSP=y ++CONFIG_VFIO=y ++CONFIG_VFIO_FSL_MC=y ++CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_MMIO=y ++CONFIG_XEN_GNTDEV=y ++CONFIG_XEN_GRANT_DEV_ALLOC=y ++CONFIG_STAGING=y ++CONFIG_STAGING_MEDIA=y ++CONFIG_VIDEO_HANTRO=m ++CONFIG_VIDEO_IMX_CAPTURE=y ++CONFIG_IMX8_MEDIA_DEVICE=m ++CONFIG_MHDP_HDMIRX=y ++CONFIG_MHDP_HDMIRX_CEC=y ++CONFIG_FSL_DPAA2=y ++CONFIG_FSL_PPFE=y ++CONFIG_FSL_PPFE_UTIL_DISABLED=y ++CONFIG_ETHOSU=y ++CONFIG_CHROME_PLATFORMS=y ++CONFIG_CROS_EC=y ++CONFIG_CROS_EC_I2C=y ++CONFIG_CROS_EC_SPI=y ++CONFIG_CROS_EC_CHARDEV=m ++CONFIG_CLK_VEXPRESS_OSC=y ++CONFIG_COMMON_CLK_RK808=y ++CONFIG_COMMON_CLK_SCMI=y ++CONFIG_COMMON_CLK_SCPI=y ++CONFIG_COMMON_CLK_CS2000_CP=y ++CONFIG_COMMON_CLK_FSL_SAI=y ++CONFIG_COMMON_CLK_S2MPS11=y ++CONFIG_COMMON_CLK_XGENE=y ++CONFIG_COMMON_CLK_PWM=y ++CONFIG_COMMON_CLK_VC5=y ++CONFIG_CLK_IMX8MM=y ++CONFIG_CLK_IMX8MN=y ++CONFIG_CLK_IMX8MP=y ++CONFIG_CLK_IMX8MQ=y ++CONFIG_CLK_IMX8QXP=y ++CONFIG_CLK_IMX8ULP=y ++CONFIG_CLK_IMX93=y ++CONFIG_HWSPINLOCK=y ++CONFIG_ARM_MHU=y ++CONFIG_IMX_MBOX=y ++CONFIG_PLATFORM_MHU=y ++CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y ++CONFIG_ARM_SMMU=y ++CONFIG_ARM_SMMU_V3=y ++CONFIG_REMOTEPROC=y ++CONFIG_IMX_REMOTEPROC=y ++CONFIG_IMX_DSP_REMOTEPROC=m ++CONFIG_RPMSG_CHAR=m ++CONFIG_RPMSG_QCOM_GLINK_RPM=y ++CONFIG_SOUNDWIRE=m ++CONFIG_SOUNDWIRE_QCOM=m ++CONFIG_SOC_BRCMSTB=y ++CONFIG_FSL_DPAA=y ++CONFIG_FSL_MC_DPIO=y ++CONFIG_FSL_RCPM=y ++CONFIG_FSL_QIXIS=y ++CONFIG_SOC_TI=y ++CONFIG_EXTCON_PTN5150=m ++CONFIG_EXTCON_USB_GPIO=y ++CONFIG_EXTCON_USBC_CROS_EC=y ++CONFIG_IIO=y ++CONFIG_FXLS8962AF_I2C=m ++CONFIG_IMX8QXP_ADC=y ++CONFIG_IMX93_ADC=y ++CONFIG_MAX9611=m ++CONFIG_QCOM_SPMI_VADC=m ++CONFIG_QCOM_SPMI_ADC5=m ++CONFIG_IIO_CROS_EC_SENSORS_CORE=m ++CONFIG_IIO_CROS_EC_SENSORS=m ++CONFIG_FXAS21002C=y ++CONFIG_FXOS8700_I2C=y ++CONFIG_RPMSG_IIO_PEDOMETER=m ++CONFIG_IIO_ST_LSM6DSX=y ++CONFIG_IIO_CROS_EC_LIGHT_PROX=m ++CONFIG_SENSORS_ISL29018=y ++CONFIG_VCNL4000=m ++CONFIG_IIO_ST_MAGN_3AXIS=m ++CONFIG_IIO_CROS_EC_BARO=m ++CONFIG_MPL3115=y ++CONFIG_PWM=y ++CONFIG_PWM_ADP5585=y ++CONFIG_PWM_CROS_EC=m ++CONFIG_PWM_FSL_FTM=m ++CONFIG_PWM_IMX27=y ++CONFIG_PWM_RPCHIP=y ++CONFIG_PWM_SL28CPLD=m ++CONFIG_SL28CPLD_INTC=y ++CONFIG_RESET_IMX7=y ++CONFIG_RESET_IMX8ULP_SIM=y ++CONFIG_PHY_XGENE=y ++CONFIG_PHY_MIXEL_LVDS=y ++CONFIG_PHY_MIXEL_LVDS_COMBO=y ++CONFIG_PHY_CADENCE_SALVO=y ++CONFIG_PHY_FSL_IMX8MP_LVDS=y ++CONFIG_PHY_FSL_IMX93_MIPI_DPHY=y ++CONFIG_PHY_MIXEL_MIPI_DPHY=y ++CONFIG_PHY_SAMSUNG_HDMI_PHY=y ++CONFIG_PHY_QCOM_USB_HS=y ++CONFIG_PHY_SAMSUNG_USB2=y ++CONFIG_ARM_SMMU_V3_PMU=m ++CONFIG_FSL_IMX8_DDR_PMU=y ++CONFIG_FSL_IMX9_DDR_PMU=y ++CONFIG_HISI_PMU=y ++CONFIG_NVMEM_IMX_OCOTP=y ++CONFIG_NVMEM_IMX_OCOTP_SCU=y ++CONFIG_NVMEM_RMEM=m ++CONFIG_FPGA=y ++CONFIG_FPGA_BRIDGE=m ++CONFIG_ALTERA_FREEZE_BRIDGE=m ++CONFIG_FPGA_REGION=m ++CONFIG_OF_FPGA_REGION=m ++CONFIG_TEE=y ++CONFIG_OPTEE=y ++CONFIG_MUX_MMIO=y ++CONFIG_SLIM_QCOM_CTRL=m ++CONFIG_MXC_SIM=y ++CONFIG_MXC_EMVSIM=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_BTRFS_FS=m ++CONFIG_BTRFS_FS_POSIX_ACL=y ++CONFIG_FANOTIFY=y ++CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y ++CONFIG_QUOTA=y ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_CUSE=m ++CONFIG_OVERLAY_FS=m ++CONFIG_VFAT_FS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_HUGETLBFS=y ++CONFIG_EFIVAR_FS=y ++CONFIG_JFFS2_FS=y ++CONFIG_UBIFS_FS=y ++CONFIG_SQUASHFS=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_V4_1=y ++CONFIG_NFS_V4_2=y ++CONFIG_ROOT_NFS=y ++CONFIG_9P_FS=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_TRUSTED_KEYS=m ++# CONFIG_TRUSTED_KEYS_TPM is not set ++# CONFIG_TRUSTED_KEYS_TEE is not set ++CONFIG_SECURITY=y ++CONFIG_CRYPTO_USER=y ++CONFIG_CRYPTO_TEST=m ++CONFIG_CRYPTO_DH=m ++CONFIG_CRYPTO_CURVE25519=m ++CONFIG_CRYPTO_CHACHA20POLY1305=m ++CONFIG_CRYPTO_ECHAINIV=y ++CONFIG_CRYPTO_TLS=m ++CONFIG_CRYPTO_CFB=m ++CONFIG_CRYPTO_CTS=m ++CONFIG_CRYPTO_LRW=m ++CONFIG_CRYPTO_OFB=m ++CONFIG_CRYPTO_PCBC=m ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_VMAC=m ++CONFIG_CRYPTO_MD4=m ++CONFIG_CRYPTO_RMD160=m ++CONFIG_CRYPTO_STREEBOG=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_ANUBIS=m ++CONFIG_CRYPTO_ARC4=m ++CONFIG_CRYPTO_BLOWFISH=m ++CONFIG_CRYPTO_CAMELLIA=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_CAST6=m ++CONFIG_CRYPTO_FCRYPT=m ++CONFIG_CRYPTO_KHAZAD=m ++CONFIG_CRYPTO_SEED=m ++CONFIG_CRYPTO_SERPENT=m ++CONFIG_CRYPTO_TEA=m ++CONFIG_CRYPTO_TWOFISH=m ++CONFIG_CRYPTO_ANSI_CPRNG=y ++CONFIG_CRYPTO_USER_API_HASH=m ++CONFIG_CRYPTO_USER_API_SKCIPHER=m ++CONFIG_CRYPTO_USER_API_RNG=m ++CONFIG_CRYPTO_USER_API_AEAD=m ++CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=m ++CONFIG_CRYPTO_DEV_FSL_CAAM=m ++CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=m ++CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=m ++CONFIG_CRYPTO_DEV_CCREE=m ++CONFIG_CRYPTO_DEV_HISI_TRNG=m ++CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m ++CONFIG_INDIRECT_PIO=y ++CONFIG_CRC8=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_IRQ_POLL=y ++CONFIG_PRINTK_TIME=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_INFO_REDUCED=y ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_FS=y ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_DEBUG_PREEMPT is not set ++# CONFIG_FTRACE is not set ++CONFIG_CORESIGHT=y ++CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y ++CONFIG_CORESIGHT_SOURCE_ETM4X=y ++CONFIG_MEMTEST=y +diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c +index 47e1a2a60..1dde096b7 100644 +--- a/drivers/gpu/drm/panel/panel-simple.c ++++ b/drivers/gpu/drm/panel/panel-simple.c +@@ -1234,6 +1234,31 @@ static const struct panel_desc auo_g101evn010 = { + .connector_type = DRM_MODE_CONNECTOR_LVDS, + }; + ++/* add by datasheet*/ ++static const struct drm_display_mode auo_g101ean02_mode = { ++ .clock = 74250, ++ .hdisplay = 1280, ++ .hsync_start = 1280 + 100, ++ .hsync_end = 1280 + 100 + 20, ++ .htotal = 1280 + 100 + 20 + 80, ++ .vdisplay = 800, ++ .vsync_start = 800 + 18, ++ .vsync_end = 800 + 18 + 6, ++ .vtotal = 800 + 18 + 6 + 12, ++}; ++ ++static const struct panel_desc auo_g101ean02 = { ++ .modes = &auo_g101ean02_mode, ++ .num_modes = 1, ++ .bpc = 8, ++ .size = { ++ .width = 228, ++ .height = 148, ++ }, ++ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, ++ .connector_type = DRM_MODE_CONNECTOR_LVDS, ++}; ++ + static const struct drm_display_mode auo_g104sn02_mode = { + .clock = 40000, + .hdisplay = 800, +@@ -4583,6 +4608,9 @@ static const struct of_device_id platform_of_match[] = { + }, { + .compatible = "auo,g101evn010", + .data = &auo_g101evn010, ++ }, { ++ .compatible = "auo,g101ean02", ++ .data = &auo_g101ean02, + }, { + .compatible = "auo,g104sn02", + .data = &auo_g104sn02, +diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig +index 8939e5fbd..1b2430047 100644 +--- a/drivers/net/usb/Kconfig ++++ b/drivers/net/usb/Kconfig +@@ -644,4 +644,11 @@ config USB_RTL8153_ECM + CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not + supported by r8152 driver. + ++config USB_GOBI_NET ++ tristate"Gobi USB Net driver for Quectel module" ++ help ++ Support Quectelmodule. ++ A modemmanager with support for GobiNet is recommended. ++ Tocompile this driver as a module, choose M here: the module will be calledGobiNet. ++ + endif # USB_NET_DRIVERS +diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile +index 4964f7b32..e34d3d112 100644 +--- a/drivers/net/usb/Makefile ++++ b/drivers/net/usb/Makefile +@@ -37,8 +37,11 @@ obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o + obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o + obj-$(CONFIG_USB_NET_HUAWEI_CDC_NCM) += huawei_cdc_ncm.o + obj-$(CONFIG_USB_VL600) += lg-vl600.o ++obj-$(CONFIG_USB_NET_QMI_WWAN) += qmi_wwan_q.o + obj-$(CONFIG_USB_NET_QMI_WWAN) += qmi_wwan.o + obj-$(CONFIG_USB_NET_CDC_MBIM) += cdc_mbim.o + obj-$(CONFIG_USB_NET_CH9200) += ch9200.o + obj-$(CONFIG_USB_NET_AQC111) += aqc111.o + obj-$(CONFIG_USB_RTL8153_ECM) += r8153_ecm.o ++# obj-$(CONFIG_USB_GOBI_NET) += GobiNet.o ++# GobiNet-objs := qmap.o GobiUSBNet.o QMIDevice.o QMI.o +diff --git a/drivers/net/usb/qmi_wwan_q.c b/drivers/net/usb/qmi_wwan_q.c +new file mode 100644 +index 000000000..5b9c9ac18 +--- /dev/null ++++ b/drivers/net/usb/qmi_wwan_q.c +@@ -0,0 +1,2577 @@ ++/* ++ * Copyright (c) 2012 Bjørn Mork <bjorn@mork.no> ++ * ++ * The probing code is heavily inspired by cdc_ether, which is: ++ * Copyright (C) 2003-2005 by David Brownell ++ * Copyright (C) 2006 by Ole Andre Vadla Ravnas (ActiveSync) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ */ ++ ++#include <linux/module.h> ++#include <linux/version.h> ++#include <linux/interrupt.h> ++#include <linux/netdevice.h> ++#include <linux/ethtool.h> ++#include <linux/etherdevice.h> ++#include <linux/time.h> ++#if LINUX_VERSION_CODE > KERNEL_VERSION(3,16,0) //8b094cd03b4a3793220d8d8d86a173bfea8c285b ++#include <linux/timekeeping.h> ++#else ++#define timespec64 timespec ++#define ktime_get_ts64 ktime_get_ts ++#define timespec64_sub timespec_sub ++#endif ++#include <net/arp.h> ++#include <net/ip.h> ++#include <net/ipv6.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/usb/cdc.h> ++#include <linux/usb/usbnet.h> ++#include <linux/usb/cdc-wdm.h> ++ ++#ifndef ETH_P_MAP ++#define ETH_P_MAP 0xDA1A ++#endif ++ ++#if (ETH_P_MAP == 0x00F9) ++#undef ETH_P_MAP ++#define ETH_P_MAP 0xDA1A ++#endif ++ ++#ifndef ARPHRD_RAWIP ++#define ARPHRD_RAWIP ARPHRD_NONE ++#endif ++ ++#ifdef CONFIG_PINCTRL_IPQ807x ++#define CONFIG_QCA_NSS_DRV ++//#define CONFIG_QCA_NSS_PACKET_FILTER ++#endif ++ ++#define _RMNET_NSS_H_ ++#define _RMENT_NSS_H_ ++struct rmnet_nss_cb { ++ int (*nss_create)(struct net_device *dev); ++ int (*nss_free)(struct net_device *dev); ++ int (*nss_tx)(struct sk_buff *skb); ++}; ++static struct rmnet_nss_cb __read_mostly *nss_cb = NULL; ++#if defined(CONFIG_PINCTRL_IPQ807x) || defined(CONFIG_PINCTRL_IPQ5018) ++#ifdef CONFIG_RMNET_DATA ++#define CONFIG_QCA_NSS_DRV ++/* define at qsdk/qca/src/linux-4.4/net/rmnet_data/rmnet_data_main.c */ ++/* set at qsdk/qca/src/data-kernel/drivers/rmnet-nss/rmnet_nss.c */ ++extern struct rmnet_nss_cb *rmnet_nss_callbacks __rcu __read_mostly; ++#endif ++#endif ++ ++/* This driver supports wwan (3G/LTE/?) devices using a vendor ++ * specific management protocol called Qualcomm MSM Interface (QMI) - ++ * in addition to the more common AT commands over serial interface ++ * management ++ * ++ * QMI is wrapped in CDC, using CDC encapsulated commands on the ++ * control ("master") interface of a two-interface CDC Union ++ * resembling standard CDC ECM. The devices do not use the control ++ * interface for any other CDC messages. Most likely because the ++ * management protocol is used in place of the standard CDC ++ * notifications NOTIFY_NETWORK_CONNECTION and NOTIFY_SPEED_CHANGE ++ * ++ * Alternatively, control and data functions can be combined in a ++ * single USB interface. ++ * ++ * Handling a protocol like QMI is out of the scope for any driver. ++ * It is exported as a character device using the cdc-wdm driver as ++ * a subdriver, enabling userspace applications ("modem managers") to ++ * handle it. ++ * ++ * These devices may alternatively/additionally be configured using AT ++ * commands on a serial interface ++ */ ++#define VERSION_NUMBER "V1.2.2" ++#define QUECTEL_WWAN_VERSION "Quectel_Linux&Android_QMI_WWAN_Driver_"VERSION_NUMBER ++static const char driver_name[] = "qmi_wwan_q"; ++ ++/* driver specific data */ ++struct qmi_wwan_state { ++ struct usb_driver *subdriver; ++ atomic_t pmcount; ++ unsigned long unused; ++ struct usb_interface *control; ++ struct usb_interface *data; ++}; ++ ++/* default ethernet address used by the modem */ ++static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3}; ++ ++#if 1 //Added by Quectel ++/* ++ Quectel_WCDMA<E_Linux_USB_Driver_User_Guide_V1.9.pdf ++ 5.6. Test QMAP on GobiNet or QMI WWAN ++ 0 - no QMAP ++ 1 - QMAP (Aggregation protocol) ++ X - QMAP (Multiplexing and Aggregation protocol) ++*/ ++#define QUECTEL_WWAN_QMAP 4 //MAX is 7 ++ ++#if defined(QUECTEL_WWAN_QMAP) ++#define QUECTEL_QMAP_MUX_ID 0x81 ++ ++static uint __read_mostly qmap_mode = 0; ++module_param( qmap_mode, uint, S_IRUGO); ++module_param_named( rx_qmap, qmap_mode, uint, S_IRUGO ); ++#endif ++ ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) || defined(CONFIG_BRIDGE_LAN) ++#define QUECTEL_BRIDGE_MODE ++#endif ++ ++#ifdef QUECTEL_BRIDGE_MODE ++static uint __read_mostly bridge_mode = 0/*|BIT(1)*/; ++module_param( bridge_mode, uint, S_IRUGO ); ++#endif ++ ++#ifdef CONFIG_BRIDGE_LAN ++static const u8 broadcast_mac_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++#endif ++ ++//#define QMI_NETDEV_ONE_CARD_MODE ++static uint __read_mostly one_card_mode = 0; ++ ++#if defined(QUECTEL_WWAN_QMAP) ++#define QUECTEL_UL_DATA_AGG 1 ++ ++#if defined(QUECTEL_UL_DATA_AGG) ++struct tx_agg_ctx { ++ /* QMIWDS_ADMIN_SET_DATA_FORMAT_RESP TLV_0x17 and TLV_0x18 */ ++ uint ul_data_aggregation_max_datagrams; //UplinkDataAggregationMaxDatagramsTlv ++ uint ul_data_aggregation_max_size; //UplinkDataAggregationMaxSizeTlv ++ uint dl_minimum_padding; //0x1A ++}; ++#endif ++ ++typedef struct { ++ unsigned int size; ++ unsigned int rx_urb_size; ++ unsigned int ep_type; ++ unsigned int iface_id; ++ unsigned int qmap_mode; ++ unsigned int qmap_version; ++ unsigned int dl_minimum_padding; ++ char ifname[8][16]; ++ unsigned char mux_id[8]; ++} RMNET_INFO; ++ ++typedef struct sQmiWwanQmap ++{ ++ struct usbnet *mpNetDev; ++ struct driver_info driver_info; ++ atomic_t refcount; ++ struct net_device *mpQmapNetDev[QUECTEL_WWAN_QMAP]; ++ uint link_state; ++ uint qmap_mode; ++ uint qmap_size; ++ uint qmap_version; ++ ++#if defined(QUECTEL_UL_DATA_AGG) ++ struct tx_agg_ctx tx_ctx; ++ struct tasklet_struct txq; ++ struct tasklet_struct usbnet_bh; ++#endif ++ ++#ifdef QUECTEL_BRIDGE_MODE ++ uint bridge_mode; ++ uint bridge_ipv4; ++ unsigned char bridge_mac[ETH_ALEN]; ++#ifdef CONFIG_BRIDGE_LAN ++ unsigned char bridge_self_mac[ETH_ALEN]; ++#endif ++#endif ++ uint use_rmnet_usb; ++ RMNET_INFO rmnet_info; ++} sQmiWwanQmap; ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(3,13,0) //8f84985fec10de64a6b4cdfea45f2b0ab8f07c78 ++#define MHI_NETDEV_STATUS64 ++#endif ++struct qmap_priv { ++ struct usbnet *dev; ++ struct net_device *real_dev; ++ struct net_device *self_dev; ++ u8 offset_id; ++ u8 mux_id; ++ u8 qmap_version; // 5~v1, 9~v5 ++ u8 link_state; ++ ++#if defined(MHI_NETDEV_STATUS64) ++ struct pcpu_sw_netstats __percpu *stats64; ++#endif ++ ++ spinlock_t agg_lock; ++ struct sk_buff *agg_skb; ++ unsigned agg_count; ++ struct timespec64 agg_time; ++ struct hrtimer agg_hrtimer; ++ struct work_struct agg_wq; ++ ++#ifdef QUECTEL_BRIDGE_MODE ++ uint bridge_mode; ++ uint bridge_ipv4; ++ unsigned char bridge_mac[ETH_ALEN]; ++#ifdef CONFIG_BRIDGE_LAN ++ unsigned char bridge_self_mac[ETH_ALEN]; ++#endif ++#endif ++ uint use_qca_nss; ++}; ++ ++struct qmap_hdr { ++ u8 cd_rsvd_pad; ++ u8 mux_id; ++ u16 pkt_len; ++} __packed; ++ ++enum rmnet_map_v5_header_type { ++ RMNET_MAP_HEADER_TYPE_UNKNOWN, ++ RMNET_MAP_HEADER_TYPE_COALESCING = 0x1, ++ RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD = 0x2, ++ RMNET_MAP_HEADER_TYPE_ENUM_LENGTH ++}; ++ ++/* Main QMAP header */ ++struct rmnet_map_header { ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++ u8 pad_len:6; ++ u8 next_hdr:1; ++ u8 cd_bit:1; ++#elif defined (__BIG_ENDIAN_BITFIELD) ++ u8 cd_bit:1; ++ u8 next_hdr:1; ++ u8 pad_len:6; ++#else ++#error "Please fix <asm/byteorder.h>" ++#endif ++ u8 mux_id; ++ __be16 pkt_len; ++} __aligned(1); ++ ++/* QMAP v5 headers */ ++struct rmnet_map_v5_csum_header { ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++ u8 next_hdr:1; ++ u8 header_type:7; ++ u8 hw_reserved:7; ++ u8 csum_valid_required:1; ++#elif defined (__BIG_ENDIAN_BITFIELD) ++ u8 header_type:7; ++ u8 next_hdr:1; ++ u8 csum_valid_required:1; ++ u8 hw_reserved:7; ++#else ++#error "Please fix <asm/byteorder.h>" ++#endif ++ __be16 reserved; ++} __aligned(1); ++ ++#ifdef QUECTEL_BRIDGE_MODE ++static int is_qmap_netdev(const struct net_device *netdev); ++#endif ++#endif ++ ++static const struct driver_info rmnet_usb_info; ++ ++#ifdef QUECTEL_BRIDGE_MODE ++static int bridge_arp_reply(struct net_device *net, struct sk_buff *skb, uint bridge_ipv4) { ++ struct arphdr *parp; ++ u8 *arpptr, *sha; ++ u8 sip[4], tip[4], ipv4[4]; ++ struct sk_buff *reply = NULL; ++ ++ ipv4[0] = (bridge_ipv4 >> 24) & 0xFF; ++ ipv4[1] = (bridge_ipv4 >> 16) & 0xFF; ++ ipv4[2] = (bridge_ipv4 >> 8) & 0xFF; ++ ipv4[3] = (bridge_ipv4 >> 0) & 0xFF; ++ ++ parp = arp_hdr(skb); ++ ++ if (parp->ar_hrd == htons(ARPHRD_ETHER) && parp->ar_pro == htons(ETH_P_IP) ++ && parp->ar_op == htons(ARPOP_REQUEST) && parp->ar_hln == 6 && parp->ar_pln == 4) { ++ arpptr = (u8 *)parp + sizeof(struct arphdr); ++ sha = arpptr; ++ arpptr += net->addr_len; /* sha */ ++ memcpy(sip, arpptr, sizeof(sip)); ++ arpptr += sizeof(sip); ++ arpptr += net->addr_len; /* tha */ ++ memcpy(tip, arpptr, sizeof(tip)); ++ ++ pr_info("%s sip = %d.%d.%d.%d, tip=%d.%d.%d.%d, ipv4=%d.%d.%d.%d\n", netdev_name(net), ++ sip[0], sip[1], sip[2], sip[3], tip[0], tip[1], tip[2], tip[3], ipv4[0], ipv4[1], ipv4[2], ipv4[3]); ++ //wwan0 sip = 10.151.137.255, tip=10.151.138.0, ipv4=10.151.137.255 ++ if (tip[0] == ipv4[0] && tip[1] == ipv4[1] && (tip[2]&0xFC) == (ipv4[2]&0xFC) && tip[3] != ipv4[3]) ++ reply = arp_create(ARPOP_REPLY, ETH_P_ARP, *((__be32 *)sip), net, *((__be32 *)tip), sha, default_modem_addr, sha); ++ ++ if (reply) { ++ skb_reset_mac_header(reply); ++ __skb_pull(reply, skb_network_offset(reply)); ++ reply->ip_summed = CHECKSUM_UNNECESSARY; ++ reply->pkt_type = PACKET_HOST; ++ ++ netif_rx_ni(reply); ++ } ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static struct sk_buff *bridge_mode_tx_fixup(struct net_device *net, struct sk_buff *skb, uint bridge_ipv4, unsigned char *bridge_mac) { ++ struct ethhdr *ehdr; ++ const struct iphdr *iph; ++ ++ skb_reset_mac_header(skb); ++ ehdr = eth_hdr(skb); ++ ++ if (ehdr->h_proto == htons(ETH_P_ARP)) { ++ if (bridge_ipv4) ++ bridge_arp_reply(net, skb, bridge_ipv4); ++ return NULL; ++ } ++ ++ iph = ip_hdr(skb); ++ //DBG("iphdr: "); ++ //PrintHex((void *)iph, sizeof(struct iphdr)); ++ ++// 1 0.000000000 0.0.0.0 255.255.255.255 DHCP 362 DHCP Request - Transaction ID 0xe7643ad7 ++ if (ehdr->h_proto == htons(ETH_P_IP) && iph->protocol == IPPROTO_UDP && iph->saddr == 0x00000000 && iph->daddr == 0xFFFFFFFF) { ++ //if (udp_hdr(skb)->dest == htons(67)) //DHCP Request ++ { ++ memcpy(bridge_mac, ehdr->h_source, ETH_ALEN); ++ pr_info("%s PC Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n", netdev_name(net), ++ bridge_mac[0], bridge_mac[1], bridge_mac[2], bridge_mac[3], bridge_mac[4], bridge_mac[5]); ++ } ++ } ++ ++#ifdef CONFIG_BRIDGE_LAN ++ //bridge Lan IP 192.168.0.0 ++ if (ehdr->h_proto == htons(ETH_P_IP) && (iph->daddr & 0xFFFF) == 0xA8C0) ++ { ++ struct sk_buff *reply = skb_copy(skb, GFP_ATOMIC); ++ ehdr = eth_hdr(reply); ++ ++ memcpy(ehdr->h_source, default_modem_addr, ETH_ALEN); ++ if(is_qmap_netdev(net)) ++ { ++ struct qmap_priv *priv = netdev_priv(net); ++ memcpy(ehdr->h_dest, priv->bridge_self_mac, ETH_ALEN); ++ } ++ else ++ { ++ struct usbnet * usbnetdev = netdev_priv(net); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ memcpy(ehdr->h_dest, pQmapDev->bridge_self_mac, ETH_ALEN); ++ } ++ ++ //pr_info("%s br rx pkt addr: %02x:%02x:%02x:%02x:%02x:%02x -> %02x:%02x:%02x:%02x:%02x:%02x\n", netdev_name(net), ++ // ehdr->h_source[0], ehdr->h_source[1], ehdr->h_source[2], ehdr->h_source[3], ehdr->h_source[4], ehdr->h_source[5], ++ // ehdr->h_dest[0], ehdr->h_dest[1], ehdr->h_dest[2], ehdr->h_dest[3], ehdr->h_dest[4], ehdr->h_dest[5]); ++ ++ skb_reset_mac_header(reply); ++ __skb_pull(reply, skb_network_offset(reply)); ++ reply->ip_summed = CHECKSUM_UNNECESSARY; ++ reply->pkt_type = PACKET_HOST; ++ netif_rx_ni(reply); ++ return NULL; ++ } ++#endif ++ ++ if (memcmp(ehdr->h_source, bridge_mac, ETH_ALEN)) { ++ return NULL; ++ } ++ ++ return skb; ++} ++ ++static void bridge_mode_rx_fixup(sQmiWwanQmap *pQmapDev, struct net_device *net, struct sk_buff *skb) { ++ uint bridge_mode = 0; ++ unsigned char *bridge_mac; ++ ++ if (pQmapDev->qmap_mode > 1 || pQmapDev->use_rmnet_usb == 1) { ++ struct qmap_priv *priv = netdev_priv(net); ++ bridge_mode = priv->bridge_mode; ++ bridge_mac = priv->bridge_mac; ++ } ++ else { ++ bridge_mode = pQmapDev->bridge_mode; ++ bridge_mac = pQmapDev->bridge_mac; ++ } ++ ++ if (bridge_mode) ++ memcpy(eth_hdr(skb)->h_dest, bridge_mac, ETH_ALEN); ++ else ++ memcpy(eth_hdr(skb)->h_dest, net->dev_addr, ETH_ALEN); ++} ++#endif ++ ++#if defined(QUECTEL_WWAN_QMAP) ++static ssize_t qmap_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { ++ struct net_device *netdev = to_net_dev(dev); ++ struct usbnet * usbnetdev = netdev_priv( netdev ); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ ++ return snprintf(buf, PAGE_SIZE, "%d\n", pQmapDev->qmap_mode); ++} ++ ++static DEVICE_ATTR(qmap_mode, S_IRUGO, qmap_mode_show, NULL); ++ ++static ssize_t qmap_size_show(struct device *dev, struct device_attribute *attr, char *buf) { ++ struct net_device *netdev = to_net_dev(dev); ++ struct usbnet * usbnetdev = netdev_priv( netdev ); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ ++ return snprintf(buf, PAGE_SIZE, "%u\n", pQmapDev->qmap_size); ++} ++ ++static DEVICE_ATTR(qmap_size, S_IRUGO, qmap_size_show, NULL); ++ ++static ssize_t link_state_show(struct device *dev, struct device_attribute *attr, char *buf) { ++ struct net_device *netdev = to_net_dev(dev); ++ struct usbnet * usbnetdev = netdev_priv( netdev ); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ ++ return snprintf(buf, PAGE_SIZE, "0x%x\n", pQmapDev->link_state); ++} ++ ++static ssize_t link_state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { ++ struct net_device *netdev = to_net_dev(dev); ++ struct usbnet * usbnetdev = netdev_priv( netdev ); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ unsigned link_state = 0; ++ unsigned old_link = pQmapDev->link_state; ++ uint offset_id = 0; ++ ++ link_state = simple_strtoul(buf, NULL, 0); ++ ++ if (pQmapDev->qmap_mode == 1) { ++ pQmapDev->link_state = !!link_state; ++ } ++ else if (pQmapDev->qmap_mode > 1) { ++ offset_id = ((link_state&0x7F) - 1); ++ ++ if (offset_id >= pQmapDev->qmap_mode) { ++ dev_info(dev, "%s offset_id is %d. but qmap_mode is %d\n", __func__, offset_id, pQmapDev->qmap_mode); ++ return count; ++ } ++ ++ if (link_state&0x80) ++ pQmapDev->link_state &= ~(1 << offset_id); ++ else ++ pQmapDev->link_state |= (1 << offset_id); ++ } ++ ++ if (old_link != pQmapDev->link_state) { ++ struct net_device *qmap_net = pQmapDev->mpQmapNetDev[offset_id]; ++ ++ if (usbnetdev->net->flags & IFF_UP) { ++ if (pQmapDev->link_state) { ++ netif_carrier_on(usbnetdev->net); ++ } ++ } ++ ++ if (qmap_net && qmap_net != netdev) { ++ struct qmap_priv *priv = netdev_priv(qmap_net); ++ ++ priv->link_state = !!(pQmapDev->link_state & (1 << offset_id)); ++ ++ if (qmap_net->flags & IFF_UP) { ++ if (priv->link_state) { ++ netif_carrier_on(qmap_net); ++ if (netif_queue_stopped(qmap_net) && !netif_queue_stopped(usbnetdev->net)) ++ netif_wake_queue(qmap_net); ++ } ++ else { ++ netif_carrier_off(qmap_net); ++ } ++ } ++ } ++ ++ if (usbnetdev->net->flags & IFF_UP) { ++ if (!pQmapDev->link_state) { ++ netif_carrier_off(usbnetdev->net); ++ } ++ } ++ ++ dev_info(dev, "link_state 0x%x -> 0x%x\n", old_link, pQmapDev->link_state); ++ } ++ ++ return count; ++} ++ ++#ifdef QUECTEL_BRIDGE_MODE ++static ssize_t bridge_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { ++ struct net_device *netdev = to_net_dev(dev); ++ uint old_mode = 0; ++ uint bridge_mode = simple_strtoul(buf, NULL, 0); ++ ++ if (netdev->type != ARPHRD_ETHER) { ++ return count; ++ } ++ ++ if (is_qmap_netdev(netdev)) { ++ struct qmap_priv *priv = netdev_priv(netdev); ++ old_mode = priv->bridge_mode; ++ priv->bridge_mode = bridge_mode; ++ } ++ else { ++ struct usbnet * usbnetdev = netdev_priv( netdev ); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ old_mode = pQmapDev->bridge_mode; ++ pQmapDev->bridge_mode = bridge_mode; ++ } ++ ++ if (old_mode != bridge_mode) { ++ dev_info(dev, "bridge_mode change to 0x%x\n", bridge_mode); ++ } ++ ++ return count; ++} ++ ++static ssize_t bridge_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { ++ struct net_device *netdev = to_net_dev(dev); ++ uint bridge_mode = 0; ++ ++ if (is_qmap_netdev(netdev)) { ++ struct qmap_priv *priv = netdev_priv(netdev); ++ bridge_mode = priv->bridge_mode; ++ } ++ else { ++ struct usbnet * usbnetdev = netdev_priv( netdev ); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ bridge_mode = pQmapDev->bridge_mode; ++ } ++ ++ return snprintf(buf, PAGE_SIZE, "%u\n", bridge_mode); ++} ++ ++static ssize_t bridge_ipv4_show(struct device *dev, struct device_attribute *attr, char *buf) { ++ struct net_device *netdev = to_net_dev(dev); ++ unsigned int bridge_ipv4 = 0; ++ unsigned char ipv4[4]; ++ ++ if (is_qmap_netdev(netdev)) { ++ struct qmap_priv *priv = netdev_priv(netdev); ++ bridge_ipv4 = priv->bridge_ipv4; ++ } ++ else { ++ struct usbnet * usbnetdev = netdev_priv( netdev ); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ bridge_ipv4 = pQmapDev->bridge_ipv4; ++ } ++ ++ ipv4[0] = (bridge_ipv4 >> 24) & 0xFF; ++ ipv4[1] = (bridge_ipv4 >> 16) & 0xFF; ++ ipv4[2] = (bridge_ipv4 >> 8) & 0xFF; ++ ipv4[3] = (bridge_ipv4 >> 0) & 0xFF; ++ ++ return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n", ipv4[0], ipv4[1], ipv4[2], ipv4[3]); ++} ++ ++static ssize_t bridge_ipv4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { ++ struct net_device *netdev = to_net_dev(dev); ++ ++ if (is_qmap_netdev(netdev)) { ++ struct qmap_priv *priv = netdev_priv(netdev); ++ priv->bridge_ipv4 = simple_strtoul(buf, NULL, 16); ++ } ++ else { ++ struct usbnet * usbnetdev = netdev_priv( netdev ); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ pQmapDev->bridge_ipv4 = simple_strtoul(buf, NULL, 16); ++ } ++ ++ return count; ++} ++#endif ++ ++static DEVICE_ATTR(link_state, S_IWUSR | S_IRUGO, link_state_show, link_state_store); ++#ifdef QUECTEL_BRIDGE_MODE ++static DEVICE_ATTR(bridge_mode, S_IWUSR | S_IRUGO, bridge_mode_show, bridge_mode_store); ++static DEVICE_ATTR(bridge_ipv4, S_IWUSR | S_IRUGO, bridge_ipv4_show, bridge_ipv4_store); ++#endif ++ ++static struct attribute *qmi_wwan_sysfs_attrs[] = { ++ &dev_attr_link_state.attr, ++ &dev_attr_qmap_mode.attr, ++ &dev_attr_qmap_size.attr, ++#ifdef QUECTEL_BRIDGE_MODE ++ &dev_attr_bridge_mode.attr, ++ &dev_attr_bridge_ipv4.attr, ++#endif ++ NULL, ++}; ++ ++static struct attribute_group qmi_wwan_sysfs_attr_group = { ++ .attrs = qmi_wwan_sysfs_attrs, ++}; ++ ++#ifdef QUECTEL_BRIDGE_MODE ++static struct attribute *qmi_qmap_sysfs_attrs[] = { ++ &dev_attr_bridge_mode.attr, ++ &dev_attr_bridge_ipv4.attr, ++ NULL, ++}; ++ ++static struct attribute_group qmi_qmap_sysfs_attr_group = { ++ .attrs = qmi_qmap_sysfs_attrs, ++}; ++#endif ++ ++static int qmap_open(struct net_device *qmap_net) ++{ ++ struct qmap_priv *priv = netdev_priv(qmap_net); ++ struct net_device *real_dev = priv->real_dev; ++ ++ //printk("%s %s real_dev %d %d %d %d+++\n", __func__, dev->name, ++ // netif_carrier_ok(real_dev), netif_queue_stopped(real_dev), netif_carrier_ok(dev), netif_queue_stopped(dev)); ++ ++ if (!(priv->real_dev->flags & IFF_UP)) ++ return -ENETDOWN; ++ ++ if (priv->link_state) { ++ netif_carrier_on(real_dev); ++ netif_carrier_on(qmap_net); ++ if (netif_queue_stopped(qmap_net) && !netif_queue_stopped(real_dev)) ++ netif_wake_queue(qmap_net); ++ } ++ //printk("%s %s real_dev %d %d %d %d---\n", __func__, dev->name, ++ // netif_carrier_ok(real_dev), netif_queue_stopped(real_dev), netif_carrier_ok(dev), netif_queue_stopped(dev)); ++ ++ return 0; ++} ++ ++static int qmap_stop(struct net_device *qmap_net) ++{ ++ //printk("%s %s %d %d+++\n", __func__, dev->name, ++ // netif_carrier_ok(dev), netif_queue_stopped(dev)); ++ ++ netif_carrier_off(qmap_net); ++ return 0; ++} ++ ++static void qmap_wake_queue(sQmiWwanQmap *pQmapDev) ++{ ++ uint i = 0; ++ ++ if (!pQmapDev || !pQmapDev->use_rmnet_usb) ++ return; ++ ++ for (i = 0; i < pQmapDev->qmap_mode; i++) { ++ struct net_device *qmap_net = pQmapDev->mpQmapNetDev[i]; ++ ++ if (qmap_net && netif_carrier_ok(qmap_net) && netif_queue_stopped(qmap_net)) { ++ netif_wake_queue(qmap_net); ++ } ++ } ++} ++ ++static struct sk_buff * add_qhdr(struct sk_buff *skb, u8 mux_id) { ++ struct qmap_hdr *qhdr; ++ int pad = 0; ++ ++ pad = skb->len%4; ++ if (pad) { ++ pad = 4 - pad; ++ if (skb_tailroom(skb) < pad) { ++ printk("skb_tailroom small!\n"); ++ pad = 0; ++ } ++ if (pad) ++ __skb_put(skb, pad); ++ } ++ ++ qhdr = (struct qmap_hdr *)skb_push(skb, sizeof(struct qmap_hdr)); ++ qhdr->cd_rsvd_pad = pad; ++ qhdr->mux_id = mux_id; ++ qhdr->pkt_len = cpu_to_be16(skb->len - sizeof(struct qmap_hdr)); ++ ++ return skb; ++} ++ ++static struct sk_buff * add_qhdr_v5(struct sk_buff *skb, u8 mux_id) { ++ struct rmnet_map_header *map_header; ++ struct rmnet_map_v5_csum_header *ul_header; ++ u32 padding, map_datalen; ++ ++ map_datalen = skb->len; ++ padding = map_datalen%4; ++ if (padding) { ++ padding = 4 - padding; ++ if (skb_tailroom(skb) < padding) { ++ printk("skb_tailroom small!\n"); ++ padding = 0; ++ } ++ if (padding) ++ __skb_put(skb, padding); ++ } ++ ++ map_header = (struct rmnet_map_header *)skb_push(skb, (sizeof(struct rmnet_map_header) + sizeof(struct rmnet_map_v5_csum_header))); ++ map_header->cd_bit = 0; ++ map_header->next_hdr = 1; ++ map_header->pad_len = padding; ++ map_header->mux_id = mux_id; ++ map_header->pkt_len = htons(map_datalen + padding); ++ ++ ul_header = (struct rmnet_map_v5_csum_header *)(map_header + 1); ++ memset(ul_header, 0, sizeof(*ul_header)); ++ ul_header->header_type = RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD; ++ if (skb->ip_summed == CHECKSUM_PARTIAL) { ++#if 0 //TODO ++ skb->ip_summed = CHECKSUM_NONE; ++ /* Ask for checksum offloading */ ++ ul_header->csum_valid_required = 1; ++#endif ++ } ++ ++ return skb; ++} ++ ++static void rmnet_vnd_update_rx_stats(struct net_device *net, ++ unsigned rx_packets, unsigned rx_bytes) { ++#if defined(MHI_NETDEV_STATUS64) ++ struct qmap_priv *dev = netdev_priv(net); ++ struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64); ++ ++ u64_stats_update_begin(&stats64->syncp); ++ stats64->rx_packets += rx_packets; ++ stats64->rx_bytes += rx_bytes; ++ u64_stats_update_end(&stats64->syncp); ++#else ++ net->stats.rx_packets += rx_packets; ++ net->stats.rx_bytes += rx_bytes; ++#endif ++} ++ ++static void rmnet_vnd_update_tx_stats(struct net_device *net, ++ unsigned tx_packets, unsigned tx_bytes) { ++#if defined(MHI_NETDEV_STATUS64) ++ struct qmap_priv *dev = netdev_priv(net); ++ struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64); ++ ++ u64_stats_update_begin(&stats64->syncp); ++ stats64->tx_packets += tx_packets; ++ stats64->tx_bytes += tx_bytes; ++ u64_stats_update_end(&stats64->syncp); ++#else ++ net->stats.tx_packets += tx_packets; ++ net->stats.tx_bytes += tx_bytes; ++#endif ++} ++ ++#if defined(MHI_NETDEV_STATUS64) ++static struct rtnl_link_stats64 *_rmnet_vnd_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) ++{ ++ struct qmap_priv *dev = netdev_priv(net); ++ unsigned int start; ++ int cpu; ++ ++ netdev_stats_to_stats64(stats, &net->stats); ++ ++ if (nss_cb && dev->use_qca_nss) { // rmnet_nss.c:rmnet_nss_tx() will update rx stats ++ stats->rx_packets = 0; ++ stats->rx_bytes = 0; ++ } ++ ++ for_each_possible_cpu(cpu) { ++ struct pcpu_sw_netstats *stats64; ++ u64 rx_packets, rx_bytes; ++ u64 tx_packets, tx_bytes; ++ ++ stats64 = per_cpu_ptr(dev->stats64, cpu); ++ ++ do { ++ start = u64_stats_fetch_begin_irq(&stats64->syncp); ++ rx_packets = stats64->rx_packets; ++ rx_bytes = stats64->rx_bytes; ++ tx_packets = stats64->tx_packets; ++ tx_bytes = stats64->tx_bytes; ++ } while (u64_stats_fetch_retry_irq(&stats64->syncp, start)); ++ ++ stats->rx_packets += rx_packets; ++ stats->rx_bytes += rx_bytes; ++ stats->tx_packets += tx_packets; ++ stats->tx_bytes += tx_bytes; ++ } ++ ++ return stats; ++} ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION( 4,10,0 )) //bc1f44709cf27fb2a5766cadafe7e2ad5e9cb221 ++static void rmnet_vnd_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) { ++ _rmnet_vnd_get_stats64(net, stats); ++} ++#else ++static struct rtnl_link_stats64 *rmnet_vnd_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) { ++ return _rmnet_vnd_get_stats64(net, stats); ++} ++#endif ++#endif ++ ++#if defined(QUECTEL_UL_DATA_AGG) ++static void usbnet_bh(unsigned long data) { ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)data; ++ struct tasklet_struct *t = &pQmapDev->usbnet_bh; ++ bool use_callback = false; ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION( 5,8,0 )) //c955e329bb9d44fab75cf2116542fcc0de0473c5 ++ use_callback = t->use_callback; ++ if (use_callback) ++ t->callback(&pQmapDev->mpNetDev->bh); ++#endif ++ ++ if (!use_callback) ++ t->func(t->data); ++ ++ if (!netif_queue_stopped(pQmapDev->mpNetDev->net)) { ++ qmap_wake_queue((sQmiWwanQmap *)data); ++ } ++} ++ ++static void rmnet_usb_tx_wake_queue(unsigned long data) { ++ qmap_wake_queue((sQmiWwanQmap *)data); ++} ++ ++#if 0 ++static void rmnet_usb_tx_skb_destructor(struct sk_buff *skb) { ++ struct net_device *net = skb->dev; ++ struct usbnet * dev = netdev_priv( net ); ++ struct qmi_wwan_state *info = (void *)&dev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ ++ if (pQmapDev && pQmapDev->use_rmnet_usb) { ++ int i; ++ ++ for (i = 0; i < pQmapDev->qmap_mode; i++) { ++ struct net_device *qmap_net = pQmapDev->mpQmapNetDev[i]; ++ ++ if (qmap_net && netif_carrier_ok(qmap_net) && netif_queue_stopped(qmap_net)) { ++ tasklet_schedule(&pQmapDev->txq); ++ break; ++ } ++ } ++ } ++} ++#endif ++ ++static int rmnet_usb_tx_agg_skip(struct sk_buff *skb, int offset) ++{ ++ u8 *packet_start = skb->data + offset; ++ int ready2send = 0; ++ ++ if (skb->protocol == htons(ETH_P_IP)) { ++ struct iphdr *ip4h = (struct iphdr *)(packet_start); ++ ++ if (ip4h->protocol == IPPROTO_TCP) { ++ const struct tcphdr *th = (const struct tcphdr *)(packet_start + sizeof(struct iphdr)); ++ if (th->psh) { ++ ready2send = 1; ++ } ++ } ++ else if (ip4h->protocol == IPPROTO_ICMP) ++ ready2send = 1; ++ ++ } else if (skb->protocol == htons(ETH_P_IPV6)) { ++ struct ipv6hdr *ip6h = (struct ipv6hdr *)(packet_start); ++ ++ if (ip6h->nexthdr == NEXTHDR_TCP) { ++ const struct tcphdr *th = (const struct tcphdr *)(packet_start + sizeof(struct ipv6hdr)); ++ if (th->psh) { ++ ready2send = 1; ++ } ++ } else if (ip6h->nexthdr == NEXTHDR_ICMP) { ++ ready2send = 1; ++ } else if (ip6h->nexthdr == NEXTHDR_FRAGMENT) { ++ struct frag_hdr *frag; ++ ++ frag = (struct frag_hdr *)(packet_start ++ + sizeof(struct ipv6hdr)); ++ if (frag->nexthdr == IPPROTO_ICMPV6) ++ ready2send = 1; ++ } ++ } ++ ++ return ready2send; ++} ++ ++static void rmnet_usb_tx_agg_work(struct work_struct *work) ++{ ++ struct qmap_priv *priv = ++ container_of(work, struct qmap_priv, agg_wq); ++ struct sk_buff *skb = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&priv->agg_lock, flags); ++ if (likely(priv->agg_skb)) { ++ skb = priv->agg_skb; ++ priv->agg_skb = NULL; ++ priv->agg_count = 0; ++ skb->protocol = htons(ETH_P_MAP); ++ skb->dev = priv->real_dev; ++ ktime_get_ts64(&priv->agg_time); ++ } ++ spin_unlock_irqrestore(&priv->agg_lock, flags); ++ ++ if (skb) { ++ int err; ++#if 0 ++ if (!skb->destructor) ++ skb->destructor = rmnet_usb_tx_skb_destructor; ++#endif ++ err = dev_queue_xmit(skb); ++ if (err != NET_XMIT_SUCCESS) { ++ priv->self_dev->stats.tx_errors++; ++ } ++ } ++} ++ ++static enum hrtimer_restart rmnet_usb_tx_agg_timer_cb(struct hrtimer *timer) ++{ ++ struct qmap_priv *priv = ++ container_of(timer, struct qmap_priv, agg_hrtimer); ++ ++ schedule_work(&priv->agg_wq); ++ return HRTIMER_NORESTART; ++} ++ ++static long agg_time_limit __read_mostly = 1000000L; //reduce this time, can get better TPUT performance, but will increase USB interrupts ++module_param(agg_time_limit, long, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(agg_time_limit, "Maximum time packets sit in the agg buf"); ++ ++static long agg_bypass_time __read_mostly = 10000000L; ++module_param(agg_bypass_time, long, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(agg_bypass_time, "Skip agg when apart spaced more than this"); ++ ++static int rmnet_usb_tx_agg(struct sk_buff *skb, struct qmap_priv *priv) { ++ struct qmi_wwan_state *info = (void *)&priv->dev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ struct tx_agg_ctx *ctx = &pQmapDev->tx_ctx; ++ int ready2send = 0; ++ int xmit_more = 0; ++ struct timespec64 diff, now; ++ struct sk_buff *agg_skb = NULL; ++ unsigned long flags; ++ int err; ++ struct net_device *pNet = priv->self_dev; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,1,0) //6b16f9ee89b8d5709f24bc3ac89ae8b5452c0d7c ++#if LINUX_VERSION_CODE > KERNEL_VERSION(3,16,0) ++ xmit_more = skb->xmit_more; ++#endif ++#else ++ xmit_more = netdev_xmit_more(); ++#endif ++ ++ rmnet_vnd_update_tx_stats(pNet, 1, skb->len); ++ ++ if (ctx->ul_data_aggregation_max_datagrams == 1) { ++ skb->protocol = htons(ETH_P_MAP); ++ skb->dev = priv->real_dev; ++#if 0 ++ if (!skb->destructor) ++ skb->destructor = rmnet_usb_tx_skb_destructor; ++#endif ++ err = dev_queue_xmit(skb); ++ if (err != NET_XMIT_SUCCESS) ++ pNet->stats.tx_errors++; ++ return NET_XMIT_SUCCESS; ++ } ++ ++new_packet: ++ spin_lock_irqsave(&priv->agg_lock, flags); ++ agg_skb = NULL; ++ ready2send = 0; ++ ktime_get_ts64(&now); ++ diff = timespec64_sub(now, priv->agg_time); ++ ++ if (priv->agg_skb) { ++ if ((priv->agg_skb->len + skb->len) < ctx->ul_data_aggregation_max_size) { ++ memcpy(skb_put(priv->agg_skb, skb->len), skb->data, skb->len); ++ priv->agg_count++; ++ ++ if (diff.tv_sec > 0 || diff.tv_nsec > agg_time_limit) { ++ ready2send = 1; ++ } ++ else if (priv->agg_count == ctx->ul_data_aggregation_max_datagrams) { ++ ready2send = 1; ++ } ++ else if (xmit_more == 0) { ++ struct rmnet_map_header *map_header = (struct rmnet_map_header *)skb->data; ++ size_t offset = sizeof(struct rmnet_map_header); ++ if (map_header->next_hdr) ++ offset += sizeof(struct rmnet_map_v5_csum_header); ++ ++ ready2send = rmnet_usb_tx_agg_skip(skb, offset); ++ } ++ ++ dev_kfree_skb_any(skb); ++ skb = NULL; ++ } ++ else { ++ ready2send = 1; ++ } ++ ++ if (ready2send) { ++ agg_skb = priv->agg_skb; ++ priv->agg_skb = NULL; ++ priv->agg_count = 0; ++ } ++ } ++ else if (skb) { ++ if (diff.tv_sec > 0 || diff.tv_nsec > agg_bypass_time) { ++ ready2send = 1; ++ } ++ else if (xmit_more == 0) { ++ struct rmnet_map_header *map_header = (struct rmnet_map_header *)skb->data; ++ size_t offset = sizeof(struct rmnet_map_header); ++ if (map_header->next_hdr) ++ offset += sizeof(struct rmnet_map_v5_csum_header); ++ ++ ready2send = rmnet_usb_tx_agg_skip(skb, offset); ++ } ++ ++ if (ready2send == 0) { ++ priv->agg_skb = alloc_skb(ctx->ul_data_aggregation_max_size, GFP_ATOMIC); ++ if (priv->agg_skb) { ++ skb_reset_network_header(priv->agg_skb); //protocol da1a is buggy, dev wwan0 ++ memcpy(skb_put(priv->agg_skb, skb->len), skb->data, skb->len); ++ priv->agg_count++; ++ dev_kfree_skb_any(skb); ++ skb = NULL; ++ } ++ else { ++ ready2send = 1; ++ } ++ } ++ ++ if (ready2send) { ++ agg_skb = skb; ++ skb = NULL; ++ } ++ } ++ ++ if (ready2send) { ++ priv->agg_time = now; ++ } ++ spin_unlock_irqrestore(&priv->agg_lock, flags); ++ ++ if (agg_skb) { ++ agg_skb->protocol = htons(ETH_P_MAP); ++ agg_skb->dev = priv->real_dev; ++#if 0 ++ if (!agg_skb->destructor) ++ agg_skb->destructor = rmnet_usb_tx_skb_destructor; ++#endif ++ err = dev_queue_xmit(agg_skb); ++ if (err != NET_XMIT_SUCCESS) { ++ pNet->stats.tx_errors++; ++ } ++ } ++ ++ if (skb) { ++ goto new_packet; ++ } ++ ++ if (priv->agg_skb) { ++ if (!hrtimer_is_queued(&priv->agg_hrtimer)) ++ hrtimer_start(&priv->agg_hrtimer, ns_to_ktime(NSEC_PER_MSEC * 2), HRTIMER_MODE_REL); ++ } ++ ++ return NET_XMIT_SUCCESS; ++} ++#endif ++ ++static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb, ++ struct net_device *pNet) ++{ ++ int err; ++ struct qmap_priv *priv = netdev_priv(pNet); ++ ++ if (netif_queue_stopped(priv->real_dev)) { ++ netif_stop_queue(pNet); ++ return NETDEV_TX_BUSY; ++ } ++ ++ //printk("%s 1 skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len); ++ if (pNet->type == ARPHRD_ETHER) { ++ skb_reset_mac_header(skb); ++ ++#ifdef QUECTEL_BRIDGE_MODE ++ if (priv->bridge_mode && bridge_mode_tx_fixup(pNet, skb, priv->bridge_ipv4, priv->bridge_mac) == NULL) { ++ dev_kfree_skb_any (skb); ++ return NETDEV_TX_OK; ++ } ++#endif ++ ++ if (skb_pull(skb, ETH_HLEN) == NULL) { ++ dev_kfree_skb_any (skb); ++ return NETDEV_TX_OK; ++ } ++ } ++ //printk("%s 2 skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len); ++ ++ if (priv->qmap_version == 5) { ++ add_qhdr(skb, priv->mux_id); ++ } ++ else if (priv->qmap_version == 9) { ++ add_qhdr_v5(skb, priv->mux_id); ++ } ++ else { ++ dev_kfree_skb_any (skb); ++ return NETDEV_TX_OK; ++ } ++ //printk("%s skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len); ++ ++ err = rmnet_usb_tx_agg(skb, priv); ++ ++ return err; ++} ++ ++static int rmnet_vnd_change_mtu(struct net_device *rmnet_dev, int new_mtu) ++{ ++ if (new_mtu < 0) ++ return -EINVAL; ++ ++ if (new_mtu > 1500) ++ printk("warning, set mtu greater than 1500, %d\n", new_mtu); ++ ++ rmnet_dev->mtu = new_mtu; ++ return 0; ++} ++ ++/* drivers may override default ethtool_ops in their bind() routine */ ++static const struct ethtool_ops rmnet_vnd_ethtool_ops = { ++ .get_link = ethtool_op_get_link, ++}; ++ ++static const struct net_device_ops rmnet_vnd_ops = { ++ .ndo_open = qmap_open, ++ .ndo_stop = qmap_stop, ++ .ndo_start_xmit = rmnet_vnd_start_xmit, ++ .ndo_change_mtu = rmnet_vnd_change_mtu, ++#if defined(MHI_NETDEV_STATUS64) ++ .ndo_get_stats64 = rmnet_vnd_get_stats64, ++#endif ++}; ++ ++static void rmnet_usb_ether_setup(struct net_device *rmnet_dev) ++{ ++ ether_setup(rmnet_dev); ++ ++ rmnet_dev->flags |= IFF_NOARP; ++ rmnet_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(4,10,0) ++ rmnet_dev->max_mtu = 65535; ++#endif ++ ++ rmnet_dev->ethtool_ops = &rmnet_vnd_ethtool_ops; ++ rmnet_dev->netdev_ops = &rmnet_vnd_ops; ++} ++ ++static void rmnet_usb_rawip_setup(struct net_device *rmnet_dev) ++{ ++ rmnet_dev->needed_headroom = 16; ++ ++ /* Raw IP mode */ ++ rmnet_dev->header_ops = NULL; /* No header */ ++ rmnet_dev->type = ARPHRD_RAWIP; ++ rmnet_dev->hard_header_len = 0; ++ rmnet_dev->flags |= IFF_NOARP; ++ rmnet_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); ++ ++ rmnet_dev->ethtool_ops = &rmnet_vnd_ethtool_ops; ++ rmnet_dev->netdev_ops = &rmnet_vnd_ops; ++} ++ ++static rx_handler_result_t qca_nss_rx_handler(struct sk_buff **pskb) ++{ ++ struct sk_buff *skb = *pskb; ++ ++ if (!skb) ++ return RX_HANDLER_CONSUMED; ++ ++ //printk("%s skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len); ++ ++ if (skb->pkt_type == PACKET_LOOPBACK) ++ return RX_HANDLER_PASS; ++ ++ /* Check this so that we dont loop around netif_receive_skb */ ++ if (skb->cb[0] == 1) { ++ skb->cb[0] = 0; ++ ++ return RX_HANDLER_PASS; ++ } ++ ++ if (nss_cb) { ++ nss_cb->nss_tx(skb); ++ return RX_HANDLER_CONSUMED; ++ } ++ ++ return RX_HANDLER_PASS; ++} ++ ++static int qmap_register_device(sQmiWwanQmap * pDev, u8 offset_id) ++{ ++ struct net_device *real_dev = pDev->mpNetDev->net; ++ struct net_device *qmap_net; ++ struct qmap_priv *priv; ++ int err; ++ char name[IFNAMSIZ]; ++ int use_qca_nss = !!nss_cb; ++ ++ sprintf(name, "%s_%d", real_dev->name, offset_id + 1); ++#ifdef NET_NAME_UNKNOWN ++ qmap_net = alloc_netdev(sizeof(struct qmap_priv), name, ++ NET_NAME_UNKNOWN, rmnet_usb_ether_setup); ++#else ++ qmap_net = alloc_netdev(sizeof(struct qmap_priv), name, ++ rmnet_usb_ether_setup); ++#endif ++ if (!qmap_net) ++ return -ENOBUFS; ++ ++ SET_NETDEV_DEV(qmap_net, &real_dev->dev); ++ priv = netdev_priv(qmap_net); ++ priv->offset_id = offset_id; ++ priv->real_dev = real_dev; ++ priv->self_dev = qmap_net; ++ priv->dev = pDev->mpNetDev; ++ priv->qmap_version = pDev->qmap_version; ++ priv->mux_id = QUECTEL_QMAP_MUX_ID + offset_id; ++ memcpy (qmap_net->dev_addr, real_dev->dev_addr, ETH_ALEN); ++ ++#ifdef QUECTEL_BRIDGE_MODE ++ priv->bridge_mode = !!(pDev->bridge_mode & BIT(offset_id)); ++ qmap_net->sysfs_groups[0] = &qmi_qmap_sysfs_attr_group; ++ if (priv->bridge_mode) ++ use_qca_nss = 0; ++#ifdef CONFIG_BRIDGE_LAN ++ memcpy(priv->bridge_self_mac, broadcast_mac_addr, ETH_ALEN); ++#endif ++#endif ++ ++ if (nss_cb && use_qca_nss) { ++ rmnet_usb_rawip_setup(qmap_net); ++ } ++ ++ priv->agg_skb = NULL; ++ priv->agg_count = 0; ++ hrtimer_init(&priv->agg_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); ++ priv->agg_hrtimer.function = rmnet_usb_tx_agg_timer_cb; ++ INIT_WORK(&priv->agg_wq, rmnet_usb_tx_agg_work); ++ ktime_get_ts64(&priv->agg_time); ++ spin_lock_init(&priv->agg_lock); ++ priv->use_qca_nss = 0; ++ ++#if defined(MHI_NETDEV_STATUS64) ++ priv->stats64 = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); ++ if (!priv->stats64) { ++ err = -ENOBUFS; ++ goto out_free_newdev; ++ } ++#endif ++ ++ err = register_netdev(qmap_net); ++ if (err) ++ dev_info(&real_dev->dev, "%s(%s)=%d\n", __func__, qmap_net->name, err); ++ if (err < 0) ++ goto out_free_newdev; ++ netif_device_attach (qmap_net); ++ netif_carrier_off(qmap_net); ++ ++ if (nss_cb && use_qca_nss) { ++ int rc = nss_cb->nss_create(qmap_net); ++ if (rc) { ++ /* Log, but don't fail the device creation */ ++ netdev_err(qmap_net, "Device will not use NSS path: %d\n", rc); ++ } else { ++ priv->use_qca_nss = 1; ++ netdev_info(qmap_net, "NSS context created\n"); ++ rtnl_lock(); ++ netdev_rx_handler_register(qmap_net, qca_nss_rx_handler, NULL); ++ rtnl_unlock(); ++ } ++ } ++ ++ strcpy(pDev->rmnet_info.ifname[offset_id], qmap_net->name); ++ pDev->rmnet_info.mux_id[offset_id] = priv->mux_id; ++ ++ pDev->mpQmapNetDev[offset_id] = qmap_net; ++ ++ dev_info(&real_dev->dev, "%s %s\n", __func__, qmap_net->name); ++ ++ return 0; ++ ++out_free_newdev: ++ free_netdev(qmap_net); ++ return err; ++} ++ ++static void qmap_unregister_device(sQmiWwanQmap * pDev, u8 offset_id) { ++ struct net_device *qmap_net = pDev->mpQmapNetDev[offset_id]; ++ ++ if (qmap_net != NULL && qmap_net != pDev->mpNetDev->net) { ++ struct qmap_priv *priv = netdev_priv(qmap_net); ++ unsigned long flags; ++ ++ pr_info("qmap_unregister_device(%s)\n", qmap_net->name); ++ pDev->mpQmapNetDev[offset_id] = NULL; ++ netif_carrier_off( qmap_net ); ++ netif_stop_queue( qmap_net ); ++ ++ hrtimer_cancel(&priv->agg_hrtimer); ++ cancel_work_sync(&priv->agg_wq); ++ spin_lock_irqsave(&priv->agg_lock, flags); ++ if (priv->agg_skb) { ++ kfree_skb(priv->agg_skb); ++ } ++ spin_unlock_irqrestore(&priv->agg_lock, flags); ++ ++ if (nss_cb && priv->use_qca_nss) { ++ rtnl_lock(); ++ netdev_rx_handler_unregister(qmap_net); ++ rtnl_unlock(); ++ nss_cb->nss_free(qmap_net); ++ } ++ ++#if defined(MHI_NETDEV_STATUS64) ++ free_percpu(priv->stats64); ++#endif ++ unregister_netdev (qmap_net); ++ free_netdev(qmap_net); ++ } ++} ++ ++typedef struct { ++ unsigned int size; ++ unsigned int rx_urb_size; ++ unsigned int ep_type; ++ unsigned int iface_id; ++ unsigned int MuxId; ++ unsigned int ul_data_aggregation_max_datagrams; //0x17 ++ unsigned int ul_data_aggregation_max_size ;//0x18 ++ unsigned int dl_minimum_padding; //0x1A ++} QMAP_SETTING; ++ ++#ifdef CONFIG_BRIDGE_LAN ++typedef struct { ++ u8 id; ++ u8 brmac[ETH_ALEN]; ++} BRMAC_SETTING; ++#endif ++ ++int qma_setting_store(struct device *dev, QMAP_SETTING *qmap_settings, size_t size) { ++ struct net_device *netdev = to_net_dev(dev); ++ struct usbnet * usbnetdev = netdev_priv( netdev ); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ ++ if (qmap_settings->size != size) { ++ dev_err(dev, "ERROR: qmap_settings.size donot match!\n"); ++ return -EOPNOTSUPP; ++ } ++ ++#ifdef QUECTEL_UL_DATA_AGG ++ netif_tx_lock_bh(netdev); ++ if (pQmapDev->tx_ctx.ul_data_aggregation_max_datagrams == 1 && qmap_settings->ul_data_aggregation_max_datagrams > 1) { ++ pQmapDev->tx_ctx.ul_data_aggregation_max_datagrams = qmap_settings->ul_data_aggregation_max_datagrams; ++ pQmapDev->tx_ctx.ul_data_aggregation_max_size = qmap_settings->ul_data_aggregation_max_size; ++ pQmapDev->tx_ctx.dl_minimum_padding = qmap_settings->dl_minimum_padding; ++ dev_info(dev, "ul_data_aggregation_max_datagrams=%d, ul_data_aggregation_max_size=%d, dl_minimum_padding=%d\n", ++ pQmapDev->tx_ctx.ul_data_aggregation_max_datagrams, ++ pQmapDev->tx_ctx.ul_data_aggregation_max_size, ++ pQmapDev->tx_ctx.dl_minimum_padding); ++ } ++ netif_tx_unlock_bh(netdev); ++ return 0; ++#endif ++ ++ return -EOPNOTSUPP; ++} ++ ++static int qmap_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { ++ struct usbnet * usbnetdev = netdev_priv( dev ); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ int rc = -EOPNOTSUPP; ++ uint link_state = 0; ++ QMAP_SETTING qmap_settings = {0}; ++#ifdef CONFIG_BRIDGE_LAN ++ BRMAC_SETTING brmac_settings = {0}; ++#endif ++ ++ switch (cmd) { ++ case 0x89F1: //SIOCDEVPRIVATE ++ rc = copy_from_user(&link_state, ifr->ifr_ifru.ifru_data, sizeof(link_state)); ++ if (!rc) { ++ char buf[32]; ++ snprintf(buf, sizeof(buf), "%u", link_state); ++ link_state_store(&dev->dev, NULL, buf, strlen(buf)); ++ } ++ break; ++ ++ case 0x89F2: //SIOCDEVPRIVATE ++ rc = copy_from_user(&qmap_settings, ifr->ifr_ifru.ifru_data, sizeof(qmap_settings)); ++ if (!rc) { ++ rc = qma_setting_store(&dev->dev, &qmap_settings, sizeof(qmap_settings)); ++ } ++ break; ++ ++ case 0x89F3: //SIOCDEVPRIVATE ++ if (pQmapDev->use_rmnet_usb) { ++ uint i; ++ ++ for (i = 0; i < pQmapDev->qmap_mode; i++) { ++ struct net_device *qmap_net = pQmapDev->mpQmapNetDev[i]; ++ ++ if (!qmap_net) ++ break; ++ ++ strcpy(pQmapDev->rmnet_info.ifname[i], qmap_net->name); ++ } ++ rc = copy_to_user(ifr->ifr_ifru.ifru_data, &pQmapDev->rmnet_info, sizeof(pQmapDev->rmnet_info)); ++ } ++ break; ++ ++#ifdef CONFIG_BRIDGE_LAN ++ case 0x89F4: //SIOCDEVPRIVATE ++ rc = copy_from_user(&brmac_settings, ifr->ifr_ifru.ifru_data, sizeof(brmac_settings)); ++ if (pQmapDev->use_rmnet_usb && brmac_settings.id < qmap_mode) { ++ struct net_device *qmap_net = pQmapDev->mpQmapNetDev[brmac_settings.id]; ++ struct qmap_priv *priv = netdev_priv(qmap_net); ++ memcpy(priv->bridge_self_mac, brmac_settings.brmac, ETH_ALEN); ++ pr_info("ioctl 0x89F4 change qmapnet bridge(%d) lan mac -> %02x:%02x:%02x:%02x:%02x:%02x\n", brmac_settings.id, priv->bridge_self_mac[0], ++ priv->bridge_self_mac[1], priv->bridge_self_mac[2], priv->bridge_self_mac[3], priv->bridge_self_mac[4], priv->bridge_self_mac[5]); ++ } ++ else if (!pQmapDev->use_rmnet_usb && brmac_settings.id == 0) { ++ memcpy(pQmapDev->bridge_self_mac, brmac_settings.brmac, ETH_ALEN); ++ pr_info("ioctl 0x89F4 change usbnet bridge(%d) lan mac -> %02x:%02x:%02x:%02x:%02x:%02x\n", brmac_settings.id, pQmapDev->bridge_self_mac[0], ++ pQmapDev->bridge_self_mac[1], pQmapDev->bridge_self_mac[2], pQmapDev->bridge_self_mac[3], pQmapDev->bridge_self_mac[4], pQmapDev->bridge_self_mac[5]); ++ } ++ else { ++ pr_info("ioctl 0x89F4 change bridge(%d) lan mac -> error id\n", brmac_settings.id); ++ rc = -1; ++ } ++ break; ++#endif ++ ++ default: ++ break; ++ } ++ ++ return rc; ++} ++ ++#ifdef QUECTEL_BRIDGE_MODE ++static int is_qmap_netdev(const struct net_device *netdev) { ++ return netdev->netdev_ops == &rmnet_vnd_ops; ++} ++#endif ++#endif ++ ++static struct sk_buff *qmi_wwan_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) { ++ //MDM9x07,MDM9628,MDM9x40,SDX20,SDX24 only work on RAW IP mode ++ if ((dev->driver_info->flags & FLAG_NOARP) == 0) ++ return skb; ++ ++ // Skip Ethernet header from message ++ if (dev->net->hard_header_len == 0) ++ return skb; ++ else ++ skb_reset_mac_header(skb); ++ ++#ifdef QUECTEL_BRIDGE_MODE ++{ ++ struct qmi_wwan_state *info = (void *)&dev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ ++ if (pQmapDev->bridge_mode && bridge_mode_tx_fixup(dev->net, skb, pQmapDev->bridge_ipv4, pQmapDev->bridge_mac) == NULL) { ++ dev_kfree_skb_any (skb); ++ return NULL; ++ } ++} ++#endif ++ ++ if (skb_pull(skb, ETH_HLEN)) { ++ return skb; ++ } else { ++ dev_err(&dev->intf->dev, "Packet Dropped "); ++ } ++ ++ // Filter the packet out, release it ++ dev_kfree_skb_any(skb); ++ return NULL; ++} ++#endif ++ ++/* Make up an ethernet header if the packet doesn't have one. ++ * ++ * A firmware bug common among several devices cause them to send raw ++ * IP packets under some circumstances. There is no way for the ++ * driver/host to know when this will happen. And even when the bug ++ * hits, some packets will still arrive with an intact header. ++ * ++ * The supported devices are only capably of sending IPv4, IPv6 and ++ * ARP packets on a point-to-point link. Any packet with an ethernet ++ * header will have either our address or a broadcast/multicast ++ * address as destination. ARP packets will always have a header. ++ * ++ * This means that this function will reliably add the appropriate ++ * header iff necessary, provided our hardware address does not start ++ * with 4 or 6. ++ * ++ * Another common firmware bug results in all packets being addressed ++ * to 00:a0:c6:00:00:00 despite the host address being different. ++ * This function will also fixup such packets. ++ */ ++static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ __be16 proto; ++ ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ ++ switch (skb->data[0] & 0xf0) { ++ case 0x40: ++ proto = htons(ETH_P_IP); ++ break; ++ case 0x60: ++ proto = htons(ETH_P_IPV6); ++ break; ++ case 0x00: ++ if (is_multicast_ether_addr(skb->data)) ++ return 1; ++ /* possibly bogus destination - rewrite just in case */ ++ skb_reset_mac_header(skb); ++ goto fix_dest; ++ default: ++ /* pass along other packets without modifications */ ++ return 1; ++ } ++ if (skb_headroom(skb) < ETH_HLEN) ++ return 0; ++ skb_push(skb, ETH_HLEN); ++ skb_reset_mac_header(skb); ++ eth_hdr(skb)->h_proto = proto; ++ memset(eth_hdr(skb)->h_source, 0, ETH_ALEN); ++#if 1 //Added by Quectel ++ //some kernel will drop ethernet packet which's souce mac is all zero ++ memcpy(eth_hdr(skb)->h_source, default_modem_addr, ETH_ALEN); ++#endif ++ ++fix_dest: ++#ifdef QUECTEL_BRIDGE_MODE ++{ ++ struct qmi_wwan_state *info = (void *)&dev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ bridge_mode_rx_fixup(pQmapDev, dev->net, skb); ++} ++#else ++ memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN); ++#endif ++ ++ return 1; ++} ++ ++#if defined(QUECTEL_WWAN_QMAP) ++static struct sk_buff *qmap_qmi_wwan_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) { ++ struct qmi_wwan_state *info = (void *)&dev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ ++ if (unlikely(pQmapDev == NULL)) { ++ goto drop_skb; ++ } else if (unlikely(pQmapDev->qmap_mode && !pQmapDev->link_state)) { ++ dev_dbg(&dev->net->dev, "link_state 0x%x, drop skb, len = %u\n", pQmapDev->link_state, skb->len); ++ goto drop_skb; ++ } else if (pQmapDev->qmap_mode == 0) { ++ skb = qmi_wwan_tx_fixup(dev, skb, flags); ++ } ++ else if (pQmapDev->qmap_mode > 1) { ++ WARN_ON(1); //never reach here. ++ } ++ else { ++ if (likely(skb)) { ++ skb = qmi_wwan_tx_fixup(dev, skb, flags); ++ ++ if (skb) { ++ if(pQmapDev->qmap_version == 5) ++ add_qhdr(skb, QUECTEL_QMAP_MUX_ID); ++ else ++ add_qhdr_v5(skb, QUECTEL_QMAP_MUX_ID); ++ } ++ else { ++ return NULL; ++ } ++ } ++ } ++ ++ return skb; ++drop_skb: ++ dev_kfree_skb_any (skb); ++ return NULL; ++} ++ ++static void qmap_packet_decode(sQmiWwanQmap *pQmapDev, ++ struct sk_buff *skb_in, struct sk_buff_head *skb_chain) ++{ ++ struct device *dev = &pQmapDev->mpNetDev->net->dev; ++ struct sk_buff *qmap_skb; ++ uint dl_minimum_padding = 0; ++ ++ if (pQmapDev->qmap_version == 9) ++ dl_minimum_padding = pQmapDev->tx_ctx.dl_minimum_padding; ++ ++ /* __skb_queue_head_init() do not call spin_lock_init(&list->lock), ++ so should not call skb_queue_tail/queue later. */ ++ __skb_queue_head_init(skb_chain); ++ ++ while (skb_in->len > sizeof(struct qmap_hdr)) { ++ struct rmnet_map_header *map_header = (struct rmnet_map_header *)skb_in->data; ++ struct rmnet_map_v5_csum_header *ul_header = NULL; ++ size_t hdr_size = sizeof(struct rmnet_map_header); ++ struct net_device *qmap_net; ++ int pkt_len = ntohs(map_header->pkt_len); ++ int skb_len; ++ __be16 protocol; ++ int mux_id; ++ int skip_nss = 0; ++ ++ if (map_header->next_hdr) { ++ ul_header = (struct rmnet_map_v5_csum_header *)(map_header + 1); ++ hdr_size += sizeof(struct rmnet_map_v5_csum_header); ++ } ++ ++ skb_len = pkt_len - (map_header->pad_len&0x3F); ++ skb_len -= dl_minimum_padding; ++ ++ mux_id = map_header->mux_id - QUECTEL_QMAP_MUX_ID; ++ if (mux_id >= pQmapDev->qmap_mode) { ++ dev_info(dev, "drop qmap unknow mux_id %x\n", map_header->mux_id); ++ goto error_pkt; ++ } ++ ++ qmap_net = pQmapDev->mpQmapNetDev[mux_id]; ++ if (qmap_net == NULL) { ++ dev_info(dev, "drop qmap unknow mux_id %x\n", map_header->mux_id); ++ goto skip_pkt; ++ } ++ ++ if (skb_len > qmap_net->mtu) { ++ dev_info(dev, "drop skb_len=%x larger than mtu=%d\n", skb_len, qmap_net->mtu); ++ goto error_pkt; ++ } ++ ++ if (skb_in->len < (pkt_len + hdr_size)) { ++ dev_info(dev, "drop qmap unknow pkt, len=%d, pkt_len=%d\n", skb_in->len, pkt_len); ++ goto error_pkt; ++ } ++ ++ if (map_header->cd_bit) { ++ dev_info(dev, "skip qmap command packet\n"); ++ goto skip_pkt; ++ } ++ ++ switch (skb_in->data[hdr_size] & 0xf0) { ++ case 0x40: ++#ifdef CONFIG_QCA_NSS_PACKET_FILTER ++ { ++ struct iphdr *ip4h = (struct iphdr *)(&skb_in->data[hdr_size]); ++ if (ip4h->protocol == IPPROTO_ICMP) { ++ skip_nss = 1; ++ } ++ } ++#endif ++ protocol = htons(ETH_P_IP); ++ break; ++ case 0x60: ++#ifdef CONFIG_QCA_NSS_PACKET_FILTER ++ { ++ struct ipv6hdr *ip6h = (struct ipv6hdr *)(&skb_in->data[hdr_size]); ++ if (ip6h->nexthdr == NEXTHDR_ICMP) { ++ skip_nss = 1; ++ } ++ } ++#endif ++ protocol = htons(ETH_P_IPV6); ++ break; ++ default: ++ dev_info(dev, "unknow skb->protocol %02x\n", skb_in->data[hdr_size]); ++ goto error_pkt; ++ } ++ ++ qmap_skb = netdev_alloc_skb(qmap_net, skb_len); ++ if (qmap_skb) { ++ skb_put(qmap_skb, skb_len); ++ memcpy(qmap_skb->data, skb_in->data + hdr_size, skb_len); ++ } ++ ++ if (qmap_skb == NULL) { ++ dev_info(dev, "fail to alloc skb, pkt_len = %d\n", skb_len); ++ goto error_pkt; ++ } ++ ++ skb_reset_transport_header(qmap_skb); ++ skb_reset_network_header(qmap_skb); ++ qmap_skb->pkt_type = PACKET_HOST; ++ skb_set_mac_header(qmap_skb, 0); ++ qmap_skb->protocol = protocol; ++ ++ if(skip_nss) ++ qmap_skb->cb[0] = 1; ++ ++ if (ul_header && ul_header->header_type == RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD ++ && ul_header->csum_valid_required) { ++#if 0 //TODO ++ qmap_skb->ip_summed = CHECKSUM_UNNECESSARY; ++#endif ++ } ++ ++ if (qmap_skb->dev->type == ARPHRD_ETHER) { ++ skb_push(qmap_skb, ETH_HLEN); ++ skb_reset_mac_header(qmap_skb); ++ memcpy(eth_hdr(qmap_skb)->h_source, default_modem_addr, ETH_ALEN); ++ memcpy(eth_hdr(qmap_skb)->h_dest, qmap_net->dev_addr, ETH_ALEN); ++ eth_hdr(qmap_skb)->h_proto = protocol; ++#ifdef QUECTEL_BRIDGE_MODE ++ bridge_mode_rx_fixup(pQmapDev, qmap_net, qmap_skb); ++#endif ++ } ++ ++ __skb_queue_tail(skb_chain, qmap_skb); ++ ++skip_pkt: ++ skb_pull(skb_in, pkt_len + hdr_size); ++ } ++ ++error_pkt: ++ return; ++} ++ ++static int qmap_qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) ++{ ++ struct qmi_wwan_state *info = (void *)&dev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ struct sk_buff *qmap_skb; ++ struct sk_buff_head skb_chain; ++ ++ if (pQmapDev->qmap_mode == 0) ++ return qmi_wwan_rx_fixup(dev, skb_in); ++ ++ qmap_packet_decode(pQmapDev, skb_in, &skb_chain); ++ ++ while ((qmap_skb = __skb_dequeue (&skb_chain))) { ++ if (qmap_skb->dev != dev->net) { ++ WARN_ON(1); //never reach here. ++ } ++ else { ++ qmap_skb->protocol = 0; ++ usbnet_skb_return(dev, qmap_skb); ++ } ++ } ++ ++ return 0; ++} ++#endif ++ ++/* very simplistic detection of IPv4 or IPv6 headers */ ++static bool possibly_iphdr(const char *data) ++{ ++ return (data[0] & 0xd0) == 0x40; ++} ++ ++/* disallow addresses which may be confused with IP headers */ ++static int qmi_wwan_mac_addr(struct net_device *dev, void *p) ++{ ++ int ret; ++ struct sockaddr *addr = p; ++ ++ ret = eth_prepare_mac_addr_change(dev, p); ++ if (ret < 0) ++ return ret; ++ if (possibly_iphdr(addr->sa_data)) ++ return -EADDRNOTAVAIL; ++ eth_commit_mac_addr_change(dev, p); ++ return 0; ++} ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION( 4,10,0 )) //bc1f44709cf27fb2a5766cadafe7e2ad5e9cb221 ++static void (*_usbnet_get_stats64)(struct net_device *net, struct rtnl_link_stats64 *stats); ++ ++static void qmi_wwan_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) { ++ if (_usbnet_get_stats64) ////c8b5d129ee293bcf972e7279ac996bb8a138505c ++ return _usbnet_get_stats64(net, stats); ++ ++ netdev_stats_to_stats64(stats, &net->stats); ++} ++#else ++static struct rtnl_link_stats64 * (*_usbnet_get_stats64)(struct net_device *net, struct rtnl_link_stats64 *stats); ++ ++static struct rtnl_link_stats64 * qmi_wwan_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) { ++ if (_usbnet_get_stats64) ++ return _usbnet_get_stats64(net, stats); ++ ++ netdev_stats_to_stats64(stats, &net->stats); ++ return stats; ++} ++#endif ++ ++static int qmi_wwan_open (struct net_device *net) { ++ struct usbnet * usbnetdev = netdev_priv( net ); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ int retval; ++ ++ retval = usbnet_open(net); ++ ++ if (!retval) { ++ if (pQmapDev && pQmapDev->qmap_mode == 1) { ++ if (pQmapDev->link_state) ++ netif_carrier_on(net); ++ } ++ } ++ ++ return retval; ++} ++ ++static netdev_tx_t qmi_wwan_start_xmit (struct sk_buff *skb, ++ struct net_device *net) ++{ ++ struct usbnet * usbnetdev = netdev_priv( net ); ++ struct qmi_wwan_state *info = (void *)&usbnetdev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ int retval; ++ ++ retval = usbnet_start_xmit(skb, net); ++ ++ if (netif_queue_stopped(net) && pQmapDev && pQmapDev->use_rmnet_usb) { ++ int i; ++ ++ for (i = 0; i < pQmapDev->qmap_mode; i++) { ++ struct net_device *qmap_net = pQmapDev->mpQmapNetDev[i]; ++ if (qmap_net) { ++ netif_stop_queue(qmap_net); ++ } ++ } ++ } ++ ++ return retval; ++} ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION( 5,14,0 )) //b9067f5dc4a07c8e24e01a1b277c6722d91be39e ++#define use_ndo_siocdevprivate ++#endif ++#ifdef use_ndo_siocdevprivate ++static int qmap_ndo_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd) { ++ return qmap_ndo_do_ioctl(dev, ifr, cmd); ++} ++#endif ++ ++static const struct net_device_ops qmi_wwan_netdev_ops = { ++ .ndo_open = qmi_wwan_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = qmi_wwan_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = usbnet_change_mtu, ++ .ndo_get_stats64 = qmi_wwan_get_stats64, ++ .ndo_set_mac_address = qmi_wwan_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++#if defined(QUECTEL_WWAN_QMAP)// && defined(CONFIG_ANDROID) ++ .ndo_do_ioctl = qmap_ndo_do_ioctl, ++#ifdef use_ndo_siocdevprivate ++ .ndo_siocdevprivate = qmap_ndo_siocdevprivate, ++#endif ++#endif ++}; ++ ++static void ql_net_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) ++{ ++ /* Inherit standard device info */ ++ usbnet_get_drvinfo(net, info); ++ strlcpy(info->driver, driver_name, sizeof(info->driver)); ++ strlcpy(info->version, VERSION_NUMBER, sizeof(info->version)); ++} ++ ++static struct ethtool_ops ql_net_ethtool_ops; ++ ++/* using a counter to merge subdriver requests with our own into a ++ * combined state ++ */ ++static int qmi_wwan_manage_power(struct usbnet *dev, int on) ++{ ++ struct qmi_wwan_state *info = (void *)&dev->data; ++ int rv; ++ ++ dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, ++ atomic_read(&info->pmcount), on); ++ ++ if ((on && atomic_add_return(1, &info->pmcount) == 1) || ++ (!on && atomic_dec_and_test(&info->pmcount))) { ++ /* need autopm_get/put here to ensure the usbcore sees ++ * the new value ++ */ ++ rv = usb_autopm_get_interface(dev->intf); ++ dev->intf->needs_remote_wakeup = on; ++ if (!rv) ++ usb_autopm_put_interface(dev->intf); ++ } ++ return 0; ++} ++ ++static int qmi_wwan_cdc_wdm_manage_power(struct usb_interface *intf, int on) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ ++ /* can be called while disconnecting */ ++ if (!dev) ++ return 0; ++ return qmi_wwan_manage_power(dev, on); ++} ++ ++/* collect all three endpoints and register subdriver */ ++static int qmi_wwan_register_subdriver(struct usbnet *dev) ++{ ++ int rv; ++ struct usb_driver *subdriver = NULL; ++ struct qmi_wwan_state *info = (void *)&dev->data; ++ ++ /* collect bulk endpoints */ ++ rv = usbnet_get_endpoints(dev, info->data); ++ if (rv < 0) ++ goto err; ++ ++ /* update status endpoint if separate control interface */ ++ if (info->control != info->data) ++ dev->status = &info->control->cur_altsetting->endpoint[0]; ++ ++ /* require interrupt endpoint for subdriver */ ++ if (!dev->status) { ++ rv = -EINVAL; ++ goto err; ++ } ++ ++ /* for subdriver power management */ ++ atomic_set(&info->pmcount, 0); ++ ++ /* register subdriver */ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION( 5,12,0 )) //cac6fb015f719104e60b1c68c15ca5b734f57b9c ++ subdriver = usb_cdc_wdm_register(info->control, &dev->status->desc, ++ 4096, WWAN_PORT_QMI, &qmi_wwan_cdc_wdm_manage_power); ++#else ++ subdriver = usb_cdc_wdm_register(info->control, &dev->status->desc, ++ 4096, &qmi_wwan_cdc_wdm_manage_power); ++ ++#endif ++ if (IS_ERR(subdriver)) { ++ dev_err(&info->control->dev, "subdriver registration failed\n"); ++ rv = PTR_ERR(subdriver); ++ goto err; ++ } ++ ++ /* prevent usbnet from using status endpoint */ ++ dev->status = NULL; ++ ++ /* save subdriver struct for suspend/resume wrappers */ ++ info->subdriver = subdriver; ++ ++err: ++ return rv; ++} ++ ++static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int status = -1; ++ struct usb_driver *driver = driver_of(intf); ++ struct qmi_wwan_state *info = (void *)&dev->data; ++ ++ BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < ++ sizeof(struct qmi_wwan_state))); ++ ++ /* set up initial state */ ++ info->control = intf; ++ info->data = intf; ++ ++ status = qmi_wwan_register_subdriver(dev); ++ if (status < 0 && info->control != info->data) { ++ usb_set_intfdata(info->data, NULL); ++ usb_driver_release_interface(driver, info->data); ++ } ++ ++ /* Never use the same address on both ends of the link, even ++ * if the buggy firmware told us to. ++ */ ++ if (ether_addr_equal(dev->net->dev_addr, default_modem_addr)) ++ eth_hw_addr_random(dev->net); ++ ++ /* make MAC addr easily distinguishable from an IP header */ ++ if (possibly_iphdr(dev->net->dev_addr)) { ++ dev->net->dev_addr[0] |= 0x02; /* set local assignment bit */ ++ dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */ ++ } ++ if (!_usbnet_get_stats64) ++ _usbnet_get_stats64 = dev->net->netdev_ops->ndo_get_stats64; ++ dev->net->netdev_ops = &qmi_wwan_netdev_ops; ++ ++ ql_net_ethtool_ops = *dev->net->ethtool_ops; ++ ql_net_ethtool_ops.get_drvinfo = ql_net_get_drvinfo; ++ dev->net->ethtool_ops = &ql_net_ethtool_ops; ++ ++#if 1 //Added by Quectel ++ if (dev->driver_info->flags & FLAG_NOARP) { ++ int ret; ++ char buf[32] = "Module"; ++ ++ ret = usb_string(dev->udev, dev->udev->descriptor.iProduct, buf, sizeof(buf)); ++ if (ret > 0) { ++ buf[ret] = '\0'; ++ } ++ ++ dev_info(&intf->dev, "Quectel %s work on RawIP mode\n", buf); ++ dev->net->flags |= IFF_NOARP; ++ dev->net->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); ++ ++ usb_control_msg( ++ interface_to_usbdev(intf), ++ usb_sndctrlpipe(interface_to_usbdev(intf), 0), ++ 0x22, //USB_CDC_REQ_SET_CONTROL_LINE_STATE ++ 0x21, //USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE ++ 1, //active CDC DTR ++ intf->cur_altsetting->desc.bInterfaceNumber, ++ NULL, 0, 100); ++ } ++ ++ //to advoid module report mtu 1460, but rx 1500 bytes IP packets, and cause the customer's system crash ++ //next setting can make usbnet.c:usbnet_change_mtu() do not modify rx_urb_size according to hard mtu ++ dev->rx_urb_size = ETH_DATA_LEN + ETH_HLEN + 6; ++ ++#if defined(QUECTEL_WWAN_QMAP) ++ if (qmap_mode > QUECTEL_WWAN_QMAP) ++ qmap_mode = QUECTEL_WWAN_QMAP; ++ ++ if (!status) ++ { ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)kzalloc(sizeof(sQmiWwanQmap), GFP_KERNEL); ++ ++ if (pQmapDev == NULL) ++ return -ENODEV; ++ ++#ifdef QUECTEL_BRIDGE_MODE ++ pQmapDev->bridge_mode = bridge_mode; ++#ifdef CONFIG_BRIDGE_LAN ++ memcpy(pQmapDev->bridge_self_mac, broadcast_mac_addr, ETH_ALEN); ++#endif ++#endif ++ pQmapDev->mpNetDev = dev; ++ pQmapDev->link_state = 1; ++ //on OpenWrt, if set rmnet_usb0.1 as WAN, '/sbin/netifd' will auto create VLAN for rmnet_usb0 ++ dev->net->features |= (NETIF_F_VLAN_CHALLENGED); ++ ++ if (dev->driver_info->flags & FLAG_NOARP) ++ { ++ int qmap_version = (dev->driver_info->data>>8)&0xFF; ++ int qmap_size = (dev->driver_info->data)&0xFF; ++ int idProduct = le16_to_cpu(dev->udev->descriptor.idProduct); ++ int lte_a = (idProduct == 0x0306 || idProduct == 0x030B || idProduct == 0x0512 || idProduct == 0x0620 || idProduct == 0x0800 || idProduct == 0x0801); ++ ++ if (qmap_size > 4096 || dev->udev->speed >= USB_SPEED_SUPER) { //if meet this requirements, must be LTE-A or 5G ++ lte_a = 1; ++ } ++ ++ pQmapDev->qmap_mode = qmap_mode; ++ if (lte_a && pQmapDev->qmap_mode == 0) { ++ pQmapDev->qmap_mode = 1; //force use QMAP ++ if(qmap_mode == 0) ++ qmap_mode = 1; //old quectel-CM only check sys/module/wwan0/parameters/qmap_mode ++ } ++ ++ if (pQmapDev->qmap_mode) { ++ pQmapDev->qmap_version = qmap_version; ++ pQmapDev->qmap_size = qmap_size*1024; ++ dev->rx_urb_size = pQmapDev->qmap_size; ++ //for these modules, if send packet before qmi_start_network, or cause host PC crash, or cause modules crash ++ pQmapDev->link_state = !lte_a; ++ ++ if (pQmapDev->qmap_mode > 1) ++ pQmapDev->use_rmnet_usb = 1; ++ else if (idProduct == 0x0800 || idProduct == 0x0801) ++ pQmapDev->use_rmnet_usb = 1; //benefit for ul data agg ++#ifdef QMI_NETDEV_ONE_CARD_MODE ++ if(pQmapDev->use_rmnet_usb == 1 && pQmapDev->qmap_mode == 1) ++ one_card_mode = 1; ++ pQmapDev->rmnet_info.mux_id[0] = QUECTEL_QMAP_MUX_ID; ++#endif ++ pQmapDev->rmnet_info.size = sizeof(RMNET_INFO); ++ pQmapDev->rmnet_info.rx_urb_size = pQmapDev->qmap_size; ++ pQmapDev->rmnet_info.ep_type = 2; //DATA_EP_TYPE_HSUSB ++ pQmapDev->rmnet_info.iface_id = 4; ++ pQmapDev->rmnet_info.qmap_mode = pQmapDev->qmap_mode; ++ pQmapDev->rmnet_info.qmap_version = pQmapDev->qmap_version; ++ pQmapDev->rmnet_info.dl_minimum_padding = 0; ++ ++#if defined(QUECTEL_UL_DATA_AGG) ++ pQmapDev->tx_ctx.ul_data_aggregation_max_datagrams = 1; ++ pQmapDev->tx_ctx.ul_data_aggregation_max_size = 1500; ++#endif ++ ++ if (pQmapDev->use_rmnet_usb && !one_card_mode) { ++ pQmapDev->driver_info = rmnet_usb_info; ++ pQmapDev->driver_info.data = dev->driver_info->data; ++ dev->driver_info = &pQmapDev->driver_info; ++ } ++ ++ if (pQmapDev->use_rmnet_usb && !one_card_mode) { ++ pQmapDev->usbnet_bh = dev->bh; ++ tasklet_init(&dev->bh, usbnet_bh, (unsigned long)pQmapDev); ++ } ++ } ++ } ++ ++ info->unused = (unsigned long)pQmapDev; ++ dev->net->sysfs_groups[0] = &qmi_wwan_sysfs_attr_group; ++ ++ dev_info(&intf->dev, "rx_urb_size = %zd\n", dev->rx_urb_size); ++ } ++#endif ++#endif ++ ++ return status; ++} ++ ++static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ struct qmi_wwan_state *info = (void *)&dev->data; ++ struct usb_driver *driver = driver_of(intf); ++ struct usb_interface *other; ++ ++ if (dev->udev && dev->udev->state == USB_STATE_CONFIGURED) { ++ usb_control_msg( ++ interface_to_usbdev(intf), ++ usb_sndctrlpipe(interface_to_usbdev(intf), 0), ++ 0x22, //USB_CDC_REQ_SET_CONTROL_LINE_STATE ++ 0x21, //USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE ++ 0, //deactive CDC DTR ++ intf->cur_altsetting->desc.bInterfaceNumber, ++ NULL, 0, 100); ++ } ++ ++ if (info->subdriver && info->subdriver->disconnect) ++ info->subdriver->disconnect(info->control); ++ ++ /* allow user to unbind using either control or data */ ++ if (intf == info->control) ++ other = info->data; ++ else ++ other = info->control; ++ ++ /* only if not shared */ ++ if (other && intf != other) { ++ usb_set_intfdata(other, NULL); ++ usb_driver_release_interface(driver, other); ++ } ++ ++ info->subdriver = NULL; ++ info->data = NULL; ++ info->control = NULL; ++} ++ ++/* suspend/resume wrappers calling both usbnet and the cdc-wdm ++ * subdriver if present. ++ * ++ * NOTE: cdc-wdm also supports pre/post_reset, but we cannot provide ++ * wrappers for those without adding usbnet reset support first. ++ */ ++static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ struct qmi_wwan_state *info = (void *)&dev->data; ++ int ret; ++ ++ /* Both usbnet_suspend() and subdriver->suspend() MUST return 0 ++ * in system sleep context, otherwise, the resume callback has ++ * to recover device from previous suspend failure. ++ */ ++ ret = usbnet_suspend(intf, message); ++ if (ret < 0) ++ goto err; ++ ++ if (intf == info->control && info->subdriver && ++ info->subdriver->suspend) ++ ret = info->subdriver->suspend(intf, message); ++ if (ret < 0) ++ usbnet_resume(intf); ++err: ++ return ret; ++} ++ ++static int qmi_wwan_resume(struct usb_interface *intf) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ struct qmi_wwan_state *info = (void *)&dev->data; ++ int ret = 0; ++ bool callsub = (intf == info->control && info->subdriver && ++ info->subdriver->resume); ++ ++ if (callsub) ++ ret = info->subdriver->resume(intf); ++ if (ret < 0) ++ goto err; ++ ret = usbnet_resume(intf); ++ if (ret < 0 && callsub) ++ info->subdriver->suspend(intf, PMSG_SUSPEND); ++ ++#if defined(QUECTEL_WWAN_QMAP) ++ if (!netif_queue_stopped(dev->net)) { ++ qmap_wake_queue((sQmiWwanQmap *)info->unused); ++ } ++#endif ++ ++err: ++ return ret; ++} ++ ++static int qmi_wwan_reset_resume(struct usb_interface *intf) ++{ ++ dev_info(&intf->dev, "device do not support reset_resume\n"); ++ intf->needs_binding = 1; ++ return -EOPNOTSUPP; ++} ++ ++static struct sk_buff *rmnet_usb_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) ++{ ++ //printk("%s skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len); ++ if (skb->protocol != htons(ETH_P_MAP)) { ++ dev_kfree_skb_any(skb); ++ return NULL; ++ } ++ ++ return skb; ++} ++ ++static int rmnet_usb_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ struct net_device *net = dev->net; ++ unsigned headroom = skb_headroom(skb); ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION( 3,3,1 )) //7bdd402706cf26bfef9050dfee3f229b7f33ee4f ++//some customers port to v3.2 ++ if (net->type == ARPHRD_ETHER && headroom < ETH_HLEN) { ++ unsigned tailroom = skb_tailroom(skb); ++ ++ if ((tailroom + headroom) >= ETH_HLEN) { ++ unsigned moveroom = ETH_HLEN - headroom; ++ ++ memmove(skb->data + moveroom ,skb->data, skb->len); ++ skb->data += moveroom; ++ skb->tail += moveroom; ++ #ifdef WARN_ONCE ++ WARN_ONCE(1, "It is better reserve headroom in usbnet.c:rx_submit()!\n"); ++ #endif ++ } ++ } ++#endif ++ ++ //printk("%s skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len); ++ if (net->type == ARPHRD_ETHER && headroom >= ETH_HLEN) { ++ //usbnet.c rx_process() usbnet_skb_return() eth_type_trans() ++ skb_push(skb, ETH_HLEN); ++ skb_reset_mac_header(skb); ++ memcpy(eth_hdr(skb)->h_source, default_modem_addr, ETH_ALEN); ++ memcpy(eth_hdr(skb)->h_dest, net->dev_addr, ETH_ALEN); ++ eth_hdr(skb)->h_proto = htons(ETH_P_MAP); ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static rx_handler_result_t rmnet_usb_rx_handler(struct sk_buff **pskb) ++{ ++ struct sk_buff *skb = *pskb; ++ struct usbnet *dev; ++ struct qmi_wwan_state *info; ++ sQmiWwanQmap *pQmapDev; ++ struct sk_buff *qmap_skb; ++ struct sk_buff_head skb_chain; ++ ++ if (!skb) ++ goto done; ++ ++ //printk("%s skb=%p, protocol=%x, len=%d\n", __func__, skb, skb->protocol, skb->len); ++ ++ if (skb->pkt_type == PACKET_LOOPBACK) ++ return RX_HANDLER_PASS; ++ ++ if (skb->protocol != htons(ETH_P_MAP)) { ++ WARN_ON(1); ++ return RX_HANDLER_PASS; ++ } ++ /* when open hyfi function, run cm will make system crash */ ++ //dev = rcu_dereference(skb->dev->rx_handler_data); ++ dev = netdev_priv(skb->dev); ++ ++ if (dev == NULL) { ++ WARN_ON(1); ++ return RX_HANDLER_PASS; ++ } ++ ++ info = (struct qmi_wwan_state *)&dev->data; ++ pQmapDev = (sQmiWwanQmap *)info->unused; ++ ++ qmap_packet_decode(pQmapDev, skb, &skb_chain); ++ while ((qmap_skb = __skb_dequeue (&skb_chain))) { ++ struct net_device *qmap_net = qmap_skb->dev; ++ ++ rmnet_vnd_update_rx_stats(qmap_net, 1, qmap_skb->len); ++ if (qmap_net->type == ARPHRD_ETHER) ++ __skb_pull(qmap_skb, ETH_HLEN); ++ netif_receive_skb(qmap_skb); ++ } ++ consume_skb(skb); ++ ++done: ++ return RX_HANDLER_CONSUMED; ++} ++ ++static const struct driver_info qmi_wwan_info = { ++ .description = "WWAN/QMI device", ++ .flags = FLAG_WWAN, ++ .bind = qmi_wwan_bind, ++ .unbind = qmi_wwan_unbind, ++ .manage_power = qmi_wwan_manage_power, ++}; ++ ++#define qmi_wwan_raw_ip_info \ ++ .description = "WWAN/QMI device", \ ++ .flags = FLAG_WWAN | FLAG_RX_ASSEMBLE | FLAG_NOARP | FLAG_SEND_ZLP, \ ++ .bind = qmi_wwan_bind, \ ++ .unbind = qmi_wwan_unbind, \ ++ .manage_power = qmi_wwan_manage_power, \ ++ .tx_fixup = qmap_qmi_wwan_tx_fixup, \ ++ .rx_fixup = qmap_qmi_wwan_rx_fixup, \ ++ ++static const struct driver_info rmnet_usb_info = { ++ .description = "RMNET/USB device", ++ .flags = FLAG_WWAN | FLAG_NOARP | FLAG_SEND_ZLP, ++ .bind = qmi_wwan_bind, ++ .unbind = qmi_wwan_unbind, ++ .manage_power = qmi_wwan_manage_power, ++ .tx_fixup = rmnet_usb_tx_fixup, ++ .rx_fixup = rmnet_usb_rx_fixup, ++}; ++ ++static const struct driver_info qmi_wwan_raw_ip_info_mdm9x07 = { ++ qmi_wwan_raw_ip_info ++ .data = (5<<8)|4, //QMAPV1 and 4KB ++}; ++ ++// mdm9x40/sdx12/sdx20/sdx24 share the same config ++static const struct driver_info qmi_wwan_raw_ip_info_mdm9x40 = { ++ qmi_wwan_raw_ip_info ++ .data = (5<<8)|16, //QMAPV1 and 16KB ++}; ++ ++static const struct driver_info qmi_wwan_raw_ip_info_sdx55 = { ++ qmi_wwan_raw_ip_info ++ .data = (9<<8)|31, //QMAPV5 and 31KB ++}; ++ ++/* map QMI/wwan function by a fixed interface number */ ++#define QMI_FIXED_INTF(vend, prod, num) \ ++ USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \ ++ .driver_info = (unsigned long)&qmi_wwan_info ++ ++#define QMI_FIXED_RAWIP_INTF(vend, prod, num, chip) \ ++ USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \ ++ .driver_info = (unsigned long)&qmi_wwan_raw_ip_info_##chip ++ ++static const struct usb_device_id products[] = { ++ { QMI_FIXED_INTF(0x05C6, 0x9003, 4) }, /* Quectel UC20 */ ++ { QMI_FIXED_INTF(0x05C6, 0x9215, 4) }, /* Quectel EC20 (MDM9215) */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0125, 4, mdm9x07) }, /* Quectel EC20 (MDM9X07)/EC25/EG25 */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0121, 4, mdm9x07) }, /* Quectel EC21 */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0191, 4, mdm9x07) }, /* Quectel EG91 */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0195, 4, mdm9x07) }, /* Quectel EG95 */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0700, 3, mdm9x07) }, /* Quectel BG95 (at+qcfgext="usbnet","rmnet") */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0306, 4, mdm9x40) }, /* Quectel EG06/EP06/EM06 */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x030B, 4, mdm9x40) }, /* Quectel EG065k/EG060K */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0512, 4, mdm9x40) }, /* Quectel EG12/EP12/EM12/EG16/EG18 */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0296, 4, mdm9x07) }, /* Quectel BG96 */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0435, 4, mdm9x07) }, /* Quectel AG35 */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0620, 4, mdm9x40) }, /* Quectel EG20 */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0800, 4, sdx55) }, /* Quectel RG500 */ ++ { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0801, 4, sdx55) }, /* Quectel RG520 */ ++ { } /* END */ ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static int qmi_wwan_probe(struct usb_interface *intf, ++ const struct usb_device_id *prod) ++{ ++ struct usb_device_id *id = (struct usb_device_id *)prod; ++ ++ /* Workaround to enable dynamic IDs. This disables usbnet ++ * blacklisting functionality. Which, if required, can be ++ * reimplemented here by using a magic "blacklist" value ++ * instead of 0 in the static device id table ++ */ ++ if (!id->driver_info) { ++ dev_dbg(&intf->dev, "setting defaults for dynamic device id\n"); ++ id->driver_info = (unsigned long)&qmi_wwan_info; ++ } ++ ++ if (intf->cur_altsetting->desc.bInterfaceClass != 0xff) { ++ dev_info(&intf->dev, "Quectel module not qmi_wwan mode! please check 'at+qcfg=\"usbnet\"'\n"); ++ return -ENODEV; ++ } ++ ++ return usbnet_probe(intf, id); ++} ++ ++#if defined(QUECTEL_WWAN_QMAP) ++static int qmap_qmi_wwan_probe(struct usb_interface *intf, ++ const struct usb_device_id *prod) ++{ ++ int status = qmi_wwan_probe(intf, prod); ++ ++ if (!status) { ++ struct usbnet *dev = usb_get_intfdata(intf); ++ struct qmi_wwan_state *info = (void *)&dev->data; ++ sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused; ++ unsigned i; ++ ++ if (!pQmapDev) ++ return status; ++ ++ tasklet_init(&pQmapDev->txq, rmnet_usb_tx_wake_queue, (unsigned long)pQmapDev); ++ ++ if (pQmapDev->qmap_mode == 1) { ++ pQmapDev->mpQmapNetDev[0] = dev->net; ++ if (pQmapDev->use_rmnet_usb && !one_card_mode) { ++ pQmapDev->mpQmapNetDev[0] = NULL; ++ qmap_register_device(pQmapDev, 0); ++ } ++ } ++ else if (pQmapDev->qmap_mode > 1) { ++ for (i = 0; i < pQmapDev->qmap_mode; i++) { ++ qmap_register_device(pQmapDev, i); ++ } ++ } ++ ++ if (pQmapDev->use_rmnet_usb && !one_card_mode) { ++ rtnl_lock(); ++ /* when open hyfi function, run cm will make system crash */ ++ //netdev_rx_handler_register(dev->net, rmnet_usb_rx_handler, dev); ++ netdev_rx_handler_register(dev->net, rmnet_usb_rx_handler, NULL); ++ rtnl_unlock(); ++ } ++ ++ if (pQmapDev->link_state == 0) { ++ netif_carrier_off(dev->net); ++ } ++ } ++ ++ return status; ++} ++ ++static void qmap_qmi_wwan_disconnect(struct usb_interface *intf) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ struct qmi_wwan_state *info; ++ sQmiWwanQmap *pQmapDev; ++ uint i; ++ ++ if (!dev) ++ return; ++ ++ info = (void *)&dev->data; ++ pQmapDev = (sQmiWwanQmap *)info->unused; ++ ++ if (!pQmapDev) { ++ return usbnet_disconnect(intf); ++ } ++ ++ pQmapDev->link_state = 0; ++ ++ if (pQmapDev->qmap_mode > 1) { ++ for (i = 0; i < pQmapDev->qmap_mode; i++) { ++ qmap_unregister_device(pQmapDev, i); ++ } ++ } ++ ++ if (pQmapDev->use_rmnet_usb && !one_card_mode) { ++ qmap_unregister_device(pQmapDev, 0); ++ rtnl_lock(); ++ netdev_rx_handler_unregister(dev->net); ++ rtnl_unlock(); ++ } ++ ++ tasklet_kill(&pQmapDev->txq); ++ ++ usbnet_disconnect(intf); ++ /* struct usbnet *dev had free by usbnet_disconnect()->free_netdev(). ++ so we should access info. */ ++ //info->unused = 0; ++ kfree(pQmapDev); ++} ++#endif ++ ++static struct usb_driver qmi_wwan_driver = { ++ .name = "qmi_wwan_q", ++ .id_table = products, ++ .probe = qmi_wwan_probe, ++#if defined(QUECTEL_WWAN_QMAP) ++ .probe = qmap_qmi_wwan_probe, ++ .disconnect = qmap_qmi_wwan_disconnect, ++#else ++ .probe = qmi_wwan_probe, ++ .disconnect = usbnet_disconnect, ++#endif ++ .suspend = qmi_wwan_suspend, ++ .resume = qmi_wwan_resume, ++ .reset_resume = qmi_wwan_reset_resume, ++ .supports_autosuspend = 1, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++static int __init qmi_wwan_driver_init(void) ++{ ++#ifdef CONFIG_QCA_NSS_DRV ++ nss_cb = rcu_dereference(rmnet_nss_callbacks); ++ if (!nss_cb) { ++ printk(KERN_ERR "qmi_wwan_driver_init: driver load must after '/etc/modules.d/42-rmnet-nss'\n"); ++ } ++#endif ++ return usb_register(&qmi_wwan_driver); ++} ++module_init(qmi_wwan_driver_init); ++static void __exit qmi_wwan_driver_exit(void) ++{ ++ usb_deregister(&qmi_wwan_driver); ++} ++module_exit(qmi_wwan_driver_exit); ++ ++MODULE_AUTHOR("Bjørn Mork <bjorn@mork.no>"); ++MODULE_DESCRIPTION("Qualcomm MSM Interface (QMI) WWAN driver"); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION(QUECTEL_WWAN_VERSION); +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 691fd8ab7..372241cd5 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -99,6 +99,9 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc) + dwc->dr_mode = mode; + } + ++ /* Add by linke */ ++ dwc->dr_mode = USB_DR_MODE_OTG; ++ + return 0; + } + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 697683e3f..3fe38fb85 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -198,8 +198,6 @@ static void option_instat_callback(struct urb *urb); + + #define DELL_PRODUCT_5821E 0x81d7 + #define DELL_PRODUCT_5821E_ESIM 0x81e0 +-#define DELL_PRODUCT_5829E_ESIM 0x81e4 +-#define DELL_PRODUCT_5829E 0x81e6 + + #define KYOCERA_VENDOR_ID 0x0c88 + #define KYOCERA_PRODUCT_KPC650 0x17da +@@ -252,14 +250,10 @@ static void option_instat_callback(struct urb *urb); + #define QUECTEL_PRODUCT_EG95 0x0195 + #define QUECTEL_PRODUCT_BG96 0x0296 + #define QUECTEL_PRODUCT_EP06 0x0306 +-#define QUECTEL_PRODUCT_EM05G 0x030a +-#define QUECTEL_PRODUCT_EM060K 0x030b + #define QUECTEL_PRODUCT_EM12 0x0512 + #define QUECTEL_PRODUCT_RM500Q 0x0800 +-#define QUECTEL_PRODUCT_RM520N 0x0801 + #define QUECTEL_PRODUCT_EC200S_CN 0x6002 + #define QUECTEL_PRODUCT_EC200T 0x6026 +-#define QUECTEL_PRODUCT_RM500K 0x7001 + + #define CMOTECH_VENDOR_ID 0x16d8 + #define CMOTECH_PRODUCT_6001 0x6001 +@@ -436,12 +430,6 @@ static void option_instat_callback(struct urb *urb); + #define CINTERION_PRODUCT_CLS8 0x00b0 + #define CINTERION_PRODUCT_MV31_MBIM 0x00b3 + #define CINTERION_PRODUCT_MV31_RMNET 0x00b7 +-#define CINTERION_PRODUCT_MV31_2_MBIM 0x00b8 +-#define CINTERION_PRODUCT_MV31_2_RMNET 0x00b9 +-#define CINTERION_PRODUCT_MV32_WA 0x00f1 +-#define CINTERION_PRODUCT_MV32_WB 0x00f2 +-#define CINTERION_PRODUCT_MV32_WA_RMNET 0x00f3 +-#define CINTERION_PRODUCT_MV32_WB_RMNET 0x00f4 + + /* Olivetti products */ + #define OLIVETTI_VENDOR_ID 0x0b3c +@@ -577,10 +565,6 @@ static void option_instat_callback(struct urb *urb); + #define WETELECOM_PRODUCT_6802 0x6802 + #define WETELECOM_PRODUCT_WMD300 0x6803 + +-/* OPPO products */ +-#define OPPO_VENDOR_ID 0x22d9 +-#define OPPO_PRODUCT_R11 0x276c +- + + /* Device flags */ + +@@ -601,6 +585,32 @@ static void option_instat_callback(struct urb *urb); + + + static const struct usb_device_id option_ids[] = { ++#if 1 //Added by Quectel ++ { USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */ ++ { USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */ ++ { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20(MDM9215) */ ++ { USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC20(MDM9x07)/EC25/EG25 */ ++ { USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */ ++ { USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */ ++ { USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */ ++ { USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */ ++ { USB_DEVICE(0x2C7C, 0x030B) }, /* Quectel EG065K/EG060K */ ++ { USB_DEVICE(0x2C7C, 0x0514) }, /* Quectel BL EG060K RNDIS Only */ ++ { USB_DEVICE(0x2C7C, 0x0512) }, /* Quectel EG12/EP12/EM12/EG16/EG18 */ ++ { USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */ ++ { USB_DEVICE(0x2C7C, 0x0700) }, /* Quectel BG95/BG77/BG600L-M3/BC69 */ ++ { USB_DEVICE(0x2C7C, 0x0435) }, /* Quectel AG35 */ ++ { USB_DEVICE(0x2C7C, 0x0415) }, /* Quectel AG15 */ ++ { USB_DEVICE(0x2C7C, 0x0452) }, /* Quectel AG520 */ ++ { USB_DEVICE(0x2C7C, 0x0455) }, /* Quectel AG550 */ ++ { USB_DEVICE(0x2C7C, 0x0620) }, /* Quectel EG20 */ ++ { USB_DEVICE(0x2C7C, 0x0800) }, /* Quectel RG500/RM500/RG510/RM510 */ ++ { USB_DEVICE(0x2C7C, 0x0801) }, /* Quectel RG520/RM520/SG520 */ ++ { USB_DEVICE(0x2C7C, 0x6026) }, /* Quectel EC200 */ ++ { USB_DEVICE(0x2C7C, 0x6120) }, /* Quectel UC200 */ ++ { USB_DEVICE(0x2C7C, 0x6000) }, /* Quectel EC200/UC200 */ ++ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR, .idVendor = 0x2C7C }, /* Match All Quectel Modules */ ++#endif + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) }, +@@ -1079,10 +1089,6 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5821E_ESIM), + .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E), +- .driver_info = RSVD(0) | RSVD(6) }, +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E_ESIM), +- .driver_info = RSVD(0) | RSVD(6) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, +@@ -1139,35 +1145,22 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0xff, 0xff), + .driver_info = NUMEP2 }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0, 0) }, +- { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 0x0203, 0xff), /* BG95-M3 */ +- .driver_info = ZLP }, + { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), + .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), + .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, +- { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff), +- .driver_info = RSVD(6) | ZLP }, +- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) }, +- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) }, +- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), + .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0xff, 0x30) }, /* EM160R-GL */ + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0, 0) }, +- { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 0x0700, 0xff), /* BG95 */ +- .driver_info = RSVD(3) | ZLP }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10), + .driver_info = ZLP }, +- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0xff, 0x30) }, +- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0x40) }, +- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, + + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, +@@ -1244,10 +1237,6 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1056, 0xff), /* Telit FD980 */ + .driver_info = NCTRL(2) | RSVD(3) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1057, 0xff), /* Telit FN980 */ +- .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1058, 0xff), /* Telit FN980 (PCIe) */ +- .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1060, 0xff), /* Telit LN920 (rmnet) */ + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1061, 0xff), /* Telit LN920 (MBIM) */ +@@ -1264,8 +1253,6 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(2) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */ + .driver_info = NCTRL(0) | RSVD(1) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990 (PCIe) */ +- .driver_info = RSVD(0) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), + .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), +@@ -1300,7 +1287,6 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1231, 0xff), /* Telit LE910Cx (RNDIS) */ + .driver_info = NCTRL(2) | RSVD(3) }, +- { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x1250, 0xff, 0x00, 0x00) }, /* Telit LE910Cx (rmnet) */ + { USB_DEVICE(TELIT_VENDOR_ID, 0x1260), + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, + { USB_DEVICE(TELIT_VENDOR_ID, 0x1261), +@@ -1313,16 +1299,10 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(2) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7011, 0xff), /* Telit LE910-S1 (ECM) */ + .driver_info = NCTRL(2) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x701a, 0xff), /* Telit LE910R1 (RNDIS) */ +- .driver_info = NCTRL(2) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x701b, 0xff), /* Telit LE910R1 (ECM) */ +- .driver_info = NCTRL(2) }, + { USB_DEVICE(TELIT_VENDOR_ID, 0x9010), /* Telit SBL FN980 flashing device */ + .driver_info = NCTRL(0) | ZLP }, + { USB_DEVICE(TELIT_VENDOR_ID, 0x9200), /* Telit LE910S1 flashing device */ + .driver_info = NCTRL(0) | ZLP }, +- { USB_DEVICE(TELIT_VENDOR_ID, 0x9201), /* Telit LE910R1 flashing device */ +- .driver_info = NCTRL(0) | ZLP }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), + .driver_info = RSVD(1) }, +@@ -1695,8 +1675,6 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(2) }, + { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x1476, 0xff) }, /* GosunCn ZTE WeLink ME3630 (ECM/NCM mode) */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1481, 0xff, 0x00, 0x00) }, /* ZTE MF871A */ +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1485, 0xff, 0xff, 0xff), /* ZTE MF286D */ +- .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) }, +@@ -2003,18 +1981,6 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(3)}, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff), + .driver_info = RSVD(0)}, +- { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_2_MBIM, 0xff), +- .driver_info = RSVD(3)}, +- { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_2_RMNET, 0xff), +- .driver_info = RSVD(0)}, +- { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff), +- .driver_info = RSVD(3)}, +- { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA_RMNET, 0xff), +- .driver_info = RSVD(0) }, +- { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB, 0xff), +- .driver_info = RSVD(3)}, +- { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB_RMNET, 0xff), +- .driver_info = RSVD(0) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100), + .driver_info = RSVD(4) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120), +@@ -2157,14 +2123,10 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(3) }, + { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */ + .driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, +- { USB_DEVICE(0x1782, 0x4d10) }, /* Fibocom L610 (AT mode) */ +- { USB_DEVICE_INTERFACE_CLASS(0x1782, 0x4d11, 0xff) }, /* Fibocom L610 (ECM/RNDIS mode) */ + { USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */ + .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ + .driver_info = RSVD(6) }, +- { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0106, 0xff) }, /* Fibocom MA510 (ECM mode w/ diag intf.) */ +- { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x010a, 0xff) }, /* Fibocom MA510 (ECM mode) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) }, /* Fibocom FG150 Diag */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) }, /* Fibocom FG150 AT */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ +@@ -2175,7 +2137,6 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ +- { USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) }, + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, option_ids); +@@ -2184,7 +2145,26 @@ MODULE_DEVICE_TABLE(usb, option_ids); + * recognizes separately, thus num_port=1. + */ + ++#if 1 //Added by Quectel ++static void cfmakeraw(struct ktermios *t) ++{ ++ t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); ++ t->c_oflag &= ~OPOST; ++ t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); ++ t->c_cflag &= ~(CSIZE|PARENB); ++ t->c_cflag |= CS8; ++ t->c_cc[VMIN] = 1; ++ t->c_cc[VTIME] = 0; ++} ++ ++static void option_init_termios(struct tty_struct *tty) ++{ ++ cfmakeraw(&tty->termios); ++} ++#endif ++ + static struct usb_serial_driver option_1port_device = { ++ .init_termios = option_init_termios, + .driver = { + .owner = THIS_MODULE, + .name = "option1", +@@ -2209,6 +2189,9 @@ static struct usb_serial_driver option_1port_device = { + #ifdef CONFIG_PM + .suspend = usb_wwan_suspend, + .resume = usb_wwan_resume, ++#if 1 //Added by Quectel ++ .reset_resume = usb_wwan_resume, ++#endif + #endif + }; + +@@ -2233,6 +2216,35 @@ static int option_probe(struct usb_serial *serial, + &serial->interface->cur_altsetting->desc; + unsigned long device_flags = id->driver_info; + ++#if 1 //Added by Quectel ++ //Quectel UC20's interface 4 can be used as USB Network device ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9003) ++ && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) ++ return -ENODEV; ++ ++ //Quectel EC20(MDM9215)'s interface 4 can be used as USB Network device ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9215) ++ && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) ++ return -ENODEV; ++ ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) { ++ __u16 idProduct = le16_to_cpu(serial->dev->descriptor.idProduct); ++ struct usb_interface_descriptor *intf = &serial->interface->cur_altsetting->desc; ++ ++ if (intf->bInterfaceClass != 0xFF || intf->bInterfaceSubClass == 0x42) { ++ //ECM, RNDIS, NCM, MBIM, ACM, UAC, ADB ++ return -ENODEV; ++ } ++ ++ if ((idProduct&0xF000) == 0x0000) { ++ //MDM interface 4 is QMI ++ if (intf->bInterfaceNumber == 4 && intf->bNumEndpoints == 3 ++ && intf->bInterfaceSubClass == 0xFF && intf->bInterfaceProtocol == 0xFF) ++ return -ENODEV; ++ } ++ } ++#endif ++ + /* Never bind to the CD-Rom emulation interface */ + if (iface_desc->bInterfaceClass == USB_CLASS_MASS_STORAGE) + return -ENODEV; +@@ -2346,7 +2358,7 @@ static void option_instat_callback(struct urb *urb) + dev_dbg(dev, "%s: error %d\n", __func__, status); + + /* Resubmit urb so we continue receiving IRQ data */ +- if (status != -ESHUTDOWN && status != -ENOENT) { ++ if (status != -ESHUTDOWN && status != -ENOENT && status != -EPROTO) { + usb_mark_last_busy(port->serial->dev); + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err) +diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c +index f21f25a8c..27e642dbd 100644 +--- a/drivers/usb/serial/usb_wwan.c ++++ b/drivers/usb/serial/usb_wwan.c +@@ -227,7 +227,7 @@ static void usb_wwan_indat_callback(struct urb *urb) + __func__, status, endpoint); + + /* don't resubmit on fatal errors */ +- if (status == -ESHUTDOWN || status == -ENOENT) ++ if (status == -ESHUTDOWN || status == -ENOENT || status == -EPROTO) + return; + } else { + if (urb->actual_length) { +@@ -389,8 +389,7 @@ void usb_wwan_close(struct usb_serial_port *port) + + /* + * Need to take susp_lock to make sure port is not already being +- * resumed, but no need to hold it due to the tty-port initialized +- * flag. ++ * resumed, but no need to hold it due to initialized + */ + spin_lock_irq(&intfdata->susp_lock); + if (--intfdata->open_ports == 0) +@@ -432,6 +431,19 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, + usb_sndbulkpipe(serial->dev, endpoint) | dir, + buf, len, callback, ctx); + ++#if 1 //Added by Quectel for Zero Packet ++ if (dir == USB_DIR_OUT) { ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9090)) ++ urb->transfer_flags |= URB_ZERO_PACKET; ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)) ++ urb->transfer_flags |= URB_ZERO_PACKET; ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)) ++ urb->transfer_flags |= URB_ZERO_PACKET; ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) ++ urb->transfer_flags |= URB_ZERO_PACKET; ++ } ++#endif ++ + if (intfdata->use_zlp && dir == USB_DIR_OUT) + urb->transfer_flags |= URB_ZERO_PACKET; + +diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c +index a8823e317..60479eb03 100644 +--- a/drivers/video/backlight/pwm_bl.c ++++ b/drivers/video/backlight/pwm_bl.c +@@ -552,6 +552,8 @@ static int pwm_backlight_probe(struct platform_device *pdev) + if (!state.period && (data->pwm_period_ns > 0)) + state.period = data->pwm_period_ns; + ++ state.enabled = true;/*add for eable default backlight*/ ++ + ret = pwm_apply_state(pb->pwm, &state); + if (ret) { + dev_err(&pdev->dev, "failed to apply initial PWM state: %d\n", +diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c +index 7e21829f2..d39d9ebf2 100644 +--- a/sound/soc/fsl/fsl-asoc-card.c ++++ b/sound/soc/fsl/fsl-asoc-card.c +@@ -27,6 +27,7 @@ + #include "../codecs/wm8962.h" + #include "../codecs/wm8960.h" + #include "../codecs/wm8994.h" ++#include "../codecs/nau8822.h" + + #define CS427x_SYSCLK_MCLK 0 + +@@ -48,6 +49,7 @@ enum fsl_asoc_card_type { + CARD_WM8524, + CARD_SI476X, + CARD_WM8958, ++ CARD_NAU8822, + }; + + /** +@@ -59,6 +61,7 @@ enum fsl_asoc_card_type { + * @pll_id: PLL id for set_pll() + */ + struct codec_priv { ++ struct clk *mclk; /* add by weihuihong */ + unsigned long mclk_freq; + unsigned long free_freq; + u32 mclk_id; +@@ -226,6 +229,8 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream, + + /* Specific configuration for PLL */ + if (codec_priv->pll_id && codec_priv->fll_id) { ++ if (!IS_ERR(codec_priv->mclk)) ++ clk_prepare_enable(codec_priv->mclk); /* add by weihuihong for enable mclk for nau8822 */ + if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE || + priv->sample_format == SNDRV_PCM_FORMAT_S20_3LE) + pll_out = priv->sample_rate * 384; +@@ -334,6 +339,7 @@ static int fsl_asoc_card_hw_free(struct snd_pcm_substream *substream) + dev_err(dev, "failed to stop FLL: %d\n", ret); + return ret; + } ++ clk_disable_unprepare(codec_priv->mclk);/* add by weihuihong */ + } + + return 0; +@@ -764,6 +770,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) + } + } + ++ dev_info(codec_dev, "codec mclk freq is %ld", priv->codec_priv.mclk_freq); /* add by weihuihong */ ++ + /* Default sample rate and format, will be updated in hw_params() */ + priv->sample_rate = 44100; + priv->sample_format = SNDRV_PCM_FORMAT_S16_LE; +@@ -813,6 +821,15 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) + priv->codec_priv.pll_id = WM8960_SYSCLK_AUTO; + priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; + priv->card_type = CARD_WM8960; ++ } else if (of_device_is_compatible(np, "fsl,imx-audio-nau8822")) { /* add by weihuihong */ ++ codec_dai_name = "nau8822-hifi"; ++ priv->codec_priv.mclk_id = NAU8822_CLK_MCLK; ++ priv->codec_priv.fll_id = NAU8822_CLK_PLL;//second clk ++ priv->codec_priv.pll_id = NAU8822_CLK_PLL; ++ priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; ++ priv->card_type = CARD_NAU8822; ++ if (codec_dev) ++ priv->codec_priv.mclk = devm_clk_get(codec_dev, NULL); + } else if (of_device_is_compatible(np, "fsl,imx-audio-ac97")) { + codec_dai_name = "ac97-hifi"; + priv->dai_fmt = SND_SOC_DAIFMT_AC97; +@@ -1171,6 +1188,7 @@ static const struct of_device_id fsl_asoc_card_dt_ids[] = { + { .compatible = "fsl,imx-audio-wm8524", }, + { .compatible = "fsl,imx-audio-si476x", }, + { .compatible = "fsl,imx-audio-wm8958", }, ++ { .compatible = "fsl,imx-audio-nau8822", }, + {} + }; + MODULE_DEVICE_TABLE(of, fsl_asoc_card_dt_ids); -- Gitblit v1.9.1