From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stefano Babic Date: Mon, 22 Jan 2018 15:00:36 +0100 Subject: [U-Boot] [PATCH V5 31/31] imx: add i.MX8MQ EVK support In-Reply-To: <20180110052048.4425-32-peng.fan@nxp.com> References: <20180110052048.4425-1-peng.fan@nxp.com> <20180110052048.4425-32-peng.fan@nxp.com> Message-ID: <41e2e905-173d-afe6-f3e0-047f82bf5d08@denx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Peng, On 10/01/2018 06:20, Peng Fan wrote: > Add i.MX8MQ EVK support. SPL will initialize ddr and load ddr phy > firmware. Then loading FIT image, ATF to OCRAM, U-Boot and DTB to > DRAM. > > The boot log with Arm trusted firmware console enabled: > " > U-Boot SPL 2018.01-00038-gbd426c08ea (Jan 10 2018 - 13:14:56) > PMIC: PFUZE100 ID=0x10 > Normal Boot > Trying to boot from MMC2 > NOTICE: Configureing TZASC380 > NOTICE: BL31: v1.4(release):o8.0.0_1.3.0_8m-prc-20171211-6-g54fb0797-dirty > NOTICE: BL31: Built : 07:17:16, Jan 8 2018 > NOTICE: sip svc init > > U-Boot 2018.01-00038-gbd426c08ea (Jan 10 2018 - 13:14:56 +0800) > > CPU: Freescale i.MX8MQ rev2.0 at 1000 MHz > Reset cause: POR > Model: Freescale i.MX8MQ EVK > DRAM: 3 GiB > MMC: FSL_SDHC: 0, FSL_SDHC: 1 > Using default environment > > In: serial > Out: serial > Err: serial > Net: No ethernet found. > Hit any key to stop autoboot: 0 > u-boot=> > " If I see the output here, I am expecting the setup forthe working peripherals. Without ethernet working, why do we activate FEC and set the PHY ? I would suggest to start with the minimal (=that is, all that is working), adding later when peripherals will be successfully added and tested. > > Signed-off-by: Peng Fan > Cc: Fabio Estevam > Cc: Stefano Babic > --- > arch/arm/dts/Makefile | 2 + > arch/arm/dts/fsl-imx8mq-evk.dts | 424 +++++++++ > arch/arm/include/asm/arch-mx8m/ddr.h | 9 + > arch/arm/mach-imx/mx8m/Kconfig | 12 + > board/freescale/mx8mq_evk/Kconfig | 12 + > board/freescale/mx8mq_evk/Makefile | 12 + > board/freescale/mx8mq_evk/README | 47 + > board/freescale/mx8mq_evk/ddr/ddr_init.c | 246 +++++ > board/freescale/mx8mq_evk/ddr/ddrphy_train.c | 1272 ++++++++++++++++++++++++++ > board/freescale/mx8mq_evk/ddr/helper.c | 101 ++ > board/freescale/mx8mq_evk/mx8mq_evk.c | 156 ++++ > board/freescale/mx8mq_evk/spl.c | 230 +++++ > configs/mx8mq_evk_defconfig | 27 + > include/configs/mx8mq_evk.h | 269 ++++++ > 14 files changed, 2819 insertions(+) > create mode 100644 arch/arm/dts/fsl-imx8mq-evk.dts > create mode 100644 board/freescale/mx8mq_evk/Kconfig > create mode 100644 board/freescale/mx8mq_evk/Makefile > create mode 100644 board/freescale/mx8mq_evk/README > create mode 100644 board/freescale/mx8mq_evk/ddr/ddr_init.c > create mode 100644 board/freescale/mx8mq_evk/ddr/ddrphy_train.c > create mode 100644 board/freescale/mx8mq_evk/ddr/helper.c > create mode 100644 board/freescale/mx8mq_evk/mx8mq_evk.c > create mode 100644 board/freescale/mx8mq_evk/spl.c > create mode 100644 configs/mx8mq_evk_defconfig > create mode 100644 include/configs/mx8mq_evk.h > > diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile > index a895c70284..299107977f 100644 > --- a/arch/arm/dts/Makefile > +++ b/arch/arm/dts/Makefile > @@ -391,6 +391,8 @@ dtb-$(CONFIG_MX7) += imx7-colibri.dtb \ > > dtb-$(CONFIG_ARCH_MX7ULP) += imx7ulp-evk.dtb > > +dtb-$(CONFIG_ARCH_MX8M) += fsl-imx8mq-evk.dtb > + > dtb-$(CONFIG_RCAR_GEN3) += \ > r8a7795-h3ulcb.dtb \ > r8a7795-salvator-x.dtb \ > diff --git a/arch/arm/dts/fsl-imx8mq-evk.dts b/arch/arm/dts/fsl-imx8mq-evk.dts > new file mode 100644 > index 0000000000..f0aa3485e6 > --- /dev/null > +++ b/arch/arm/dts/fsl-imx8mq-evk.dts > @@ -0,0 +1,424 @@ > +/* > + * Copyright (C) 2016 Freescale Semiconductor, Inc. > + * Copyright 2017 NXP > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +/dts-v1/; > + > +/* First 128KB is for PSCI ATF. */ > +/memreserve/ 0x40000000 0x00020000; > + > +#include "fsl-imx8mq.dtsi" > + > +/ { > + model = "Freescale i.MX8MQ EVK"; > + compatible = "fsl,imx8mq-evk", "fsl,imx8mq"; > + > + chosen { > + bootargs = "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200"; > + }; > + > + regulators { > + compatible = "simple-bus"; > + #address-cells = <1>; > + #size-cells = <0>; > + > + reg_usdhc2_vmmc: usdhc2_vmmc { > + compatible = "regulator-fixed"; > + regulator-name = "VSD_3V3"; > + regulator-min-microvolt = <3300000>; > + regulator-max-microvolt = <3300000>; > + gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; > + enable-active-high; > + }; > + }; > + > + pwmleds { > + compatible = "pwm-leds"; > + > + ledpwm2 { > + label = "PWM2"; > + pwms = <&pwm2 0 50000>; > + max-brightness = <255>; > + }; > + }; > +}; > + > +&iomuxc { > + pinctrl-names = "default"; > + > + imx8mq-evk { > + pinctrl_fec1: fec1grp { > + fsl,pins = < > + MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3 > + MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23 > + MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f > + MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f > + MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f > + MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f > + MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 > + MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 > + MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 > + MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 > + MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f > + MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 > + MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 > + MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f > + MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 > + >; > + }; > + > + pinctrl_i2c1: i2c1grp { > + fsl,pins = < > + MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x4000007f > + MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x4000007f > + >; > + }; > + > + pinctrl_i2c2: i2c2grp { > + fsl,pins = < > + MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x4000007f > + MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x4000007f > + >; > + }; > + > + pinctrl_pwm2: pwm2grp { > + fsl,pins = < > + MX8MQ_IOMUXC_GPIO1_IO13_PWM2_OUT 0x16 > + >; > + }; > + > + pinctrl_qspi: qspigrp { > + fsl,pins = < > + MX8MQ_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x82 > + MX8MQ_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x82 > + MX8MQ_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x82 > + MX8MQ_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x82 > + MX8MQ_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x82 > + MX8MQ_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x82 > + > + >; > + }; > + > + pinctrl_usdhc1: usdhc1grp { > + fsl,pins = < > + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83 > + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc3 > + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc3 > + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc3 > + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc3 > + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc3 > + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc3 > + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc3 > + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc3 > + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc3 > + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x83 > + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 > + >; > + }; > + > + pinctrl_usdhc1_100mhz: usdhc1grp100mhz { > + fsl,pins = < > + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x85 > + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc5 > + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc5 > + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc5 > + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc5 > + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc5 > + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc5 > + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc5 > + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc5 > + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc5 > + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x85 > + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 > + >; > + }; > + > + pinctrl_usdhc1_200mhz: usdhc1grp200mhz { > + fsl,pins = < > + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x87 > + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc7 > + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc7 > + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc7 > + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc7 > + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc7 > + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc7 > + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc7 > + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc7 > + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc7 > + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x87 > + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 > + >; > + }; > + > + pinctrl_usdhc2_gpio: usdhc2grpgpio { > + fsl,pins = < > + MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x41 > + MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 > + >; > + }; > + > + pinctrl_usdhc2: usdhc2grp { > + fsl,pins = < > + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x83 > + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3 > + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3 > + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3 > + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3 > + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc3 > + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 > + >; > + }; > + > + pinctrl_usdhc2_100mhz: usdhc2grp100mhz { > + fsl,pins = < > + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x85 > + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc5 > + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc5 > + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc5 > + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc5 > + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc5 > + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 > + >; > + }; > + > + pinctrl_usdhc2_200mhz: usdhc2grp200mhz { > + fsl,pins = < > + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x87 > + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc7 > + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc7 > + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc7 > + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc7 > + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc7 > + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 > + >; > + }; > + > + pinctrl_sai2: sai2grp { > + fsl,pins = < > + MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6 > + MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6 > + MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6 > + MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6 > + MX8MQ_IOMUXC_GPIO1_IO08_GPIO1_IO8 0xd6 > + >; > + }; > + > + pinctrl_wdog: wdoggrp { > + fsl,pins = < > + MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 > + >; > + }; > + }; > +}; > + > +&fec1 { > + pinctrl-names = "default"; > + pinctrl-0 = <&pinctrl_fec1>; > + phy-mode = "rgmii-id"; > + phy-handle = <ðphy0>; > + fsl,magic-packet; > + status = "okay"; > + > + mdio { > + #address-cells = <1>; > + #size-cells = <0>; > + > + ethphy0: ethernet-phy at 0 { > + compatible = "ethernet-phy-ieee802.3-c22"; > + reg = <0>; > + at803x,led-act-blind-workaround; > + at803x,eee-disabled; > + }; > + }; > +}; > + > +&i2c1 { > + clock-frequency = <100000>; > + pinctrl-names = "default"; > + pinctrl-0 = <&pinctrl_i2c1>; > + status = "okay"; > + > + pmic: pfuze100 at 08 { > + compatible = "fsl,pfuze100"; > + reg = <0x08>; > + > + regulators { > + sw1a_reg: sw1ab { > + regulator-min-microvolt = <300000>; > + regulator-max-microvolt = <1875000>; > + regulator-always-on; > + }; > + > + sw1c_reg: sw1c { > + regulator-min-microvolt = <300000>; > + regulator-max-microvolt = <1875000>; > + regulator-always-on; > + }; > + > + sw2_reg: sw2 { > + regulator-min-microvolt = <800000>; > + regulator-max-microvolt = <3300000>; > + regulator-always-on; > + }; > + > + sw3a_reg: sw3ab { > + regulator-min-microvolt = <400000>; > + regulator-max-microvolt = <1975000>; > + regulator-always-on; > + }; > + > + sw4_reg: sw4 { > + regulator-min-microvolt = <800000>; > + regulator-max-microvolt = <3300000>; > + regulator-always-on; > + }; > + > + swbst_reg: swbst { > + regulator-min-microvolt = <5000000>; > + regulator-max-microvolt = <5150000>; > + }; > + > + snvs_reg: vsnvs { > + regulator-min-microvolt = <1000000>; > + regulator-max-microvolt = <3000000>; > + regulator-always-on; > + }; > + > + vref_reg: vrefddr { > + regulator-always-on; > + }; > + > + vgen1_reg: vgen1 { > + regulator-min-microvolt = <800000>; > + regulator-max-microvolt = <1550000>; > + }; > + > + vgen2_reg: vgen2 { > + regulator-min-microvolt = <800000>; > + regulator-max-microvolt = <1550000>; > + regulator-always-on; > + }; > + > + vgen3_reg: vgen3 { > + regulator-min-microvolt = <1800000>; > + regulator-max-microvolt = <3300000>; > + regulator-always-on; > + }; > + > + vgen4_reg: vgen4 { > + regulator-min-microvolt = <1800000>; > + regulator-max-microvolt = <3300000>; > + regulator-always-on; > + }; > + > + vgen5_reg: vgen5 { > + regulator-min-microvolt = <1800000>; > + regulator-max-microvolt = <3300000>; > + regulator-always-on; > + }; > + > + vgen6_reg: vgen6 { > + regulator-min-microvolt = <1800000>; > + regulator-max-microvolt = <3300000>; > + }; > + }; > + }; > +}; > + > +&i2c2 { > + clock-frequency = <100000>; > + pinctrl-names = "default"; > + pinctrl-0 = <&pinctrl_i2c2>; > + status = "disabled"; > +}; > + > +&pwm2 { > + pinctrl-names = "default"; > + pinctrl-0 = <&pinctrl_pwm2>; > + status = "okay"; > +}; > + > +&lcdif { > + status = "okay"; > + disp-dev = "mipi_dsi_northwest"; > + display = <&display0>; > + > + display0: display at 0 { > + bits-per-pixel = <24>; > + bus-width = <24>; > + > + display-timings { > + native-mode = <&timing0>; > + timing0: timing0 { > + clock-frequency = <9200000>; > + hactive = <480>; > + vactive = <272>; > + hfront-porch = <8>; > + hback-porch = <4>; > + hsync-len = <41>; > + vback-porch = <2>; > + vfront-porch = <4>; > + vsync-len = <10>; > + > + hsync-active = <0>; > + vsync-active = <0>; > + de-active = <1>; > + pixelclk-active = <0>; > + }; > + }; > + }; > +}; > + > +&qspi { > + pinctrl-names = "default"; > + pinctrl-0 = <&pinctrl_qspi>; > + status = "okay"; > + > + flash0: n25q256a at 0 { > + reg = <0>; > + #address-cells = <1>; > + #size-cells = <1>; > + compatible = "micron,n25q256a"; > + spi-max-frequency = <29000000>; > + spi-nor,ddr-quad-read-dummy = <6>; > + }; > +}; > + > +&usdhc1 { > + pinctrl-names = "default", "state_100mhz", "state_200mhz"; > + pinctrl-0 = <&pinctrl_usdhc1>; > + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; > + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; > + bus-width = <8>; > + non-removable; > + status = "okay"; > +}; > + > +&usdhc2 { > + pinctrl-names = "default", "state_100mhz", "state_200mhz"; > + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; > + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; > + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; > + bus-width = <4>; > + cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; > + vmmc-supply = <®_usdhc2_vmmc>; > + status = "okay"; > +}; > + > +&wdog1 { > + pinctrl-names = "default"; > + pinctrl-0 = <&pinctrl_wdog>; > + fsl,ext-reset-output; > + status = "okay"; > +}; > diff --git a/arch/arm/include/asm/arch-mx8m/ddr.h b/arch/arm/include/asm/arch-mx8m/ddr.h > index b37382eab0..11016c9278 100644 > --- a/arch/arm/include/asm/arch-mx8m/ddr.h > +++ b/arch/arm/include/asm/arch-mx8m/ddr.h > @@ -353,4 +353,13 @@ enum msg_response { > TRAIN_FAIL = 0xff, > }; > > +enum fw_type { > + FW_1D_IMAGE, > + FW_2D_IMAGE, > +}; > + > +void ddr_init(void); > +void ddr_load_train_code(enum fw_type type); > +void lpddr4_800M_cfg_phy(void); > +void dram_pll_init(void); > #endif > diff --git a/arch/arm/mach-imx/mx8m/Kconfig b/arch/arm/mach-imx/mx8m/Kconfig > index 3a84c2f2b0..e3b57b7915 100644 > --- a/arch/arm/mach-imx/mx8m/Kconfig > +++ b/arch/arm/mach-imx/mx8m/Kconfig > @@ -7,4 +7,16 @@ config MX8M > config SYS_SOC > default "mx8m" > > +choice > + prompt "NXP i.MX8M board select" > + optional > + > +config TARGET_MX8MQ_EVK > + bool "mx8mq_evk" > + select MX8M > + > +endchoice > + > +source "board/freescale/mx8mq_evk/Kconfig" > + > endif > diff --git a/board/freescale/mx8mq_evk/Kconfig b/board/freescale/mx8mq_evk/Kconfig > new file mode 100644 > index 0000000000..4e23002803 > --- /dev/null > +++ b/board/freescale/mx8mq_evk/Kconfig > @@ -0,0 +1,12 @@ > +if TARGET_MX8MQ_EVK > + > +config SYS_BOARD > + default "mx8mq_evk" > + > +config SYS_VENDOR > + default "freescale" > + > +config SYS_CONFIG_NAME > + default "mx8mq_evk" > + > +endif > diff --git a/board/freescale/mx8mq_evk/Makefile b/board/freescale/mx8mq_evk/Makefile > new file mode 100644 > index 0000000000..286396ee96 > --- /dev/null > +++ b/board/freescale/mx8mq_evk/Makefile > @@ -0,0 +1,12 @@ > +# > +# Copyright 2017 NXP > +# > +# SPDX-License-Identifier: GPL-2.0+ > +# > + > +obj-y += mx8mq_evk.o > + > +ifdef CONFIG_SPL_BUILD > +obj-y += spl.o > +obj-y += ddr/ddr_init.o ddr/ddrphy_train.o ddr/helper.o > +endif > diff --git a/board/freescale/mx8mq_evk/README b/board/freescale/mx8mq_evk/README > new file mode 100644 > index 0000000000..e214401a8a > --- /dev/null > +++ b/board/freescale/mx8mq_evk/README > @@ -0,0 +1,47 @@ > +U-Boot for the NXP i.MX8MQ EVK board > + > +Quick Start > +==================== > +- Build the ARM Trusted firmware binary > +- Build U-Boot > +- Get ddr fimware and tools > +- Generate flash.bin using imx-mkimage > +- Boot > + > +Get and Build the ARM Trusted firmware > +==================== > +Get ATF from: https://source.codeaurora.org/external/imx/imx-atf This is currently not enough - master is empty, which branch should be selected ? Is this maintainable ? I am asking why this is coming from here and not from an official source, like : https://github.com/ARM-software/arm-trusted-firmware > +$ make PLAT=imx8mq bl31 > + > +Build U-Boot > +==================== > +$ export ARCH=arm64 > +$ export CROSS_COMPILE=aarch64-poky-linux- > +$ make mx8mq_evk_defconfig > +$ make > + > +Get the ddr firmware and tools > +==================== > +Note: Better to use NXP released yocto to get the firmware in case > + there is new releases. > +https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-7.2.bin > +imx-mkimage: https://source.codeaurora.org/external/imx/imx-mkimage/ I am just asking which is the plan here. This is a fork of U-Boot's mkimage tool. I did not see attempts to push changes to imximage mainline. Any thoughts ? This means that it is not possible inside U-Boot to produce a U-Boot image, but we need an external tool that was *based* on U-Boot code.... I have not understood the usage of firmware-imx-7.2.bin. You ask to load it, but it is not used in further commands. > + > +Generate flash.bin using imx-mkimage > +==================== > +Copy bl31.bin u-boot-nodtb.bin u-boot-spl.bin fsl-imx8mq-evk.dtb to > + imx-mkimage/iMX8M > +Copy lpddr4_pmu_train_1d_dmem.bin lpddr4_pmu_train_1d_imem.bin > + lpddr4_pmu_train_2d_dmem.bin lpddr4_pmu_train_2d_imem.bin to > + imx-mkimage/iMX8M Where are coming the DDR binary files ? > +If you want to run with HDMI, copy signed_hdmi_imx8m.bin to imx-mkimage/iMX8M > + > +make SOC=iMX8M flash_hdmi_spl_uboot or make SOC=iMX8M flash_spl_uboot to > +generate flash.bin. > + > +Burn the flash.bin to MicroSD card offset 33KB > +$sudo dd if=iMX8M/flash.bin of=/dev/sd[x] bs=1024 seek=33 > + > +Boot > +==================== > +Set Boot switch SW801: 1100 and Bmode: 10 to boot from Micro SD. > diff --git a/board/freescale/mx8mq_evk/ddr/ddr_init.c b/board/freescale/mx8mq_evk/ddr/ddr_init.c > new file mode 100644 > index 0000000000..9ff4341bd9 > --- /dev/null > +++ b/board/freescale/mx8mq_evk/ddr/ddr_init.c > @@ -0,0 +1,246 @@ > +/* > + * Copyright 2017 NXP > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct imx8m_ddrc_regs *ddrc_regs = (struct imx8m_ddrc_regs *)DDRC_IPS_BASE_ADDR(0); > +static struct gpc_reg *gpc_reg = (struct gpc_reg *)GPC_BASE_ADDR; > +static struct src *src = (struct src *)SRC_BASE_ADDR; > + > +void lpddr4_800mhz_cfg_umctl2(void) > +{ > + writel(0x00000001, &ddrc_regs->dbg1); > + writel(0x00000001, &ddrc_regs->pwrctl); > + writel(0x83080020, &ddrc_regs->mstr); > + writel(0x006180e0, &ddrc_regs->rfshtmg); > + writel(0xc003061b, &ddrc_regs->init0); > + writel(0x009d0000, &ddrc_regs->init1); > + writel(0x0000fe05, &ddrc_regs->init2); > + writel(0x00d4002d, &ddrc_regs->init3); > + writel(0x00310008, &ddrc_regs->init4); > + writel(0x00040009, &ddrc_regs->init5); > + writel(0x0046004d, &ddrc_regs->init6); > + writel(0x0005004d, &ddrc_regs->init7); > + writel(0x00000979, &ddrc_regs->rankctl); > + writel(0x1a203522, &ddrc_regs->dramtmg0); I guess we will not have any improvement here, at least for first version. I cannot say this is optimal, because it becomes difficult to add further MX8M targets. Just an example: dramtmgX contain timings, and they are computed from the RAM chip (tRAS, and so on). The best way (and I hope, this will go on sometimes..) should be to add a table for the chosen RAM chip and registers are then computed. It will be even ok if there is a tool(I guess, you or the DDR-team is using such as tool) to derive registers value from chip datasheet. Fabio, what do you think about this ? > + writel(0x00060630, &ddrc_regs->dramtmg1); > + writel(0x070e1214, &ddrc_regs->dramtmg2); > + writel(0x00b0c006, &ddrc_regs->dramtmg3); > + writel(0x0f04080f, &ddrc_regs->dramtmg4); > + writel(0x0d0d0c0c, &ddrc_regs->dramtmg5); > + writel(0x01010007, &ddrc_regs->dramtmg6); > + writel(0x0000060a, &ddrc_regs->dramtmg7); > + writel(0x01010101, &ddrc_regs->dramtmg8); > + writel(0x40000008, &ddrc_regs->dramtmg9); > + writel(0x00050d01, &ddrc_regs->dramtmg10); > + writel(0x01010008, &ddrc_regs->dramtmg11); > + writel(0x00020000, &ddrc_regs->dramtmg12); > + writel(0x18100002, &ddrc_regs->dramtmg13); > + writel(0x00000dc2, &ddrc_regs->dramtmg14); > + writel(0x80000000, &ddrc_regs->dramtmg15); > + writel(0x00a00050, &ddrc_regs->dramtmg17); > + writel(0x53200018, &ddrc_regs->zqctl0); > + writel(0x02800070, &ddrc_regs->zqctl1); > + writel(0x00000000, &ddrc_regs->zqctl2); > + writel(0x0397820a, &ddrc_regs->dfitmg0); > + writel(0x0397820a, &ddrc_regs->freq1.dfitmg0); > + writel(0x0397820a, &ddrc_regs->freq2.dfitmg0); > + writel(0x00020103, &ddrc_regs->dfitmg1); > + writel(0xe0400018, &ddrc_regs->dfiupd0); > + writel(0x00df00e4, &ddrc_regs->dfiupd1); > + writel(0x00000000, &ddrc_regs->dfiupd2); > + writel(0x00000011, &ddrc_regs->dfimisc); > + writel(0x0000170a, &ddrc_regs->dfitmg2); > + writel(0x00000001, &ddrc_regs->dbictl); > + writel(0x00000000, &ddrc_regs->dfiphymstr); > + /* Address map is from MSB 29: r15, r14, cs, r13-r0, b2-b0, c9-c0 */ > + writel(0x00000015, &ddrc_regs->addrmap0); > + writel(0x00001f1f, &ddrc_regs->addrmap4); > + /* bank interleave */ > + writel(0x00080808, &ddrc_regs->addrmap1); > + writel(0x07070707, &ddrc_regs->addrmap5); > + writel(0x08080707, &ddrc_regs->addrmap6); > + writel(0x020f0c54, &ddrc_regs->odtcfg); > + writel(0x00000000, &ddrc_regs->odtmap); > + writel(0x00000001, &ddrc_regs->pcfg[0].pctrl); > + > + /* performance setting */ > + writel(0x0b060908, &ddrc_regs->odtcfg); > + writel(0x00000000, &ddrc_regs->odtmap); > + writel(0x29511505, &ddrc_regs->sched); > + writel(0x0000002c, &ddrc_regs->sched1); > + writel(0x5900575b, &ddrc_regs->perfhpr1); > + writel(0x900093e7, &ddrc_regs->perflpr1); > + writel(0x02005574, &ddrc_regs->perfwr1); > + writel(0x00000016, &ddrc_regs->dbg0); > + writel(0x00000000, &ddrc_regs->dbg1); > + writel(0x00000000, &ddrc_regs->dbgcmd); > + writel(0x00000001, &ddrc_regs->swctl); > + writel(0x00000011, &ddrc_regs->poisoncfg); > + writel(0x00000111, &ddrc_regs->pccfg); > + writel(0x000010f3, &ddrc_regs->pcfg[0].pcfgr); > + writel(0x000072ff, &ddrc_regs->pcfg[0].pcfgw); > + writel(0x00000001, &ddrc_regs->pcfg[0].pctrl); > + writel(0x01110d00, &ddrc_regs->pcfg[0].pcfgqos0); > + writel(0x00620790, &ddrc_regs->pcfg[0].pcfgqos1); > + writel(0x00100001, &ddrc_regs->pcfg[0].pcfgwqos0); > + writel(0x0000041f, &ddrc_regs->pcfg[0].pcfgwqos1); > + writel(0x00000202, &ddrc_regs->freq1.derateen); > + writel(0xec78f4b5, &ddrc_regs->freq1.derateint); > + writel(0x00618040, &ddrc_regs->freq1.rfshctl0); > + writel(0x00610090, &ddrc_regs->freq1.rfshtmg); > +} > + > +void lpddr4_100mhz_cfg_umctl2(void) > +{ > + writel(0x0d0b010c, &ddrc_regs->freq1.dramtmg0); > + writel(0x00030410, &ddrc_regs->freq1.dramtmg1); > + writel(0x0305090c, &ddrc_regs->freq1.dramtmg2); > + writel(0x00505006, &ddrc_regs->freq1.dramtmg3); > + writel(0x05040305, &ddrc_regs->freq1.dramtmg4); > + writel(0x0d0e0504, &ddrc_regs->freq1.dramtmg5); > + writel(0x0a060004, &ddrc_regs->freq1.dramtmg6); > + writel(0x0000090e, &ddrc_regs->freq1.dramtmg7); > + writel(0x00000032, &ddrc_regs->freq1.dramtmg14); > + writel(0x00000000, &ddrc_regs->freq1.dramtmg15); > + writel(0x0036001b, &ddrc_regs->freq1.dramtmg17); > + writel(0x7e9fbeb1, &ddrc_regs->freq1.derateint); > + writel(0x0020d040, &ddrc_regs->freq1.rfshctl0); > + writel(0x03818200, &ddrc_regs->freq1.dfitmg0); > + writel(0x0a1a096c, &ddrc_regs->freq1.odtcfg); > + writel(0x00000000, &ddrc_regs->freq1.dfitmg2); > + writel(0x00038014, &ddrc_regs->freq1.rfshtmg); > + writel(0x00840000, &ddrc_regs->freq1.init3); > + writel(0x0000004d, &ddrc_regs->freq1.init6); > + writel(0x0000004d, &ddrc_regs->freq1.init7); > + writel(0x00310000, &ddrc_regs->freq1.init4); > +} > + > +void lpddr4_25mhz_cfg_umctl2(void) > +{ > + writel(0x0d0b010c, &ddrc_regs->freq2.dramtmg0); > + writel(0x00030410, &ddrc_regs->freq2.dramtmg1); > + writel(0x0305090c, &ddrc_regs->freq2.dramtmg2); > + writel(0x00505006, &ddrc_regs->freq2.dramtmg3); > + writel(0x05040305, &ddrc_regs->freq2.dramtmg4); > + writel(0x0d0e0504, &ddrc_regs->freq2.dramtmg5); > + writel(0x0a060004, &ddrc_regs->freq2.dramtmg6); > + writel(0x0000090e, &ddrc_regs->freq2.dramtmg7); > + writel(0x00000032, &ddrc_regs->freq2.dramtmg14); > + writel(0x00000000, &ddrc_regs->freq2.dramtmg15); > + writel(0x0036001b, &ddrc_regs->freq2.dramtmg17); > + writel(0x7e9fbeb1, &ddrc_regs->freq2.derateint); > + writel(0x0020d040, &ddrc_regs->freq2.rfshctl0); > + writel(0x03818200, &ddrc_regs->freq2.dfitmg0); > + writel(0x0a1a096c, &ddrc_regs->freq2.odtcfg); > + writel(0x00000000, &ddrc_regs->freq2.dfitmg2); > + writel(0x0003800c, &ddrc_regs->freq2.rfshtmg); > + writel(0x00840000, &ddrc_regs->freq2.init3); > + writel(0x0000004d, &ddrc_regs->freq2.init6); > + writel(0x0000004d, &ddrc_regs->freq2.init7); > + writel(0x00310000, &ddrc_regs->freq2.init4); > +} > + > +void ddr_init(void) > +{ > + int ret; > + u32 val; > + > + /* change the clock source of dram_apb_clk_root */ > + clock_set_target_val(DRAM_APB_CLK_ROOT, CLK_ROOT_ON | > + CLK_ROOT_SOURCE_SEL(4) | > + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV4)); > + > + /* disable the clock gating */ > + writel(0xFFFF, &gpc_reg->pgc_cpu_0_1_mapping); > + setbits_le32(&gpc_reg->pu_pgc_up_trg, BIT(5)); > + > + writel(SRC_DDR2_ENABLE_MASK, &src->ddr2_rcr); > + > + dram_pll_init(); > + > + writel(SRC_DDR1_ENABLE_MASK | SRC_DDR1_RCR_PHY_RESET_MASK | > + SRC_DDR1_RCR_CORE_RESET_N_MASK, &src->ddr1_rcr); > + > + /* Configure uMCTL2's registers */ > + lpddr4_800mhz_cfg_umctl2(); > + > + writel(SRC_DDR1_ENABLE_MASK | SRC_DDR1_RCR_PHY_RESET_MASK, > + &src->ddr1_rcr); > + writel(SRC_DDR1_ENABLE_MASK, &src->ddr1_rcr); > + > + writel(0x00000000, &ddrc_regs->dbg1); > + writel(0x000000a8, &ddrc_regs->pwrctl); > + /* writel(0x0000018a, DDRC_PWRCTL(0), )*/ > + writel(0x00000000, &ddrc_regs->swctl); > + writel(0x01, DDRC_DDR_SS_GPR0); > + writel(0x00000010, &ddrc_regs->dfimisc); > + > + /* Configure LPDDR4 PHY's registers */ > + lpddr4_800M_cfg_phy(); > + > + writel(0x00000000, &ddrc_regs->rfshctl3); > + writel(0x0000, &ddrc_regs->swctl); > + /* > + * ------------------- 9 ------------------- > + * Set DFIMISC.dfi_init_start to 1 > + * ----------------------------------------- > + */ > + writel(0x00000030, &ddrc_regs->dfimisc); > + writel(0x0001, &ddrc_regs->swctl); > + > + /* wait DFISTAT.dfi_init_complete to 1 */ > + ret = readl_poll_timeout(&ddrc_regs->dfistat, val, val & BIT(0), 1000); > + if (ret) > + puts("DFISTAT.dfi_init_complete timeout\n"); > + > + writel(0x0000, &ddrc_regs->swctl); > + > + /* clear DFIMISC.dfi_init_complete_en */ > + writel(0x00000010, &ddrc_regs->dfimisc); > + writel(0x00000011, &ddrc_regs->dfimisc); > + writel(0x00000088, &ddrc_regs->pwrctl); > + > + /* > + * set SWCTL.sw_done to enable quasi-dynamic register > + * programming outside reset. > + */ > + writel(0x00000001, &ddrc_regs->swctl); > + > + /* wait SWSTAT.sw_done_ack to 1 */ > + ret = readl_poll_timeout(&ddrc_regs->swstat, val, val & BIT(0), 1000); > + if (ret) > + puts("SWSTAT.sw_done timeout\n"); > + > + /* wait STAT.operating_mode([1:0] for ddr3) to normal state */ > + ret = readl_poll_timeout(&ddrc_regs->stat, val, (val & 0x3) == 1, 1000); > + if (ret) > + puts("STAT.operating_mode timeout\n"); > + > + writel(0x00000088, &ddrc_regs->pwrctl); > + > + /* enable port 0 */ > + writel(0x00000001, &ddrc_regs->pcfg[0].pctrl); > + writel(0x00000000, &ddrc_regs->rfshctl3); > + > + writel(0x0, &ddrc_regs->swctl); > + lpddr4_100mhz_cfg_umctl2(); > + lpddr4_25mhz_cfg_umctl2(); > + writel(0x1, &ddrc_regs->swctl); > +> + /* wait SWSTAT.sw_done_ack to 1 */ > + ret = readl_poll_timeout(&ddrc_regs->swstat, val, val & BIT(0), 1000); > + if (ret) > + puts("SWSTAT.sw_done timeout\n"); > + > + writel(0x0, &ddrc_regs->swctl); > +} > diff --git a/board/freescale/mx8mq_evk/ddr/ddrphy_train.c b/board/freescale/mx8mq_evk/ddr/ddrphy_train.c > new file mode 100644 > index 0000000000..a2bf8b8449 > --- /dev/null > +++ b/board/freescale/mx8mq_evk/ddr/ddrphy_train.c > @@ -0,0 +1,1272 @@ > +/* > + * Copyright 2017 NXP > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +static struct ccm_reg *ccm_reg = (struct ccm_reg *)CCM_BASE_ADDR; > +static struct imx8m_ddrphy_regs *regs = (struct imx8m_ddrphy_regs *)IP2APB_DDRPHY_IPS_BASE_ADDR(0); > +static struct gpc_reg *gpc_reg = (struct gpc_reg *)GPC_BASE_ADDR; It is uncommon to have these as global (for a module) in U-Boot. > + > +static inline void poll_pmu_message_ready(void) > +{ > + int ret; > + u32 val; > + > + /* > + * When BIT0 set to 0, the PMU has a message for the user > + * 10ms seems not enough for poll message, so use 1s here. > + */ > + ret = readl_poll_timeout(®s->reg[0xd0004], val, > + !(val & BIT(0)), 1000000); > + if (ret) > + puts("PMU message timeout\n"); > +} > + > +static inline void ack_pmu_message_receive(void) > +{ > + int ret; > + u32 val; > + /* > + * By setting this register to 0, the user acknowledges the > + * receipt of the message. > + */ > + writel(0x0, ®s->reg[0xd0031]); > + > + /* When BIT0 set to 0, the PMU has a message for the user*/ > + ret = readl_poll_timeout(®s->reg[0xd0004], val, val & BIT(0), 1000); > + if (ret) > + printf("%s timeout\n", __func__); > + > + writel(0x1, ®s->reg[0xd0031]); > +} > + > +static inline unsigned int get_mail(void) > +{ > + unsigned int reg; > + > + poll_pmu_message_ready(); > + > + /* Get the major message ID */ > + reg = readl(®s->reg[0xd0032]); > + > + ack_pmu_message_receive(); > + > + return reg; > +} > + > +static inline unsigned int get_stream_message(void) > +{ > + unsigned int reg, reg2; > + > + poll_pmu_message_ready(); > + > + reg = readl(®s->reg[0xd0032]); > + reg2 = readl(®s->reg[0xd0034]); > + reg2 = (reg2 << 16) | reg; > + > + ack_pmu_message_receive(); > + > + return reg2; > +} > + > +static inline void decode_major_message(unsigned int mail) > +{ > + debug("[PMU Major message = 0x%08x]\n", mail); > +} > + > +static inline void decode_streaming_message(void) > +{ > + unsigned int string_index, arg __maybe_unused; > + int i = 0; > + > + string_index = get_stream_message(); > + debug(" PMU String index = 0x%08x\n", string_index); > + while (i < (string_index & 0xffff)) { > + arg = get_stream_message(); > + debug(" arg[%d] = 0x%08x\n", i, arg); > + i++; > + } > + > + debug("\n"); > +} > + > +static void wait_ddrphy_training_complete(void) > +{ > + unsigned int mail; > + > + while (true) { > + mail = get_mail(); > + decode_major_message(mail); > + if (mail == TRAIN_STREAM_START) { > + decode_streaming_message(); > + } else if (mail == TRAIN_SUCCESS) { > + debug("Training PASS\n"); > + break; > + } else if (mail == TRAIN_FAIL) { > + printf("Training FAILED\n"); > + break; > + } Is it not possible that code remains in loop forever ? > + } > +} > + > +static void ddr_pll_bypass_100mts(void) > +{ > + /* change the clock source of dram_alt_clk_root to source 2 --100MHZ */ > + clock_set_target_val(DRAM_ALT_CLK_ROOT, CLK_ROOT_ON | > + CLK_ROOT_SOURCE_SEL(2) | > + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1)); > + > + /* change the clock source of dram_apb_clk_root to source 2 --40MHZ */ > + clock_set_target_val(DRAM_APB_CLK_ROOT, CLK_ROOT_ON | > + CLK_ROOT_SOURCE_SEL(2) | > + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV2)); > + > + /* disable the clock gating */ > + writel(0xFFFF, &gpc_reg->pgc_cpu_0_1_mapping); > + /* configure ddr1_sw_pup_req */ > + setbits_le32(&gpc_reg->pu_pgc_up_trg, BIT(5)); > + > + /* configure pll bypass mode */ > + writel(BIT(24), &ccm_reg->dram_sel.target_root_set); > + > + debug("PLL bypass to 100MTS setting done\n"); > +} > + > +static void ddr_pll_bypass_400mts(void) > +{ > + /* change the clock source of dram_alt_clk_root to source 2 --400MHZ */ > + clock_set_target_val(DRAM_ALT_CLK_ROOT, CLK_ROOT_ON | > + CLK_ROOT_SOURCE_SEL(5) | > + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1)); > + > + /* change the clock source of dram_apb_clk_root to source 2 --40MHZ/2 */ > + clock_set_target_val(DRAM_APB_CLK_ROOT, CLK_ROOT_ON | > + CLK_ROOT_SOURCE_SEL(2) | > + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV2)); > + > + /* disable the clock gating */ > + writel(0xFFFF, &gpc_reg->pgc_cpu_0_1_mapping); > + /* configure ddr1_sw_pup_req */ > + setbits_le32(&gpc_reg->pu_pgc_up_trg, BIT(5)); > + > + /* configure pll bypass mode */ > + writel(BIT(24), &ccm_reg->dram_sel.target_root_set); > + > + debug("PLL bypass to 400MTS setting done\n"); > +} > + > +static void dwc_ddrphy_phyinit_usercustom_e_setdficlk(enum pstate state) > +{ > + if (state == PS2) { > + ddr_pll_bypass_100mts(); > + } else if (state == PS1) { > + ddr_pll_bypass_400mts(); > + } else { > + clock_set_target_val(DRAM_APB_CLK_ROOT, CLK_ROOT_ON | > + CLK_ROOT_SOURCE_SEL(4) | > + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV4)); > + writel(BIT(24), &ccm_reg->dram_sel.target_root_set); > + } > +} > + > +void lpddr4_800M_cfg_phy(void) > +{ > + int ret; > + u32 val; > + > + writel(0x02, ®s->reg[0x20110]); > + writel(0x03, ®s->reg[0x20111]); > + writel(0x04, ®s->reg[0x20112]); > + writel(0x05, ®s->reg[0x20113]); > + writel(0x00, ®s->reg[0x20114]); > + writel(0x01, ®s->reg[0x20115]); > + writel(0x1ff, ®s->reg[0x1005f]); > + writel(0x1ff, ®s->reg[0x1015f]); > + writel(0x1ff, ®s->reg[0x1105f]); > + writel(0x1ff, ®s->reg[0x1115f]); > + writel(0x1ff, ®s->reg[0x1205f]); > + writel(0x1ff, ®s->reg[0x1215f]); > + writel(0x1ff, ®s->reg[0x1305f]); > + writel(0x1ff, ®s->reg[0x1315f]); > + writel(0x1ff, ®s->reg[0x11005f]); > + writel(0x1ff, ®s->reg[0x11015f]); > + writel(0x1ff, ®s->reg[0x11105f]); > + writel(0x1ff, ®s->reg[0x11115f]); > + writel(0x1ff, ®s->reg[0x11205f]); > + writel(0x1ff, ®s->reg[0x11215f]); > + writel(0x1ff, ®s->reg[0x11305f]); > + writel(0x1ff, ®s->reg[0x11315f]); > + writel(0x1ff, ®s->reg[0x21005f]); > + writel(0x1ff, ®s->reg[0x21015f]); > + writel(0x1ff, ®s->reg[0x21105f]); > + writel(0x1ff, ®s->reg[0x21115f]); > + writel(0x1ff, ®s->reg[0x21205f]); > + writel(0x1ff, ®s->reg[0x21215f]); > + writel(0x1ff, ®s->reg[0x21305f]); > + writel(0x1ff, ®s->reg[0x21315f]); > + writel(0x1ff, ®s->reg[0x55]); > + writel(0x1ff, ®s->reg[0x1055]); > + writel(0x1ff, ®s->reg[0x2055]); > + writel(0x1ff, ®s->reg[0x3055]); > + writel(0x1ff, ®s->reg[0x4055]); > + writel(0x1ff, ®s->reg[0x5055]); > + writel(0x1ff, ®s->reg[0x6055]); > + writel(0x1ff, ®s->reg[0x7055]); > + writel(0x1ff, ®s->reg[0x8055]); > + writel(0x1ff, ®s->reg[0x9055]); > + writel(0x19, ®s->reg[0x200c5]); > + writel(0x7, ®s->reg[0x1200c5]); > + writel(0x7, ®s->reg[0x2200c5]); > + writel(0x2, ®s->reg[0x2002e]); > + writel(0x2, ®s->reg[0x12002e]); > + writel(0x2, ®s->reg[0x22002e]); > + writel(0x0, ®s->reg[0x90204]); > + writel(0x0, ®s->reg[0x190204]); > + writel(0x0, ®s->reg[0x290204]); > + writel(0xab, ®s->reg[0x20024]); > + writel(0x0, ®s->reg[0x2003a]); > + writel(0xab, ®s->reg[0x120024]); > + writel(0x0, ®s->reg[0x2003a]); > + writel(0xab, ®s->reg[0x220024]); > + writel(0x0, ®s->reg[0x2003a]); > + writel(0x3, ®s->reg[0x20056]); > + writel(0xa, ®s->reg[0x120056]); > + writel(0xa, ®s->reg[0x220056]); > + writel(0xe00, ®s->reg[0x1004d]); > + writel(0xe00, ®s->reg[0x1014d]); > + writel(0xe00, ®s->reg[0x1104d]); > + writel(0xe00, ®s->reg[0x1114d]); > + writel(0xe00, ®s->reg[0x1204d]); > + writel(0xe00, ®s->reg[0x1214d]); > + writel(0xe00, ®s->reg[0x1304d]); > + writel(0xe00, ®s->reg[0x1314d]); > + writel(0xe00, ®s->reg[0x11004d]); > + writel(0xe00, ®s->reg[0x11014d]); > + writel(0xe00, ®s->reg[0x11104d]); > + writel(0xe00, ®s->reg[0x11114d]); > + writel(0xe00, ®s->reg[0x11204d]); > + writel(0xe00, ®s->reg[0x11214d]); > + writel(0xe00, ®s->reg[0x11304d]); > + writel(0xe00, ®s->reg[0x11314d]); > + writel(0xe00, ®s->reg[0x21004d]); > + writel(0xe00, ®s->reg[0x21014d]); > + writel(0xe00, ®s->reg[0x21104d]); > + writel(0xe00, ®s->reg[0x21114d]); > + writel(0xe00, ®s->reg[0x21204d]); > + writel(0xe00, ®s->reg[0x21214d]); > + writel(0xe00, ®s->reg[0x21304d]); > + writel(0xe00, ®s->reg[0x21314d]); > + writel(0xe38, ®s->reg[0x10049]); > + writel(0xe38, ®s->reg[0x10149]); > + writel(0xe38, ®s->reg[0x11049]); > + writel(0xe38, ®s->reg[0x11149]); > + writel(0xe38, ®s->reg[0x12049]); > + writel(0xe38, ®s->reg[0x12149]); > + writel(0xe38, ®s->reg[0x13049]); > + writel(0xe38, ®s->reg[0x13149]); > + writel(0xe38, ®s->reg[0x110049]); > + writel(0xe38, ®s->reg[0x110149]); > + writel(0xe38, ®s->reg[0x111049]); > + writel(0xe38, ®s->reg[0x111149]); > + writel(0xe38, ®s->reg[0x112049]); > + writel(0xe38, ®s->reg[0x112149]); > + writel(0xe38, ®s->reg[0x113049]); > + writel(0xe38, ®s->reg[0x113149]); > + writel(0xe38, ®s->reg[0x210049]); > + writel(0xe38, ®s->reg[0x210149]); > + writel(0xe38, ®s->reg[0x211049]); > + writel(0xe38, ®s->reg[0x211149]); > + writel(0xe38, ®s->reg[0x212049]); > + writel(0xe38, ®s->reg[0x212149]); > + writel(0xe38, ®s->reg[0x213049]); > + writel(0xe38, ®s->reg[0x213149]); > + writel(0x21, ®s->reg[0x43]); > + writel(0x21, ®s->reg[0x1043]); > + writel(0x21, ®s->reg[0x2043]); > + writel(0x21, ®s->reg[0x3043]); > + writel(0x21, ®s->reg[0x4043]); > + writel(0x21, ®s->reg[0x5043]); > + writel(0x21, ®s->reg[0x6043]); > + writel(0x21, ®s->reg[0x7043]); > + writel(0x21, ®s->reg[0x8043]); > + writel(0x21, ®s->reg[0x9043]); > + writel(0x3, ®s->reg[0x20018]); > + writel(0x4, ®s->reg[0x20075]); > + writel(0x0, ®s->reg[0x20050]); > + writel(0x320, ®s->reg[0x20008]); > + writel(0x64, ®s->reg[0x120008]); > + writel(0x19, ®s->reg[0x220008]); > + writel(0x9, ®s->reg[0x20088]); > + writel(0x19c, ®s->reg[0x200b2]); > + writel(0x5a1, ®s->reg[0x10043]); > + writel(0x5a1, ®s->reg[0x10143]); > + writel(0x5a1, ®s->reg[0x11043]); > + writel(0x5a1, ®s->reg[0x11143]); > + writel(0x5a1, ®s->reg[0x12043]); > + writel(0x5a1, ®s->reg[0x12143]); > + writel(0x5a1, ®s->reg[0x13043]); > + writel(0x5a1, ®s->reg[0x13143]); > + writel(0x19c, ®s->reg[0x1200b2]); > + writel(0x5a1, ®s->reg[0x110043]); > + writel(0x5a1, ®s->reg[0x110143]); > + writel(0x5a1, ®s->reg[0x111043]); > + writel(0x5a1, ®s->reg[0x111143]); > + writel(0x5a1, ®s->reg[0x112043]); > + writel(0x5a1, ®s->reg[0x112143]); > + writel(0x5a1, ®s->reg[0x113043]); > + writel(0x5a1, ®s->reg[0x113143]); > + writel(0x19c, ®s->reg[0x2200b2]); > + writel(0x5a1, ®s->reg[0x210043]); > + writel(0x5a1, ®s->reg[0x210143]); > + writel(0x5a1, ®s->reg[0x211043]); > + writel(0x5a1, ®s->reg[0x211143]); > + writel(0x5a1, ®s->reg[0x212043]); > + writel(0x5a1, ®s->reg[0x212143]); > + writel(0x5a1, ®s->reg[0x213043]); > + writel(0x5a1, ®s->reg[0x213143]); > + writel(0x1, ®s->reg[0x200fa]); > + writel(0x1, ®s->reg[0x1200fa]); > + writel(0x1, ®s->reg[0x2200fa]); > + writel(0x1, ®s->reg[0x20019]); > + writel(0x1, ®s->reg[0x120019]); > + writel(0x1, ®s->reg[0x220019]); > + writel(0x660, ®s->reg[0x200f0]); > + writel(0x0, ®s->reg[0x200f1]); > + writel(0x4444, ®s->reg[0x200f2]); > + writel(0x8888, ®s->reg[0x200f3]); > + writel(0x5555, ®s->reg[0x200f4]); > + writel(0x0, ®s->reg[0x200f5]); > + writel(0x0, ®s->reg[0x200f6]); > + writel(0xf000, ®s->reg[0x200f7]); > + writel(0x65, ®s->reg[0x2000b]); > + writel(0xc9, ®s->reg[0x2000c]); > + writel(0x7d1, ®s->reg[0x2000d]); > + writel(0x2c, ®s->reg[0x2000e]); > + writel(0xd, ®s->reg[0x12000b]); > + writel(0x1a, ®s->reg[0x12000c]); > + writel(0xfb, ®s->reg[0x12000d]); > + writel(0x10, ®s->reg[0x12000e]); > + writel(0x4, ®s->reg[0x22000b]); > + writel(0x7, ®s->reg[0x22000c]); > + writel(0x3f, ®s->reg[0x22000d]); > + writel(0x10, ®s->reg[0x22000e]); > + writel(0x0, ®s->reg[0x20025]); > + writel(0x0, ®s->reg[0x2002d]); > + writel(0x0, ®s->reg[0x12002d]); > + writel(0x0, ®s->reg[0x22002d]); > + writel(0x2, ®s->reg[0x20060]); > + writel(0x0, ®s->reg[0xd0000]); > + > + /* load the 1D training image */ > + ddr_load_train_code(FW_1D_IMAGE); > + > + writel(0x0, ®s->reg[0xd0000]); > + writel(0x1, ®s->reg[0xd0000]); > + > + /* set the PHY input clock to the desired frequency for pstate 2 */ > + dwc_ddrphy_phyinit_usercustom_e_setdficlk(PS2); > + > + writel(0x0, ®s->reg[0xd0000]); > + writel(0x0, ®s->reg[0x54000]); > + writel(0x0, ®s->reg[0x54001]); > + writel(0x102, ®s->reg[0x54002]); > + writel(0x64, ®s->reg[0x54003]); > + writel(0x2, ®s->reg[0x54004]); > + writel(0x2828, ®s->reg[0x54005]); > + writel(0x14, ®s->reg[0x54006]); > + writel(0x0, ®s->reg[0x54007]); > + writel(0x121f, ®s->reg[0x54008]); > + writel(0xc8, ®s->reg[0x54009]); > + writel(0x0, ®s->reg[0x5400a]); > + writel(0x2, ®s->reg[0x5400b]); > + writel(0x0, ®s->reg[0x5400c]); > + writel(0x0, ®s->reg[0x5400d]); > + writel(0x0, ®s->reg[0x5400e]); > + writel(0x0, ®s->reg[0x5400f]); > + writel(0x0, ®s->reg[0x54010]); > + writel(0x0, ®s->reg[0x54011]); > + writel(0x310, ®s->reg[0x54012]); > + writel(0x0, ®s->reg[0x54013]); > + writel(0x0, ®s->reg[0x54014]); > + writel(0x0, ®s->reg[0x54015]); > + writel(0x0, ®s->reg[0x54016]); > + writel(0x0, ®s->reg[0x54017]); > + writel(0x0, ®s->reg[0x54018]); > + writel(0x4, ®s->reg[0x54019]); > + writel(0x31, ®s->reg[0x5401a]); > + writel(0x4d46, ®s->reg[0x5401b]); > + writel(0x4d08, ®s->reg[0x5401c]); > + writel(0x0, ®s->reg[0x5401d]); > + writel(0x5, ®s->reg[0x5401e]); > + writel(0x4, ®s->reg[0x5401f]); > + writel(0x31, ®s->reg[0x54020]); > + writel(0x4d46, ®s->reg[0x54021]); > + writel(0x4d08, ®s->reg[0x54022]); > + writel(0x0, ®s->reg[0x54023]); > + writel(0x5, ®s->reg[0x54024]); > + writel(0x0, ®s->reg[0x54025]); > + writel(0x0, ®s->reg[0x54026]); > + writel(0x0, ®s->reg[0x54027]); > + writel(0x0, ®s->reg[0x54028]); > + writel(0x0, ®s->reg[0x54029]); > + writel(0x0, ®s->reg[0x5402a]); > + writel(0x1000, ®s->reg[0x5402b]); > + writel(0x3, ®s->reg[0x5402c]); > + writel(0x0, ®s->reg[0x5402d]); > + writel(0x0, ®s->reg[0x5402e]); > + writel(0x0, ®s->reg[0x5402f]); > + writel(0x0, ®s->reg[0x54030]); > + writel(0x0, ®s->reg[0x54031]); > + writel(0x400, ®s->reg[0x54032]); > + writel(0x3100, ®s->reg[0x54033]); > + writel(0x4600, ®s->reg[0x54034]); > + writel(0x84d, ®s->reg[0x54035]); > + writel(0x4d, ®s->reg[0x54036]); > + writel(0x500, ®s->reg[0x54037]); > + writel(0x400, ®s->reg[0x54038]); > + writel(0x3100, ®s->reg[0x54039]); > + writel(0x4600, ®s->reg[0x5403a]); > + writel(0x84d, ®s->reg[0x5403b]); > + writel(0x4d, ®s->reg[0x5403c]); > + writel(0x500, ®s->reg[0x5403d]); > + writel(0x1, ®s->reg[0xd0000]); > + writel(0x1, ®s->reg[0xd0000]); > + writel(0x9, ®s->reg[0xd0099]); > + writel(0x1, ®s->reg[0xd0099]); > + writel(0x0, ®s->reg[0xd0099]); > + > + wait_ddrphy_training_complete(); > + > + writel(0x1, ®s->reg[0xd0099]); > + writel(0x0, ®s->reg[0xd0000]); > + writel(0x1, ®s->reg[0xd0000]); > + > + /* set the PHY input clock to the desired frequency for pstate 1 */ > + dwc_ddrphy_phyinit_usercustom_e_setdficlk(PS1); > + > + writel(0x0, ®s->reg[0xd0000]); > + writel(0x0, ®s->reg[0x54000]); > + writel(0x0, ®s->reg[0x54001]); > + writel(0x101, ®s->reg[0x54002]); > + writel(0x190, ®s->reg[0x54003]); > + writel(0x2, ®s->reg[0x54004]); > + writel(0x2828, ®s->reg[0x54005]); > + writel(0x14, ®s->reg[0x54006]); > + writel(0x0, ®s->reg[0x54007]); > + writel(0x121f, ®s->reg[0x54008]); > + writel(0xc8, ®s->reg[0x54009]); > + writel(0x0, ®s->reg[0x5400a]); > + writel(0x2, ®s->reg[0x5400b]); > + writel(0x0, ®s->reg[0x5400c]); > + writel(0x0, ®s->reg[0x5400d]); > + writel(0x0, ®s->reg[0x5400e]); > + writel(0x0, ®s->reg[0x5400f]); > + writel(0x0, ®s->reg[0x54010]); > + writel(0x0, ®s->reg[0x54011]); > + writel(0x310, ®s->reg[0x54012]); > + writel(0x0, ®s->reg[0x54013]); > + writel(0x0, ®s->reg[0x54014]); > + writel(0x0, ®s->reg[0x54015]); > + writel(0x0, ®s->reg[0x54016]); > + writel(0x0, ®s->reg[0x54017]); > + writel(0x0, ®s->reg[0x54018]); > + writel(0x4, ®s->reg[0x54019]); > + writel(0x31, ®s->reg[0x5401a]); > + writel(0x4d46, ®s->reg[0x5401b]); > + writel(0x4d08, ®s->reg[0x5401c]); > + writel(0x0, ®s->reg[0x5401d]); > + writel(0x5, ®s->reg[0x5401e]); > + writel(0x4, ®s->reg[0x5401f]); > + writel(0x31, ®s->reg[0x54020]); > + writel(0x4d46, ®s->reg[0x54021]); > + writel(0x4d08, ®s->reg[0x54022]); > + writel(0x0, ®s->reg[0x54023]); > + writel(0x5, ®s->reg[0x54024]); > + writel(0x0, ®s->reg[0x54025]); > + writel(0x0, ®s->reg[0x54026]); > + writel(0x0, ®s->reg[0x54027]); > + writel(0x0, ®s->reg[0x54028]); > + writel(0x0, ®s->reg[0x54029]); > + writel(0x0, ®s->reg[0x5402a]); > + writel(0x1000, ®s->reg[0x5402b]); > + writel(0x3, ®s->reg[0x5402c]); > + writel(0x0, ®s->reg[0x5402d]); > + writel(0x0, ®s->reg[0x5402e]); > + writel(0x0, ®s->reg[0x5402f]); > + writel(0x0, ®s->reg[0x54030]); > + writel(0x0, ®s->reg[0x54031]); > + writel(0x400, ®s->reg[0x54032]); > + writel(0x3100, ®s->reg[0x54033]); > + writel(0x4600, ®s->reg[0x54034]); > + writel(0x84d, ®s->reg[0x54035]); > + writel(0x4d, ®s->reg[0x54036]); > + writel(0x500, ®s->reg[0x54037]); > + writel(0x400, ®s->reg[0x54038]); > + writel(0x3100, ®s->reg[0x54039]); > + writel(0x4600, ®s->reg[0x5403a]); > + writel(0x84d, ®s->reg[0x5403b]); > + writel(0x4d, ®s->reg[0x5403c]); > + writel(0x500, ®s->reg[0x5403d]); > + writel(0x1, ®s->reg[0xd0000]); > + writel(0x1, ®s->reg[0xd0000]); > + writel(0x9, ®s->reg[0xd0099]); > + writel(0x1, ®s->reg[0xd0099]); > + writel(0x0, ®s->reg[0xd0099]); > + > + wait_ddrphy_training_complete(); > + > + writel(0x1, ®s->reg[0xd0099]); > + writel(0x0, ®s->reg[0xd0000]); > + writel(0x1, ®s->reg[0xd0000]); > + > + /* set the PHY input clock to the desired frequency for pstate 0 */ > + dwc_ddrphy_phyinit_usercustom_e_setdficlk(PS0); > + > + writel(0x0, ®s->reg[0xd0000]); > + writel(0x0, ®s->reg[0x54000]); > + writel(0x0, ®s->reg[0x54001]); > + writel(0x0, ®s->reg[0x54002]); > + writel(0xc80, ®s->reg[0x54003]); > + writel(0x2, ®s->reg[0x54004]); > + writel(0x2828, ®s->reg[0x54005]); > + writel(0x14, ®s->reg[0x54006]); > + writel(0x0, ®s->reg[0x54007]); > + writel(0x131f, ®s->reg[0x54008]); > + writel(0x5, ®s->reg[0x54009]); > + writel(0x0, ®s->reg[0x5400a]); > + writel(0x2, ®s->reg[0x5400b]); > + writel(0x0, ®s->reg[0x5400c]); > + writel(0x0, ®s->reg[0x5400d]); > + writel(0x0, ®s->reg[0x5400e]); > + writel(0x0, ®s->reg[0x5400f]); > + writel(0x0, ®s->reg[0x54010]); > + writel(0x0, ®s->reg[0x54011]); > + writel(0x310, ®s->reg[0x54012]); > + writel(0x0, ®s->reg[0x54013]); > + writel(0x0, ®s->reg[0x54014]); > + writel(0x0, ®s->reg[0x54015]); > + writel(0x0, ®s->reg[0x54016]); > + writel(0x0, ®s->reg[0x54017]); > + writel(0x0, ®s->reg[0x54018]); > + writel(0x2dd4, ®s->reg[0x54019]); > + writel(0x31, ®s->reg[0x5401a]); > + writel(0x4d46, ®s->reg[0x5401b]); > + writel(0x4d08, ®s->reg[0x5401c]); > + writel(0x0, ®s->reg[0x5401d]); > + writel(0x5, ®s->reg[0x5401e]); > + writel(0x2dd4, ®s->reg[0x5401f]); > + writel(0x31, ®s->reg[0x54020]); > + writel(0x4d46, ®s->reg[0x54021]); > + writel(0x4d08, ®s->reg[0x54022]); > + writel(0x0, ®s->reg[0x54023]); > + writel(0x5, ®s->reg[0x54024]); > + writel(0x0, ®s->reg[0x54025]); > + writel(0x0, ®s->reg[0x54026]); > + writel(0x0, ®s->reg[0x54027]); > + writel(0x0, ®s->reg[0x54028]); > + writel(0x0, ®s->reg[0x54029]); > + writel(0x0, ®s->reg[0x5402a]); > + writel(0x1000, ®s->reg[0x5402b]); > + writel(0x3, ®s->reg[0x5402c]); > + writel(0x0, ®s->reg[0x5402d]); > + writel(0x0, ®s->reg[0x5402e]); > + writel(0x0, ®s->reg[0x5402f]); > + writel(0x0, ®s->reg[0x54030]); > + writel(0x0, ®s->reg[0x54031]); > + writel(0xd400, ®s->reg[0x54032]); > + writel(0x312d, ®s->reg[0x54033]); > + writel(0x4600, ®s->reg[0x54034]); > + writel(0x84d, ®s->reg[0x54035]); > + writel(0x4d, ®s->reg[0x54036]); > + writel(0x500, ®s->reg[0x54037]); > + writel(0xd400, ®s->reg[0x54038]); > + writel(0x312d, ®s->reg[0x54039]); > + writel(0x4600, ®s->reg[0x5403a]); > + writel(0x84d, ®s->reg[0x5403b]); > + writel(0x4d, ®s->reg[0x5403c]); > + writel(0x500, ®s->reg[0x5403d]); > + writel(0x1, ®s->reg[0xd0000]); > + writel(0x1, ®s->reg[0xd0000]); > + writel(0x9, ®s->reg[0xd0099]); > + writel(0x1, ®s->reg[0xd0099]); > + writel(0x0, ®s->reg[0xd0099]); > + > + wait_ddrphy_training_complete(); > + > + writel(0x1, ®s->reg[0xd0099]); > + writel(0x0, ®s->reg[0xd0000]); > + writel(0x1, ®s->reg[0xd0000]); > + writel(0x0, ®s->reg[0xd0000]); > + > + /* load the 2D training image */ > + ddr_load_train_code(FW_2D_IMAGE); > + > + writel(0x0, ®s->reg[0xd0000]); > + writel(0x1, ®s->reg[0xd0000]); > + writel(0x0, ®s->reg[0xd0000]); > + > + writel(0x0, ®s->reg[0x54000]); > + writel(0x0, ®s->reg[0x54001]); > + writel(0x0, ®s->reg[0x54002]); > + writel(0xc80, ®s->reg[0x54003]); > + writel(0x2, ®s->reg[0x54004]); > + writel(0x2828, ®s->reg[0x54005]); > + writel(0x14, ®s->reg[0x54006]); > + writel(0x0, ®s->reg[0x54007]); > + writel(0x61, ®s->reg[0x54008]); > + writel(0xc8, ®s->reg[0x54009]); > + writel(0x0, ®s->reg[0x5400a]); > + writel(0x2, ®s->reg[0x5400b]); > + writel(0x0, ®s->reg[0x5400c]); > + writel(0x100, ®s->reg[0x5400d]); > + writel(0x0, ®s->reg[0x5400e]); > + writel(0x100, ®s->reg[0x5400f]); > + writel(0x1f7f, ®s->reg[0x54010]); > + writel(0x0, ®s->reg[0x54011]); > + writel(0x310, ®s->reg[0x54012]); > + writel(0x0, ®s->reg[0x54013]); > + writel(0x0, ®s->reg[0x54014]); > + writel(0x0, ®s->reg[0x54015]); > + writel(0x0, ®s->reg[0x54016]); > + writel(0x0, ®s->reg[0x54017]); > + writel(0x0, ®s->reg[0x54018]); > + writel(0x2dd4, ®s->reg[0x54019]); > + writel(0x31, ®s->reg[0x5401a]); > + writel(0x4d46, ®s->reg[0x5401b]); > + writel(0x4d08, ®s->reg[0x5401c]); > + writel(0x0, ®s->reg[0x5401d]); > + writel(0x5, ®s->reg[0x5401e]); > + writel(0x2dd4, ®s->reg[0x5401f]); > + writel(0x31, ®s->reg[0x54020]); > + writel(0x4d46, ®s->reg[0x54021]); > + writel(0x4d08, ®s->reg[0x54022]); > + writel(0x0, ®s->reg[0x54023]); > + writel(0x5, ®s->reg[0x54024]); > + writel(0x0, ®s->reg[0x54025]); > + writel(0x0, ®s->reg[0x54026]); > + writel(0x0, ®s->reg[0x54027]); > + writel(0x0, ®s->reg[0x54028]); > + writel(0x0, ®s->reg[0x54029]); > + writel(0x0, ®s->reg[0x5402a]); > + writel(0x1000, ®s->reg[0x5402b]); > + writel(0x3, ®s->reg[0x5402c]); > + writel(0x0, ®s->reg[0x5402d]); > + writel(0x0, ®s->reg[0x5402e]); > + writel(0x0, ®s->reg[0x5402f]); > + writel(0x0, ®s->reg[0x54030]); > + writel(0x0, ®s->reg[0x54031]); > + writel(0xd400, ®s->reg[0x54032]); > + writel(0x312d, ®s->reg[0x54033]); > + writel(0x4600, ®s->reg[0x54034]); > + writel(0x084d, ®s->reg[0x54035]); > + writel(0x4d, ®s->reg[0x54036]); > + writel(0x500, ®s->reg[0x54037]); > + writel(0xd400, ®s->reg[0x54038]); > + writel(0x312d, ®s->reg[0x54039]); > + writel(0x4600, ®s->reg[0x5403a]); > + writel(0x084d, ®s->reg[0x5403b]); > + writel(0x4d, ®s->reg[0x5403c]); > + writel(0x500, ®s->reg[0x5403d]); > + writel(0x1, ®s->reg[0xd0000]); > + /* Execute the Training Firmware */ > + writel(0x1, ®s->reg[0xd0000]); > + writel(0x9, ®s->reg[0xd0099]); > + writel(0x1, ®s->reg[0xd0099]); > + writel(0x0, ®s->reg[0xd0099]); > + /* wait for 2D training complete */ > + wait_ddrphy_training_complete(); > + > + writel(0x1, ®s->reg[0xd0099]); > + writel(0x0, ®s->reg[0xd0000]); > + writel(0x1, ®s->reg[0xd0000]); > + > + /* (I) Load PHY Init Engine Image */ > + writel(0x0, ®s->reg[0xd0000]); > + writel(0x10, ®s->reg[0x90000]); > + writel(0x400, ®s->reg[0x90001]); > + writel(0x10e, ®s->reg[0x90002]); > + writel(0x0, ®s->reg[0x90003]); > + writel(0x0, ®s->reg[0x90004]); > + writel(0x8, ®s->reg[0x90005]); > + writel(0xb, ®s->reg[0x90029]); > + writel(0x480, ®s->reg[0x9002a]); > + writel(0x109, ®s->reg[0x9002b]); > + writel(0x8, ®s->reg[0x9002c]); > + writel(0x448, ®s->reg[0x9002d]); > + writel(0x139, ®s->reg[0x9002e]); > + writel(0x8, ®s->reg[0x9002f]); > + writel(0x478, ®s->reg[0x90030]); > + writel(0x109, ®s->reg[0x90031]); > + writel(0x0, ®s->reg[0x90032]); > + writel(0xe8, ®s->reg[0x90033]); > + writel(0x109, ®s->reg[0x90034]); > + writel(0x2, ®s->reg[0x90035]); > + writel(0x10, ®s->reg[0x90036]); > + writel(0x139, ®s->reg[0x90037]); > + writel(0xf, ®s->reg[0x90038]); > + writel(0x7c0, ®s->reg[0x90039]); > + writel(0x139, ®s->reg[0x9003a]); > + writel(0x44, ®s->reg[0x9003b]); > + writel(0x630, ®s->reg[0x9003c]); > + writel(0x159, ®s->reg[0x9003d]); > + writel(0x14f, ®s->reg[0x9003e]); > + writel(0x630, ®s->reg[0x9003f]); > + writel(0x159, ®s->reg[0x90040]); > + writel(0x47, ®s->reg[0x90041]); > + writel(0x630, ®s->reg[0x90042]); > + writel(0x149, ®s->reg[0x90043]); > + writel(0x4f, ®s->reg[0x90044]); > + writel(0x630, ®s->reg[0x90045]); > + writel(0x179, ®s->reg[0x90046]); > + writel(0x8, ®s->reg[0x90047]); > + writel(0xe0, ®s->reg[0x90048]); > + writel(0x109, ®s->reg[0x90049]); > + writel(0x0, ®s->reg[0x9004a]); > + writel(0x7c8, ®s->reg[0x9004b]); > + writel(0x109, ®s->reg[0x9004c]); > + writel(0x0, ®s->reg[0x9004d]); > + writel(0x1, ®s->reg[0x9004e]); > + writel(0x8, ®s->reg[0x9004f]); > + writel(0x0, ®s->reg[0x90050]); > + writel(0x45a, ®s->reg[0x90051]); > + writel(0x9, ®s->reg[0x90052]); > + writel(0x0, ®s->reg[0x90053]); > + writel(0x448, ®s->reg[0x90054]); > + writel(0x109, ®s->reg[0x90055]); > + writel(0x40, ®s->reg[0x90056]); > + writel(0x630, ®s->reg[0x90057]); > + writel(0x179, ®s->reg[0x90058]); > + writel(0x1, ®s->reg[0x90059]); > + writel(0x618, ®s->reg[0x9005a]); > + writel(0x109, ®s->reg[0x9005b]); > + writel(0x40c0, ®s->reg[0x9005c]); > + writel(0x630, ®s->reg[0x9005d]); > + writel(0x149, ®s->reg[0x9005e]); > + writel(0x8, ®s->reg[0x9005f]); > + writel(0x4, ®s->reg[0x90060]); > + writel(0x48, ®s->reg[0x90061]); > + writel(0x4040, ®s->reg[0x90062]); > + writel(0x630, ®s->reg[0x90063]); > + writel(0x149, ®s->reg[0x90064]); > + writel(0x0, ®s->reg[0x90065]); > + writel(0x4, ®s->reg[0x90066]); > + writel(0x48, ®s->reg[0x90067]); > + writel(0x40, ®s->reg[0x90068]); > + writel(0x630, ®s->reg[0x90069]); > + writel(0x149, ®s->reg[0x9006a]); > + writel(0x10, ®s->reg[0x9006b]); > + writel(0x4, ®s->reg[0x9006c]); > + writel(0x18, ®s->reg[0x9006d]); > + writel(0x0, ®s->reg[0x9006e]); > + writel(0x4, ®s->reg[0x9006f]); > + writel(0x78, ®s->reg[0x90070]); > + writel(0x549, ®s->reg[0x90071]); > + writel(0x630, ®s->reg[0x90072]); > + writel(0x159, ®s->reg[0x90073]); > + writel(0xd49, ®s->reg[0x90074]); > + writel(0x630, ®s->reg[0x90075]); > + writel(0x159, ®s->reg[0x90076]); > + writel(0x94a, ®s->reg[0x90077]); > + writel(0x630, ®s->reg[0x90078]); > + writel(0x159, ®s->reg[0x90079]); > + writel(0x441, ®s->reg[0x9007a]); > + writel(0x630, ®s->reg[0x9007b]); > + writel(0x149, ®s->reg[0x9007c]); > + writel(0x42, ®s->reg[0x9007d]); > + writel(0x630, ®s->reg[0x9007e]); > + writel(0x149, ®s->reg[0x9007f]); > + writel(0x1, ®s->reg[0x90080]); > + writel(0x630, ®s->reg[0x90081]); > + writel(0x149, ®s->reg[0x90082]); > + writel(0x0, ®s->reg[0x90083]); > + writel(0xe0, ®s->reg[0x90084]); > + writel(0x109, ®s->reg[0x90085]); > + writel(0xa, ®s->reg[0x90086]); > + writel(0x10, ®s->reg[0x90087]); > + writel(0x109, ®s->reg[0x90088]); > + writel(0x9, ®s->reg[0x90089]); > + writel(0x3c0, ®s->reg[0x9008a]); > + writel(0x149, ®s->reg[0x9008b]); > + writel(0x9, ®s->reg[0x9008c]); > + writel(0x3c0, ®s->reg[0x9008d]); > + writel(0x159, ®s->reg[0x9008e]); > + writel(0x18, ®s->reg[0x9008f]); > + writel(0x10, ®s->reg[0x90090]); > + writel(0x109, ®s->reg[0x90091]); > + writel(0x0, ®s->reg[0x90092]); > + writel(0x3c0, ®s->reg[0x90093]); > + writel(0x109, ®s->reg[0x90094]); > + writel(0x18, ®s->reg[0x90095]); > + writel(0x4, ®s->reg[0x90096]); > + writel(0x48, ®s->reg[0x90097]); > + writel(0x18, ®s->reg[0x90098]); > + writel(0x4, ®s->reg[0x90099]); > + writel(0x58, ®s->reg[0x9009a]); > + writel(0xa, ®s->reg[0x9009b]); > + writel(0x10, ®s->reg[0x9009c]); > + writel(0x109, ®s->reg[0x9009d]); > + writel(0x2, ®s->reg[0x9009e]); > + writel(0x10, ®s->reg[0x9009f]); > + writel(0x109, ®s->reg[0x900a0]); > + writel(0x5, ®s->reg[0x900a1]); > + writel(0x7c0, ®s->reg[0x900a2]); > + writel(0x109, ®s->reg[0x900a3]); > + writel(0x10, ®s->reg[0x900a4]); > + writel(0x10, ®s->reg[0x900a5]); > + writel(0x109, ®s->reg[0x900a6]); > + writel(0x811, ®s->reg[0x40000]); > + writel(0x880, ®s->reg[0x40020]); > + writel(0x0, ®s->reg[0x40040]); > + writel(0x0, ®s->reg[0x40060]); > + writel(0x4016, ®s->reg[0x40001]); > + writel(0x83, ®s->reg[0x40021]); > + writel(0x4f, ®s->reg[0x40041]); > + writel(0x0, ®s->reg[0x40061]); > + writel(0x4040, ®s->reg[0x40002]); > + writel(0x83, ®s->reg[0x40022]); > + writel(0x51, ®s->reg[0x40042]); > + writel(0x0, ®s->reg[0x40062]); > + writel(0x811, ®s->reg[0x40003]); > + writel(0x880, ®s->reg[0x40023]); > + writel(0x0, ®s->reg[0x40043]); > + writel(0x0, ®s->reg[0x40063]); > + writel(0x720, ®s->reg[0x40004]); > + writel(0xf, ®s->reg[0x40024]); > + writel(0x1740, ®s->reg[0x40044]); > + writel(0x0, ®s->reg[0x40064]); > + writel(0x16, ®s->reg[0x40005]); > + writel(0x83, ®s->reg[0x40025]); > + writel(0x4b, ®s->reg[0x40045]); > + writel(0x0, ®s->reg[0x40065]); > + writel(0x716, ®s->reg[0x40006]); > + writel(0xf, ®s->reg[0x40026]); > + writel(0x2001, ®s->reg[0x40046]); > + writel(0x0, ®s->reg[0x40066]); > + writel(0x716, ®s->reg[0x40007]); > + writel(0xf, ®s->reg[0x40027]); > + writel(0x2800, ®s->reg[0x40047]); > + writel(0x0, ®s->reg[0x40067]); > + writel(0x716, ®s->reg[0x40008]); > + writel(0xf, ®s->reg[0x40028]); > + writel(0xf00, ®s->reg[0x40048]); > + writel(0x0, ®s->reg[0x40068]); > + writel(0x720, ®s->reg[0x40009]); > + writel(0xf, ®s->reg[0x40029]); > + writel(0x1400, ®s->reg[0x40049]); > + writel(0x0, ®s->reg[0x40069]); > + writel(0xe08, ®s->reg[0x4000a]); > + writel(0xc15, ®s->reg[0x4002a]); > + writel(0x0, ®s->reg[0x4004a]); > + writel(0x0, ®s->reg[0x4006a]); > + writel(0x623, ®s->reg[0x4000b]); > + writel(0x15, ®s->reg[0x4002b]); > + writel(0x0, ®s->reg[0x4004b]); > + writel(0x0, ®s->reg[0x4006b]); > + writel(0x4004, ®s->reg[0x4000c]); > + writel(0x80, ®s->reg[0x4002c]); > + writel(0x0, ®s->reg[0x4004c]); > + writel(0x0, ®s->reg[0x4006c]); > + writel(0xe08, ®s->reg[0x4000d]); > + writel(0xc1a, ®s->reg[0x4002d]); > + writel(0x0, ®s->reg[0x4004d]); > + writel(0x0, ®s->reg[0x4006d]); > + writel(0x623, ®s->reg[0x4000e]); > + writel(0x1a, ®s->reg[0x4002e]); > + writel(0x0, ®s->reg[0x4004e]); > + writel(0x0, ®s->reg[0x4006e]); > + writel(0x4040, ®s->reg[0x4000f]); > + writel(0x80, ®s->reg[0x4002f]); > + writel(0x0, ®s->reg[0x4004f]); > + writel(0x0, ®s->reg[0x4006f]); > + writel(0x2604, ®s->reg[0x40010]); > + writel(0x15, ®s->reg[0x40030]); > + writel(0x0, ®s->reg[0x40050]); > + writel(0x0, ®s->reg[0x40070]); > + writel(0x708, ®s->reg[0x40011]); > + writel(0x5, ®s->reg[0x40031]); > + writel(0x0, ®s->reg[0x40051]); > + writel(0x2002, ®s->reg[0x40071]); > + writel(0x8, ®s->reg[0x40012]); > + writel(0x80, ®s->reg[0x40032]); > + writel(0x0, ®s->reg[0x40052]); > + writel(0x0, ®s->reg[0x40072]); > + writel(0x2604, ®s->reg[0x40013]); > + writel(0x1a, ®s->reg[0x40033]); > + writel(0x0, ®s->reg[0x40053]); > + writel(0x0, ®s->reg[0x40073]); > + writel(0x708, ®s->reg[0x40014]); > + writel(0xa, ®s->reg[0x40034]); > + writel(0x0, ®s->reg[0x40054]); > + writel(0x2002, ®s->reg[0x40074]); > + writel(0x4040, ®s->reg[0x40015]); > + writel(0x80, ®s->reg[0x40035]); > + writel(0x0, ®s->reg[0x40055]); > + writel(0x0, ®s->reg[0x40075]); > + writel(0x60a, ®s->reg[0x40016]); > + writel(0x15, ®s->reg[0x40036]); > + writel(0x1200, ®s->reg[0x40056]); > + writel(0x0, ®s->reg[0x40076]); > + writel(0x61a, ®s->reg[0x40017]); > + writel(0x15, ®s->reg[0x40037]); > + writel(0x1300, ®s->reg[0x40057]); > + writel(0x0, ®s->reg[0x40077]); > + writel(0x60a, ®s->reg[0x40018]); > + writel(0x1a, ®s->reg[0x40038]); > + writel(0x1200, ®s->reg[0x40058]); > + writel(0x0, ®s->reg[0x40078]); > + writel(0x642, ®s->reg[0x40019]); > + writel(0x1a, ®s->reg[0x40039]); > + writel(0x1300, ®s->reg[0x40059]); > + writel(0x0, ®s->reg[0x40079]); > + writel(0x4808, ®s->reg[0x4001a]); > + writel(0x880, ®s->reg[0x4003a]); > + writel(0x0, ®s->reg[0x4005a]); > + writel(0x0, ®s->reg[0x4007a]); > + writel(0x0, ®s->reg[0x900a7]); > + writel(0x790, ®s->reg[0x900a8]); > + writel(0x11a, ®s->reg[0x900a9]); > + writel(0x8, ®s->reg[0x900aa]); > + writel(0x7aa, ®s->reg[0x900ab]); > + writel(0x2a, ®s->reg[0x900ac]); > + writel(0x10, ®s->reg[0x900ad]); > + writel(0x7b2, ®s->reg[0x900ae]); > + writel(0x2a, ®s->reg[0x900af]); > + writel(0x0, ®s->reg[0x900b0]); > + writel(0x7c8, ®s->reg[0x900b1]); > + writel(0x109, ®s->reg[0x900b2]); > + writel(0x10, ®s->reg[0x900b3]); > + writel(0x2a8, ®s->reg[0x900b4]); > + writel(0x129, ®s->reg[0x900b5]); > + writel(0x8, ®s->reg[0x900b6]); > + writel(0x370, ®s->reg[0x900b7]); > + writel(0x129, ®s->reg[0x900b8]); > + writel(0xa, ®s->reg[0x900b9]); > + writel(0x3c8, ®s->reg[0x900ba]); > + writel(0x1a9, ®s->reg[0x900bb]); > + writel(0xc, ®s->reg[0x900bc]); > + writel(0x408, ®s->reg[0x900bd]); > + writel(0x199, ®s->reg[0x900be]); > + writel(0x14, ®s->reg[0x900bf]); > + writel(0x790, ®s->reg[0x900c0]); > + writel(0x11a, ®s->reg[0x900c1]); > + writel(0x8, ®s->reg[0x900c2]); > + writel(0x4, ®s->reg[0x900c3]); > + writel(0x18, ®s->reg[0x900c4]); > + writel(0xc, ®s->reg[0x900c5]); > + writel(0x408, ®s->reg[0x900c6]); > + writel(0x199, ®s->reg[0x900c7]); > + writel(0x8, ®s->reg[0x900c8]); > + writel(0x8568, ®s->reg[0x900c9]); > + writel(0x108, ®s->reg[0x900ca]); > + writel(0x18, ®s->reg[0x900cb]); > + writel(0x790, ®s->reg[0x900cc]); > + writel(0x16a, ®s->reg[0x900cd]); > + writel(0x8, ®s->reg[0x900ce]); > + writel(0x1d8, ®s->reg[0x900cf]); > + writel(0x169, ®s->reg[0x900d0]); > + writel(0x10, ®s->reg[0x900d1]); > + writel(0x8558, ®s->reg[0x900d2]); > + writel(0x168, ®s->reg[0x900d3]); > + writel(0x70, ®s->reg[0x900d4]); > + writel(0x788, ®s->reg[0x900d5]); > + writel(0x16a, ®s->reg[0x900d6]); > + writel(0x1ff8, ®s->reg[0x900d7]); > + writel(0x85a8, ®s->reg[0x900d8]); > + writel(0x1e8, ®s->reg[0x900d9]); > + writel(0x50, ®s->reg[0x900da]); > + writel(0x798, ®s->reg[0x900db]); > + writel(0x16a, ®s->reg[0x900dc]); > + writel(0x60, ®s->reg[0x900dd]); > + writel(0x7a0, ®s->reg[0x900de]); > + writel(0x16a, ®s->reg[0x900df]); > + writel(0x8, ®s->reg[0x900e0]); > + writel(0x8310, ®s->reg[0x900e1]); > + writel(0x168, ®s->reg[0x900e2]); > + writel(0x8, ®s->reg[0x900e3]); > + writel(0xa310, ®s->reg[0x900e4]); > + writel(0x168, ®s->reg[0x900e5]); > + writel(0xa, ®s->reg[0x900e6]); > + writel(0x408, ®s->reg[0x900e7]); > + writel(0x169, ®s->reg[0x900e8]); > + writel(0x6e, ®s->reg[0x900e9]); > + writel(0x0, ®s->reg[0x900ea]); > + writel(0x68, ®s->reg[0x900eb]); > + writel(0x0, ®s->reg[0x900ec]); > + writel(0x408, ®s->reg[0x900ed]); > + writel(0x169, ®s->reg[0x900ee]); > + writel(0x0, ®s->reg[0x900ef]); > + writel(0x8310, ®s->reg[0x900f0]); > + writel(0x168, ®s->reg[0x900f1]); > + writel(0x0, ®s->reg[0x900f2]); > + writel(0xa310, ®s->reg[0x900f3]); > + writel(0x168, ®s->reg[0x900f4]); > + writel(0x1ff8, ®s->reg[0x900f5]); > + writel(0x85a8, ®s->reg[0x900f6]); > + writel(0x1e8, ®s->reg[0x900f7]); > + writel(0x68, ®s->reg[0x900f8]); > + writel(0x798, ®s->reg[0x900f9]); > + writel(0x16a, ®s->reg[0x900fa]); > + writel(0x78, ®s->reg[0x900fb]); > + writel(0x7a0, ®s->reg[0x900fc]); > + writel(0x16a, ®s->reg[0x900fd]); > + writel(0x68, ®s->reg[0x900fe]); > + writel(0x790, ®s->reg[0x900ff]); > + writel(0x16a, ®s->reg[0x90100]); > + writel(0x8, ®s->reg[0x90101]); > + writel(0x8b10, ®s->reg[0x90102]); > + writel(0x168, ®s->reg[0x90103]); > + writel(0x8, ®s->reg[0x90104]); > + writel(0xab10, ®s->reg[0x90105]); > + writel(0x168, ®s->reg[0x90106]); > + writel(0xa, ®s->reg[0x90107]); > + writel(0x408, ®s->reg[0x90108]); > + writel(0x169, ®s->reg[0x90109]); > + writel(0x58, ®s->reg[0x9010a]); > + writel(0x0, ®s->reg[0x9010b]); > + writel(0x68, ®s->reg[0x9010c]); > + writel(0x0, ®s->reg[0x9010d]); > + writel(0x408, ®s->reg[0x9010e]); > + writel(0x169, ®s->reg[0x9010f]); > + writel(0x0, ®s->reg[0x90110]); > + writel(0x8b10, ®s->reg[0x90111]); > + writel(0x168, ®s->reg[0x90112]); > + writel(0x0, ®s->reg[0x90113]); > + writel(0xab10, ®s->reg[0x90114]); > + writel(0x168, ®s->reg[0x90115]); > + writel(0x0, ®s->reg[0x90116]); > + writel(0x1d8, ®s->reg[0x90117]); > + writel(0x169, ®s->reg[0x90118]); > + writel(0x80, ®s->reg[0x90119]); > + writel(0x790, ®s->reg[0x9011a]); > + writel(0x16a, ®s->reg[0x9011b]); > + writel(0x18, ®s->reg[0x9011c]); > + writel(0x7aa, ®s->reg[0x9011d]); > + writel(0x6a, ®s->reg[0x9011e]); > + writel(0xa, ®s->reg[0x9011f]); > + writel(0x0, ®s->reg[0x90120]); > + writel(0x1e9, ®s->reg[0x90121]); > + writel(0x8, ®s->reg[0x90122]); > + writel(0x8080, ®s->reg[0x90123]); > + writel(0x108, ®s->reg[0x90124]); > + writel(0xf, ®s->reg[0x90125]); > + writel(0x408, ®s->reg[0x90126]); > + writel(0x169, ®s->reg[0x90127]); > + writel(0xc, ®s->reg[0x90128]); > + writel(0x0, ®s->reg[0x90129]); > + writel(0x68, ®s->reg[0x9012a]); > + writel(0x9, ®s->reg[0x9012b]); > + writel(0x0, ®s->reg[0x9012c]); > + writel(0x1a9, ®s->reg[0x9012d]); > + writel(0x0, ®s->reg[0x9012e]); > + writel(0x408, ®s->reg[0x9012f]); > + writel(0x169, ®s->reg[0x90130]); > + writel(0x0, ®s->reg[0x90131]); > + writel(0x8080, ®s->reg[0x90132]); > + writel(0x108, ®s->reg[0x90133]); > + writel(0x8, ®s->reg[0x90134]); > + writel(0x7aa, ®s->reg[0x90135]); > + writel(0x6a, ®s->reg[0x90136]); > + writel(0x0, ®s->reg[0x90137]); > + writel(0x8568, ®s->reg[0x90138]); > + writel(0x108, ®s->reg[0x90139]); > + writel(0xb7, ®s->reg[0x9013a]); > + writel(0x790, ®s->reg[0x9013b]); > + writel(0x16a, ®s->reg[0x9013c]); > + writel(0x1d, ®s->reg[0x9013d]); > + writel(0x0, ®s->reg[0x9013e]); > + writel(0x68, ®s->reg[0x9013f]); > + writel(0x8, ®s->reg[0x90140]); > + writel(0x8558, ®s->reg[0x90141]); > + writel(0x168, ®s->reg[0x90142]); > + writel(0xf, ®s->reg[0x90143]); > + writel(0x408, ®s->reg[0x90144]); > + writel(0x169, ®s->reg[0x90145]); > + writel(0xc, ®s->reg[0x90146]); > + writel(0x0, ®s->reg[0x90147]); > + writel(0x68, ®s->reg[0x90148]); > + writel(0x0, ®s->reg[0x90149]); > + writel(0x408, ®s->reg[0x9014a]); > + writel(0x169, ®s->reg[0x9014b]); > + writel(0x0, ®s->reg[0x9014c]); > + writel(0x8558, ®s->reg[0x9014d]); > + writel(0x168, ®s->reg[0x9014e]); > + writel(0x8, ®s->reg[0x9014f]); > + writel(0x3c8, ®s->reg[0x90150]); > + writel(0x1a9, ®s->reg[0x90151]); > + writel(0x3, ®s->reg[0x90152]); > + writel(0x370, ®s->reg[0x90153]); > + writel(0x129, ®s->reg[0x90154]); > + writel(0x20, ®s->reg[0x90155]); > + writel(0x2aa, ®s->reg[0x90156]); > + writel(0x9, ®s->reg[0x90157]); > + writel(0x0, ®s->reg[0x90158]); > + writel(0x400, ®s->reg[0x90159]); > + writel(0x10e, ®s->reg[0x9015a]); > + writel(0x8, ®s->reg[0x9015b]); > + writel(0xe8, ®s->reg[0x9015c]); > + writel(0x109, ®s->reg[0x9015d]); > + writel(0x0, ®s->reg[0x9015e]); > + writel(0x8140, ®s->reg[0x9015f]); > + writel(0x10c, ®s->reg[0x90160]); > + writel(0x10, ®s->reg[0x90161]); > + writel(0x8138, ®s->reg[0x90162]); > + writel(0x10c, ®s->reg[0x90163]); > + writel(0x8, ®s->reg[0x90164]); > + writel(0x7c8, ®s->reg[0x90165]); > + writel(0x101, ®s->reg[0x90166]); > + writel(0x8, ®s->reg[0x90167]); > + writel(0x0, ®s->reg[0x90168]); > + writel(0x8, ®s->reg[0x90169]); > + writel(0x8, ®s->reg[0x9016a]); > + writel(0x448, ®s->reg[0x9016b]); > + writel(0x109, ®s->reg[0x9016c]); > + writel(0xf, ®s->reg[0x9016d]); > + writel(0x7c0, ®s->reg[0x9016e]); > + writel(0x109, ®s->reg[0x9016f]); > + writel(0x0, ®s->reg[0x90170]); > + writel(0xe8, ®s->reg[0x90171]); > + writel(0x109, ®s->reg[0x90172]); > + writel(0x47, ®s->reg[0x90173]); > + writel(0x630, ®s->reg[0x90174]); > + writel(0x109, ®s->reg[0x90175]); > + writel(0x8, ®s->reg[0x90176]); > + writel(0x618, ®s->reg[0x90177]); > + writel(0x109, ®s->reg[0x90178]); > + writel(0x8, ®s->reg[0x90179]); > + writel(0xe0, ®s->reg[0x9017a]); > + writel(0x109, ®s->reg[0x9017b]); > + writel(0x0, ®s->reg[0x9017c]); > + writel(0x7c8, ®s->reg[0x9017d]); > + writel(0x109, ®s->reg[0x9017e]); > + writel(0x8, ®s->reg[0x9017f]); > + writel(0x8140, ®s->reg[0x90180]); > + writel(0x10c, ®s->reg[0x90181]); > + writel(0x0, ®s->reg[0x90182]); > + writel(0x1, ®s->reg[0x90183]); > + writel(0x8, ®s->reg[0x90184]); > + writel(0x8, ®s->reg[0x90185]); > + writel(0x4, ®s->reg[0x90186]); > + writel(0x8, ®s->reg[0x90187]); > + writel(0x8, ®s->reg[0x90188]); > + writel(0x7c8, ®s->reg[0x90189]); > + writel(0x101, ®s->reg[0x9018a]); > + writel(0x0, ®s->reg[0x90006]); > + writel(0x0, ®s->reg[0x90007]); > + writel(0x8, ®s->reg[0x90008]); > + writel(0x0, ®s->reg[0x90009]); > + writel(0x0, ®s->reg[0x9000a]); > + writel(0x0, ®s->reg[0x9000b]); > + writel(0x400, ®s->reg[0xd00e7]); > + writel(0x0, ®s->reg[0x90017]); > + writel(0x2a, ®s->reg[0x9001f]); > + writel(0x6a, ®s->reg[0x90026]); > + writel(0x0, ®s->reg[0x400d0]); > + writel(0x101, ®s->reg[0x400d1]); > + writel(0x105, ®s->reg[0x400d2]); > + writel(0x107, ®s->reg[0x400d3]); > + writel(0x10f, ®s->reg[0x400d4]); > + writel(0x202, ®s->reg[0x400d5]); > + writel(0x20a, ®s->reg[0x400d6]); > + writel(0x20b, ®s->reg[0x400d7]); > + writel(0x2, ®s->reg[0x2003a]); > + writel(0x0, ®s->reg[0x9000c]); > + writel(0x173, ®s->reg[0x9000d]); > + writel(0x60, ®s->reg[0x9000e]); > + writel(0x6110, ®s->reg[0x9000f]); > + writel(0x2152, ®s->reg[0x90010]); > + writel(0xdfbd, ®s->reg[0x90011]); > + writel(0x60, ®s->reg[0x90012]); > + writel(0x6152, ®s->reg[0x90013]); > + writel(0x5a, ®s->reg[0x20010]); > + writel(0x3, ®s->reg[0x20011]); > + writel(0xe0, ®s->reg[0x40080]); > + writel(0x12, ®s->reg[0x40081]); > + writel(0xe0, ®s->reg[0x40082]); > + writel(0x12, ®s->reg[0x40083]); > + writel(0xe0, ®s->reg[0x40084]); > + writel(0x12, ®s->reg[0x40085]); > + writel(0xf, ®s->reg[0x400fd]); > + writel(0x1, ®s->reg[0x10011]); > + writel(0x1, ®s->reg[0x10012]); > + writel(0x180, ®s->reg[0x10013]); > + writel(0x1, ®s->reg[0x10018]); > + writel(0x6209, ®s->reg[0x10002]); > + writel(0x1, ®s->reg[0x100b2]); > + writel(0x1, ®s->reg[0x101b4]); > + writel(0x1, ®s->reg[0x102b4]); > + writel(0x1, ®s->reg[0x103b4]); > + writel(0x1, ®s->reg[0x104b4]); > + writel(0x1, ®s->reg[0x105b4]); > + writel(0x1, ®s->reg[0x106b4]); > + writel(0x1, ®s->reg[0x107b4]); > + writel(0x1, ®s->reg[0x108b4]); > + writel(0x1, ®s->reg[0x11011]); > + writel(0x1, ®s->reg[0x11012]); > + writel(0x180, ®s->reg[0x11013]); > + writel(0x1, ®s->reg[0x11018]); > + writel(0x6209, ®s->reg[0x11002]); > + writel(0x1, ®s->reg[0x110b2]); > + writel(0x1, ®s->reg[0x111b4]); > + writel(0x1, ®s->reg[0x112b4]); > + writel(0x1, ®s->reg[0x113b4]); > + writel(0x1, ®s->reg[0x114b4]); > + writel(0x1, ®s->reg[0x115b4]); > + writel(0x1, ®s->reg[0x116b4]); > + writel(0x1, ®s->reg[0x117b4]); > + writel(0x1, ®s->reg[0x118b4]); > + writel(0x1, ®s->reg[0x12011]); > + writel(0x1, ®s->reg[0x12012]); > + writel(0x180, ®s->reg[0x12013]); > + writel(0x1, ®s->reg[0x12018]); > + writel(0x6209, ®s->reg[0x12002]); > + writel(0x1, ®s->reg[0x120b2]); > + writel(0x1, ®s->reg[0x121b4]); > + writel(0x1, ®s->reg[0x122b4]); > + writel(0x1, ®s->reg[0x123b4]); > + writel(0x1, ®s->reg[0x124b4]); > + writel(0x1, ®s->reg[0x125b4]); > + writel(0x1, ®s->reg[0x126b4]); > + writel(0x1, ®s->reg[0x127b4]); > + writel(0x1, ®s->reg[0x128b4]); > + writel(0x1, ®s->reg[0x13011]); > + writel(0x1, ®s->reg[0x13012]); > + writel(0x180, ®s->reg[0x13013]); > + writel(0x1, ®s->reg[0x13018]); > + writel(0x6209, ®s->reg[0x13002]); > + writel(0x1, ®s->reg[0x130b2]); > + writel(0x1, ®s->reg[0x131b4]); > + writel(0x1, ®s->reg[0x132b4]); > + writel(0x1, ®s->reg[0x133b4]); > + writel(0x1, ®s->reg[0x134b4]); > + writel(0x1, ®s->reg[0x135b4]); > + writel(0x1, ®s->reg[0x136b4]); > + writel(0x1, ®s->reg[0x137b4]); > + writel(0x1, ®s->reg[0x138b4]); > + writel(0x2, ®s->reg[0x2003a]); > + writel(0x2, ®s->reg[0xc0080]); > + writel(0x1, ®s->reg[0xd0000]); > + writel(0x0, ®s->reg[0x000d0000]); > + readl(®s->reg[0x00020010]); > + writel(0x6a, ®s->reg[0x00020010]); > + readl(®s->reg[0x0002001d]); > + writel(0x1, ®s->reg[0x0002001d]); > + /* > + * CalBusy.0 =1, indicates the calibrator is actively calibrating. > + * Wait Calibrating done. > + */ > + ret = readl_poll_timeout(®s->reg[0x20097], val, > + !(val & BIT(1)), 1000); > + if (ret) > + puts("CalBusy.0 timeout\n"); > + > + writel(0x0, ®s->reg[0xd0000]); > + writel(0x0, ®s->reg[0x2006e]); > +} This function tells me that we do not need a compiler at all :-(. I cannot say it is self-explaining.... > diff --git a/board/freescale/mx8mq_evk/ddr/helper.c b/board/freescale/mx8mq_evk/ddr/helper.c > new file mode 100644 > index 0000000000..4e87991c7b > --- /dev/null > +++ b/board/freescale/mx8mq_evk/ddr/helper.c > @@ -0,0 +1,101 @@ > +/* > + * Copyright 2017 NXP > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +DECLARE_GLOBAL_DATA_PTR; > + > +#define IMEM_LEN 32768 > +#define DMEM_LEN 16384 > +#define IMEM_2D_OFFSET 49152 > + > +#define IMEM_OFFSET_ADDR 0x00050000 > +#define DMEM_OFFSET_ADDR 0x00054000 > +#define DDR_TRAIN_CODE_BASE_ADDR IP2APB_DDRPHY_IPS_BASE_ADDR(0) > + > +/* We need PHY iMEM PHY is 32KB padded */ > +void ddr_load_train_code(enum fw_type type) > +{ > + u32 tmp32, i; > + u32 error = 0; > + unsigned long pr_to32, pr_from32; > + unsigned long fw_offset = type ? IMEM_2D_OFFSET : 0; > + unsigned long imem_start = (unsigned long)&_end + fw_offset; > + unsigned long dmem_start = imem_start + IMEM_LEN; > + > + pr_from32 = imem_start; > + pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * IMEM_OFFSET_ADDR; > + for (i = 0x0; i < IMEM_LEN; ) { > + tmp32 = readl(pr_from32); > + writew(tmp32 & 0x0000ffff, pr_to32); > + pr_to32 += 4; > + writew((tmp32 >> 16) & 0x0000ffff, pr_to32); > + pr_to32 += 4; > + pr_from32 += 4; > + i += 4; > + } > + > + pr_from32 = dmem_start; > + pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * DMEM_OFFSET_ADDR; > + for (i = 0x0; i < DMEM_LEN;) { > + tmp32 = readl(pr_from32); > + writew(tmp32 & 0x0000ffff, pr_to32); > + pr_to32 += 4; > + writew((tmp32 >> 16) & 0x0000ffff, pr_to32); > + pr_to32 += 4; > + pr_from32 += 4; > + i += 4; > + } > + > + debug("check ddr4_pmu_train_imem code\n"); > + pr_from32 = imem_start; > + pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * IMEM_OFFSET_ADDR; > + for (i = 0x0; i < IMEM_LEN;) { > + tmp32 = (readw(pr_to32) & 0x0000ffff); > + pr_to32 += 4; > + tmp32 += ((readw(pr_to32) & 0x0000ffff) << 16); > + > + if (tmp32 != readl(pr_from32)) { > + printf("%lx %lx\n", pr_from32, pr_to32); > + error++; > + } > + pr_from32 += 4; > + pr_to32 += 4; > + i += 4; > + } > + if (error) > + printf("check ddr4_pmu_train_imem code fail=%d\n", error); > + else > + debug("check ddr4_pmu_train_imem code pass\n"); > + > + debug("check ddr4_pmu_train_dmem code\n"); > + pr_from32 = dmem_start; > + pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * DMEM_OFFSET_ADDR; > + for (i = 0x0; i < DMEM_LEN;) { > + tmp32 = (readw(pr_to32) & 0x0000ffff); > + pr_to32 += 4; > + tmp32 += ((readw(pr_to32) & 0x0000ffff) << 16); > + if (tmp32 != readl(pr_from32)) { > + printf("%lx %lx\n", pr_from32, pr_to32); > + error++; > + } > + pr_from32 += 4; > + pr_to32 += 4; > + i += 4; > + } > + > + if (error) > + printf("check ddr4_pmu_train_dmem code fail=%d", error); > + else > + debug("check ddr4_pmu_train_dmem code pass\n"); > +} > diff --git a/board/freescale/mx8mq_evk/mx8mq_evk.c b/board/freescale/mx8mq_evk/mx8mq_evk.c > new file mode 100644 > index 0000000000..e31678efb7 > --- /dev/null > +++ b/board/freescale/mx8mq_evk/mx8mq_evk.c > @@ -0,0 +1,156 @@ > +/* > + * Copyright 2017 NXP > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "../common/pfuze.h" > + > +DECLARE_GLOBAL_DATA_PTR; > + > +#define QSPI_PAD_CTRL (PAD_CTL_DSE2 | PAD_CTL_HYS) > + > +#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1) > + > +#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE) > + > +static iomux_v3_cfg_t const wdog_pads[] = { > + IMX8MQ_PAD_GPIO1_IO02__WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL), > +}; > + > +#ifdef CONFIG_FSL_QSPI > +static iomux_v3_cfg_t const qspi_pads[] = { > + IMX8MQ_PAD_NAND_ALE__QSPI_A_SCLK | MUX_PAD_CTRL(QSPI_PAD_CTRL), > + IMX8MQ_PAD_NAND_CE0_B__QSPI_A_SS0_B | MUX_PAD_CTRL(QSPI_PAD_CTRL), > + > + IMX8MQ_PAD_NAND_DATA00__QSPI_A_DATA0 | MUX_PAD_CTRL(QSPI_PAD_CTRL), > + IMX8MQ_PAD_NAND_DATA01__QSPI_A_DATA1 | MUX_PAD_CTRL(QSPI_PAD_CTRL), > + IMX8MQ_PAD_NAND_DATA02__QSPI_A_DATA2 | MUX_PAD_CTRL(QSPI_PAD_CTRL), > + IMX8MQ_PAD_NAND_DATA03__QSPI_A_DATA3 | MUX_PAD_CTRL(QSPI_PAD_CTRL), > +}; > + > +int board_qspi_init(void) > +{ > + imx_iomux_v3_setup_multiple_pads(qspi_pads, ARRAY_SIZE(qspi_pads)); > + > + set_clk_qspi(); > + > + return 0; > +} > +#endif > + > +static iomux_v3_cfg_t const uart_pads[] = { > + IMX8MQ_PAD_UART1_RXD__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), > + IMX8MQ_PAD_UART1_TXD__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), > +}; > + > +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)); > + > + return 0; > +} > + > +int dram_init(void) > +{ > + /* rom_pointer[1] contains the size of TEE occupies */ > + if (rom_pointer[1]) > + gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; > + else > + gd->ram_size = PHYS_SDRAM_SIZE; > + > + return 0; > +} > + > +#ifdef CONFIG_FEC_MXC > +#define FEC_RST_PAD IMX_GPIO_NR(1, 9) > +static iomux_v3_cfg_t const fec1_rst_pads[] = { > + IMX8MQ_PAD_GPIO1_IO09__GPIO1_IO9 | MUX_PAD_CTRL(NO_PAD_CTRL), > +}; > + > +static void setup_iomux_fec(void) > +{ > + imx_iomux_v3_setup_multiple_pads(fec1_rst_pads, > + ARRAY_SIZE(fec1_rst_pads)); > + > + gpio_request(IMX_GPIO_NR(1, 9), "fec1_rst"); > + gpio_direction_output(IMX_GPIO_NR(1, 9), 0); > + udelay(500); > + gpio_direction_output(IMX_GPIO_NR(1, 9), 1); > +} > + > +static int setup_fec(void) > +{ > + struct iomuxc_gpr_base_regs *gpr = > + (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; > + > + setup_iomux_fec(); > + > + /* Use 125M anatop REF_CLK1 for ENET1, not from external */ > + clrsetbits_le32(&gpr->gpr[1], BIT(13) | BIT(17), 0); > + return set_clk_enet(ENET_125MHZ); > +} > + > +int board_phy_config(struct phy_device *phydev) > +{ > + /* enable rgmii rxc skew and phy mode select to RGMII copper */ > + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); > + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); > + > + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); > + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); > + > + if (phydev->drv->config) > + phydev->drv->config(phydev); > + return 0; > +} > +#endif > + > +int board_init(void) > +{ > + board_qspi_init(); > + > +#ifdef CONFIG_FEC_MXC > + setup_fec(); > +#endif > + > + return 0; > +} > + > +int board_mmc_get_env_dev(int devno) > +{ > + return devno; > +} > + > +int board_late_init(void) > +{ > +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG > + env_set("board_name", "EVK"); > + env_set("board_rev", "iMX8MQ"); > +#endif > + > + return 0; > +} > diff --git a/board/freescale/mx8mq_evk/spl.c b/board/freescale/mx8mq_evk/spl.c > new file mode 100644 > index 0000000000..3e6aa51692 > --- /dev/null > +++ b/board/freescale/mx8mq_evk/spl.c > @@ -0,0 +1,230 @@ > +/* > + * Copyright 2017 NXP > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "../common/pfuze.h" > + > +DECLARE_GLOBAL_DATA_PTR; > + > +void spl_dram_init(void) > +{ > + /* ddr init */ > + ddr_init(); > +} > + > +#define I2C_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE) > +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) > +struct i2c_pads_info i2c_pad_info1 = { > + .scl = { > + .i2c_mode = IMX8MQ_PAD_I2C1_SCL__I2C1_SCL | PC, > + .gpio_mode = IMX8MQ_PAD_I2C1_SCL__GPIO5_IO14 | PC, > + .gp = IMX_GPIO_NR(5, 14), > + }, > + .sda = { > + .i2c_mode = IMX8MQ_PAD_I2C1_SDA__I2C1_SDA | PC, > + .gpio_mode = IMX8MQ_PAD_I2C1_SDA__GPIO5_IO15 | PC, > + .gp = IMX_GPIO_NR(5, 15), > + }, > +}; > + > +#define USDHC2_CD_GPIO IMX_GPIO_NR(2, 12) > +#define USDHC1_PWR_GPIO IMX_GPIO_NR(2, 10) > +#define USDHC2_PWR_GPIO IMX_GPIO_NR(2, 19) > + > +int board_mmc_getcd(struct mmc *mmc) > +{ > + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; > + int ret = 0; > + > + switch (cfg->esdhc_base) { > + case USDHC1_BASE_ADDR: > + ret = 1; > + break; > + case USDHC2_BASE_ADDR: > + ret = !gpio_get_value(USDHC2_CD_GPIO); > + return ret; > + } > + > + return 1; > +} > + > +#define USDHC_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | \ > + PAD_CTL_FSEL2) > + > +static iomux_v3_cfg_t const usdhc1_pads[] = { > + IMX8MQ_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD1_DATA4__USDHC1_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD1_DATA5__USDHC1_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD1_DATA6__USDHC1_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD1_DATA7__USDHC1_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD1_RESET_B__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL), > +}; > + > +static iomux_v3_cfg_t const usdhc2_pads[] = { > + IMX8MQ_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), > + IMX8MQ_PAD_SD2_CD_B__GPIO2_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL), > + IMX8MQ_PAD_SD2_RESET_B__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL), > +}; > + > +static struct fsl_esdhc_cfg usdhc_cfg[2] = { > + {USDHC1_BASE_ADDR, 0, 8}, > + {USDHC2_BASE_ADDR, 0, 4}, > +}; > + > +int board_mmc_init(bd_t *bis) > +{ > + int i, ret; > + /* > + * According to the board_mmc_init() the following map is done: > + * (U-Boot device node) (Physical Port) > + * mmc0 USDHC1 > + * mmc1 USDHC2 > + */ > + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { > + switch (i) { > + case 0: > + init_clk_usdhc(0); > + usdhc_cfg[0].sdhc_clk = mxc_get_clock(USDHC1_CLK_ROOT); > + imx_iomux_v3_setup_multiple_pads( > + usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); > + gpio_request(USDHC1_PWR_GPIO, "usdhc1_reset"); > + gpio_direction_output(USDHC1_PWR_GPIO, 0); > + udelay(500); > + gpio_direction_output(USDHC1_PWR_GPIO, 1); > + break; > + case 1: > + init_clk_usdhc(1); > + usdhc_cfg[1].sdhc_clk = mxc_get_clock(USDHC2_CLK_ROOT); > + imx_iomux_v3_setup_multiple_pads( > + usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); > + gpio_request(USDHC2_PWR_GPIO, "usdhc2_reset"); > + gpio_direction_output(USDHC2_PWR_GPIO, 0); > + udelay(500); > + gpio_direction_output(USDHC2_PWR_GPIO, 1); > + break; > + default: > + printf("Warning: you configured more USDHC controllers(%d) than supported by the board\n", i + 1); > + return -EINVAL; > + } > + > + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); > + if (ret) > + return ret; > + } > + > + return 0; > +} > + > +#ifdef CONFIG_POWER > +#define I2C_PMIC 0 > +int power_init_board(void) > +{ > + struct pmic *p; > + int ret; > + unsigned int reg; > + > + ret = power_pfuze100_init(I2C_PMIC); > + if (ret) > + return -ENODEV; > + > + p = pmic_get("PFUZE100"); > + ret = pmic_probe(p); > + if (ret) > + return -ENODEV; > + > + pmic_reg_read(p, PFUZE100_DEVICEID, ®); > + printf("PMIC: PFUZE100 ID=0x%02x\n", reg); > + > + pmic_reg_read(p, PFUZE100_SW3AVOL, ®); > + if ((reg & 0x3f) != 0x18) { > + reg &= ~0x3f; > + reg |= 0x18; > + pmic_reg_write(p, PFUZE100_SW3AVOL, reg); > + } > + > + ret = pfuze_mode_init(p, APS_PFM); > + if (ret < 0) > + return ret; > + > + return 0; > +} > +#endif > + > +void spl_board_init(void) > +{ > + enable_tzc380(); > + > + /* Adjust pmic voltage to 1.0V for 800M */ > + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); > + > + power_init_board(); > + > + /* DDR initialization */ > + spl_dram_init(); > + > + /* Serial download mode */ > + if (is_usb_boot()) { > + puts("Back to ROM, SDP\n"); > + restore_boot_params(); > + } > + puts("Normal Boot\n"); > +} > + > +#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) > +{ > + /* Clear global data */ > + memset((void *)gd, 0, sizeof(gd_t)); > + > + arch_cpu_init(); > + > + init_uart_clk(0); > + > + board_early_init_f(); > + > + timer_init(); > + > + preloader_console_init(); > + > + /* Clear the BSS. */ > + memset(__bss_start, 0, __bss_end - __bss_start); > + > + board_init_r(NULL, 0); > +} > diff --git a/configs/mx8mq_evk_defconfig b/configs/mx8mq_evk_defconfig > new file mode 100644 > index 0000000000..5848168ac3 > --- /dev/null > +++ b/configs/mx8mq_evk_defconfig > @@ -0,0 +1,27 @@ > +CONFIG_ARM=y > +CONFIG_ARCH_MX8M=y > +CONFIG_SYS_MALLOC_F_LEN=0x2000 > +CONFIG_TARGET_MX8MQ_EVK=y > +CONFIG_DEFAULT_DEVICE_TREE="fsl-imx8mq-evk" > +CONFIG_FIT=y > +CONFIG_SPL_LOAD_FIT=y > +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg" > +CONFIG_SPL=y > +CONFIG_HUSH_PARSER=y > +CONFIG_CMD_GPIO=y > +CONFIG_CMD_I2C=y > +CONFIG_CMD_CACHE=y > +CONFIG_CMD_REGULATOR=y > +CONFIG_OF_CONTROL=y > +CONFIG_DM_GPIO=y > +CONFIG_DM_I2C=y > +CONFIG_DM_MMC=y > +CONFIG_DM_ETH=y > +CONFIG_PINCTRL=y > +CONFIG_DM_PMIC_PFUZE100=y > +CONFIG_DM_REGULATOR=y > +CONFIG_DM_REGULATOR_PFUZE100=y > +CONFIG_DM_REGULATOR_FIXED=y > +CONFIG_DM_REGULATOR_GPIO=y > +CONFIG_DM_THERMAL=y > +CONFIG_FS_FAT=y > diff --git a/include/configs/mx8mq_evk.h b/include/configs/mx8mq_evk.h > new file mode 100644 > index 0000000000..6fb8669bbe > --- /dev/null > +++ b/include/configs/mx8mq_evk.h > @@ -0,0 +1,269 @@ > +/* > + * Copyright 2017 NXP > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#ifndef __IMX8M_EVK_H > +#define __IMX8M_EVK_H > + > +#include > +#include > + > +#ifdef CONFIG_SECURE_BOOT > +#define CONFIG_CSF_SIZE 0x2000 /* 8K region */ > +#endif > + > +#define CONFIG_SPL_FRAMEWORK > +#define CONFIG_SPL_TEXT_BASE 0x7E1000 > +#define CONFIG_SPL_MAX_SIZE (124 * 1024) > +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) > +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR > +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 > +#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1 > + > +#ifdef CONFIG_SPL_BUILD > +/*#define CONFIG_ENABLE_DDR_TRAINING_DEBUG*/ > +#define CONFIG_SPL_WATCHDOG_SUPPORT > +#define CONFIG_SPL_DRIVERS_MISC_SUPPORT > +#define CONFIG_SPL_POWER_SUPPORT > +#define CONFIG_SPL_I2C_SUPPORT > +#define CONFIG_SPL_BOARD_INIT > +#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv8/u-boot-spl.lds" > +#define CONFIG_SPL_STACK 0x187FF0 > +#define CONFIG_SPL_LIBCOMMON_SUPPORT > +#define CONFIG_SPL_LIBGENERIC_SUPPORT > +#define CONFIG_SPL_SERIAL_SUPPORT > +#define CONFIG_SPL_GPIO_SUPPORT > +#define CONFIG_SPL_MMC_SUPPORT > +#define CONFIG_SPL_BSS_START_ADDR 0x00180000 > +#define CONFIG_SPL_BSS_MAX_SIZE 0x2000 /* 8 KB */ > +#define CONFIG_SYS_SPL_MALLOC_START 0x00182000 > +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x2000 /* 8 KB */ > +#define CONFIG_SYS_ICACHE_OFF > +#define CONFIG_SYS_DCACHE_OFF > + > +#define CONFIG_SPL_ABORT_ON_RAW_IMAGE > + > +#undef CONFIG_DM_MMC > +#undef CONFIG_DM_PMIC > +#undef CONFIG_DM_PMIC_PFUZE100 > + > +#define CONFIG_SYS_I2C > +#define CONFIG_SYS_I2C_MXC > +#define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */ > +#define CONFIG_SYS_I2C_MXC_I2C2 /* enable I2C bus 2 */ > +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ > + > +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG > + > +#define CONFIG_POWER > +#define CONFIG_POWER_I2C > +#define CONFIG_POWER_PFUZE100 > +#define CONFIG_POWER_PFUZE100_I2C_ADDR 0x08 > +#endif > + > +#define CONFIG_REMAKE_ELF > + > +#define CONFIG_BOARD_EARLY_INIT_F > +#define CONFIG_BOARD_LATE_INIT > + > +#undef CONFIG_CMD_EXPORTENV > +#undef CONFIG_CMD_IMPORTENV > +#undef CONFIG_CMD_IMLS > + > +#undef CONFIG_CMD_CRC32 > +#undef CONFIG_BOOTM_NETBSD > + > +/* ENET Config */ > +/* ENET1 */ > +#if defined(CONFIG_CMD_NET) > +#define CONFIG_CMD_PING > +#define CONFIG_CMD_DHCP > +#define CONFIG_CMD_MII > +#define CONFIG_MII > +#define CONFIG_ETHPRIME "FEC" > + > +#define CONFIG_FEC_MXC > +#define CONFIG_FEC_XCV_TYPE RGMII > +#define CONFIG_FEC_MXC_PHYADDR 0 > +#define FEC_QUIRK_ENET_MAC > + > +#define CONFIG_PHY_GIGE > +#define IMX_FEC_BASE 0x30BE0000 > + > +#define CONFIG_PHYLIB > +#define CONFIG_PHY_ATHEROS > +#endif > + > +#define CONFIG_MFG_ENV_SETTINGS \ > + "mfgtool_args=setenv bootargs console=${console},${baudrate} " \ > + "rdinit=/linuxrc " \ > + "g_mass_storage.stall=0 g_mass_storage.removable=1 " \ > + "g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF "\ > + "g_mass_storage.iSerialNumber=\"\" "\ > + "clk_ignore_unused "\ > + "\0" \ > + "initrd_addr=0x43800000\0" \ > + "initrd_high=0xffffffff\0" \ > + "bootcmd_mfg=run mfgtool_args;booti ${loadaddr} ${initrd_addr} ${fdt_addr};\0" \ > +/* Initial environment variables */ > +#define CONFIG_EXTRA_ENV_SETTINGS \ > + CONFIG_MFG_ENV_SETTINGS \ > + "script=boot.scr\0" \ > + "image=Image\0" \ > + "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200\0" \ > + "fdt_addr=0x43000000\0" \ > + "fdt_high=0xffffffffffffffff\0" \ > + "boot_fdt=try\0" \ > + "fdt_file=fsl-imx8mq-evk.dtb\0" \ > + "initrd_addr=0x43800000\0" \ > + "initrd_high=0xffffffffffffffff\0" \ > + "mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \ > + "mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \ > + "mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \ > + "mmcautodetect=yes\0" \ > + "mmcargs=setenv bootargs console=${console} root=${mmcroot}\0 " \ > + "loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${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} ${fdt_file}\0" \ > + "mmcboot=echo Booting from mmc ...; " \ > + "run mmcargs; " \ > + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ > + "if run loadfdt; then " \ > + "booti ${loadaddr} - ${fdt_addr}; " \ > + "else " \ > + "echo WARN: Cannot load the DT; " \ > + "fi; " \ > + "else " \ > + "echo wait for boot; " \ > + "fi;\0" \ > + "netargs=setenv bootargs console=${console} " \ > + "root=/dev/nfs " \ > + "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \ > + "netboot=echo Booting from net ...; " \ > + "run netargs; " \ > + "if test ${ip_dyn} = yes; then " \ > + "setenv get_cmd dhcp; " \ > + "else " \ > + "setenv get_cmd tftp; " \ > + "fi; " \ > + "${get_cmd} ${loadaddr} ${image}; " \ > + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ > + "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \ > + "booti ${loadaddr} - ${fdt_addr}; " \ > + "else " \ > + "echo WARN: Cannot load the DT; " \ > + "fi; " \ > + "else " \ > + "booti; " \ > + "fi;\0" > + > +#define CONFIG_BOOTCOMMAND \ > + "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; " \ > + "else booti ${loadaddr} - ${fdt_addr}; fi" > + > +/* Link Definitions */ > +#define CONFIG_LOADADDR 0x40480000 > +#define CONFIG_SYS_TEXT_BASE 0x40200000 > + > +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR > + > +#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_ENV_OVERWRITE > +#define CONFIG_ENV_OFFSET (64 * SZ_64K) > +#define CONFIG_ENV_SIZE 0x1000 > +#define CONFIG_ENV_IS_IN_MMC > +#define CONFIG_SYS_MMC_ENV_DEV 1 /* USDHC2 */ > +#define CONFIG_MMCROOT "/dev/mmcblk1p2" /* USDHC2 */ > + > +/* Size of malloc() pool */ > +#define CONFIG_SYS_MALLOC_LEN ((CONFIG_ENV_SIZE + (2 * 1024)) * 1024) > + > +#define CONFIG_SYS_SDRAM_BASE 0x40000000 > +#define PHYS_SDRAM 0x40000000 > +#define PHYS_SDRAM_SIZE 0xC0000000 /* 3GB DDR */ > +#define CONFIG_NR_DRAM_BANKS 1 > + > +#define CONFIG_BAUDRATE 115200 > + > +#define CONFIG_MXC_UART > +#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR > + > +/* Monitor Command Prompt */ > +#undef CONFIG_SYS_PROMPT > +#define CONFIG_SYS_PROMPT "u-boot=> " > +#define CONFIG_SYS_LONGHELP > +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " > +#define CONFIG_AUTO_COMPLETE > +#define CONFIG_SYS_CBSIZE 1024 > +#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_CMDLINE_EDITING > + > +#define CONFIG_IMX_BOOTAUX > + > +#define CONFIG_CMD_MMC > +#define CONFIG_FSL_ESDHC > +#define CONFIG_FSL_USDHC > + > +#define CONFIG_SYS_FSL_USDHC_NUM 2 > +#define CONFIG_SYS_FSL_ESDHC_ADDR 0 > + > +#define CONFIG_DOS_PARTITION > +#define CONFIG_CMD_EXT2 > +#define CONFIG_CMD_EXT4 > +#define CONFIG_CMD_EXT4_WRITE > +#define CONFIG_CMD_FAT > + > +#define CONFIG_SUPPORT_EMMC_BOOT /* eMMC specific */ > +#define CONFIG_SYS_MMC_IMG_LOAD_PART 1 > + > +#define CONFIG_FSL_QSPI /* enable the QUADSPI driver */ > +#ifdef CONFIG_FSL_QSPI > +#define CONFIG_CMD_SF > +#define CONFIG_SPI_FLASH > +#define CONFIG_SPI_FLASH_STMICRO > +#define CONFIG_SPI_FLASH_BAR > +#define CONFIG_SF_DEFAULT_BUS 0 > +#define CONFIG_SF_DEFAULT_CS 0 > +#define CONFIG_SF_DEFAULT_SPEED 40000000 > +#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 > + > +#define FSL_QSPI_FLASH_SIZE (SZ_32M) > +#define FSL_QSPI_FLASH_NUM 1 > +#endif > + > +#define CONFIG_MXC_GPIO > + > +#define CONFIG_MXC_OCOTP > +#define CONFIG_CMD_FUSE > + > +/* I2C Configs */ > +#define CONFIG_SYS_I2C_SPEED 100000 > + > +#define CONFIG_OF_SYSTEM_SETUP > + > +#ifndef CONFIG_SPL_BUILD > +#define CONFIG_DM_PMIC > +#endif > + > +#endif > Im open to suggestions how to go on. The big isssues with the patchset is IMHO the cryptical part with the LPDDR settings. We could start to merge most of patches - they were already reviewed and they are freee of comments. Fabio, do you have a best approach ? Best regards, Stefano -- ===================================================================== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de =====================================================================