[PATCH 0/1] Add support for the Purism Librem5 Phone

This is all of the code required to boot the Librem5 Phone. I wasn't sure if a single large patch including all of the code would be better or multiple patches, here it is all at once.
It can boot the phone in uuu mode or directly from the eMMC
Angus Ainslie (1): board: purism: librem5: add the Librem5 phone files
MAINTAINERS | 8 + arch/arm/dts/Makefile | 3 +- arch/arm/dts/imx8mq-librem5-u-boot.dtsi | 134 ++ arch/arm/dts/imx8mq-librem5.dts | 593 ++++++++ arch/arm/mach-imx/imx8m/Kconfig | 9 + board/purism/librem5/Kconfig | 15 + board/purism/librem5/MAINTAINERS | 7 + board/purism/librem5/Makefile | 13 + board/purism/librem5/imximage-8mq-lpddr4.cfg | 9 + board/purism/librem5/librem5.c | 710 ++++++++++ board/purism/librem5/librem5.h | 176 +++ board/purism/librem5/lpddr4_timing.c | 1324 ++++++++++++++++++ board/purism/librem5/lpddr4_timing_b0.c | 1191 ++++++++++++++++ board/purism/librem5/spl.c | 481 +++++++ configs/librem5_defconfig | 120 ++ doc/board/purism/librem5/librem5.rst | 60 + include/configs/librem5.h | 173 +++ 17 files changed, 5025 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/imx8mq-librem5-u-boot.dtsi create mode 100644 arch/arm/dts/imx8mq-librem5.dts create mode 100644 board/purism/librem5/Kconfig create mode 100644 board/purism/librem5/MAINTAINERS create mode 100644 board/purism/librem5/Makefile create mode 100644 board/purism/librem5/imximage-8mq-lpddr4.cfg create mode 100644 board/purism/librem5/librem5.c create mode 100644 board/purism/librem5/librem5.h create mode 100644 board/purism/librem5/lpddr4_timing.c create mode 100644 board/purism/librem5/lpddr4_timing_b0.c create mode 100644 board/purism/librem5/spl.c create mode 100644 configs/librem5_defconfig create mode 100644 doc/board/purism/librem5/librem5.rst create mode 100644 include/configs/librem5.h

Initial commit of librem5 spl and u-boot based on the imx8mq_evk u-boot
Signed-off-by: Angus Ainslie angus@akkea.ca Co-authored-by: Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm Signed-off-by: Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm
--- MAINTAINERS | 8 + arch/arm/dts/Makefile | 3 +- arch/arm/dts/imx8mq-librem5-u-boot.dtsi | 134 ++ arch/arm/dts/imx8mq-librem5.dts | 593 ++++++++ arch/arm/mach-imx/imx8m/Kconfig | 9 + board/purism/librem5/Kconfig | 15 + board/purism/librem5/MAINTAINERS | 7 + board/purism/librem5/Makefile | 13 + board/purism/librem5/imximage-8mq-lpddr4.cfg | 9 + board/purism/librem5/librem5.c | 710 ++++++++++ board/purism/librem5/librem5.h | 176 +++ board/purism/librem5/lpddr4_timing.c | 1324 ++++++++++++++++++ board/purism/librem5/lpddr4_timing_b0.c | 1191 ++++++++++++++++ board/purism/librem5/spl.c | 481 +++++++ configs/librem5_defconfig | 120 ++ doc/board/purism/librem5/librem5.rst | 60 + include/configs/librem5.h | 173 +++ 17 files changed, 5025 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/imx8mq-librem5-u-boot.dtsi create mode 100644 arch/arm/dts/imx8mq-librem5.dts create mode 100644 board/purism/librem5/Kconfig create mode 100644 board/purism/librem5/MAINTAINERS create mode 100644 board/purism/librem5/Makefile create mode 100644 board/purism/librem5/imximage-8mq-lpddr4.cfg create mode 100644 board/purism/librem5/librem5.c create mode 100644 board/purism/librem5/librem5.h create mode 100644 board/purism/librem5/lpddr4_timing.c create mode 100644 board/purism/librem5/lpddr4_timing_b0.c create mode 100644 board/purism/librem5/spl.c create mode 100644 configs/librem5_defconfig create mode 100644 doc/board/purism/librem5/librem5.rst create mode 100644 include/configs/librem5.h
diff --git a/MAINTAINERS b/MAINTAINERS index 90666ce376..6ac916dfaf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1057,6 +1057,14 @@ S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-mpc85xx.git F: arch/powerpc/cpu/mpc85xx/
+PURISM LIBREM5 PHONE +M: Angus Ainslie angus@akkea.ca +R: kernel@puri.sm +S: Supported +F: board/purism/librem5/ +F: configs/librem5_defconfig +F: include/configs/librem5.h + RISC-V M: Rick Chen rick@andestech.com M: Leo ycliang@andestech.com diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 7f622fedbd..eef3955785 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -908,7 +908,8 @@ dtb-$(CONFIG_ARCH_IMX8M) += \ imx8mq-phanbell.dtb \ imx8mp-evk.dtb \ imx8mp-phyboard-pollux-rdk.dtb \ - imx8mq-pico-pi.dtb + imx8mq-pico-pi.dtb \ + imx8mq-librem5.dtb
dtb-$(CONFIG_ARCH_IMXRT) += imxrt1050-evk.dtb \ imxrt1020-evk.dtb diff --git a/arch/arm/dts/imx8mq-librem5-u-boot.dtsi b/arch/arm/dts/imx8mq-librem5-u-boot.dtsi new file mode 100644 index 0000000000..e3f780ca75 --- /dev/null +++ b/arch/arm/dts/imx8mq-librem5-u-boot.dtsi @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +/ { + binman: binman { + multiple-images; + }; +}; + +&binman { + u-boot-spl-ddr { + filename = "u-boot-spl-ddr.bin"; + pad-byte = <0xff>; + align-size = <4>; + align = <4>; + + u-boot-spl { + align-end = <4>; + }; + + blob_1: blob-ext@1 { + filename = "lpddr4_pmu_train_1d_imem.bin"; + size = <0x8000>; + }; + + blob_2: blob-ext@2 { + filename = "lpddr4_pmu_train_1d_dmem.bin"; + size = <0x4000>; + }; + + blob_3: blob-ext@3 { + filename = "lpddr4_pmu_train_2d_imem.bin"; + size = <0x8000>; + }; + + blob_4: blob-ext@4 { + filename = "lpddr4_pmu_train_2d_dmem.bin"; + size = <0x4000>; + }; + }; + + spl { + filename = "spl.bin"; + + mkimage { + args = "-n spl/u-boot-spl.cfgout -T imx8mimage -e 0x7e1000"; + + blob { + filename = "u-boot-spl-ddr.bin"; + }; + }; + }; + + itb { + filename = "u-boot.itb"; + + fit { + description = "Configuration to load ATF before U-Boot"; + #address-cells = <1>; + fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>; + + images { + uboot { + description = "U-Boot (64-bit)"; + type = "standalone"; + arch = "arm64"; + compression = "none"; + load = <CONFIG_SYS_TEXT_BASE>; + + uboot_blob: blob-ext { + filename = "u-boot-nodtb.bin"; + }; + }; + + atf { + description = "ARM Trusted Firmware"; + type = "firmware"; + arch = "arm64"; + compression = "none"; + load = <0x910000>; + entry = <0x910000>; + + atf_blob: blob-ext { + filename = "bl31.bin"; + }; + }; + + fdt { + description = "NAME"; + type = "flat_dt"; + compression = "none"; + + uboot_fdt_blob: blob-ext { + filename = "u-boot.dtb"; + }; + }; + }; + + configurations { + default = "conf"; + + conf { + description = "NAME"; + firmware = "uboot"; + loadables = "atf"; + fdt = "fdt"; + }; + }; + }; + }; + + imx-boot { + filename = "flash.bin"; + pad-byte = <0x00>; + + spl: blob-ext@1 { + offset = <0x0>; + filename = "spl.bin"; + }; + + uboot: blob-ext@2 { + offset = <0x57c00>; + filename = "u-boot.itb"; + }; + }; +}; + +&usdhc1 { + mmc-hs400-1_8v; +}; + +&usdhc2 { + sd-uhs-sdr104; + sd-uhs-ddr50; +}; diff --git a/arch/arm/dts/imx8mq-librem5.dts b/arch/arm/dts/imx8mq-librem5.dts new file mode 100644 index 0000000000..93939df18f --- /dev/null +++ b/arch/arm/dts/imx8mq-librem5.dts @@ -0,0 +1,593 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + * Copyright (C) 2021 Purism SPC + * + */ + +/dts-v1/; + +#include "imx8mq.dtsi" + +/ { + model = "Librem 5"; + compatible = "purism,librem5", "fsl,imx8mq"; + + chosen { + bootargs = "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200"; + stdout-path = &uart1; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + reg_usdhc2_vmmc: usdhc2_vmmc { + u-boot,dm-spl; + compatible = "regulator-fixed"; + regulator-name = "VSD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + pinctrl-0 = <&pinctrl_led>; + + ledr { + label = "LED_R"; + gpios = <&gpio5 3 0>; + }; + ledg { + label = "LED_G"; + gpios = <&gpio5 2 0>; + }; + ledb { + label = "LED_B"; + gpios = <&gpio1 13 0>; + }; + }; +}; + +&iomuxc { + pinctrl_hog1: hoggrp1 { + fsl,pins = < + MX8MQ_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x83 /* CAMERA_PWR_EN_3V3 */ + MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x83 /* TF_PWR_3V3_EN */ + MX8MQ_IOMUXC_GPIO1_IO04_GPIO1_IO4 0x83 /* AUDIO_POWER_EN_3V3 */ + MX8MQ_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x83 /* DSI_EN_3V3 */ + MX8MQ_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x3f + MX8MQ_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x3f + MX8MQ_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x83 /* HUB_PWR_3V3_EN */ + MX8MQ_IOMUXC_ENET_MDC_GPIO1_IO16 0xC0 + MX8MQ_IOMUXC_ENET_MDIO_GPIO1_IO17 0xC0 + MX8MQ_IOMUXC_ENET_TD1_GPIO1_IO20 0x83 /* DSI_BIAS_EN */ + MX8MQ_IOMUXC_ENET_TXC_GPIO1_IO23 0x83 /* FLASH_EN */ + >; + }; + + pinctrl_hog3: hoggrp3 { + fsl,pins = < + MX8MQ_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x3 /* CHG_EN */ + MX8MQ_IOMUXC_NAND_CE3_B_GPIO3_IO4 0x3 /* CHG_OTG_OUT_EN */ + MX8MQ_IOMUXC_NAND_DATA04_GPIO3_IO10 0x83 /* WIFI3V3_EN */ + MX8MQ_IOMUXC_NAND_DATA06_GPIO3_IO12 0x83 /* GPS3V3_EN */ + MX8MQ_IOMUXC_NAND_DQS_GPIO3_IO14 0x83 /* BACKLINGE_EN */ + MX8MQ_IOMUXC_NAND_WP_B_GPIO3_IO18 0x83 /* 4G_PWR_EN */ + MX8MQ_IOMUXC_SAI5_RXD3_GPIO3_IO24 0x83 /* TPS_RESET */ + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x4000003f + MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x4000003f + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x4000001f + MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x4000001f + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL 0x4000001f + MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA 0x4000001f + >; + }; + + pinctrl_i2c4: i2c4grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C4_SCL_I2C4_SCL 0x4000003f + MX8MQ_IOMUXC_I2C4_SDA_I2C4_SDA 0x4000003f + >; + }; + + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + MX8MQ_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x82 + MX8MQ_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x19 + MX8MQ_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x82 + MX8MQ_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x80 + >; + }; + + pinctrl_led: ledgrp { + fsl,pins = < + MX8MQ_IOMUXC_SPDIF_TX_GPIO5_IO3 0x16 /* LED_R */ + MX8MQ_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x16 /* LED_G */ + MX8MQ_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x16 /* LED_B */ + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + MX8MQ_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x80 /* PMIC_NINT */ + >; + }; + + pinctrl_pwm1: pwm1grp { + fsl,pins = < + MX8MQ_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5 0x83 /* MOTO */ + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x79 + MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x79 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX 0x49 + MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX 0x49 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX8MQ_IOMUXC_UART3_TXD_UART3_DCE_TX 0x79 + MX8MQ_IOMUXC_UART3_RXD_UART3_DCE_RX 0x79 + MX8MQ_IOMUXC_NAND_CLE_GPIO3_IO5 0x19 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX8MQ_IOMUXC_ECSPI2_SCLK_UART4_DCE_RX 0x49 + MX8MQ_IOMUXC_ECSPI2_MOSI_UART4_DCE_TX 0x49 + MX8MQ_IOMUXC_ECSPI2_MISO_UART4_DCE_CTS_B 0x49 + MX8MQ_IOMUXC_ECSPI2_SS0_UART4_DCE_RTS_B 0x49 + >; + }; + + 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 0x8d + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xcd + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xcd + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xcd + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xcd + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xcd + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xcd + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xcd + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xcd + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xcd + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x8d + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x8f + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xcf + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xcf + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xcf + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xcf + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xcf + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xcf + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xcf + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xcf + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xcf + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x8f + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc2_gpio: usdhc2grpgpio { + fsl,pins = < + MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 /* WIFI_nRST */ + >; + }; + + 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 0x8d + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xcd + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xcd + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xcd + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xcd + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xcd + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x8f + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xcf + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xcf + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xcf + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xcf + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xcf + 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 + >; + }; +}; + +&gpio1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog1>; + + csi_en { + gpio-hog; + output-low; + gpios = <0 GPIO_ACTIVE_HIGH>; + line-name = "csi_en"; + }; + sdcard_pwr { + gpio-hog; + output-high; + gpios = <3 GPIO_ACTIVE_HIGH>; + }; + audio_pwr { + gpio-hog; + output-high; + gpios = <4 GPIO_ACTIVE_HIGH>; + }; + hub_nreset { + gpio-hog; + output-high; + gpios = <12 GPIO_ACTIVE_HIGH>; + line-name = "hub_nreset"; + }; + hub_pwr { + gpio-hog; + output-high; + gpios = <14 GPIO_ACTIVE_HIGH>; + line-name = "hub_pwr"; + }; +}; + +&gpio3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog3>; + status = "okay"; + + chg_en { + gpio-hog; + output-low; + gpios = <17 GPIO_ACTIVE_HIGH>; + }; + tps_reset { + gpio-hog; + output-low; + gpios = <24 GPIO_ACTIVE_HIGH>; + }; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + u-boot,dm-pre-reloc; + + pmic@4b { + compatible = "rohm,bd71837"; + reg = <0x4b>; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio1>; + interrupts = <7 GPIO_ACTIVE_LOW>; + rohm,reset-snvs-powered; + u-boot,dm-pre-reloc; + regulators { + buck1_reg: BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <900000>; + rohm,dvs-idle-voltage = <850000>; + rohm,dvs-suspend-voltage = <800000>; + regulator-always-on; + }; + + buck2_reg: BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <1000000>; + rohm,dvs-idle-voltage = <900000>; + regulator-always-on; + }; + + buck3_reg: BUCK3 { + regulator-name = "buck3"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + rohm,dvs-run-voltage = <900000>; + regulator-always-on; + }; + + buck4_reg: BUCK4 { + regulator-name = "buck4"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + rohm,dvs-run-voltage = <1000000>; + }; + + buck5_reg: BUCK5 { + regulator-name = "buck5"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1350000>; + regulator-boot-on; + regulator-always-on; + }; + + buck6_reg: BUCK6 { + regulator-name = "buck6"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + buck7_reg: BUCK7 { + regulator-name = "buck7"; + regulator-min-microvolt = <1605000>; + regulator-max-microvolt = <1995000>; + regulator-boot-on; + regulator-always-on; + }; + + buck8_reg: BUCK8 { + regulator-name = "buck8"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1_reg: LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + /* leave on for snvs power button */ + regulator-always-on; + }; + + ldo2_reg: LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + /* leave on for snvs power button */ + regulator-always-on; + }; + + ldo3_reg: LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo4_reg: LDO4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo5_reg: LDO5 { + /* VDD_PHY_0V9 - MIPI and HDMI domains */ + regulator-name = "ldo5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + ldo6_reg: LDO6 { + /* VDD_PHY_0V9 - MIPI, HDMI and USB domains */ + regulator-name = "ldo6"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo7_reg: LDO7 { + /* VDD_PHY_3V3 - USB domain */ + regulator-name = "ldo7"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; +}; + +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; +}; + +&i2c4 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4>; + status = "okay"; +}; + +&ecspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1>; + cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; + status = "okay"; + + flash0: winbond@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <29000000>; + }; +}; + +&uart1 { /* console */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + assigned-clocks = <&clk IMX8MQ_CLK_UART1_ROOT>; + assigned-clock-parents = <&clk IMX8MQ_CLK_25M>; + status = "okay"; +}; + +&uart3 { /* BT */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + assigned-clocks = <&clk IMX8MQ_CLK_UART3_ROOT>; + assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>; + fsl,uart-has-rtscts; + status = "disabled"; +}; + +&usdhc1 { + u-boot,dm-pre-reloc; + u-boot,dm-spl; + 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>; + broken-cd; + vmmc-supply = <®_usdhc2_vmmc>; + status = "okay"; +}; + +&usb3_phy0 { + u-boot,dm-pre-reloc; + u-boot,dm-spl; + status = "okay"; +}; + +&usb_dwc3_0 { + compatible = "snps,dwc3-gadget"; + u-boot,dm-pre-reloc; + u-boot,dm-spl; + status = "okay"; + dr_mode = "peripheral"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + maximum-speed = "high-speed"; +}; + +&usb3_phy1 { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&usb_dwc3_1 { + u-boot,dm-pre-reloc; + status = "okay"; + dr_mode = "host"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig index 276b8bd974..424ed5b2e3 100644 --- a/arch/arm/mach-imx/imx8m/Kconfig +++ b/arch/arm/mach-imx/imx8m/Kconfig @@ -154,6 +154,14 @@ config TARGET_IMX8MM_CL_IOT_GATE_OPTEE select IMX8MM select SUPPORT_SPL select IMX8M_LPDDR4 + +config TARGET_LIBREM5 + bool "Purism Librem5 Phone" + select BINMAN + select IMX8MQ + select SUPPORT_SPL + select IMX8M_LPDDR4 + endchoice
source "board/beacon/imx8mm/Kconfig" @@ -169,6 +177,7 @@ source "board/google/imx8mq_phanbell/Kconfig" source "board/kontron/sl-mx8mm/Kconfig" source "board/phytec/phycore_imx8mm/Kconfig" source "board/phytec/phycore_imx8mp/Kconfig" +source "board/purism/librem5/Kconfig" source "board/ronetix/imx8mq-cm/Kconfig" source "board/technexion/pico-imx8mq/Kconfig" source "board/toradex/verdin-imx8mm/Kconfig" diff --git a/board/purism/librem5/Kconfig b/board/purism/librem5/Kconfig new file mode 100644 index 0000000000..cf0f303683 --- /dev/null +++ b/board/purism/librem5/Kconfig @@ -0,0 +1,15 @@ +if TARGET_LIBREM5 + +config SYS_BOARD + default "librem5" + +config SYS_VENDOR + default "purism" + +config SYS_CONFIG_NAME + default "librem5" + +config IMX_CONFIG + default "board/purism/librem5/imximage-8mq-lpddr4.cfg" + +endif diff --git a/board/purism/librem5/MAINTAINERS b/board/purism/librem5/MAINTAINERS new file mode 100644 index 0000000000..818e185030 --- /dev/null +++ b/board/purism/librem5/MAINTAINERS @@ -0,0 +1,7 @@ +PURISM LIBREM5 PHONE +M: Angus Ainslie angus@akkea.ca +R: kernel@puri.sm +S: Supported +F: board/purism/librem5/ +F: configs/librem5_defconfig +F: include/configs/librem5.h diff --git a/board/purism/librem5/Makefile b/board/purism/librem5/Makefile new file mode 100644 index 0000000000..47f25f047b --- /dev/null +++ b/board/purism/librem5/Makefile @@ -0,0 +1,13 @@ +# +# Copyright 2017 NXP +# Copyright 2019 Purism +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += librem5.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4_timing.o lpddr4_timing_b0.o +endif diff --git a/board/purism/librem5/imximage-8mq-lpddr4.cfg b/board/purism/librem5/imximage-8mq-lpddr4.cfg new file mode 100644 index 0000000000..90573be5fd --- /dev/null +++ b/board/purism/librem5/imximage-8mq-lpddr4.cfg @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2021 NXP + */ + +#define __ASSEMBLY__ + +BOOT_FROM sd +LOADER u-boot-spl-ddr.bin 0x7E1000 diff --git a/board/purism/librem5/librem5.c b/board/purism/librem5/librem5.c new file mode 100644 index 0000000000..93c2ac0630 --- /dev/null +++ b/board/purism/librem5/librem5.c @@ -0,0 +1,710 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + * Copyright 2021 Purism + */ + +#include <common.h> +#include <malloc.h> +#include <errno.h> +#include <asm/io.h> +#include <miiphy.h> +#include <asm/mach-imx/iomux-v3.h> +#include <asm-generic/gpio.h> +#include <asm/arch/sys_proto.h> +#include <fsl_esdhc.h> +#include <mmc.h> +#include <asm/arch/imx8mq_pins.h> +#include <asm/arch/sys_proto.h> +#include <asm/mach-imx/gpio.h> +#include <asm/mach-imx/mxc_i2c.h> +#include <asm/arch/clock.h> +#include <asm/mach-imx/video.h> +#include <fuse.h> +#include <i2c.h> +#include <spl.h> +#include <usb.h> +#include <dwc3-uboot.h> +#include <linux/delay.h> +#include <linux/bitfield.h> +#include <usb/xhci.h> +#include "librem5.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define ENABLE_TPS_RESET + +#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE) + +static const iomux_v3_cfg_t wdog_pads[] = { + IMX8MQ_PAD_GPIO1_IO02__WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL), +}; + +int board_early_init_f(void) +{ + struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; + + log_debug("%s: starting\n", __func__); + + imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads)); + set_wdog_reset(wdog); + + return 0; +} + +#ifdef CONFIG_OF_BOARD_SETUP +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return 0; +} +#endif + +#ifdef CONFIG_BOARD_POSTCLK_INIT +int board_postclk_init(void) +{ + /* TODO */ + return 0; +} +#endif + +#ifndef CONFIG_DM_USB +int usb_gadget_handle_interrupts(void) +{ + dwc3_uboot_handle_interrupt(0); + return 0; +} + +#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_IMX8M) +static void dwc3_nxp_usb_phy_init(struct dwc3_device *dwc3) +{ + u32 RegData; + + RegData = readl(dwc3->base + USB_PHY_CTRL1); + RegData &= ~(USB_PHY_CTRL1_VDATSRCENB0 | USB_PHY_CTRL1_VDATDETENB0 | + USB_PHY_CTRL1_COMMONONN); + RegData |= USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET; + writel(RegData, dwc3->base + USB_PHY_CTRL1); + + RegData = readl(dwc3->base + USB_PHY_CTRL0); + RegData |= USB_PHY_CTRL0_REF_SSP_EN; + writel(RegData, dwc3->base + USB_PHY_CTRL0); + + RegData = readl(dwc3->base + USB_PHY_CTRL2); + RegData |= USB_PHY_CTRL2_TXENABLEN0; + writel(RegData, dwc3->base + USB_PHY_CTRL2); + + RegData = readl(dwc3->base + USB_PHY_CTRL1); + RegData &= ~(USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET); + writel(RegData, dwc3->base + USB_PHY_CTRL1); +} + +static struct dwc3_device dwc3_device0_data = { +#ifdef CONFIG_SPL_BUILD + .maximum_speed = USB_SPEED_HIGH, +#else + .maximum_speed = USB_SPEED_SUPER, +#endif + .base = USB1_BASE_ADDR, + .dr_mode = USB_DR_MODE_PERIPHERAL, + .index = 0, + .dis_u2_susphy_quirk = 1, +}; + +static struct dwc3_device dwc3_device1_data = { +#ifdef CONFIG_SPL_BUILD + .maximum_speed = USB_SPEED_HIGH, +#else + .maximum_speed = USB_SPEED_SUPER, +#endif + .base = USB2_BASE_ADDR, + .dr_mode = USB_DR_MODE_HOST, + .index = 1, + .dis_u2_susphy_quirk = 1, +}; + +int board_usb_init(int index, enum usb_init_type init) +{ + int ret = 0; + + log_debug("%s: starting %d %d %d\n", __func__, index, init); + + imx8m_usb_power(index, true); + + if (index == 0 && init == USB_INIT_DEVICE) { + dwc3_nxp_usb_phy_init(&dwc3_device0_data); + ret = dwc3_uboot_init(&dwc3_device0_data); + } + if (index == 1 && init == USB_INIT_HOST) { + dwc3_nxp_usb_phy_init(&dwc3_device1_data); + ret = dwc3_uboot_init(&dwc3_device1_data); + } + + log_debug("%s: ending %d\n", __func__, ret); + + return ret; +} + +int board_usb_cleanup(int index, enum usb_init_type init) +{ + int ret = 0; + + if (index == 0 && init == USB_INIT_DEVICE) + dwc3_uboot_exit(index); + + if (index == 1 && init == USB_INIT_HOST) + dwc3_uboot_exit(index); + + imx8m_usb_power(index, false); + + return ret; +} +#endif + +int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor) +{ + return 0; +} + +void xhci_hcd_stop(int index) +{ +} +#endif + +#ifdef CONFIG_LOAD_ENV_FROM_MMC_BOOT_PARTITION +uint board_mmc_get_env_part(struct mmc *mmc) +{ + log_debug("%s: starting\n", __func__); + uint part = (mmc->part_config >> 3) & PART_ACCESS_MASK; + + if (part == 7) + part = 0; + return part; +} +#endif + +#define SPI_FLASH_CS IMX_GPIO_NR(5, 9) + +int board_spi_cs_gpio(unsigned int bus, unsigned int cs) +{ + return (bus == 0 && cs == 0) ? (SPI_FLASH_CS) : -1; +} + +#define ECSPI_PAD_CTRL (PAD_CTL_DSE2 | PAD_CTL_HYS) + +static const iomux_v3_cfg_t ecspi_pads[] = { + IMX8MQ_PAD_ECSPI1_SCLK__ECSPI1_SCLK | MUX_PAD_CTRL(ECSPI_PAD_CTRL), + IMX8MQ_PAD_ECSPI1_SS0__GPIO5_IO9 | MUX_PAD_CTRL(ECSPI_PAD_CTRL), + IMX8MQ_PAD_ECSPI1_MOSI__ECSPI1_MOSI | MUX_PAD_CTRL(ECSPI_PAD_CTRL), + IMX8MQ_PAD_ECSPI1_MISO__ECSPI1_MISO | MUX_PAD_CTRL(ECSPI_PAD_CTRL), +}; + +/* used if we reset the TPS65982 */ +static const iomux_v3_cfg_t ecspi_pads_hiz[] = { + IMX8MQ_PAD_ECSPI1_SCLK__GPIO5_IO6, + IMX8MQ_PAD_ECSPI1_MOSI__GPIO5_IO7, + IMX8MQ_PAD_ECSPI1_MISO__GPIO5_IO8, + IMX8MQ_PAD_ECSPI1_SS0__GPIO5_IO9, +}; + +extern int set_clk_ecspi(int); + +int board_ecspi_init(void) +{ + log_debug("%s: starting\n", __func__); + + imx_iomux_v3_setup_multiple_pads(ecspi_pads, ARRAY_SIZE(ecspi_pads)); + + set_clk_ecspi(1); + + return 0; +} + +void ecspi_hiz(void) +{ + log_debug("%s: starting\n", __func__); + + imx_iomux_v3_setup_multiple_pads(ecspi_pads_hiz, ARRAY_SIZE(ecspi_pads_hiz)); + + gpio_direction_input(SPI1_SCLK); + gpio_direction_input(SPI1_MISO); + gpio_direction_input(SPI1_MOSI); + gpio_direction_input(SPI1_SS0); +} + +int bq_read_reg(int reg_index) +{ + struct udevice *udev, *bus; + u8 reg; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_I2C, 3, &bus); + if (ret) { + log_err("%s: No bus %d\n", __func__, 3); + return -ENODEV; + } + + ret = i2c_get_chip(bus, 0x6a, 1, &udev); + if (ret) { + log_err("%s: setting chip offset failed %d\n", __func__, ret); + return -EINVAL; + } + + dm_i2c_read(udev, reg_index, ®, 1); + + return reg; +} + +int bq_write_reg(int reg_index, u8 val) +{ + struct udevice *udev, *bus; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_I2C, 3, &bus); + if (ret) { + log_err("%s: No bus %d\n", __func__, 3); + return 1; + } + + ret = i2c_get_chip(bus, 0x6a, 1, &udev); + if (ret) { + log_err("%s: setting chip offset failed %d\n", __func__, ret); + return 1; + } + + dm_i2c_write(udev, reg_index, &val, 1); + + return 0; +} + +int read_vbat(void) +{ + u8 reg02, reg03, reg0e; + int timeout = 1000; // ms + + /* disable the charger and enable BAT_LOADEN to discharge the decoupling + * CAP + * https://e2e.ti.com/support/power-management/f/196/t/567401 + */ + reg03 = bq_read_reg(0x03); + bq_write_reg(0x03, (reg03 | 0x80) & ~0x10); + + mdelay(10); + + /* force a conversion */ + reg02 = bq_read_reg(0x02); + bq_write_reg(0x02, (reg02 | 0x80) & ~0x40); + + do { + mdelay(10); + timeout -= 10; + } while ((bq_read_reg(0x02) & 0x80) && (timeout > 0)); + + reg0e = bq_read_reg(0x0e); + + /* return the charger to it's original state */ + bq_write_reg(0x03, reg03); + bq_write_reg(0x02, reg02); + + return (reg0e & 0x7f) * 20 + 2304; +} + +int tps65982_wait_for_app(int timeout, int timeout_step) +{ + int ret; + char response[6]; +#ifdef CONFIG_DM_I2C + struct udevice *udev, *bus; +#endif + + log_debug("%s: starting\n", __func__); + + /* Set the i2c bus */ +#ifndef CONFIG_DM_I2C + log_debug("%s: using i2c device mode\n", __func__); + i2c_set_bus_num(0); +#else + ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus); + if (ret) { + log_err("%s: No bus %d\n", __func__, 0); + return 1; + } + + ret = i2c_get_chip(bus, 0x3f, 1, &udev); + if (ret) { + log_err("%s: setting chip offset failed %d\n", __func__, ret); + return 1; + } +#endif + + while (timeout > 0) { +#ifndef CONFIG_DM_I2C + ret = i2c_read(0x3f, 0x03, 1, (u8 *)response, 5); +#else + ret = dm_i2c_read(udev, 0x03, (u8 *)response, 5); +#endif + log_debug("tps65982 mode %s\n", response); + if (response[1] == 'A') + return 0; + mdelay(timeout_step); + timeout -= timeout_step; + log_debug("tps65982 waited %d ms %c\n", timeout_step, response[1]); + } + + return 1; +} + +#define TPS_POWER_STATUS_PWROPMODE(x) FIELD_GET(GENMASK(3, 2), x) + +#define TPS_PDO_CONTRACT_TYPE(x) FIELD_GET(GENMASK(31, 30), x) +#define TPS_PDO_CONTRACT_FIXED 0 +#define TPS_PDO_CONTRACT_BATTERY 1 +#define TPS_PDO_CONTRACT_VARIABLE 2 + +#define TPS_TYPEC_PWR_MODE_USB 0 +#define TPS_TYPEC_PWR_MODE_1_5A 1 +#define TPS_TYPEC_PWR_MODE_3_0A 2 +#define TPS_TYPEC_PWR_MODE_PD 3 + +#define TPS_PDO_FIXED_CONTRACT_MAX_CURRENT(x) (FIELD_GET(GENMASK(9, 0), x) * 10) +#define TPS_PDO_VAR_CONTRACT_MAX_CURRENT(x) (FIELD_GET(GENMASK(9, 0), x) * 10) +#define TPS_PDO_BAT_CONTRACT_MAX_VOLTAGE(x) (FIELD_GET(GENMASK(29, 20), x) * 50) +#define TPS_PDO_BAT_CONTRACT_MAX_POWER(x) (FIELD_GET(GENMASK(9, 0), x) * 250) + +int tps65982_get_max_current(void) +{ + int ret; + u8 buf[7]; + u8 pwr_status; + u32 contract; + int type, mode; + struct udevice *udev, *bus; + + log_debug("%s: starting\n", __func__); + + /* Set the i2c bus */ + ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus); + if (ret) { + log_debug("%s: No bus %d\n", __func__, 0); + return -1; + } + + ret = i2c_get_chip(bus, 0x3f, 1, &udev); + if (ret) { + log_debug("%s: setting chip offset failed %d\n", __func__, ret); + return -1; + } + + ret = dm_i2c_read(udev, 0x3f, buf, 3); + if (ret) { + log_debug("%s: reading pwr_status failed %d\n", __func__, ret); + return -1; + } + + pwr_status = buf[1]; + + if (!(pwr_status & 1)) + return 0; + + mode = TPS_POWER_STATUS_PWROPMODE(pwr_status); + switch (mode) { + case TPS_TYPEC_PWR_MODE_1_5A: + return 1500; + case TPS_TYPEC_PWR_MODE_3_0A: + return 3000; + case TPS_TYPEC_PWR_MODE_PD: + ret = dm_i2c_read(udev, 0x34, buf, 7); + if (ret) { + log_debug("%s: reading active contract failed %d\n", __func__, ret); + return -1; + } + + contract = buf[1] + (buf[2] << 8) + (buf[3] << 16) + (buf[4] << 24); + + type = TPS_PDO_CONTRACT_TYPE(contract); + + switch (type) { + case TPS_PDO_CONTRACT_FIXED: + return TPS_PDO_FIXED_CONTRACT_MAX_CURRENT(contract); + case TPS_PDO_CONTRACT_BATTERY: + return 1000 * TPS_PDO_BAT_CONTRACT_MAX_POWER(contract) + / TPS_PDO_BAT_CONTRACT_MAX_VOLTAGE(contract); + case TPS_PDO_CONTRACT_VARIABLE: + return TPS_PDO_VAR_CONTRACT_MAX_CURRENT(contract); + default: + log_debug("Unknown contract type: %d\n", type); + return -1; + } + case TPS_TYPEC_PWR_MODE_USB: + return 500; + default: + log_debug("Unknown power mode: %d\n", mode); + return -1; + } +} + +int init_tps65982(void) +{ + int vbat; + + log_debug("%s: starting\n", __func__); + + if (tps65982_wait_for_app(500, 100)) { + /* check that VBAT is present and greater than 3000 mV. resetting the + * tps65982 disconnects VBUS so we need a different power source. + * Battery voltage greater than 4.15V likely means the battery is not + * present. + */ + vbat = read_vbat(); +#ifdef ENABLE_TPS_RESET + if (vbat > 3000 && vbat < 4150) { + log_info("tps65982 attempting reset - %d mV\n", vbat); + ecspi_hiz(); + + gpio_direction_output(TPS_RESET, 0); + mdelay(3); + gpio_direction_output(TPS_RESET, 1); + mdelay(2); + gpio_direction_output(TPS_RESET, 0); + mdelay(100); + + if (tps65982_wait_for_app(1000, 250)) { + log_err("tps65982 failed to boot\n"); + board_ecspi_init(); + gpio_direction_output(LED_G, 0); + gpio_direction_output(LED_R, 1); + return 1; + } + + board_ecspi_init(); + } else { + log_err("vbat out of range to reset tps65982 %d mV\n", vbat); + return 1; + } +#else + log_err("tps65982 APP boot failed %d mV\n", vbat); + return 1; +#endif + } + + log_info("tps65982 boot successful\n"); + return 0; +} + +int bq25896_set_iinlim(int current) +{ + u8 val, iinlim; + int ret; + struct udevice *udev, *bus; + + /* Set the i2c bus */ + ret = uclass_get_device_by_seq(UCLASS_I2C, 3, &bus); + if (ret) { + log_err("%s: No bus 3\n", __func__); + return ret; + } + + ret = i2c_get_chip(bus, 0x6a, 1, &udev); + if (ret) { + log_err("%s: setting chip offset failed %d\n", __func__, ret); + return ret; + } + + if (current > 3250) + current = 3250; + if (current < 100) + current = 100; + + val = dm_i2c_reg_read(udev, 0x00); + iinlim = ((current - 100) / 50) & 0x3f; + val = (val & 0xc0) | iinlim; + dm_i2c_reg_write(udev, 0x00, val); + log_debug("REG00 0x%x\n", val); + + return 0; +} + +/* + * set some safe defaults for the battery charger + */ +int init_charger_bq25896(void) +{ + u8 val; + int iinlim, vbat, ret; + struct udevice *udev, *bus; + + /* Set the i2c bus */ + ret = uclass_get_device_by_seq(UCLASS_I2C, 3, &bus); + if (ret) { + log_debug("%s: No bus 3\n", __func__); + return ret; + } + + ret = i2c_get_chip(bus, 0x6a, 1, &udev); + if (ret) { + log_debug("%s: setting chip offset failed %d\n", __func__, ret); + return ret; + } + + /* enable automatic DC conversions */ + val = dm_i2c_reg_read(udev, 0x02); + log_debug("REG0B 0x%x\n", val); + val = (val & ~0xc0) | 0x40; + dm_i2c_reg_write(udev, 0x02, val); + + /* check VBUS good */ + val = dm_i2c_reg_read(udev, 0x11); + log_debug("VBUS good %d\n", (val >> 7) & 1); + log_debug("VBUS mV %d\n", (val & 0x7f) * 100 + 2600); + + val = dm_i2c_reg_read(udev, 0x0b); + log_debug("REG0B 0x%x\n", val); + + log_debug("VBUS_STAT 0x%x\n", val >> 5); + switch (val >> 5) { + case 0: + log_debug("VBUS not detected\n"); + break; + case 1: + log_debug("USB SDP IINLIM 500mA\n"); + break; + case 2: + log_debug("USB CDP IINLIM 1500mA\n"); + break; + case 3: + log_debug("USB DCP IINLIM 3500mA\n"); + break; + case 4: + log_debug("MAXCHARGE IINLIM 1500mA\n"); + break; + case 5: + log_debug("Unknown IINLIM 500mA\n"); + break; + case 6: + log_debug("DIVIDER IINLIM > 1000mA\n"); + break; + case 7: + log_debug("OTG\n"); + break; + }; + + log_debug("CHRG_STAT 0x%x\n", (val >> 3) & 0x3); + log_debug("PG_STAT 0x%x\n", (val >> 2) & 1); + log_debug("SDP_STAT 0x%x\n", (val >> 1) & 1); + log_debug("VSYS_STAT 0x%x\n", val & 1); + + val = dm_i2c_reg_read(udev, 0x00); + log_debug("REG00 0x%x\n", val); + iinlim = 100 + (val & 0x3f) * 50; + log_debug("IINLIM %d mA\n", iinlim); + log_debug("EN_HIZ 0x%x\n", (val >> 7) & 1); + log_debug("EN_ILIM 0x%x\n", (val >> 6) & 1); + + /* check VBAT */ + vbat = read_vbat(); + log_debug("VBAT mV %d\n", vbat); + + if (vbat < 2800 && iinlim <= 500) { + /* battery voltage too low and + * insufficient current to boot linux. + */ + gpio_direction_output(LED_R, 1); + log_err("%s: voltage and current too low linux probably won't boot\n", __func__); + } + + /* set 1.6A charge limit */ + dm_i2c_reg_write(udev, 0x04, 0x19); + + /* re-enable charger */ + val = dm_i2c_reg_read(udev, 0x03); + val = val | 0x10; + dm_i2c_reg_write(udev, 0x03, val); + + /* limit the VINDPM to 3.9V */ + dm_i2c_reg_write(udev, 0x0d, 0x8d); + + /* set the max voltage to 4.192V */ + val = dm_i2c_reg_read(udev, 0x6); + val = (val & ~0xFC) | 0x16 << 2; + dm_i2c_reg_write(udev, 0x6, val); + + /* set the SYS_MIN to 3.7V */ + val = dm_i2c_reg_read(udev, 0x3); + val = val | 0xE; + dm_i2c_reg_write(udev, 0x3, val); + + return 0; +} + +void init_usb_clk(void); + +int board_init(void) +{ + int tps_ret; + + log_debug("%s: starting %d mV\n", __func__, read_vbat()); + + init_pinmux(); + +#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_IMX8M) + log_debug("%s: initializing USB clk\n", __func__); + init_usb_clk(); +#endif + + tps_ret = init_tps65982(); + init_charger_bq25896(); + + if (!tps_ret) { + int current = tps65982_get_max_current(); + + if (current > 500) + bq25896_set_iinlim(current); + } + + return 0; +} + +#define VOL_DOWN IMX_GPIO_NR(1, 17) + +int fastboot_key_pressed(void) +{ + int val; + + gpio_direction_input(VOL_DOWN); + + val = gpio_get_value(VOL_DOWN); + log_debug("%s : %d\n", __func__, val); + + return !val; +} + +int board_late_init(void) +{ +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + u32 vid, rev; + char rev_str[3]; + + env_set("board_name", "librem5"); + if (fuse_read(8, 2, &vid) || fuse_read(14, 0, &rev)) { + env_set("board_rev", BOARD_REV_ERROR); + } else if (vid == 0) { + env_set("board_rev", BOARD_REV_UNKNOWN); + } else if (vid == (PURISM_PID << 16 | PURISM_VID)) { + sprintf(rev_str, "%u", rev); + env_set("board_rev", rev_str); + } + + printf("Board name: %s\n", env_get("board_name")); + printf("Board rev: %s\n", env_get("board_rev")); +#endif + + if (is_usb_boot()) { + puts("USB Boot\n"); + env_set("bootcmd", "fastboot 0"); + } else if (fastboot_key_pressed()) { + log_debug("stop in u-boot\n"); + env_set("bootcmd", ""); + } + + return 0; +} + diff --git a/board/purism/librem5/librem5.h b/board/purism/librem5/librem5.h new file mode 100644 index 0000000000..54e8f5adf2 --- /dev/null +++ b/board/purism/librem5/librem5.h @@ -0,0 +1,176 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2021 Purism + */ + +#ifndef __LIBREM5_H__ +#define __LIBREM5_H__ + +#define CAMERA_EN IMX_GPIO_NR(1, 0) +#define SD_EN IMX_GPIO_NR(1, 3) +#define AUDIO_EN IMX_GPIO_NR(1, 4) +#define DSI_EN IMX_GPIO_NR(1, 5) +#define SMC_EN IMX_GPIO_NR(1, 6) +#define TYPEC_MUX_EN IMX_GPIO_NR(1, 11) +#define HUB_NRESET IMX_GPIO_NR(1, 12) +#define HUB_EN IMX_GPIO_NR(1, 14) +#define VOL_UP IMX_GPIO_NR(1, 16) +#define VOL_DOWN IMX_GPIO_NR(1, 17) +#define DSI_BIAS_EN IMX_GPIO_NR(1, 20) +#define FLASH_EN IMX_GPIO_NR(1, 23) +#define WWAN_NRESET IMX_GPIO_NR(3, 1) +#define CHG_EN IMX_GPIO_NR(3, 2) +#define CHG_OTG_OUT_EN IMX_GPIO_NR(3, 4) +#define WIFI_EN IMX_GPIO_NR(3, 10) +#define GPS_EN IMX_GPIO_NR(3, 12) +#define BL_EN IMX_GPIO_NR(3, 14) +#define WWAN_EN IMX_GPIO_NR(3, 18) +#define NFC_EN IMX_GPIO_NR(4, 28) +#define LED_G IMX_GPIO_NR(5, 2) +#define LED_R IMX_GPIO_NR(5, 3) +#define LED_B IMX_GPIO_NR(1, 13) +#define MOTO IMX_GPIO_NR(5, 5) +#define SPI1_SCLK IMX_GPIO_NR(5, 6) +#define SPI1_MOSI IMX_GPIO_NR(5, 7) +#define SPI1_MISO IMX_GPIO_NR(5, 8) +#define SPI1_SS0 IMX_GPIO_NR(5, 9) + +#define UART1_TX IMX_GPIO_NR(5, 23) +#define UART1_RX IMX_GPIO_NR(5, 22) +#define UART2_TX IMX_GPIO_NR(5, 25) +#define UART2_RX IMX_GPIO_NR(5, 24) +#define UART3_TX IMX_GPIO_NR(5, 27) +#define UART3_RX IMX_GPIO_NR(5, 26) +#define UART4_TX IMX_GPIO_NR(5, 11) +#define UART4_RX IMX_GPIO_NR(5, 10) + +#define TPS_RESET IMX_GPIO_NR(3, 24) + +#define PURISM_VID 0x316d +#define PURISM_PID 0x4c05 + +#define BOARD_REV_ERROR "unknown" +#define BOARD_REV_BIRCH "1" +#define BOARD_REV_CHESTNUT "2" +#define BOARD_REV_DOGWOOD "3" +/* Could be ASPEN, BIRCH or CHESTNUT. assume CHESTNUT */ +#define BOARD_REV_UNKNOWN BOARD_REV_CHESTNUT + +#ifdef CONFIG_DM_GPIO +static inline void init_pinmux(void) +{ + gpio_request(WIFI_EN, "WIFI_EN"); +#ifdef CONSOLE_ON_UART4 + gpio_direction_output(WIFI_EN, 1); +#else + gpio_direction_output(WIFI_EN, 0); +#endif /* CONSOLE_ON_UART4 */ +} +#else +static const iomux_v3_cfg_t configure_pads[] = { + IMX8MQ_PAD_GPIO1_IO00__GPIO1_IO0 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_GPIO1_IO03__GPIO1_IO3 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_GPIO1_IO04__GPIO1_IO4 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_GPIO1_IO05__GPIO1_IO5 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_GPIO1_IO06__GPIO1_IO6 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_GPIO1_IO11__GPIO1_IO11 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_GPIO1_IO12__GPIO1_IO12 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_GPIO1_IO14__GPIO1_IO14 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_ENET_MDC__GPIO1_IO16 | MUX_PAD_CTRL(PAD_CTL_PUE), + IMX8MQ_PAD_ENET_MDIO__GPIO1_IO17 | MUX_PAD_CTRL(PAD_CTL_PUE), + IMX8MQ_PAD_ENET_TD1__GPIO1_IO20 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_ENET_TXC__GPIO1_IO23 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_NAND_CE0_B__GPIO3_IO1 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_NAND_CE1_B__GPIO3_IO2 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_NAND_CE3_B__GPIO3_IO4 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_NAND_DATA04__GPIO3_IO10 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_NAND_DATA06__GPIO3_IO12 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_NAND_DQS__GPIO3_IO14 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_NAND_WP_B__GPIO3_IO18 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_SAI3_RXFS__GPIO4_IO28 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_SAI3_MCLK__GPIO5_IO2 | MUX_PAD_CTRL(PAD_CTL_DSE6), + IMX8MQ_PAD_SAI5_RXD3__GPIO3_IO24, +}; + +static inline void init_pinmux(void) +{ + imx_iomux_v3_setup_multiple_pads(configure_pads, ARRAY_SIZE(configure_pads)); + + gpio_request(LED_R, "LED_R"); + gpio_request(LED_G, "LED_G"); + gpio_request(LED_B, "LED_B"); + gpio_request(VOL_UP, "VOL_UP"); + gpio_request(VOL_DOWN, "VOL_DOWN"); + + gpio_request(NFC_EN, "NFC_EN"); + gpio_request(CHG_EN, "CHG_EN"); + gpio_request(CHG_OTG_OUT_EN, "CHG_OTG_OUT_EN"); + + gpio_request(TYPEC_MUX_EN, "TYPEC_MUX_EN"); + + gpio_request(TPS_RESET, "TPS_RESET"); + + gpio_request(WWAN_EN, "WWAN_EN"); + gpio_request(WWAN_NRESET, "WWAN_NRESET"); + + gpio_request(HUB_EN, "HUB_EN"); + gpio_request(HUB_NRESET, "HUB_NRESET"); + gpio_request(SD_EN, "SD_EN"); + gpio_request(AUDIO_EN, "AUDIO_EN"); + gpio_request(DSI_EN, "DSI_EN"); + gpio_request(SMC_EN, "SMC_EN"); + gpio_request(CAMERA_EN, "CAMERA_EN"); + gpio_request(FLASH_EN, "FLASH_EN"); + gpio_request(DSI_BIAS_EN, "DSI_BIAS_EN"); + gpio_request(GPS_EN, "GPS_EN"); + gpio_request(BL_EN, "BL_EN"); +#ifndef CONSOLE_ON_UART4 + gpio_request(WIFI_EN, "WIFI_EN"); + gpio_direction_output(WIFI_EN, 0); +#endif /* CONSOLE_ON_UART4 */ + gpio_direction_input(VOL_UP); + gpio_direction_input(VOL_DOWN); + + /* ensure charger is in the automated mode */ + gpio_direction_output(NFC_EN, 0); + gpio_direction_output(CHG_EN, 0); + gpio_direction_output(CHG_OTG_OUT_EN, 0); + + gpio_direction_input(TYPEC_MUX_EN); + + gpio_direction_output(TPS_RESET, 0); + + gpio_direction_output(WWAN_EN, 0); + gpio_direction_output(WWAN_NRESET, 1); + + gpio_direction_output(HUB_EN, 0); + gpio_direction_output(HUB_NRESET, 1); + gpio_direction_output(SD_EN, 0); + gpio_direction_output(AUDIO_EN, 1); + gpio_direction_output(DSI_EN, 0); + gpio_direction_output(SMC_EN, 0); + gpio_direction_output(CAMERA_EN, 0); + gpio_direction_output(FLASH_EN, 0); + gpio_direction_output(DSI_BIAS_EN, 0); + gpio_direction_output(GPS_EN, 0); + gpio_direction_output(BL_EN, 0); +} +#endif /* CONFIG_DM_GPIO */ + +#define USB_PHY_CTRL0 0xF0040 +#define USB_PHY_CTRL0_REF_SSP_EN BIT(2) + +#define USB_PHY_CTRL1 0xF0044 +#define USB_PHY_CTRL1_RESET BIT(0) +#define USB_PHY_CTRL1_COMMONONN BIT(1) +#define USB_PHY_CTRL1_ATERESET BIT(3) +#define USB_PHY_CTRL1_VDATSRCENB0 BIT(19) +#define USB_PHY_CTRL1_VDATDETENB0 BIT(20) + +#define USB_PHY_CTRL2 0xF0048 +#define USB_PHY_CTRL2_TXENABLEN0 BIT(8) + +extern struct dram_timing_info dram_timing_b0; +extern int board_ecspi_init(void); + +#endif diff --git a/board/purism/librem5/lpddr4_timing.c b/board/purism/librem5/lpddr4_timing.c new file mode 100644 index 0000000000..46bc7f8591 --- /dev/null +++ b/board/purism/librem5/lpddr4_timing.c @@ -0,0 +1,1324 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include <linux/kernel.h> +#include <common.h> +#include <asm/arch/ddr.h> +#include <asm/arch/lpddr4_define.h> + +#define WR_POST_EXT_3200 /* recommened to define */ + +struct dram_cfg_param lpddr4_ddrc_cfg[] = { + /* Start to config, default 3200mbps */ + { DDRC_DBG1(0), 0x00000001 }, + { DDRC_PWRCTL(0), 0x00000001 }, + { DDRC_MSTR(0), 0xa3080020 }, + { DDRC_MSTR2(0), 0x00000000 }, + { DDRC_RFSHTMG(0), 0x006100E0 }, + { DDRC_INIT0(0), 0xC003061B }, + { DDRC_INIT1(0), 0x009D0000 }, + { DDRC_INIT3(0), 0x00D4002D }, +#ifdef WR_POST_EXT_3200 + { DDRC_INIT4(0), 0x00330008 }, +#else + { DDRC_INIT4(0), 0x00310008 }, +#endif + { DDRC_INIT6(0), 0x0066004a }, + { DDRC_INIT7(0), 0x0006004a }, + + { DDRC_DRAMTMG0(0), 0x1A201B22 }, + { DDRC_DRAMTMG1(0), 0x00060633 }, + { DDRC_DRAMTMG3(0), 0x00C0C000 }, + { DDRC_DRAMTMG4(0), 0x0F04080F }, + { DDRC_DRAMTMG5(0), 0x02040C0C }, + { DDRC_DRAMTMG6(0), 0x01010007 }, + { DDRC_DRAMTMG7(0), 0x00000401 }, + { DDRC_DRAMTMG12(0), 0x00020600 }, + { DDRC_DRAMTMG13(0), 0x0C100002 }, + { DDRC_DRAMTMG14(0), 0x000000E6 }, + { DDRC_DRAMTMG17(0), 0x00A00050 }, + + { DDRC_ZQCTL0(0), 0x03200018 }, + { DDRC_ZQCTL1(0), 0x028061A8 }, + { DDRC_ZQCTL2(0), 0x00000000 }, + + { DDRC_DFITMG0(0), 0x0497820A }, + { DDRC_DFITMG1(0), 0x00080303 }, + { DDRC_DFIUPD0(0), 0xE0400018 }, + { DDRC_DFIUPD1(0), 0x00DF00E4 }, + { DDRC_DFIUPD2(0), 0x80000000 }, + { DDRC_DFIMISC(0), 0x00000011 }, + { DDRC_DFITMG2(0), 0x0000170A }, + + { DDRC_DBICTL(0), 0x00000001 }, + { DDRC_DFIPHYMSTR(0), 0x00000001 }, + { DDRC_RANKCTL(0), 0x00000c99 }, + { DDRC_DRAMTMG2(0), 0x070E171a }, + + /* address mapping */ + { DDRC_ADDRMAP0(0), 0x00000015 }, + { DDRC_ADDRMAP3(0), 0x00000000 }, + { DDRC_ADDRMAP4(0), 0x00001F1F }, + /* bank interleave */ + { DDRC_ADDRMAP1(0), 0x00080808 }, + { DDRC_ADDRMAP5(0), 0x07070707 }, + { DDRC_ADDRMAP6(0), 0x08080707 }, + + /* performance setting */ + { DDRC_ODTCFG(0), 0x0b060908 }, + { DDRC_ODTMAP(0), 0x00000000 }, + { DDRC_SCHED(0), 0x29511505 }, + { DDRC_SCHED1(0), 0x0000002c }, + { DDRC_PERFHPR1(0), 0x5900575b }, + /* 150T starve and 0x90 max tran len */ + { DDRC_PERFLPR1(0), 0x90000096 }, + /* 300T starve and 0x10 max tran len */ + { DDRC_PERFWR1(0), 0x1000012c }, + { DDRC_DBG0(0), 0x00000016 }, + { DDRC_DBG1(0), 0x00000000 }, + { DDRC_DBGCMD(0), 0x00000000 }, + { DDRC_SWCTL(0), 0x00000001 }, + { DDRC_POISONCFG(0), 0x00000011 }, + { DDRC_PCCFG(0), 0x00000111 }, + { DDRC_PCFGR_0(0), 0x000010f3 }, + { DDRC_PCFGW_0(0), 0x000072ff }, + { DDRC_PCTRL_0(0), 0x00000001 }, + /* disable Read Qos*/ + { DDRC_PCFGQOS0_0(0), 0x00000e00 }, + { DDRC_PCFGQOS1_0(0), 0x0062ffff }, + /* disable Write Qos*/ + { DDRC_PCFGWQOS0_0(0), 0x00000e00 }, + { DDRC_PCFGWQOS1_0(0), 0x0000ffff }, + + /* Frequency 1: 400mbps */ + { DDRC_FREQ1_DRAMTMG0(0), 0x0d0b010c }, + { DDRC_FREQ1_DRAMTMG1(0), 0x00030410 }, + { DDRC_FREQ1_DRAMTMG2(0), 0x0305090c }, + { DDRC_FREQ1_DRAMTMG3(0), 0x00505006 }, + { DDRC_FREQ1_DRAMTMG4(0), 0x05040305 }, + { DDRC_FREQ1_DRAMTMG5(0), 0x0d0e0504 }, + { DDRC_FREQ1_DRAMTMG6(0), 0x0a060004 }, + { DDRC_FREQ1_DRAMTMG7(0), 0x0000090e }, + { DDRC_FREQ1_DRAMTMG14(0), 0x00000032 }, + { DDRC_FREQ1_DRAMTMG15(0), 0x00000000 }, + { DDRC_FREQ1_DRAMTMG17(0), 0x0036001b }, + { DDRC_FREQ1_DERATEINT(0), 0x7e9fbeb1 }, + { DDRC_FREQ1_DFITMG0(0), 0x03818200 }, + { DDRC_FREQ1_DFITMG2(0), 0x00000000 }, + { DDRC_FREQ1_RFSHTMG(0), 0x000C001c }, + { DDRC_FREQ1_INIT3(0), 0x00840000 }, + { DDRC_FREQ1_INIT4(0), 0x00310008 }, + { DDRC_FREQ1_INIT6(0), 0x0066004a }, + { DDRC_FREQ1_INIT7(0), 0x0006004a }, + + /* Frequency 2: 100mbps */ + { DDRC_FREQ2_DRAMTMG0(0), 0x0d0b010c }, + { DDRC_FREQ2_DRAMTMG1(0), 0x00030410 }, + { DDRC_FREQ2_DRAMTMG2(0), 0x0305090c }, + { DDRC_FREQ2_DRAMTMG3(0), 0x00505006 }, + { DDRC_FREQ2_DRAMTMG4(0), 0x05040305 }, + { DDRC_FREQ2_DRAMTMG5(0), 0x0d0e0504 }, + { DDRC_FREQ2_DRAMTMG6(0), 0x0a060004 }, + { DDRC_FREQ2_DRAMTMG7(0), 0x0000090e }, + { DDRC_FREQ2_DRAMTMG14(0), 0x00000032 }, + { DDRC_FREQ2_DRAMTMG17(0), 0x0036001b }, + { DDRC_FREQ2_DERATEINT(0), 0x7e9fbeb1 }, + { DDRC_FREQ2_DFITMG0(0), 0x03818200 }, + { DDRC_FREQ2_DFITMG2(0), 0x00000000 }, + { DDRC_FREQ2_RFSHTMG(0), 0x00030007 }, + { DDRC_FREQ2_INIT3(0), 0x00840000 }, + { DDRC_FREQ2_INIT4(0), 0x00310008 }, + { DDRC_FREQ2_INIT6(0), 0x0066004a }, + { DDRC_FREQ2_INIT7(0), 0x0006004a }, +}; + +/* PHY Initialize Configuration */ +struct dram_cfg_param lpddr4_ddrphy_cfg[] = { + { 0x20110, 0x02 }, + { 0x20111, 0x03 }, + { 0x20112, 0x04 }, + { 0x20113, 0x05 }, + { 0x20114, 0x00 }, + { 0x20115, 0x01 }, + + { 0x1005f, 0x1ff }, + { 0x1015f, 0x1ff }, + { 0x1105f, 0x1ff }, + { 0x1115f, 0x1ff }, + { 0x1205f, 0x1ff }, + { 0x1215f, 0x1ff }, + { 0x1305f, 0x1ff }, + { 0x1315f, 0x1ff }, + + { 0x11005f, 0x1ff }, + { 0x11015f, 0x1ff }, + { 0x11105f, 0x1ff }, + { 0x11115f, 0x1ff }, + { 0x11205f, 0x1ff }, + { 0x11215f, 0x1ff }, + { 0x11305f, 0x1ff }, + { 0x11315f, 0x1ff }, + + { 0x21005f, 0x1ff }, + { 0x21015f, 0x1ff }, + { 0x21105f, 0x1ff }, + { 0x21115f, 0x1ff }, + { 0x21205f, 0x1ff }, + { 0x21215f, 0x1ff }, + { 0x21305f, 0x1ff }, + { 0x21315f, 0x1ff }, + + { 0x55, 0x1ff }, + { 0x1055, 0x1ff }, + { 0x2055, 0x1ff }, + { 0x3055, 0x1ff }, + { 0x4055, 0x1ff }, + { 0x5055, 0x1ff }, + { 0x6055, 0x1ff }, + { 0x7055, 0x1ff }, + { 0x8055, 0x1ff }, + { 0x9055, 0x1ff }, + + { 0x200c5, 0x19 }, + { 0x1200c5, 0x7 }, + { 0x2200c5, 0x7 }, + + { 0x2002e, 0x2 }, + { 0x12002e, 0x2 }, + { 0x22002e, 0x2 }, + + { 0x90204, 0x0 }, + { 0x190204, 0x0 }, + { 0x290204, 0x0 }, + +#ifdef WR_POST_EXT_3200 + { 0x20024, 0xeb }, +#else + { 0x20024, 0xab }, +#endif + { 0x2003a, 0x0 }, + { 0x120024, 0xab }, + { 0x2003a, 0x0 }, + { 0x220024, 0xab }, + { 0x2003a, 0x0 }, + { 0x20056, 0x3 }, + { 0x120056, 0xa }, + { 0x220056, 0xa }, + { 0x1004d, 0xe00 }, + { 0x1014d, 0xe00 }, + { 0x1104d, 0xe00 }, + { 0x1114d, 0xe00 }, + { 0x1204d, 0xe00 }, + { 0x1214d, 0xe00 }, + { 0x1304d, 0xe00 }, + { 0x1314d, 0xe00 }, + { 0x11004d, 0xe00 }, + { 0x11014d, 0xe00 }, + { 0x11104d, 0xe00 }, + { 0x11114d, 0xe00 }, + { 0x11204d, 0xe00 }, + { 0x11214d, 0xe00 }, + { 0x11304d, 0xe00 }, + { 0x11314d, 0xe00 }, + { 0x21004d, 0xe00 }, + { 0x21014d, 0xe00 }, + { 0x21104d, 0xe00 }, + { 0x21114d, 0xe00 }, + { 0x21204d, 0xe00 }, + { 0x21214d, 0xe00 }, + { 0x21304d, 0xe00 }, + { 0x21314d, 0xe00 }, + + { 0x10049, 0xfbe }, + { 0x10149, 0xfbe }, + { 0x11049, 0xfbe }, + { 0x11149, 0xfbe }, + { 0x12049, 0xfbe }, + { 0x12149, 0xfbe }, + { 0x13049, 0xfbe }, + { 0x13149, 0xfbe }, + { 0x110049, 0xfbe }, + { 0x110149, 0xfbe }, + { 0x111049, 0xfbe }, + { 0x111149, 0xfbe }, + { 0x112049, 0xfbe }, + { 0x112149, 0xfbe }, + { 0x113049, 0xfbe }, + { 0x113149, 0xfbe }, + { 0x210049, 0xfbe }, + { 0x210149, 0xfbe }, + { 0x211049, 0xfbe }, + { 0x211149, 0xfbe }, + { 0x212049, 0xfbe }, + { 0x212149, 0xfbe }, + { 0x213049, 0xfbe }, + { 0x213149, 0xfbe }, + + { 0x43, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x1043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x2043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x3043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x4043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x5043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x6043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x7043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x8043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x9043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + + { 0x20018, 0x3 }, + { 0x20075, 0x4 }, + { 0x20050, 0x0 }, + { 0x20008, 0x320 }, + { 0x120008, 0x64 }, + { 0x220008, 0x19 }, + { 0x20088, 0x9 }, + { 0x200b2, 0x104 }, + { 0x10043, 0x5a1 }, + { 0x10143, 0x5a1 }, + { 0x11043, 0x5a1 }, + { 0x11143, 0x5a1 }, + { 0x12043, 0x5a1 }, + { 0x12143, 0x5a1 }, + { 0x13043, 0x5a1 }, + { 0x13143, 0x5a1 }, + { 0x1200b2, 0x104 }, + { 0x110043, 0x5a1 }, + { 0x110143, 0x5a1 }, + { 0x111043, 0x5a1 }, + { 0x111143, 0x5a1 }, + { 0x112043, 0x5a1 }, + { 0x112143, 0x5a1 }, + { 0x113043, 0x5a1 }, + { 0x113143, 0x5a1 }, + { 0x2200b2, 0x104 }, + { 0x210043, 0x5a1 }, + { 0x210143, 0x5a1 }, + { 0x211043, 0x5a1 }, + { 0x211143, 0x5a1 }, + { 0x212043, 0x5a1 }, + { 0x212143, 0x5a1 }, + { 0x213043, 0x5a1 }, + { 0x213143, 0x5a1 }, + { 0x200fa, 0x1 }, + { 0x1200fa, 0x1 }, + { 0x2200fa, 0x1 }, + { 0x20019, 0x1 }, + { 0x120019, 0x1 }, + { 0x220019, 0x1 }, + { 0x200f0, 0x660 }, + { 0x200f1, 0x0 }, + { 0x200f2, 0x4444 }, + { 0x200f3, 0x8888 }, + { 0x200f4, 0x5665 }, + { 0x200f5, 0x0 }, + { 0x200f6, 0x0 }, + { 0x200f7, 0xf000 }, + { 0x20025, 0x0 }, + { 0x2002d, 0x0 }, + { 0x12002d, 0x0 }, + { 0x22002d, 0x0 }, + + { 0x200c7, 0x80 }, + { 0x1200c7, 0x80 }, + { 0x2200c7, 0x80 }, + { 0x200ca, 0x106 }, + { 0x1200ca, 0x106 }, + { 0x2200ca, 0x106 }, +}; + +/* P0 message block paremeter for training firmware */ +struct dram_cfg_param lpddr4_fsp0_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x0 }, + { 0x54003, 0xc80 }, + { 0x54004, 0x2 }, + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT) }, /* PHY Ron/Rtt */ + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, 0x131f }, + { 0x54009, LPDDR4_HDT_CTL_3200_1D }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, (LPDDR4_CATRAIN_3200_1d << 8) }, + { 0x5400e, 0x0 }, + { 0x5400f, 0x0 }, + { 0x54010, 0x0 }, + { 0x54011, 0x0 }, + { 0x54012, 0x310 }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + + { 0x54019, 0x2dd4 }, +#ifdef WR_POST_EXT_3200 + { 0x5401a, (((LPDDR4_RON) << 3) | 0x3) }, +#else + { 0x5401a, (((LPDDR4_RON) << 3) | 0x1) }, +#endif + { 0x5401b, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT_CA_BANK0 << 4) | LPDDR4_RTT_DQ) }, + { 0x5401c, ((LPDDR4_VREF_VALUE_DQ_RANK0 << 8) | 0x08) }, + { 0x5401d, 0x0 }, + { 0x5401e, LPDDR4_MR22_RANK0 }, + { 0x5401f, 0x2dd4 }, +#ifdef WR_POST_EXT_3200 + { 0x54020, (((LPDDR4_RON) << 3) | 0x3) }, +#else + { 0x54020, (((LPDDR4_RON) << 3) | 0x1) }, +#endif + { 0x54021, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT_CA_BANK1 << 4) | LPDDR4_RTT_DQ) }, + { 0x54022, ((LPDDR4_VREF_VALUE_DQ_RANK1 << 8) | 0x08) }, + { 0x54023, 0x0 }, + { 0x54024, LPDDR4_MR22_RANK1 }, + + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x3 }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + { 0x54032, 0xd400 }, + /* MR3/MR2 */ +#ifdef WR_POST_EXT_3200 + { 0x54033, ((((LPDDR4_RON) << 3) | 0x3) << 8) | 0x2d /*0x312d*/ }, +#else + { 0x54033, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x2d/*0x312d*/ }, +#endif + /* MR11/MR4 */ + { 0x54034, (((LPDDR4_RTT_CA_BANK0 << 4) | LPDDR4_RTT_DQ) << 8) }, + /* self:0x284d//MR13/MR12 */ + { 0x54035, (0x0800 | LPDDR4_VREF_VALUE_CA)/*0x084d*/ }, + /* MR16/MR14*/ + { 0x54036, LPDDR4_VREF_VALUE_DQ_RANK0/*0x4d*/ }, + { 0x54037, (LPDDR4_MR22_RANK0 << 8)/*0x500*/ }, + /* MR1 */ + { 0x54038, 0xd400 }, + /* MR3/MR2 */ +#ifdef WR_POST_EXT_3200 + { 0x54039, ((((LPDDR4_RON) << 3) | 0x3) << 8) | 0x2d/*0x312d*/ }, +#else + { 0x54039, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x2d/*0x312d*/ }, +#endif + /* MR11/MR4 */ + { 0x5403a, (((LPDDR4_RTT_CA_BANK1 << 4) | LPDDR4_RTT_DQ) << 8) }, + /* self:0x284d//MR13/MR12 */ + { 0x5403b, (0x0800 | LPDDR4_VREF_VALUE_CA)/*0x084d*/ }, + /* MR16/MR14 */ + { 0x5403c, LPDDR4_VREF_VALUE_DQ_RANK1/*0x4d*/ }, + { 0x5403d, (LPDDR4_MR22_RANK1 << 8)/*0x500*/ }, + /* { 0x5403d, 0x500 } */ + { 0x5403d, (LPDDR4_MR22_RANK1 << 8)/*0x500*/ }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, +}; + +/* P1 message block paremeter for training firmware */ +struct dram_cfg_param lpddr4_fsp1_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x101 }, + { 0x54003, 0x190 }, + { 0x54004, 0x2 }, + /* PHY Ron/Rtt */ + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT)/*0x2828*/ }, + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, LPDDR4_TRAIN_SEQ_400 }, + { 0x54009, LPDDR4_HDT_CTL_400_1D }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, (LPDDR4_CATRAIN_400 << 8) }, + { 0x5400e, 0x0 }, + { 0x5400f, 0x0 }, + { 0x54010, 0x0 }, + { 0x54011, 0x0 }, + { 0x54012, 0x310 }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + { 0x54019, 0x84 }, + /* MR4/MR3 */ + { 0x5401a, (((LPDDR4_RON) << 3) | 0x1)/*0x31*/ }, + /* MR12/MR11 */ + { 0x5401b, ((LPDDR4_VREF_VALUE_CA << 8) | (LPDDR4_RTT_CA << 4) | + LPDDR4_RTT_DQ)/*0x4d46*/ }, + /* self:0x4d28//MR14/MR13 */ + { 0x5401c, ((LPDDR4_VREF_VALUE_DQ_RANK0 << 8) | 0x08)/*0x4d08*/ }, + { 0x5401d, 0x0 }, + { 0x5401e, LPDDR4_MR22_RANK0/*0x5*/ }, + { 0x5401f, 0x84 }, + { 0x54020, (((LPDDR4_RON) << 3) | 0x1)/*0x31*/ }, /* MR4/MR3 */ + { 0x54021, ((LPDDR4_VREF_VALUE_CA << 8) | (LPDDR4_RTT_CA << 4) | + LPDDR4_RTT_DQ)/*0x4d46*/ },/* MR12/MR11 */ + /* self:0x4d28//MR14/MR13 */ + { 0x54022, ((LPDDR4_VREF_VALUE_DQ_RANK1 << 8) | 0x08)/*0x4d08*/ }, + { 0x54023, 0x0 }, + { 0x54024, LPDDR4_MR22_RANK1 }, + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x3 }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + { 0x54032, 0x8400 }, + { 0x54033, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x00 }, + { 0x54034, (((LPDDR4_RTT_CA << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x54035, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x54036, LPDDR4_VREF_VALUE_DQ_RANK0 }, + { 0x54037, (LPDDR4_MR22_RANK0 << 8) }, + { 0x54038, 0x8400 }, + { 0x54039, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x00 }, + { 0x5403a, (((LPDDR4_RTT_CA << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x5403b, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x5403c, LPDDR4_VREF_VALUE_DQ_RANK1 }, + { 0x5403d, (LPDDR4_MR22_RANK1 << 8) }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, +}; + +/* P2 message block paremeter for training firmware */ +struct dram_cfg_param lpddr4_fsp2_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x102 }, + { 0x54003, 0x64 }, + { 0x54004, 0x2 }, + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT) }, + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, LPDDR4_TRAIN_SEQ_100 }, + { 0x54009, LPDDR4_HDT_CTL_100_1D }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, (LPDDR4_CATRAIN_100 << 8) }, + { 0x5400e, 0x0 }, + { 0x5400f, 0x0 }, + { 0x54010, 0x0 }, + { 0x54011, 0x0 }, + { 0x54012, 0x310 }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + { 0x54019, 0x84 }, + { 0x5401a, (((LPDDR4_RON) << 3) | 0x1) }, + { 0x5401b, ((LPDDR4_VREF_VALUE_CA << 8) | (LPDDR4_RTT_CA << 4) | + LPDDR4_RTT_DQ) }, + { 0x5401c, ((LPDDR4_VREF_VALUE_DQ_RANK0 << 8) | 0x08) }, + { 0x5401d, 0x0 }, + { 0x5401e, LPDDR4_MR22_RANK0 }, + { 0x5401f, 0x84 }, + { 0x54020, (((LPDDR4_RON) << 3) | 0x1) }, + { 0x54021, ((LPDDR4_VREF_VALUE_CA << 8) | (LPDDR4_RTT_CA << 4) | + LPDDR4_RTT_DQ) }, + { 0x54022, ((LPDDR4_VREF_VALUE_DQ_RANK1 << 8) | 0x08) }, + { 0x54023, 0x0 }, + { 0x54024, LPDDR4_MR22_RANK1 }, + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x3 }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + { 0x54032, 0x8400 }, + { 0x54033, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x00 }, + { 0x54034, (((LPDDR4_RTT_CA << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x54035, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x54036, LPDDR4_VREF_VALUE_DQ_RANK0 }, + { 0x54037, (LPDDR4_MR22_RANK0 << 8) }, + { 0x54038, 0x8400 }, + { 0x54039, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x00 }, + { 0x5403a, (((LPDDR4_RTT_CA << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x5403b, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x5403c, LPDDR4_VREF_VALUE_DQ_RANK1 }, + { 0x5403d, (LPDDR4_MR22_RANK1 << 8) }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, +}; + +/* P0 2D message block paremeter for training firmware */ +struct dram_cfg_param lpddr4_fsp0_2d_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x0 }, + { 0x54003, 0xc80 }, + { 0x54004, 0x2 }, + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT) }, + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, 0x61 }, + { 0x54009, LPDDR4_HDT_CTL_2D }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, (LPDDR4_CATRAIN_3200_2d << 8) }, + { 0x5400e, 0x0 }, + { 0x5400f, (LPDDR4_2D_SHARE << 8) | 0x00 }, + { 0x54010, LPDDR4_2D_WEIGHT }, + { 0x54011, 0x0 }, + { 0x54012, 0x310 }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + { 0x54019, 0x2dd4 }, +#ifdef WR_POST_EXT_3200 + { 0x5401a, (((LPDDR4_RON) << 3) | 0x3) }, +#else + { 0x5401a, (((LPDDR4_RON) << 3) | 0x1) }, +#endif + { 0x5401b, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT_CA_BANK0 << 4) | LPDDR4_RTT_DQ) }, + { 0x5401c, ((LPDDR4_VREF_VALUE_DQ_RANK0 << 8) | 0x08) }, + { 0x5401d, 0x0 }, + { 0x5401e, LPDDR4_MR22_RANK0 }, + { 0x5401f, 0x2dd4 }, +#ifdef WR_POST_EXT_3200 + { 0x54020, (((LPDDR4_RON) << 3) | 0x3) }, +#else + { 0x54020, (((LPDDR4_RON) << 3) | 0x1) }, +#endif + { 0x54021, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT_CA_BANK1 << 4) | LPDDR4_RTT_DQ) }, + { 0x54022, ((LPDDR4_VREF_VALUE_DQ_RANK1 << 8) | 0x08) }, + { 0x54023, 0x0 }, + { 0x54024, LPDDR4_MR22_RANK1 }, + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x3 }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + + { 0x54032, 0xd400 }, +#ifdef WR_POST_EXT_3200 + { 0x54033, ((((LPDDR4_RON) << 3) | 0x3) << 8) | 0x2d }, +#else + { 0x54033, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x2d }, +#endif + { 0x54034, (((LPDDR4_RTT_CA_BANK0 << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x54035, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x54036, LPDDR4_VREF_VALUE_DQ_RANK0 }, + { 0x54037, (LPDDR4_MR22_RANK0 << 8) }, + { 0x54038, 0xd400 }, +#ifdef WR_POST_EXT_3200 + { 0x54039, ((((LPDDR4_RON) << 3) | 0x3) << 8) | 0x2d }, +#else + { 0x54039, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x2d }, +#endif + { 0x5403a, (((LPDDR4_RTT_CA_BANK1 << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x5403b, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x5403c, LPDDR4_VREF_VALUE_DQ_RANK1 }, + { 0x5403d, (LPDDR4_MR22_RANK1 << 8) }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, +}; + +/* DRAM PHY init engine image */ +struct dram_cfg_param lpddr4_phy_pie[] = { + { 0xd0000, 0x0 }, + { 0x90000, 0x10 }, + { 0x90001, 0x400 }, + { 0x90002, 0x10e }, + { 0x90003, 0x0 }, + { 0x90004, 0x0 }, + { 0x90005, 0x8 }, + { 0x90029, 0xb }, + { 0x9002a, 0x480 }, + { 0x9002b, 0x109 }, + { 0x9002c, 0x8 }, + { 0x9002d, 0x448 }, + { 0x9002e, 0x139 }, + { 0x9002f, 0x8 }, + { 0x90030, 0x478 }, + { 0x90031, 0x109 }, + { 0x90032, 0x0 }, + { 0x90033, 0xe8 }, + { 0x90034, 0x109 }, + { 0x90035, 0x2 }, + { 0x90036, 0x10 }, + { 0x90037, 0x139 }, + { 0x90038, 0xf }, + { 0x90039, 0x7c0 }, + { 0x9003a, 0x139 }, + { 0x9003b, 0x44 }, + { 0x9003c, 0x630 }, + { 0x9003d, 0x159 }, + { 0x9003e, 0x14f }, + { 0x9003f, 0x630 }, + { 0x90040, 0x159 }, + { 0x90041, 0x47 }, + { 0x90042, 0x630 }, + { 0x90043, 0x149 }, + { 0x90044, 0x4f }, + { 0x90045, 0x630 }, + { 0x90046, 0x179 }, + { 0x90047, 0x8 }, + { 0x90048, 0xe0 }, + { 0x90049, 0x109 }, + { 0x9004a, 0x0 }, + { 0x9004b, 0x7c8 }, + { 0x9004c, 0x109 }, + { 0x9004d, 0x0 }, + { 0x9004e, 0x1 }, + { 0x9004f, 0x8 }, + { 0x90050, 0x0 }, + { 0x90051, 0x45a }, + { 0x90052, 0x9 }, + { 0x90053, 0x0 }, + { 0x90054, 0x448 }, + { 0x90055, 0x109 }, + { 0x90056, 0x40 }, + { 0x90057, 0x630 }, + { 0x90058, 0x179 }, + { 0x90059, 0x1 }, + { 0x9005a, 0x618 }, + { 0x9005b, 0x109 }, + { 0x9005c, 0x40c0 }, + { 0x9005d, 0x630 }, + { 0x9005e, 0x149 }, + { 0x9005f, 0x8 }, + { 0x90060, 0x4 }, + { 0x90061, 0x48 }, + { 0x90062, 0x4040 }, + { 0x90063, 0x630 }, + { 0x90064, 0x149 }, + { 0x90065, 0x0 }, + { 0x90066, 0x4 }, + { 0x90067, 0x48 }, + { 0x90068, 0x40 }, + { 0x90069, 0x630 }, + { 0x9006a, 0x149 }, + { 0x9006b, 0x10 }, + { 0x9006c, 0x4 }, + { 0x9006d, 0x18 }, + { 0x9006e, 0x0 }, + { 0x9006f, 0x4 }, + { 0x90070, 0x78 }, + { 0x90071, 0x549 }, + { 0x90072, 0x630 }, + { 0x90073, 0x159 }, + { 0x90074, 0xd49 }, + { 0x90075, 0x630 }, + { 0x90076, 0x159 }, + { 0x90077, 0x94a }, + { 0x90078, 0x630 }, + { 0x90079, 0x159 }, + { 0x9007a, 0x441 }, + { 0x9007b, 0x630 }, + { 0x9007c, 0x149 }, + { 0x9007d, 0x42 }, + { 0x9007e, 0x630 }, + { 0x9007f, 0x149 }, + { 0x90080, 0x1 }, + { 0x90081, 0x630 }, + { 0x90082, 0x149 }, + { 0x90083, 0x0 }, + { 0x90084, 0xe0 }, + { 0x90085, 0x109 }, + { 0x90086, 0xa }, + { 0x90087, 0x10 }, + { 0x90088, 0x109 }, + { 0x90089, 0x9 }, + { 0x9008a, 0x3c0 }, + { 0x9008b, 0x149 }, + { 0x9008c, 0x9 }, + { 0x9008d, 0x3c0 }, + { 0x9008e, 0x159 }, + { 0x9008f, 0x18 }, + { 0x90090, 0x10 }, + { 0x90091, 0x109 }, + { 0x90092, 0x0 }, + { 0x90093, 0x3c0 }, + { 0x90094, 0x109 }, + { 0x90095, 0x18 }, + { 0x90096, 0x4 }, + { 0x90097, 0x48 }, + { 0x90098, 0x18 }, + { 0x90099, 0x4 }, + { 0x9009a, 0x58 }, + { 0x9009b, 0xa }, + { 0x9009c, 0x10 }, + { 0x9009d, 0x109 }, + { 0x9009e, 0x2 }, + { 0x9009f, 0x10 }, + { 0x900a0, 0x109 }, + { 0x900a1, 0x5 }, + { 0x900a2, 0x7c0 }, + { 0x900a3, 0x109 }, + { 0x900a4, 0x10 }, + { 0x900a5, 0x10 }, + { 0x900a6, 0x109 }, + { 0x40000, 0x811 }, + { 0x40020, 0x880 }, + { 0x40040, 0x0 }, + { 0x40060, 0x0 }, + { 0x40001, 0x4008 }, + { 0x40021, 0x83 }, + { 0x40041, 0x4f }, + { 0x40061, 0x0 }, + { 0x40002, 0x4040 }, + { 0x40022, 0x83 }, + { 0x40042, 0x51 }, + { 0x40062, 0x0 }, + { 0x40003, 0x811 }, + { 0x40023, 0x880 }, + { 0x40043, 0x0 }, + { 0x40063, 0x0 }, + { 0x40004, 0x720 }, + { 0x40024, 0xf }, + { 0x40044, 0x1740 }, + { 0x40064, 0x0 }, + { 0x40005, 0x16 }, + { 0x40025, 0x83 }, + { 0x40045, 0x4b }, + { 0x40065, 0x0 }, + { 0x40006, 0x716 }, + { 0x40026, 0xf }, + { 0x40046, 0x2001 }, + { 0x40066, 0x0 }, + { 0x40007, 0x716 }, + { 0x40027, 0xf }, + { 0x40047, 0x2800 }, + { 0x40067, 0x0 }, + { 0x40008, 0x716 }, + { 0x40028, 0xf }, + { 0x40048, 0xf00 }, + { 0x40068, 0x0 }, + { 0x40009, 0x720 }, + { 0x40029, 0xf }, + { 0x40049, 0x1400 }, + { 0x40069, 0x0 }, + { 0x4000a, 0xe08 }, + { 0x4002a, 0xc15 }, + { 0x4004a, 0x0 }, + { 0x4006a, 0x0 }, + { 0x4000b, 0x623 }, + { 0x4002b, 0x15 }, + { 0x4004b, 0x0 }, + { 0x4006b, 0x0 }, + { 0x4000c, 0x4028 }, + { 0x4002c, 0x80 }, + { 0x4004c, 0x0 }, + { 0x4006c, 0x0 }, + { 0x4000d, 0xe08 }, + { 0x4002d, 0xc1a }, + { 0x4004d, 0x0 }, + { 0x4006d, 0x0 }, + { 0x4000e, 0x623 }, + { 0x4002e, 0x1a }, + { 0x4004e, 0x0 }, + { 0x4006e, 0x0 }, + { 0x4000f, 0x4040 }, + { 0x4002f, 0x80 }, + { 0x4004f, 0x0 }, + { 0x4006f, 0x0 }, + { 0x40010, 0x2604 }, + { 0x40030, 0x15 }, + { 0x40050, 0x0 }, + { 0x40070, 0x0 }, + { 0x40011, 0x708 }, + { 0x40031, 0x5 }, + { 0x40051, 0x0 }, + { 0x40071, 0x2002 }, + { 0x40012, 0x8 }, + { 0x40032, 0x80 }, + { 0x40052, 0x0 }, + { 0x40072, 0x0 }, + { 0x40013, 0x2604 }, + { 0x40033, 0x1a }, + { 0x40053, 0x0 }, + { 0x40073, 0x0 }, + { 0x40014, 0x708 }, + { 0x40034, 0xa }, + { 0x40054, 0x0 }, + { 0x40074, 0x2002 }, + { 0x40015, 0x4040 }, + { 0x40035, 0x80 }, + { 0x40055, 0x0 }, + { 0x40075, 0x0 }, + { 0x40016, 0x60a }, + { 0x40036, 0x15 }, + { 0x40056, 0x1200 }, + { 0x40076, 0x0 }, + { 0x40017, 0x61a }, + { 0x40037, 0x15 }, + { 0x40057, 0x1300 }, + { 0x40077, 0x0 }, + { 0x40018, 0x60a }, + { 0x40038, 0x1a }, + { 0x40058, 0x1200 }, + { 0x40078, 0x0 }, + { 0x40019, 0x642 }, + { 0x40039, 0x1a }, + { 0x40059, 0x1300 }, + { 0x40079, 0x0 }, + { 0x4001a, 0x4808 }, + { 0x4003a, 0x880 }, + { 0x4005a, 0x0 }, + { 0x4007a, 0x0 }, + { 0x900a7, 0x0 }, + { 0x900a8, 0x790 }, + { 0x900a9, 0x11a }, + { 0x900aa, 0x8 }, + { 0x900ab, 0x7aa }, + { 0x900ac, 0x2a }, + { 0x900ad, 0x10 }, + { 0x900ae, 0x7b2 }, + { 0x900af, 0x2a }, + { 0x900b0, 0x0 }, + { 0x900b1, 0x7c8 }, + { 0x900b2, 0x109 }, + { 0x900b3, 0x10 }, + { 0x900b4, 0x2a8 }, + { 0x900b5, 0x129 }, + { 0x900b6, 0x8 }, + { 0x900b7, 0x370 }, + { 0x900b8, 0x129 }, + { 0x900b9, 0xa }, + { 0x900ba, 0x3c8 }, + { 0x900bb, 0x1a9 }, + { 0x900bc, 0xc }, + { 0x900bd, 0x408 }, + { 0x900be, 0x199 }, + { 0x900bf, 0x14 }, + { 0x900c0, 0x790 }, + { 0x900c1, 0x11a }, + { 0x900c2, 0x8 }, + { 0x900c3, 0x4 }, + { 0x900c4, 0x18 }, + { 0x900c5, 0xe }, + { 0x900c6, 0x408 }, + { 0x900c7, 0x199 }, + { 0x900c8, 0x8 }, + { 0x900c9, 0x8568 }, + { 0x900ca, 0x108 }, + { 0x900cb, 0x18 }, + { 0x900cc, 0x790 }, + { 0x900cd, 0x16a }, + { 0x900ce, 0x8 }, + { 0x900cf, 0x1d8 }, + { 0x900d0, 0x169 }, + { 0x900d1, 0x10 }, + { 0x900d2, 0x8558 }, + { 0x900d3, 0x168 }, + { 0x900d4, 0x70 }, + { 0x900d5, 0x788 }, + { 0x900d6, 0x16a }, + { 0x900d7, 0x1ff8 }, + { 0x900d8, 0x85a8 }, + { 0x900d9, 0x1e8 }, + { 0x900da, 0x50 }, + { 0x900db, 0x798 }, + { 0x900dc, 0x16a }, + { 0x900dd, 0x60 }, + { 0x900de, 0x7a0 }, + { 0x900df, 0x16a }, + { 0x900e0, 0x8 }, + { 0x900e1, 0x8310 }, + { 0x900e2, 0x168 }, + { 0x900e3, 0x8 }, + { 0x900e4, 0xa310 }, + { 0x900e5, 0x168 }, + { 0x900e6, 0xa }, + { 0x900e7, 0x408 }, + { 0x900e8, 0x169 }, + { 0x900e9, 0x6e }, + { 0x900ea, 0x0 }, + { 0x900eb, 0x68 }, + { 0x900ec, 0x0 }, + { 0x900ed, 0x408 }, + { 0x900ee, 0x169 }, + { 0x900ef, 0x0 }, + { 0x900f0, 0x8310 }, + { 0x900f1, 0x168 }, + { 0x900f2, 0x0 }, + { 0x900f3, 0xa310 }, + { 0x900f4, 0x168 }, + { 0x900f5, 0x1ff8 }, + { 0x900f6, 0x85a8 }, + { 0x900f7, 0x1e8 }, + { 0x900f8, 0x68 }, + { 0x900f9, 0x798 }, + { 0x900fa, 0x16a }, + { 0x900fb, 0x78 }, + { 0x900fc, 0x7a0 }, + { 0x900fd, 0x16a }, + { 0x900fe, 0x68 }, + { 0x900ff, 0x790 }, + { 0x90100, 0x16a }, + { 0x90101, 0x8 }, + { 0x90102, 0x8b10 }, + { 0x90103, 0x168 }, + { 0x90104, 0x8 }, + { 0x90105, 0xab10 }, + { 0x90106, 0x168 }, + { 0x90107, 0xa }, + { 0x90108, 0x408 }, + { 0x90109, 0x169 }, + { 0x9010a, 0x58 }, + { 0x9010b, 0x0 }, + { 0x9010c, 0x68 }, + { 0x9010d, 0x0 }, + { 0x9010e, 0x408 }, + { 0x9010f, 0x169 }, + { 0x90110, 0x0 }, + { 0x90111, 0x8b10 }, + { 0x90112, 0x168 }, + { 0x90113, 0x0 }, + { 0x90114, 0xab10 }, + { 0x90115, 0x168 }, + { 0x90116, 0x0 }, + { 0x90117, 0x1d8 }, + { 0x90118, 0x169 }, + { 0x90119, 0x80 }, + { 0x9011a, 0x790 }, + { 0x9011b, 0x16a }, + { 0x9011c, 0x18 }, + { 0x9011d, 0x7aa }, + { 0x9011e, 0x6a }, + { 0x9011f, 0xa }, + { 0x90120, 0x0 }, + { 0x90121, 0x1e9 }, + { 0x90122, 0x8 }, + { 0x90123, 0x8080 }, + { 0x90124, 0x108 }, + { 0x90125, 0xf }, + { 0x90126, 0x408 }, + { 0x90127, 0x169 }, + { 0x90128, 0xc }, + { 0x90129, 0x0 }, + { 0x9012a, 0x68 }, + { 0x9012b, 0x9 }, + { 0x9012c, 0x0 }, + { 0x9012d, 0x1a9 }, + { 0x9012e, 0x0 }, + { 0x9012f, 0x408 }, + { 0x90130, 0x169 }, + { 0x90131, 0x0 }, + { 0x90132, 0x8080 }, + { 0x90133, 0x108 }, + { 0x90134, 0x8 }, + { 0x90135, 0x7aa }, + { 0x90136, 0x6a }, + { 0x90137, 0x0 }, + { 0x90138, 0x8568 }, + { 0x90139, 0x108 }, + { 0x9013a, 0xb7 }, + { 0x9013b, 0x790 }, + { 0x9013c, 0x16a }, + { 0x9013d, 0x1f }, + { 0x9013e, 0x0 }, + { 0x9013f, 0x68 }, + { 0x90140, 0x8 }, + { 0x90141, 0x8558 }, + { 0x90142, 0x168 }, + { 0x90143, 0xf }, + { 0x90144, 0x408 }, + { 0x90145, 0x169 }, + { 0x90146, 0xc }, + { 0x90147, 0x0 }, + { 0x90148, 0x68 }, + { 0x90149, 0x0 }, + { 0x9014a, 0x408 }, + { 0x9014b, 0x169 }, + { 0x9014c, 0x0 }, + { 0x9014d, 0x8558 }, + { 0x9014e, 0x168 }, + { 0x9014f, 0x8 }, + { 0x90150, 0x3c8 }, + { 0x90151, 0x1a9 }, + { 0x90152, 0x3 }, + { 0x90153, 0x370 }, + { 0x90154, 0x129 }, + { 0x90155, 0x20 }, + { 0x90156, 0x2aa }, + { 0x90157, 0x9 }, + { 0x90158, 0x0 }, + { 0x90159, 0x400 }, + { 0x9015a, 0x10e }, + { 0x9015b, 0x8 }, + { 0x9015c, 0xe8 }, + { 0x9015d, 0x109 }, + { 0x9015e, 0x0 }, + { 0x9015f, 0x8140 }, + { 0x90160, 0x10c }, + { 0x90161, 0x10 }, + { 0x90162, 0x8138 }, + { 0x90163, 0x10c }, + { 0x90164, 0x8 }, + { 0x90165, 0x7c8 }, + { 0x90166, 0x101 }, + { 0x90167, 0x8 }, + { 0x90168, 0x0 }, + { 0x90169, 0x8 }, + { 0x9016a, 0x8 }, + { 0x9016b, 0x448 }, + { 0x9016c, 0x109 }, + { 0x9016d, 0xf }, + { 0x9016e, 0x7c0 }, + { 0x9016f, 0x109 }, + { 0x90170, 0x0 }, + { 0x90171, 0xe8 }, + { 0x90172, 0x109 }, + { 0x90173, 0x47 }, + { 0x90174, 0x630 }, + { 0x90175, 0x109 }, + { 0x90176, 0x8 }, + { 0x90177, 0x618 }, + { 0x90178, 0x109 }, + { 0x90179, 0x8 }, + { 0x9017a, 0xe0 }, + { 0x9017b, 0x109 }, + { 0x9017c, 0x0 }, + { 0x9017d, 0x7c8 }, + { 0x9017e, 0x109 }, + { 0x9017f, 0x8 }, + { 0x90180, 0x8140 }, + { 0x90181, 0x10c }, + { 0x90182, 0x0 }, + { 0x90183, 0x1 }, + { 0x90184, 0x8 }, + { 0x90185, 0x8 }, + { 0x90186, 0x4 }, + { 0x90187, 0x8 }, + { 0x90188, 0x8 }, + { 0x90189, 0x7c8 }, + { 0x9018a, 0x101 }, + { 0x90006, 0x0 }, + { 0x90007, 0x0 }, + { 0x90008, 0x8 }, + { 0x90009, 0x0 }, + { 0x9000a, 0x0 }, + { 0x9000b, 0x0 }, + { 0xd00e7, 0x400 }, + { 0x90017, 0x0 }, + { 0x9001f, 0x2a }, + { 0x90026, 0x6a }, + { 0x400d0, 0x0 }, + { 0x400d1, 0x101 }, + { 0x400d2, 0x105 }, + { 0x400d3, 0x107 }, + { 0x400d4, 0x10f }, + { 0x400d5, 0x202 }, + { 0x400d6, 0x20a }, + { 0x400d7, 0x20b }, + { 0x2003a, 0x2 }, + { 0x2000b, 0x64 }, + { 0x2000c, 0xc8 }, + { 0x2000d, 0x7d0 }, + { 0x2000e, 0x2c }, + { 0x12000b, 0xc }, + { 0x12000c, 0x19 }, + { 0x12000d, 0xfa }, + { 0x12000e, 0x10 }, + { 0x22000b, 0x3 }, + { 0x22000c, 0x6 }, + { 0x22000d, 0x3e }, + { 0x22000e, 0x10 }, + { 0x9000c, 0x0 }, + { 0x9000d, 0x173 }, + { 0x9000e, 0x60 }, + { 0x9000f, 0x6110 }, + { 0x90010, 0x2152 }, + { 0x90011, 0xdfbd }, + { 0x90012, 0x60 }, + { 0x90013, 0x6152 }, + { 0x20010, 0x5a }, + { 0x20011, 0x3 }, + { 0x40080, 0xe0 }, + { 0x40081, 0x12 }, + { 0x40082, 0xe0 }, + { 0x40083, 0x12 }, + { 0x40084, 0xe0 }, + { 0x40085, 0x12 }, + { 0x140080, 0xe0 }, + { 0x140081, 0x12 }, + { 0x140082, 0xe0 }, + { 0x140083, 0x12 }, + { 0x140084, 0xe0 }, + { 0x140085, 0x12 }, + { 0x240080, 0xe0 }, + { 0x240081, 0x12 }, + { 0x240082, 0xe0 }, + { 0x240083, 0x12 }, + { 0x240084, 0xe0 }, + { 0x240085, 0x12 }, + { 0x400fd, 0xf }, + { 0x10011, 0x1 }, + { 0x10012, 0x1 }, + { 0x10013, 0x180 }, + { 0x10018, 0x1 }, + { 0x10002, 0x6209 }, + { 0x100b2, 0x1 }, + { 0x101b4, 0x1 }, + { 0x102b4, 0x1 }, + { 0x103b4, 0x1 }, + { 0x104b4, 0x1 }, + { 0x105b4, 0x1 }, + { 0x106b4, 0x1 }, + { 0x107b4, 0x1 }, + { 0x108b4, 0x1 }, + { 0x11011, 0x1 }, + { 0x11012, 0x1 }, + { 0x11013, 0x180 }, + { 0x11018, 0x1 }, + { 0x11002, 0x6209 }, + { 0x110b2, 0x1 }, + { 0x111b4, 0x1 }, + { 0x112b4, 0x1 }, + { 0x113b4, 0x1 }, + { 0x114b4, 0x1 }, + { 0x115b4, 0x1 }, + { 0x116b4, 0x1 }, + { 0x117b4, 0x1 }, + { 0x118b4, 0x1 }, + { 0x12011, 0x1 }, + { 0x12012, 0x1 }, + { 0x12013, 0x180 }, + { 0x12018, 0x1 }, + { 0x12002, 0x6209 }, + { 0x120b2, 0x1 }, + { 0x121b4, 0x1 }, + { 0x122b4, 0x1 }, + { 0x123b4, 0x1 }, + { 0x124b4, 0x1 }, + { 0x125b4, 0x1 }, + { 0x126b4, 0x1 }, + { 0x127b4, 0x1 }, + { 0x128b4, 0x1 }, + { 0x13011, 0x1 }, + { 0x13012, 0x1 }, + { 0x13013, 0x180 }, + { 0x13018, 0x1 }, + { 0x13002, 0x6209 }, + { 0x130b2, 0x1 }, + { 0x131b4, 0x1 }, + { 0x132b4, 0x1 }, + { 0x133b4, 0x1 }, + { 0x134b4, 0x1 }, + { 0x135b4, 0x1 }, + { 0x136b4, 0x1 }, + { 0x137b4, 0x1 }, + { 0x138b4, 0x1 }, + { 0x2003a, 0x2 }, + { 0xc0080, 0x2 }, + { 0xd0000, 0x1 }, +}; + +struct dram_fsp_msg lpddr4_dram_fsp_msg[] = { + { + /* P0 3200mts 1D */ + .drate = 3200, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = lpddr4_fsp0_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp0_cfg), + }, + { + /* P1 400mts 1D */ + .drate = 400, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = lpddr4_fsp1_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp1_cfg), + }, + { + /* P1 100mts 1D */ + .drate = 100, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = lpddr4_fsp2_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp2_cfg), + }, + { + /* P0 3200mts 2D */ + .drate = 3200, + .fw_type = FW_2D_IMAGE, + .fsp_cfg = lpddr4_fsp0_2d_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp0_2d_cfg), + }, +}; + +/* lpddr4 timing config params on EVK board */ +struct dram_timing_info dram_timing = { + .ddrc_cfg = lpddr4_ddrc_cfg, + .ddrc_cfg_num = ARRAY_SIZE(lpddr4_ddrc_cfg), + .ddrphy_cfg = lpddr4_ddrphy_cfg, + .ddrphy_cfg_num = ARRAY_SIZE(lpddr4_ddrphy_cfg), + .fsp_msg = lpddr4_dram_fsp_msg, + .fsp_msg_num = ARRAY_SIZE(lpddr4_dram_fsp_msg), + .ddrphy_pie = lpddr4_phy_pie, + .ddrphy_pie_num = ARRAY_SIZE(lpddr4_phy_pie), + .fsp_table = { 3200, 400, 100, }, +}; diff --git a/board/purism/librem5/lpddr4_timing_b0.c b/board/purism/librem5/lpddr4_timing_b0.c new file mode 100644 index 0000000000..ec68edaf69 --- /dev/null +++ b/board/purism/librem5/lpddr4_timing_b0.c @@ -0,0 +1,1191 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include <linux/kernel.h> +#include <common.h> +#include <asm/arch/ddr.h> +#include <asm/arch/lpddr4_define.h> + +#define WR_POST_EXT_3200 /* recommened to define */ + +static struct dram_cfg_param lpddr4_ddrc_cfg[] = { + /* Start to config, default 3200mbps */ + /* dis_dq=1, indicates no reads or writes are issued to SDRAM */ + { DDRC_DBG1(0), 0x00000001 }, + /* selfref_en=1, SDRAM enter self-refresh state */ + { DDRC_PWRCTL(0), 0x00000001 }, + { DDRC_MSTR(0), 0xa3080020 }, + { DDRC_MSTR2(0), 0x00000000 }, + { DDRC_RFSHTMG(0), 0x006100E0 }, + { DDRC_INIT0(0), 0xC003061B }, + { DDRC_INIT1(0), 0x009D0000 }, + { DDRC_INIT3(0), 0x00D4002D }, +#ifdef WR_POST_EXT_3200 /* recommened to define */ + { DDRC_INIT4(0), 0x00330008 }, +#else + { DDRC_INIT4(0), 0x00310008 }, +#endif + { DDRC_INIT6(0), 0x0066004a }, + { DDRC_INIT7(0), 0x0006004a }, + + { DDRC_DRAMTMG0(0), 0x1A201B22 }, + { DDRC_DRAMTMG1(0), 0x00060633 }, + { DDRC_DRAMTMG3(0), 0x00C0C000 }, + { DDRC_DRAMTMG4(0), 0x0F04080F }, + { DDRC_DRAMTMG5(0), 0x02040C0C }, + { DDRC_DRAMTMG6(0), 0x01010007 }, + { DDRC_DRAMTMG7(0), 0x00000401 }, + { DDRC_DRAMTMG12(0), 0x00020600 }, + { DDRC_DRAMTMG13(0), 0x0C100002 }, + { DDRC_DRAMTMG14(0), 0x000000E6 }, + { DDRC_DRAMTMG17(0), 0x00A00050 }, + + { DDRC_ZQCTL0(0), 0x03200018 }, + { DDRC_ZQCTL1(0), 0x028061A8 }, + { DDRC_ZQCTL2(0), 0x00000000 }, + + { DDRC_DFITMG0(0), 0x0497820A }, + { DDRC_DFITMG1(0), 0x00080303 }, + { DDRC_DFIUPD0(0), 0xE0400018 }, + { DDRC_DFIUPD1(0), 0x00DF00E4 }, + { DDRC_DFIUPD2(0), 0x80000000 }, + { DDRC_DFIMISC(0), 0x00000011 }, + { DDRC_DFITMG2(0), 0x0000170A }, + + { DDRC_DBICTL(0), 0x00000001 }, + { DDRC_DFIPHYMSTR(0), 0x00000001 }, + + /* need be refined by ddrphy trained value */ + { DDRC_RANKCTL(0), 0x00000c99 }, + { DDRC_DRAMTMG2(0), 0x070E171a }, + + /* address mapping */ + /* Address map is from MSB 29: r15, r14, cs, r13-r0, b2-b0, c9-c0 */ + { DDRC_ADDRMAP0(0), 0x00000015 }, + { DDRC_ADDRMAP3(0), 0x00000000 }, + /* addrmap_col_b10 addrmap_col_b11 set to de-activated (5-bit width) */ + { DDRC_ADDRMAP4(0), 0x00001F1F }, + /* bank interleave */ + /* addrmap_bank_b2, addrmap_bank_b1, addrmap_bank_b0 */ + { DDRC_ADDRMAP1(0), 0x00080808 }, + /* addrmap_row_b11 addrmap_row_b10_b2 addrmap_row_b1 addrmap_row_b0 */ + { DDRC_ADDRMAP5(0), 0x07070707 }, + /* addrmap_row_b15 addrmap_row_b14 addrmap_row_b13 addrmap_row_b12 */ + { DDRC_ADDRMAP6(0), 0x08080707 }, + + /* 667mts frequency setting */ + { DDRC_FREQ1_DERATEEN(0), 0x0000000 }, + { DDRC_FREQ1_DERATEINT(0), 0x0800000 }, + { DDRC_FREQ1_RFSHCTL0(0), 0x0210000 }, + { DDRC_FREQ1_RFSHTMG(0), 0x014001E }, + { DDRC_FREQ1_INIT3(0), 0x0140009 }, + { DDRC_FREQ1_INIT4(0), 0x00310008 }, + { DDRC_FREQ1_INIT6(0), 0x0066004a }, + { DDRC_FREQ1_INIT7(0), 0x0006004a }, + { DDRC_FREQ1_DRAMTMG0(0), 0xB070A07 }, + { DDRC_FREQ1_DRAMTMG1(0), 0x003040A }, + { DDRC_FREQ1_DRAMTMG2(0), 0x305080C }, + { DDRC_FREQ1_DRAMTMG3(0), 0x0505000 }, + { DDRC_FREQ1_DRAMTMG4(0), 0x3040203 }, + { DDRC_FREQ1_DRAMTMG5(0), 0x2030303 }, + { DDRC_FREQ1_DRAMTMG6(0), 0x2020004 }, + { DDRC_FREQ1_DRAMTMG7(0), 0x0000302 }, + { DDRC_FREQ1_DRAMTMG12(0), 0x0020310 }, + { DDRC_FREQ1_DRAMTMG13(0), 0xA100002 }, + { DDRC_FREQ1_DRAMTMG14(0), 0x0000020 }, + { DDRC_FREQ1_DRAMTMG17(0), 0x0220011 }, + { DDRC_FREQ1_ZQCTL0(0), 0x0A70005 }, + { DDRC_FREQ1_DFITMG0(0), 0x3858202 }, + { DDRC_FREQ1_DFITMG1(0), 0x0000404 }, + { DDRC_FREQ1_DFITMG2(0), 0x0000502 }, + + /* performance setting */ + { DDRC_ODTCFG(0), 0x0b060908 }, + { DDRC_ODTMAP(0), 0x00000000 }, + { DDRC_SCHED(0), 0x29511505 }, + { DDRC_SCHED1(0), 0x0000002c }, + { DDRC_PERFHPR1(0), 0x5900575b }, + /* 150T starve and 0x90 max tran len */ + { DDRC_PERFLPR1(0), 0x90000096 }, + /* 300T starve and 0x10 max tran len */ + { DDRC_PERFWR1(0), 0x1000012c }, + { DDRC_DBG0(0), 0x00000016 }, + { DDRC_DBG1(0), 0x00000000 }, + { DDRC_DBGCMD(0), 0x00000000 }, + { DDRC_SWCTL(0), 0x00000001 }, + { DDRC_POISONCFG(0), 0x00000011 }, + { DDRC_PCCFG(0), 0x00000111 }, + { DDRC_PCFGR_0(0), 0x000010f3 }, + { DDRC_PCFGW_0(0), 0x000072ff }, + { DDRC_PCTRL_0(0), 0x00000001 }, + /* disable Read Qos*/ + { DDRC_PCFGQOS0_0(0), 0x00000e00 }, + { DDRC_PCFGQOS1_0(0), 0x0062ffff }, + /* disable Write Qos*/ + { DDRC_PCFGWQOS0_0(0), 0x00000e00 }, + { DDRC_PCFGWQOS1_0(0), 0x0000ffff }, + { DDRC_FREQ1_DERATEEN(0), 0x00000202 }, + { DDRC_FREQ1_DERATEINT(0), 0xec78f4b5 }, + { DDRC_FREQ1_RFSHCTL0(0), 0x00618040 }, + { DDRC_FREQ1_RFSHTMG(0), 0x00610090 }, +}; + +/* PHY Initialize Configuration */ +static struct dram_cfg_param lpddr4_ddrphy_cfg[] = { + { 0x20110, 0x02 }, /* MapCAB0toDFI */ + { 0x20111, 0x03 }, /* MapCAB1toDFI */ + { 0x20112, 0x04 }, /* MapCAB2toDFI */ + { 0x20113, 0x05 }, /* MapCAB3toDFI */ + { 0x20114, 0x00 }, /* MapCAB4toDFI */ + { 0x20115, 0x01 }, /* MapCAB5toDFI */ + + /* Initialize PHY Configuration */ + { 0x1005f, 0x1ff }, + { 0x1015f, 0x1ff }, + { 0x1105f, 0x1ff }, + { 0x1115f, 0x1ff }, + { 0x1205f, 0x1ff }, + { 0x1215f, 0x1ff }, + { 0x1305f, 0x1ff }, + { 0x1315f, 0x1ff }, + + { 0x11005f, 0x1ff }, + { 0x11015f, 0x1ff }, + { 0x11105f, 0x1ff }, + { 0x11115f, 0x1ff }, + { 0x11205f, 0x1ff }, + { 0x11215f, 0x1ff }, + { 0x11305f, 0x1ff }, + { 0x11315f, 0x1ff }, + + { 0x21005f, 0x1ff }, + { 0x21015f, 0x1ff }, + { 0x21105f, 0x1ff }, + { 0x21115f, 0x1ff }, + { 0x21205f, 0x1ff }, + { 0x21215f, 0x1ff }, + { 0x21305f, 0x1ff }, + { 0x21315f, 0x1ff }, + + { 0x55, 0x1ff }, + { 0x1055, 0x1ff }, + { 0x2055, 0x1ff }, + { 0x3055, 0x1ff }, + { 0x4055, 0x1ff }, + { 0x5055, 0x1ff }, + { 0x6055, 0x1ff }, + { 0x7055, 0x1ff }, + { 0x8055, 0x1ff }, + { 0x9055, 0x1ff }, + { 0x200c5, 0x19 }, + { 0x1200c5, 0x7 }, + { 0x2200c5, 0x7 }, + { 0x2002e, 0x2 }, + { 0x12002e, 0x1 }, + { 0x22002e, 0x2 }, + { 0x90204, 0x0 }, + { 0x190204, 0x0 }, + { 0x290204, 0x0 }, + + { 0x20024, 0xe3 }, + { 0x2003a, 0x2 }, + { 0x120024, 0xa3 }, + { 0x2003a, 0x2 }, + { 0x220024, 0xa3 }, + { 0x2003a, 0x2 }, + + { 0x20056, 0x3 }, + { 0x120056, 0xa }, + { 0x220056, 0xa }, + + { 0x1004d, 0xe00 }, + { 0x1014d, 0xe00 }, + { 0x1104d, 0xe00 }, + { 0x1114d, 0xe00 }, + { 0x1204d, 0xe00 }, + { 0x1214d, 0xe00 }, + { 0x1304d, 0xe00 }, + { 0x1314d, 0xe00 }, + { 0x11004d, 0xe00 }, + { 0x11014d, 0xe00 }, + { 0x11104d, 0xe00 }, + { 0x11114d, 0xe00 }, + { 0x11204d, 0xe00 }, + { 0x11214d, 0xe00 }, + { 0x11304d, 0xe00 }, + { 0x11314d, 0xe00 }, + { 0x21004d, 0xe00 }, + { 0x21014d, 0xe00 }, + { 0x21104d, 0xe00 }, + { 0x21114d, 0xe00 }, + { 0x21204d, 0xe00 }, + { 0x21214d, 0xe00 }, + { 0x21304d, 0xe00 }, + { 0x21314d, 0xe00 }, + + { 0x10049, 0xfbe }, + { 0x10149, 0xfbe }, + { 0x11049, 0xfbe }, + { 0x11149, 0xfbe }, + { 0x12049, 0xfbe }, + { 0x12149, 0xfbe }, + { 0x13049, 0xfbe }, + { 0x13149, 0xfbe }, + + { 0x110049, 0xfbe }, + { 0x110149, 0xfbe }, + { 0x111049, 0xfbe }, + { 0x111149, 0xfbe }, + { 0x112049, 0xfbe }, + { 0x112149, 0xfbe }, + { 0x113049, 0xfbe }, + { 0x113149, 0xfbe }, + + { 0x210049, 0xfbe }, + { 0x210149, 0xfbe }, + { 0x211049, 0xfbe }, + { 0x211149, 0xfbe }, + { 0x212049, 0xfbe }, + { 0x212149, 0xfbe }, + { 0x213049, 0xfbe }, + { 0x213149, 0xfbe }, + + { 0x43, 0x63 }, + { 0x1043, 0x63 }, + { 0x2043, 0x63 }, + { 0x3043, 0x63 }, + { 0x4043, 0x63 }, + { 0x5043, 0x63 }, + { 0x6043, 0x63 }, + { 0x7043, 0x63 }, + { 0x8043, 0x63 }, + { 0x9043, 0x63 }, + + { 0x20018, 0x3 }, + { 0x20075, 0x4 }, + { 0x20050, 0x0 }, + { 0x20008, 0x320 }, + { 0x120008, 0xa7 }, + { 0x220008, 0x19 }, + { 0x20088, 0x9 }, + { 0x200b2, 0x104 }, + { 0x10043, 0x5a1 }, + { 0x10143, 0x5a1 }, + { 0x11043, 0x5a1 }, + { 0x11143, 0x5a1 }, + { 0x12043, 0x5a1 }, + { 0x12143, 0x5a1 }, + { 0x13043, 0x5a1 }, + { 0x13143, 0x5a1 }, + { 0x1200b2, 0x104 }, + { 0x110043, 0x5a1 }, + { 0x110143, 0x5a1 }, + { 0x111043, 0x5a1 }, + { 0x111143, 0x5a1 }, + { 0x112043, 0x5a1 }, + { 0x112143, 0x5a1 }, + { 0x113043, 0x5a1 }, + { 0x113143, 0x5a1 }, + { 0x2200b2, 0x104 }, + { 0x210043, 0x5a1 }, + { 0x210143, 0x5a1 }, + { 0x211043, 0x5a1 }, + { 0x211143, 0x5a1 }, + { 0x212043, 0x5a1 }, + { 0x212143, 0x5a1 }, + { 0x213043, 0x5a1 }, + { 0x213143, 0x5a1 }, + { 0x200fa, 0x1 }, + { 0x1200fa, 0x1 }, + { 0x2200fa, 0x1 }, + { 0x20019, 0x1 }, + { 0x120019, 0x1 }, + { 0x220019, 0x1 }, + { 0x200f0, 0x600 }, + { 0x200f1, 0x0 }, + { 0x200f2, 0x4444 }, + { 0x200f3, 0x8888 }, + { 0x200f4, 0x5655 }, + { 0x200f5, 0x0 }, + { 0x200f6, 0x0 }, + { 0x200f7, 0xf000 }, + { 0x20025, 0x0 }, + { 0x2002d, 0x0 }, + { 0x12002d, 0x0 }, + { 0x22002d, 0x0 }, +}; + +/* P0 message block paremeter for training firmware */ +static struct dram_cfg_param lpddr4_fsp0_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x0 }, + { 0x54003, 0xc80 }, + { 0x54004, 0x2 }, + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT) }, + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, 0x131f }, + { 0x54009, LPDDR4_HDT_CTL_3200_1D }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, (LPDDR4_CATRAIN_3200_1d << 8) }, + { 0x5400e, 0x0 }, + { 0x5400f, 0x0 }, + { 0x54010, 0x0 }, + { 0x54011, 0x0 }, + { 0x54012, 0x310 }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + { 0x54019, 0x2dd4 }, + { 0x5401a, (((LPDDR4_RON) << 3) | 0x3) }, + { 0x5401b, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT_CA_BANK0 << 4) | LPDDR4_RTT_DQ) }, + { 0x5401c, ((LPDDR4_VREF_VALUE_DQ_RANK0 << 8) | 0x08) }, + { 0x5401d, 0x0 }, + { 0x5401e, LPDDR4_MR22_RANK0 }, + { 0x5401f, 0x2dd4 }, + { 0x54020, (((LPDDR4_RON) << 3) | 0x3) }, + { 0x54021, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT_CA_BANK1 << 4) | LPDDR4_RTT_DQ) }, + { 0x54022, ((LPDDR4_VREF_VALUE_DQ_RANK1 << 8) | 0x08) }, + { 0x54023, 0x0 }, + { 0x54024, LPDDR4_MR22_RANK1 }, + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x3 }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + { 0x54032, 0xd400 }, + { 0x54033, ((((LPDDR4_RON) << 3) | 0x3) << 8) | 0x2d }, + { 0x54034, (((LPDDR4_RTT_CA_BANK0 << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x54035, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x54036, LPDDR4_VREF_VALUE_DQ_RANK0 }, + { 0x54037, (LPDDR4_MR22_RANK0 << 8) }, + { 0x54038, 0xd400 }, + { 0x54039, ((((LPDDR4_RON) << 3) | 0x3) << 8) | 0x2d }, + { 0x5403a, (((LPDDR4_RTT_CA_BANK1 << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x5403b, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x5403c, LPDDR4_VREF_VALUE_DQ_RANK1 }, + { 0x5403d, (LPDDR4_MR22_RANK1 << 8) }, + { 0x5403d, (LPDDR4_MR22_RANK1 << 8) }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, +}; + +/* P1 message block paremeter for training firmware */ +static struct dram_cfg_param lpddr4_fsp1_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x1 }, + { 0x54003, 0x29c }, + { 0x54004, 0x2 }, + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT) }, + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, 0x121f }, + { 0x54009, 0xc8 }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, 0x0 }, + { 0x5400e, 0x0 }, + { 0x5400f, 0x0 }, + { 0x54010, 0x0 }, + { 0x54011, 0x0 }, + { 0x54012, 0x310 }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + { 0x54019, 0x914 }, + { 0x5401a, (((LPDDR4_RON) << 3) | 0x1) }, + { 0x5401b, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT_CA_BANK0 << 4) | LPDDR4_RTT_DQ) }, + { 0x5401c, ((LPDDR4_VREF_VALUE_DQ_RANK0 << 8) | 0x08) }, + { 0x5401e, 0x6 }, + { 0x5401f, 0x914 }, + { 0x54020, (((LPDDR4_RON) << 3) | 0x1) }, + { 0x54021, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT_CA_BANK1 << 4) | LPDDR4_RTT_DQ) }, + { 0x54022, ((LPDDR4_VREF_VALUE_DQ_RANK1 << 8) | 0x08) }, + { 0x54023, 0x0 }, + { 0x54024, LPDDR4_MR22_RANK1 }, + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x3 }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + { 0x54032, 0x1400 }, + { 0x54033, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x09 }, + { 0x54034, (((LPDDR4_RTT_CA_BANK0 << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x54035, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x54036, LPDDR4_VREF_VALUE_DQ_RANK0 }, + { 0x54037, 0x600 }, + { 0x54038, 0x1400 }, + { 0x54039, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x09 }, + { 0x5403a, (((LPDDR4_RTT_CA_BANK1 << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x5403b, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x5403c, LPDDR4_VREF_VALUE_DQ_RANK1 }, + { 0x5403d, (LPDDR4_MR22_RANK1 << 8) }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0xd0000, 0x1 }, + +}; + +/* P0 2D message block paremeter for training firmware */ +static struct dram_cfg_param lpddr4_fsp0_2d_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x0 }, + { 0x54003, 0xc80 }, + { 0x54004, 0x2 }, + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT) }, + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, 0x61 }, + { 0x54009, LPDDR4_HDT_CTL_2D }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, (LPDDR4_CATRAIN_3200_2d << 8) }, + { 0x5400e, 0x0 }, + { 0x5400f, (LPDDR4_2D_SHARE << 8) | 0x00 }, + { 0x54010, LPDDR4_2D_WEIGHT }, + { 0x54011, 0x0 }, + { 0x54012, 0x310 }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + { 0x54024, 0x5 }, + { 0x54019, 0x2dd4 }, + { 0x5401a, (((LPDDR4_RON) << 3) | 0x3) }, + { 0x5401b, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT_CA_BANK0 << 4) | LPDDR4_RTT_DQ) }, + { 0x5401c, ((LPDDR4_VREF_VALUE_DQ_RANK0 << 8) | 0x08) }, + { 0x5401d, 0x0 }, + { 0x5401e, LPDDR4_MR22_RANK0 }, + { 0x5401f, 0x2dd4 }, + { 0x54020, (((LPDDR4_RON) << 3) | 0x3) }, + { 0x54021, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT_CA_BANK1 << 4) | LPDDR4_RTT_DQ) }, + { 0x54022, ((LPDDR4_VREF_VALUE_DQ_RANK1 << 8) | 0x08) }, + { 0x54023, 0x0 }, + { 0x54024, LPDDR4_MR22_RANK1 }, + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x3 }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + { 0x54032, 0xd400 }, + { 0x54033, ((((LPDDR4_RON) << 3) | 0x3) << 8) | 0x2d }, + { 0x54034, (((LPDDR4_RTT_CA_BANK0 << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x54035, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x54036, LPDDR4_VREF_VALUE_DQ_RANK0 }, + { 0x54037, (LPDDR4_MR22_RANK0 << 8) }, + { 0x54038, 0xd400 }, + { 0x54039, ((((LPDDR4_RON) << 3) | 0x3) << 8) | 0x2d }, + { 0x5403a, (((LPDDR4_RTT_CA_BANK1 << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x5403b, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x5403c, LPDDR4_VREF_VALUE_DQ_RANK1 }, + { 0x5403d, (LPDDR4_MR22_RANK1 << 8) }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, + +}; + +/* DRAM PHY init engine image */ +static struct dram_cfg_param lpddr4_phy_pie[] = { + { 0xd0000, 0x0 }, + { 0x90000, 0x10 }, + { 0x90001, 0x400 }, + { 0x90002, 0x10e }, + { 0x90003, 0x0 }, + { 0x90004, 0x0 }, + { 0x90005, 0x8 }, + { 0x90029, 0xb }, + { 0x9002a, 0x480 }, + { 0x9002b, 0x109 }, + { 0x9002c, 0x8 }, + { 0x9002d, 0x448 }, + { 0x9002e, 0x139 }, + { 0x9002f, 0x8 }, + { 0x90030, 0x478 }, + { 0x90031, 0x109 }, + { 0x90032, 0x0 }, + { 0x90033, 0xe8 }, + { 0x90034, 0x109 }, + { 0x90035, 0x2 }, + { 0x90036, 0x10 }, + { 0x90037, 0x139 }, + { 0x90038, 0xb }, + { 0x90039, 0x7c0 }, + { 0x9003a, 0x139 }, + { 0x9003b, 0x44 }, + { 0x9003c, 0x630 }, + { 0x9003d, 0x159 }, + { 0x9003e, 0x14f }, + { 0x9003f, 0x630 }, + { 0x90040, 0x159 }, + { 0x90041, 0x47 }, + { 0x90042, 0x630 }, + { 0x90043, 0x149 }, + { 0x90044, 0x4f }, + { 0x90045, 0x630 }, + { 0x90046, 0x179 }, + { 0x90047, 0x8 }, + { 0x90048, 0xe0 }, + { 0x90049, 0x109 }, + { 0x9004a, 0x0 }, + { 0x9004b, 0x7c8 }, + { 0x9004c, 0x109 }, + { 0x9004d, 0x0 }, + { 0x9004e, 0x1 }, + { 0x9004f, 0x8 }, + { 0x90050, 0x0 }, + { 0x90051, 0x45a }, + { 0x90052, 0x9 }, + { 0x90053, 0x0 }, + { 0x90054, 0x448 }, + { 0x90055, 0x109 }, + { 0x90056, 0x40 }, + { 0x90057, 0x630 }, + { 0x90058, 0x179 }, + { 0x90059, 0x1 }, + { 0x9005a, 0x618 }, + { 0x9005b, 0x109 }, + { 0x9005c, 0x40c0 }, + { 0x9005d, 0x630 }, + { 0x9005e, 0x149 }, + { 0x9005f, 0x8 }, + { 0x90060, 0x4 }, + { 0x90061, 0x48 }, + { 0x90062, 0x4040 }, + { 0x90063, 0x630 }, + { 0x90064, 0x149 }, + { 0x90065, 0x0 }, + { 0x90066, 0x4 }, + { 0x90067, 0x48 }, + { 0x90068, 0x40 }, + { 0x90069, 0x630 }, + { 0x9006a, 0x149 }, + { 0x9006b, 0x10 }, + { 0x9006c, 0x4 }, + { 0x9006d, 0x18 }, + { 0x9006e, 0x0 }, + { 0x9006f, 0x4 }, + { 0x90070, 0x78 }, + { 0x90071, 0x549 }, + { 0x90072, 0x630 }, + { 0x90073, 0x159 }, + { 0x90074, 0xd49 }, + { 0x90075, 0x630 }, + { 0x90076, 0x159 }, + { 0x90077, 0x94a }, + { 0x90078, 0x630 }, + { 0x90079, 0x159 }, + { 0x9007a, 0x441 }, + { 0x9007b, 0x630 }, + { 0x9007c, 0x149 }, + { 0x9007d, 0x42 }, + { 0x9007e, 0x630 }, + { 0x9007f, 0x149 }, + { 0x90080, 0x1 }, + { 0x90081, 0x630 }, + { 0x90082, 0x149 }, + { 0x90083, 0x0 }, + { 0x90084, 0xe0 }, + { 0x90085, 0x109 }, + { 0x90086, 0xa }, + { 0x90087, 0x10 }, + { 0x90088, 0x109 }, + { 0x90089, 0x9 }, + { 0x9008a, 0x3c0 }, + { 0x9008b, 0x149 }, + { 0x9008c, 0x9 }, + { 0x9008d, 0x3c0 }, + { 0x9008e, 0x159 }, + { 0x9008f, 0x18 }, + { 0x90090, 0x10 }, + { 0x90091, 0x109 }, + { 0x90092, 0x0 }, + { 0x90093, 0x3c0 }, + { 0x90094, 0x109 }, + { 0x90095, 0x18 }, + { 0x90096, 0x4 }, + { 0x90097, 0x48 }, + { 0x90098, 0x18 }, + { 0x90099, 0x4 }, + { 0x9009a, 0x58 }, + { 0x9009b, 0xa }, + { 0x9009c, 0x10 }, + { 0x9009d, 0x109 }, + { 0x9009e, 0x2 }, + { 0x9009f, 0x10 }, + { 0x900a0, 0x109 }, + { 0x900a1, 0x5 }, + { 0x900a2, 0x7c0 }, + { 0x900a3, 0x109 }, + { 0x900a4, 0xd }, + { 0x900a5, 0x7c0 }, + { 0x900a6, 0x109 }, + { 0x900a7, 0x4 }, + { 0x900a8, 0x7c0 }, + { 0x900a9, 0x109 }, + { 0x40000, 0x811 }, + { 0x40020, 0x880 }, + { 0x40040, 0x0 }, + { 0x40060, 0x0 }, + { 0x40001, 0x4008 }, + { 0x40021, 0x83 }, + { 0x40041, 0x4f }, + { 0x40061, 0x0 }, + { 0x40002, 0x4040 }, + { 0x40022, 0x83 }, + { 0x40042, 0x51 }, + { 0x40062, 0x0 }, + { 0x40003, 0x811 }, + { 0x40023, 0x880 }, + { 0x40043, 0x0 }, + { 0x40063, 0x0 }, + { 0x40004, 0x720 }, + { 0x40024, 0xf }, + { 0x40044, 0x1740 }, + { 0x40064, 0x0 }, + { 0x40005, 0x16 }, + { 0x40025, 0x83 }, + { 0x40045, 0x4b }, + { 0x40065, 0x0 }, + { 0x40006, 0x716 }, + { 0x40026, 0xf }, + { 0x40046, 0x2001 }, + { 0x40066, 0x0 }, + { 0x40007, 0x716 }, + { 0x40027, 0xf }, + { 0x40047, 0x2800 }, + { 0x40067, 0x0 }, + { 0x40008, 0x716 }, + { 0x40028, 0xf }, + { 0x40048, 0xf00 }, + { 0x40068, 0x0 }, + { 0x40009, 0x720 }, + { 0x40029, 0xf }, + { 0x40049, 0x1400 }, + { 0x40069, 0x0 }, + { 0x4000a, 0xe08 }, + { 0x4002a, 0xc15 }, + { 0x4004a, 0x0 }, + { 0x4006a, 0x0 }, + { 0x4000b, 0x623 }, + { 0x4002b, 0x15 }, + { 0x4004b, 0x0 }, + { 0x4006b, 0x0 }, + { 0x4000c, 0x4028 }, + { 0x4002c, 0x80 }, + { 0x4004c, 0x0 }, + { 0x4006c, 0x0 }, + { 0x4000d, 0xe08 }, + { 0x4002d, 0xc1a }, + { 0x4004d, 0x0 }, + { 0x4006d, 0x0 }, + { 0x4000e, 0x623 }, + { 0x4002e, 0x1a }, + { 0x4004e, 0x0 }, + { 0x4006e, 0x0 }, + { 0x4000f, 0x4040 }, + { 0x4002f, 0x80 }, + { 0x4004f, 0x0 }, + { 0x4006f, 0x0 }, + { 0x40010, 0x2604 }, + { 0x40030, 0x15 }, + { 0x40050, 0x0 }, + { 0x40070, 0x0 }, + { 0x40011, 0x708 }, + { 0x40031, 0x5 }, + { 0x40051, 0x0 }, + { 0x40071, 0x2002 }, + { 0x40012, 0x8 }, + { 0x40032, 0x80 }, + { 0x40052, 0x0 }, + { 0x40072, 0x0 }, + { 0x40013, 0x2604 }, + { 0x40033, 0x1a }, + { 0x40053, 0x0 }, + { 0x40073, 0x0 }, + { 0x40014, 0x708 }, + { 0x40034, 0xa }, + { 0x40054, 0x0 }, + { 0x40074, 0x2002 }, + { 0x40015, 0x4040 }, + { 0x40035, 0x80 }, + { 0x40055, 0x0 }, + { 0x40075, 0x0 }, + { 0x40016, 0x60a }, + { 0x40036, 0x15 }, + { 0x40056, 0x1200 }, + { 0x40076, 0x0 }, + { 0x40017, 0x61a }, + { 0x40037, 0x15 }, + { 0x40057, 0x1300 }, + { 0x40077, 0x0 }, + { 0x40018, 0x60a }, + { 0x40038, 0x1a }, + { 0x40058, 0x1200 }, + { 0x40078, 0x0 }, + { 0x40019, 0x642 }, + { 0x40039, 0x1a }, + { 0x40059, 0x1300 }, + { 0x40079, 0x0 }, + { 0x4001a, 0x4808 }, + { 0x4003a, 0x880 }, + { 0x4005a, 0x0 }, + { 0x4007a, 0x0 }, + { 0x900aa, 0x0 }, + { 0x900ab, 0x790 }, + { 0x900ac, 0x11a }, + { 0x900ad, 0x8 }, + { 0x900ae, 0x7aa }, + { 0x900af, 0x2a }, + { 0x900b0, 0x10 }, + { 0x900b1, 0x7b2 }, + { 0x900b2, 0x2a }, + { 0x900b3, 0x0 }, + { 0x900b4, 0x7c8 }, + { 0x900b5, 0x109 }, + { 0x900b6, 0x10 }, + { 0x900b7, 0x10 }, + { 0x900b8, 0x109 }, + { 0x900b9, 0x10 }, + { 0x900ba, 0x2a8 }, + { 0x900bb, 0x129 }, + { 0x900bc, 0x8 }, + { 0x900bd, 0x370 }, + { 0x900be, 0x129 }, + { 0x900bf, 0xa }, + { 0x900c0, 0x3c8 }, + { 0x900c1, 0x1a9 }, + { 0x900c2, 0xc }, + { 0x900c3, 0x408 }, + { 0x900c4, 0x199 }, + { 0x900c5, 0x14 }, + { 0x900c6, 0x790 }, + { 0x900c7, 0x11a }, + { 0x900c8, 0x8 }, + { 0x900c9, 0x4 }, + { 0x900ca, 0x18 }, + { 0x900cb, 0xe }, + { 0x900cc, 0x408 }, + { 0x900cd, 0x199 }, + { 0x900ce, 0x8 }, + { 0x900cf, 0x8568 }, + { 0x900d0, 0x108 }, + { 0x900d1, 0x18 }, + { 0x900d2, 0x790 }, + { 0x900d3, 0x16a }, + { 0x900d4, 0x8 }, + { 0x900d5, 0x1d8 }, + { 0x900d6, 0x169 }, + { 0x900d7, 0x10 }, + { 0x900d8, 0x8558 }, + { 0x900d9, 0x168 }, + { 0x900da, 0x70 }, + { 0x900db, 0x788 }, + { 0x900dc, 0x16a }, + { 0x900dd, 0x1ff8 }, + { 0x900de, 0x85a8 }, + { 0x900df, 0x1e8 }, + { 0x900e0, 0x50 }, + { 0x900e1, 0x798 }, + { 0x900e2, 0x16a }, + { 0x900e3, 0x60 }, + { 0x900e4, 0x7a0 }, + { 0x900e5, 0x16a }, + { 0x900e6, 0x8 }, + { 0x900e7, 0x8310 }, + { 0x900e8, 0x168 }, + { 0x900e9, 0x8 }, + { 0x900ea, 0xa310 }, + { 0x900eb, 0x168 }, + { 0x900ec, 0xa }, + { 0x900ed, 0x408 }, + { 0x900ee, 0x169 }, + { 0x900ef, 0x6e }, + { 0x900f0, 0x0 }, + { 0x900f1, 0x68 }, + { 0x900f2, 0x0 }, + { 0x900f3, 0x408 }, + { 0x900f4, 0x169 }, + { 0x900f5, 0x0 }, + { 0x900f6, 0x8310 }, + { 0x900f7, 0x168 }, + { 0x900f8, 0x0 }, + { 0x900f9, 0xa310 }, + { 0x900fa, 0x168 }, + { 0x900fb, 0x1ff8 }, + { 0x900fc, 0x85a8 }, + { 0x900fd, 0x1e8 }, + { 0x900fe, 0x68 }, + { 0x900ff, 0x798 }, + { 0x90100, 0x16a }, + { 0x90101, 0x78 }, + { 0x90102, 0x7a0 }, + { 0x90103, 0x16a }, + { 0x90104, 0x68 }, + { 0x90105, 0x790 }, + { 0x90106, 0x16a }, + { 0x90107, 0x8 }, + { 0x90108, 0x8b10 }, + { 0x90109, 0x168 }, + { 0x9010a, 0x8 }, + { 0x9010b, 0xab10 }, + { 0x9010c, 0x168 }, + { 0x9010d, 0xa }, + { 0x9010e, 0x408 }, + { 0x9010f, 0x169 }, + { 0x90110, 0x58 }, + { 0x90111, 0x0 }, + { 0x90112, 0x68 }, + { 0x90113, 0x0 }, + { 0x90114, 0x408 }, + { 0x90115, 0x169 }, + { 0x90116, 0x0 }, + { 0x90117, 0x8b10 }, + { 0x90118, 0x168 }, + { 0x90119, 0x0 }, + { 0x9011a, 0xab10 }, + { 0x9011b, 0x168 }, + { 0x9011c, 0x0 }, + { 0x9011d, 0x1d8 }, + { 0x9011e, 0x169 }, + { 0x9011f, 0x80 }, + { 0x90120, 0x790 }, + { 0x90121, 0x16a }, + { 0x90122, 0x18 }, + { 0x90123, 0x7aa }, + { 0x90124, 0x6a }, + { 0x90125, 0xa }, + { 0x90126, 0x0 }, + { 0x90127, 0x1e9 }, + { 0x90128, 0x8 }, + { 0x90129, 0x8080 }, + { 0x9012a, 0x108 }, + { 0x9012b, 0xf }, + { 0x9012c, 0x408 }, + { 0x9012d, 0x169 }, + { 0x9012e, 0xc }, + { 0x9012f, 0x0 }, + { 0x90130, 0x68 }, + { 0x90131, 0x9 }, + { 0x90132, 0x0 }, + { 0x90133, 0x1a9 }, + { 0x90134, 0x0 }, + { 0x90135, 0x408 }, + { 0x90136, 0x169 }, + { 0x90137, 0x0 }, + { 0x90138, 0x8080 }, + { 0x90139, 0x108 }, + { 0x9013a, 0x8 }, + { 0x9013b, 0x7aa }, + { 0x9013c, 0x6a }, + { 0x9013d, 0x0 }, + { 0x9013e, 0x8568 }, + { 0x9013f, 0x108 }, + { 0x90140, 0xb7 }, + { 0x90141, 0x790 }, + { 0x90142, 0x16a }, + { 0x90143, 0x1f }, + { 0x90144, 0x0 }, + { 0x90145, 0x68 }, + { 0x90146, 0x8 }, + { 0x90147, 0x8558 }, + { 0x90148, 0x168 }, + { 0x90149, 0xf }, + { 0x9014a, 0x408 }, + { 0x9014b, 0x169 }, + { 0x9014c, 0xc }, + { 0x9014d, 0x0 }, + { 0x9014e, 0x68 }, + { 0x9014f, 0x0 }, + { 0x90150, 0x408 }, + { 0x90151, 0x169 }, + { 0x90152, 0x0 }, + { 0x90153, 0x8558 }, + { 0x90154, 0x168 }, + { 0x90155, 0x8 }, + { 0x90156, 0x3c8 }, + { 0x90157, 0x1a9 }, + { 0x90158, 0x3 }, + { 0x90159, 0x370 }, + { 0x9015a, 0x129 }, + { 0x9015b, 0x20 }, + { 0x9015c, 0x2aa }, + { 0x9015d, 0x9 }, + { 0x9015e, 0x0 }, + { 0x9015f, 0x400 }, + { 0x90160, 0x10e }, + { 0x90161, 0x8 }, + { 0x90162, 0xe8 }, + { 0x90163, 0x109 }, + { 0x90164, 0x0 }, + { 0x90165, 0x8140 }, + { 0x90166, 0x10c }, + { 0x90167, 0x10 }, + { 0x90168, 0x8138 }, + { 0x90169, 0x10c }, + { 0x9016a, 0x8 }, + { 0x9016b, 0x7c8 }, + { 0x9016c, 0x101 }, + { 0x9016d, 0x8 }, + { 0x9016e, 0x0 }, + { 0x9016f, 0x8 }, + { 0x90170, 0x8 }, + { 0x90171, 0x448 }, + { 0x90172, 0x109 }, + { 0x90173, 0xf }, + { 0x90174, 0x7c0 }, + { 0x90175, 0x109 }, + { 0x90176, 0x0 }, + { 0x90177, 0xe8 }, + { 0x90178, 0x109 }, + { 0x90179, 0x47 }, + { 0x9017a, 0x630 }, + { 0x9017b, 0x109 }, + { 0x9017c, 0x8 }, + { 0x9017d, 0x618 }, + { 0x9017e, 0x109 }, + { 0x9017f, 0x8 }, + { 0x90180, 0xe0 }, + { 0x90181, 0x109 }, + { 0x90182, 0x0 }, + { 0x90183, 0x7c8 }, + { 0x90184, 0x109 }, + { 0x90185, 0x8 }, + { 0x90186, 0x8140 }, + { 0x90187, 0x10c }, + { 0x90188, 0x0 }, + { 0x90189, 0x1 }, + { 0x9018a, 0x8 }, + { 0x9018b, 0x8 }, + { 0x9018c, 0x4 }, + { 0x9018d, 0x8 }, + { 0x9018e, 0x8 }, + { 0x9018f, 0x7c8 }, + { 0x90190, 0x101 }, + { 0x90006, 0x0 }, + { 0x90007, 0x0 }, + { 0x90008, 0x8 }, + { 0x90009, 0x0 }, + { 0x9000a, 0x0 }, + { 0x9000b, 0x0 }, + { 0xd00e7, 0x400 }, + { 0x90017, 0x0 }, + { 0x9001f, 0x2b }, + { 0x90026, 0x6c }, + { 0x400d0, 0x0 }, + { 0x400d1, 0x101 }, + { 0x400d2, 0x105 }, + { 0x400d3, 0x107 }, + { 0x400d4, 0x10f }, + { 0x400d5, 0x202 }, + { 0x400d6, 0x20a }, + { 0x400d7, 0x20b }, + { 0x2003a, 0x2 }, + { 0x2000b, 0x64 }, + { 0x2000c, 0xc8 }, + { 0x2000d, 0x7d0 }, + { 0x2000e, 0x2c }, + { 0x12000b, 0x14 }, + { 0x12000c, 0x29 }, + { 0x12000d, 0x1a1 }, + { 0x12000e, 0x10 }, + { 0x22000b, 0x3 }, + { 0x22000c, 0x6 }, + { 0x22000d, 0x3e }, + { 0x22000e, 0x10 }, + { 0x9000c, 0x0 }, + { 0x9000d, 0x173 }, + { 0x9000e, 0x60 }, + { 0x9000f, 0x6110 }, + { 0x90010, 0x2152 }, + { 0x90011, 0xdfbd }, + { 0x90012, 0x60 }, + { 0x90013, 0x6152 }, + { 0x20010, 0x5a }, + { 0x20011, 0x3 }, + { 0x40080, 0xe0 }, + { 0x40081, 0x12 }, + { 0x40082, 0xe0 }, + { 0x40083, 0x12 }, + { 0x40084, 0xe0 }, + { 0x40085, 0x12 }, + { 0x140080, 0xe0 }, + { 0x140081, 0x12 }, + { 0x140082, 0xe0 }, + { 0x140083, 0x12 }, + { 0x140084, 0xe0 }, + { 0x140085, 0x12 }, + { 0x240080, 0xe0 }, + { 0x240081, 0x12 }, + { 0x240082, 0xe0 }, + { 0x240083, 0x12 }, + { 0x240084, 0xe0 }, + { 0x240085, 0x12 }, + { 0x400fd, 0xf }, + { 0x10011, 0x1 }, + { 0x10012, 0x1 }, + { 0x10013, 0x180 }, + { 0x10018, 0x1 }, + { 0x10002, 0x6209 }, + { 0x100b2, 0x1 }, + { 0x101b4, 0x1 }, + { 0x102b4, 0x1 }, + { 0x103b4, 0x1 }, + { 0x104b4, 0x1 }, + { 0x105b4, 0x1 }, + { 0x106b4, 0x1 }, + { 0x107b4, 0x1 }, + { 0x108b4, 0x1 }, + { 0x11011, 0x1 }, + { 0x11012, 0x1 }, + { 0x11013, 0x180 }, + { 0x11018, 0x1 }, + { 0x11002, 0x6209 }, + { 0x110b2, 0x1 }, + { 0x111b4, 0x1 }, + { 0x112b4, 0x1 }, + { 0x113b4, 0x1 }, + { 0x114b4, 0x1 }, + { 0x115b4, 0x1 }, + { 0x116b4, 0x1 }, + { 0x117b4, 0x1 }, + { 0x118b4, 0x1 }, + { 0x12011, 0x1 }, + { 0x12012, 0x1 }, + { 0x12013, 0x180 }, + { 0x12018, 0x1 }, + { 0x12002, 0x6209 }, + { 0x120b2, 0x1 }, + { 0x121b4, 0x1 }, + { 0x122b4, 0x1 }, + { 0x123b4, 0x1 }, + { 0x124b4, 0x1 }, + { 0x125b4, 0x1 }, + { 0x126b4, 0x1 }, + { 0x127b4, 0x1 }, + { 0x128b4, 0x1 }, + { 0x13011, 0x1 }, + { 0x13012, 0x1 }, + { 0x13013, 0x180 }, + { 0x13018, 0x1 }, + { 0x13002, 0x6209 }, + { 0x130b2, 0x1 }, + { 0x131b4, 0x1 }, + { 0x132b4, 0x1 }, + { 0x133b4, 0x1 }, + { 0x134b4, 0x1 }, + { 0x135b4, 0x1 }, + { 0x136b4, 0x1 }, + { 0x137b4, 0x1 }, + { 0x138b4, 0x1 }, + { 0x20089, 0x1 }, + { 0x20088, 0x19 }, + { 0xc0080, 0x2 }, + { 0xd0000, 0x1 }, +}; + +static struct dram_fsp_msg lpddr4_dram_fsp_msg[] = { + { + /* P0 3200mts 1D */ + .drate = 3200, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = lpddr4_fsp0_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp0_cfg), + }, + { + /* P1 667mts 1D */ + .drate = 667, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = lpddr4_fsp1_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp1_cfg), + }, + { + /* P0 3200mts 2D */ + .drate = 3200, + .fw_type = FW_2D_IMAGE, + .fsp_cfg = lpddr4_fsp0_2d_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp0_2d_cfg), + }, +}; + +/* lpddr4 timing config params on EVK board */ +struct dram_timing_info dram_timing_b0 = { + .ddrc_cfg = lpddr4_ddrc_cfg, + .ddrc_cfg_num = ARRAY_SIZE(lpddr4_ddrc_cfg), + .ddrphy_cfg = lpddr4_ddrphy_cfg, + .ddrphy_cfg_num = ARRAY_SIZE(lpddr4_ddrphy_cfg), + .fsp_msg = lpddr4_dram_fsp_msg, + .fsp_msg_num = ARRAY_SIZE(lpddr4_dram_fsp_msg), + .ddrphy_pie = lpddr4_phy_pie, + .ddrphy_pie_num = ARRAY_SIZE(lpddr4_phy_pie), + /* + * this table must be initialized if DDRPHY bypass mode is + * not used: all fsp drate > 666MTS. + */ + .fsp_table = { 3200, 667, }, +}; diff --git a/board/purism/librem5/spl.c b/board/purism/librem5/spl.c new file mode 100644 index 0000000000..976033a6e5 --- /dev/null +++ b/board/purism/librem5/spl.c @@ -0,0 +1,481 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + * Copyright 2021 Purism + */ + +#include <common.h> +#include <asm/io.h> +#include <errno.h> +#include <asm/io.h> +#include <asm/arch/ddr.h> +#include <asm/arch/imx8mq_pins.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/clock.h> +#include <asm/mach-imx/boot_mode.h> +#include <asm/mach-imx/iomux-v3.h> +#include <asm/mach-imx/gpio.h> +#include <asm/mach-imx/mxc_i2c.h> +#include <fsl_esdhc_imx.h> +#include <mmc.h> +#include <power/pmic.h> +#include <power/bd71837.h> +#include <hang.h> +#include <init.h> +#include <spl.h> +#include <usb.h> +#include <dwc3-uboot.h> +#include <linux/delay.h> +#include "librem5.h" + +DECLARE_GLOBAL_DATA_PTR; + +void spl_dram_init(void) +{ + /* ddr init */ + if ((get_cpu_rev() & 0xfff) == CHIP_REV_2_1) + ddr_init(&dram_timing); + else + ddr_init(&dram_timing_b0); +} + +int spl_board_boot_device(enum boot_device boot_dev_spl) +{ + log_debug("%s : starting\n", __func__); + + switch (boot_dev_spl) { + case SD1_BOOT: + case MMC1_BOOT: + return BOOT_DEVICE_MMC1; + case USB_BOOT: + return BOOT_DEVICE_BOARD; + default: + return BOOT_DEVICE_NONE; + } +} + +#define I2C_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_ODE | PAD_CTL_DSE7 | PAD_CTL_FSEL3) +#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), + }, +}; + +struct i2c_pads_info i2c_pad_info2 = { + .scl = { + .i2c_mode = IMX8MQ_PAD_I2C2_SCL__I2C2_SCL | PC, + .gpio_mode = IMX8MQ_PAD_I2C2_SCL__GPIO5_IO16 | PC, + .gp = IMX_GPIO_NR(5, 16), + }, + .sda = { + .i2c_mode = IMX8MQ_PAD_I2C2_SDA__I2C2_SDA | PC, + .gpio_mode = IMX8MQ_PAD_I2C2_SDA__GPIO5_IO17 | PC, + .gp = IMX_GPIO_NR(5, 17), + }, +}; + +struct i2c_pads_info i2c_pad_info3 = { + .scl = { + .i2c_mode = IMX8MQ_PAD_I2C3_SCL__I2C3_SCL | PC, + .gpio_mode = IMX8MQ_PAD_I2C3_SCL__GPIO5_IO18 | PC, + .gp = IMX_GPIO_NR(5, 18), + }, + .sda = { + .i2c_mode = IMX8MQ_PAD_I2C3_SDA__I2C3_SDA | PC, + .gpio_mode = IMX8MQ_PAD_I2C3_SDA__GPIO5_IO19 | PC, + .gp = IMX_GPIO_NR(5, 19), + }, +}; + +struct i2c_pads_info i2c_pad_info4 = { + .scl = { + .i2c_mode = IMX8MQ_PAD_I2C4_SCL__I2C4_SCL | PC, + .gpio_mode = IMX8MQ_PAD_I2C4_SCL__GPIO5_IO20 | PC, + .gp = IMX_GPIO_NR(5, 20), + }, + .sda = { + .i2c_mode = IMX8MQ_PAD_I2C4_SDA__I2C4_SDA | PC, + .gpio_mode = IMX8MQ_PAD_I2C4_SDA__GPIO5_IO21 | PC, + .gp = IMX_GPIO_NR(5, 21), + }, +}; + +#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1) + +static const iomux_v3_cfg_t 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), + IMX8MQ_PAD_UART2_RXD__UART2_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + IMX8MQ_PAD_UART2_TXD__UART2_TX | MUX_PAD_CTRL(UART_PAD_CTRL), + IMX8MQ_PAD_UART3_RXD__UART3_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + IMX8MQ_PAD_UART3_TXD__UART3_TX | MUX_PAD_CTRL(UART_PAD_CTRL), + IMX8MQ_PAD_ECSPI2_SCLK__UART4_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + IMX8MQ_PAD_ECSPI2_MOSI__UART4_TX | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +#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 = 1; + break; + } + + return ret; +} + +#define USDHC_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | \ + PAD_CTL_FSEL1) +#define USDHC_GPIO_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_DSE1) + +static const iomux_v3_cfg_t 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 const iomux_v3_cfg_t usdhc2_pads[] = { + IMX8MQ_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0x16 */ + IMX8MQ_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_RESET_B__GPIO2_IO19 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL), +}; + +static struct fsl_esdhc_cfg usdhc_cfg[2] = { + {USDHC1_BASE_ADDR, 0, 8}, +#ifndef CONFIG_SPL_BUILD + {USDHC2_BASE_ADDR, 0, 4}, +#endif +}; + +int board_mmc_init(struct bd_info *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++) { + log_debug("Initializing FSL USDHC port %d\n", 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: + log_err("Warning: USDHC controller(%d) not supported\n", i + 1); + return -EINVAL; + } + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); + if (ret) + return ret; + } + + return 0; +} + +#define LDO_VOLT_EN BIT(6) + +/* + * Disable the charger - it will be re-enabled in u-boot + */ +void disable_charger_bq25896(void) +{ + u8 val; + int timeout = 1000; // ms + + /* Set the i2c bus */ + i2c_set_bus_num(3); + + /* disable ship mode if BATFET_DLY is set */ + val = i2c_reg_read(0x6a, 0x09); + log_debug("REG09 0x%x\n", val); + if (val & 0x28) { + val = val & ~0x28; + i2c_reg_write(0x6a, 0x09, val); + } + + /* disable and trigger DPDM, ICO, HVDCP and MaxCharge */ + val = i2c_reg_read(0x6a, 0x02); + log_debug("REG02 0x%x\n", val); + val &= 0xe0; + i2c_reg_write(0x6a, 0x02, val); + + /* disable charger and enable BAT_LOADEN */ + val = i2c_reg_read(0x6a, 0x03); + log_debug("REG03 0x%x\n", val); + val = (val | 0x80) & ~0x10; + i2c_reg_write(0x6a, 0x03, val); + + mdelay(10); + + /* force ADC conversions */ + val = i2c_reg_read(0x6a, 0x02); + log_debug("REG02 0x%x\n", val); + val = (val | 0x80) & ~0x40; + i2c_reg_write(0x6a, 0x02, val); + + do { + mdelay(10); + timeout -= 10; + } while ((i2c_reg_read(0x6a, 0x02) & 0x80) && (timeout > 0)); + + /* enable STAT pin */ + val = i2c_reg_read(0x6a, 0x07); + log_debug("REG07 0x%x\n", val); + val = val & ~0x40; + i2c_reg_write(0x6a, 0x07, val); + + /* check VBUS */ + val = i2c_reg_read(0x6a, 0x11); + log_debug("VBUS good %d\n", (val >> 7) & 1); + log_debug("VBUS mV %d\n", (val & 0x7f) * 100 + 2600); + + /* check VBAT */ + val = i2c_reg_read(0x6a, 0x0e); + log_debug("VBAT mV %d\n", (val & 0x7f) * 20 + 2304); + + /* limit the VINDPM to 3.9V */ + i2c_reg_write(0x6a, 0x0d, 0x8d); + + /* set the max voltage to 4.192V */ + val = i2c_reg_read(0x6a, 0x6); + val = (val & ~0xFC) | 0x16 << 2; + i2c_reg_write(0x6a, 0x6, val); + + /* set the SYS_MIN to 3.7V */ + val = i2c_reg_read(0x6a, 0x3); + val = val | 0xE; + i2c_reg_write(0x6a, 0x3, val); + + /* disable BAT_LOADEN */ + val = i2c_reg_read(0x6a, 0x03); + log_debug("REG03 0x%x\n", val); + val = val & ~0x80; + i2c_reg_write(0x6a, 0x03, val); +} + +#define I2C_PMIC 0 + +int power_bd71837_init(unsigned char bus) +{ + static const char name[] = BD718XX_REGULATOR_DRIVER; + struct pmic *p = pmic_alloc(); + + if (!p) { + log_err("%s: POWER allocation error!\n", __func__); + return -ENOMEM; + } + + p->name = name; + p->interface = I2C_PMIC; + p->number_of_regs = BD718XX_MAX_REGISTER; + p->hw.i2c.addr = CONFIG_POWER_BD71837_I2C_ADDR; + p->hw.i2c.tx_num = 1; + p->bus = bus; + + return 0; +} + +int power_init_board(void) +{ + struct pmic *p; + int ldo[] = {BD718XX_LDO5_VOLT, BD718XX_LDO6_VOLT, + BD71837_LDO7_VOLT}; + u32 val; + int i, rv; + + /* Set the i2c bus */ + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); + + /* + * Init PMIC + */ + rv = power_bd71837_init(CONFIG_POWER_BD71837_I2C_BUS); + if (rv) { + log_err("%s: power_bd71837_init(%d) error %d\n", __func__, + CONFIG_POWER_BD71837_I2C_BUS, rv); + goto out; + } + + p = pmic_get(BD718XX_REGULATOR_DRIVER); + if (!p) { + log_err("%s: pmic_get(%s) failed\n", __func__, BD718XX_REGULATOR_DRIVER); + rv = -ENODEV; + goto out; + } + + rv = pmic_probe(p); + if (rv) { + log_err("%s: pmic_probe() error %d\n", __func__, rv); + goto out; + } + + /* + * Unlock all regs + */ + pmic_reg_write(p, BD718XX_REGLOCK, 0); + + /* find the reset cause */ + pmic_reg_read(p, 0x29, &val); + log_debug("%s: reset cause %d\n", __func__, val); + + /* + * Reconfigure default voltages and disable: + * - BUCK3: VDD_GPU_0V9 (1.00 -> 0.90) + * - BUCK4: VDD_VPU_0V9 (1.00 -> 0.90) + */ + pmic_reg_write(p, BD71837_BUCK3_VOLT_RUN, 0x14); + pmic_reg_write(p, BD71837_BUCK4_VOLT_RUN, 0x14); + + /* + * Enable PHYs voltages: LDO5-7 + */ + for (i = 0; i < ARRAY_SIZE(ldo); i++) { + rv = pmic_reg_read(p, ldo[i], &val); + if (rv) { + log_err("%s: pmic_read(%x) error %d\n", __func__, + ldo[i], rv); + continue; + } + + pmic_reg_write(p, ldo[i], val | LDO_VOLT_EN); + } + + udelay(500); + + rv = 0; +out: + return rv; +} + +void spl_board_init(void) +{ + init_usb_clk(); + + if (is_usb_boot()) + puts("USB Boot\n"); + else + puts("Normal Boot\n"); +} + +void board_boot_order(u32 *spl_boot_list) +{ + if (is_usb_boot()) + spl_boot_list[0] = BOOT_DEVICE_BOARD; + else + spl_boot_list[0] = BOOT_DEVICE_MMC1; +} + +int board_fit_config_name_match(const char *name) +{ + /* Just empty function now - can't decide what to choose */ + return 0; +} + +void board_init_f(ulong dummy) +{ + int ret; + + /* Clear global data */ + memset((void *)gd, 0, sizeof(gd_t)); + + arch_cpu_init(); + + init_uart_clk(CONSOLE_UART_CLK); + imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); + +#ifdef CONSOLE_ON_UART4 + gpio_request(WIFI_EN, "WIFI_EN"); + gpio_direction_output(WIFI_EN, 1); +#endif + + board_early_init_f(); + + timer_init(); + + preloader_console_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + ret = spl_init(); + if (ret) { + log_err("spl_init() failed: %d\n", ret); + hang(); + } + + enable_tzc380(); + + printf("Initializing pinmux\n"); + init_pinmux(); + gpio_direction_output(LED_G, 1); + gpio_direction_output(MOTO, 1); + mdelay(50); + gpio_direction_output(MOTO, 0); + + /* Enable and configure i2c buses not used below */ + setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); + setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info3); + setup_i2c(3, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info4); + + power_init_board(); + + disable_charger_bq25896(); + + /* initialize this for M4 even if u-boot doesn't have SF_CMD */ + printf("Initializing ECSPI\n"); + board_ecspi_init(); + + /* DDR initialization */ + printf("Initializing DRAM\n"); + spl_dram_init(); +} + diff --git a/configs/librem5_defconfig b/configs/librem5_defconfig new file mode 100644 index 0000000000..23f4260403 --- /dev/null +++ b/configs/librem5_defconfig @@ -0,0 +1,120 @@ +CONFIG_ARM=y +CONFIG_ARCH_IMX8M=y +CONFIG_SYS_TEXT_BASE=0x40200000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_ENV_SIZE=0x2000 +CONFIG_ENV_OFFSET=0x3FE000 +CONFIG_SYS_I2C_MXC_I2C1=y +CONFIG_SYS_I2C_MXC_I2C2=y +CONFIG_SYS_I2C_MXC_I2C3=y +CONFIG_SYS_I2C_MXC_I2C4=y +CONFIG_DM_GPIO=y +CONFIG_DEFAULT_DEVICE_TREE="imx8mq-librem5" +CONFIG_SPL_TEXT_BASE=0x7E1000 +CONFIG_TARGET_LIBREM5=y +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL=y +CONFIG_IMX_BOOTAUX=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_SYS_LOAD_ADDR=0x40480000 +CONFIG_FIT=y +CONFIG_FIT_EXTERNAL_OFFSET=0x3000 +CONFIG_SPL_LOAD_FIT=y +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_OF_SYSTEM_SETUP=y +CONFIG_ARCH_MISC_INIT=y +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_BOARD_LATE_INIT=y +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SPL_I2C=y +CONFIG_SPL_POWER=y +CONFIG_SPL_USB_GADGET=y +CONFIG_SPL_USB_SDP_SUPPORT=y +CONFIG_SPL_WATCHDOG=y +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_FUSE=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_SDP=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_WARN=y +# CONFIG_SPL_BLK is not set +CONFIG_SAVED_DRAM_TIMING_BASE=0x40000000 +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x43000000 +CONFIG_FASTBOOT_BUF_SIZE=0x40000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_UUU_SUPPORT=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_MMC_BOOT_SUPPORT=y +CONFIG_FASTBOOT_MMC_USER_SUPPORT=y +CONFIG_FASTBOOT_CMD_OEM_PARTCONF=y +CONFIG_FASTBOOT_CMD_OEM_BOOTBUS=y +# CONFIG_SPL_DM_GPIO is not set +CONFIG_GPIO_HOG=y +CONFIG_DM_GPIO_LOOKUP_LABEL=y +CONFIG_MXC_GPIO=y +CONFIG_DM_I2C=y +# CONFIG_SPL_DM_I2C is not set +CONFIG_SPL_SYS_I2C_LEGACY=y +CONFIG_SYS_I2C_EARLY_INIT=y +CONFIG_SYS_MXC_I2C1_SPEED=50000 +CONFIG_SYS_MXC_I2C2_SPEED=50000 +CONFIG_SYS_MXC_I2C3_SPEED=50000 +CONFIG_SYS_MXC_I2C4_SPEED=50000 +CONFIG_SYS_I2C_SPEED=50000 +CONFIG_LED=y +CONFIG_LED_BLINK=y +CONFIG_LED_GPIO=y +CONFIG_MISC=y +# CONFIG_SPL_DM_MMC is not set +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_FSL_USDHC=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_DM_ETH=y +CONFIG_PHY=y +CONFIG_PHY_IMX8MQ_USB=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_IMX8M=y +CONFIG_POWER_LEGACY=y +CONFIG_POWER_DOMAIN=y +CONFIG_IMX8M_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_POWER_I2C=y +CONFIG_DM_RESET=y +CONFIG_MXC_UART=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_MXC_SPI=y +CONFIG_DM_THERMAL=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Purism" +CONFIG_USB_GADGET_VENDOR_NUM=0x0525 +CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 +CONFIG_SDP_LOADADDR=0x40400000 diff --git a/doc/board/purism/librem5/librem5.rst b/doc/board/purism/librem5/librem5.rst new file mode 100644 index 0000000000..d380d48c71 --- /dev/null +++ b/doc/board/purism/librem5/librem5.rst @@ -0,0 +1,60 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Librem5 +========== + +U-Boot for the Purism Librem5 phone + +Quick Start +----------- + +- Build the ARM Trusted firmware binary +- Get ddr and hdmi firmware +- Build U-Boot + +Get and Build the ARM Trusted firmware +-------------------------------------- + +Note: srctree is U-Boot source directory +Get ATF from: https://source.puri.sm/Librem5/arm-trusted-firmware +branch: librem5 + +.. code-block:: bash + + $ make PLAT=imx8mq bl31 + $ cp build/imx8mq/release/bl31.bin $(builddir) + +Get the ddr and hdmi firmware +----------------------------- + +.. code-block:: bash + + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.10.bin + $ chmod +x firmware-imx-8.10.bin + $ ./firmware-imx-8.10.bin + $ cp firmware-imx-8.10/firmware/hdmi/cadence/signed_hdmi_imx8m.bin $(builddir) + $ cp firmware-imx-8.10/firmware/ddr/synopsys/lpddr4*.bin $(builddir) + +Build U-Boot +------------ + +.. code-block:: bash + + $ export CROSS_COMPILE=aarch64-linux-gnu + $ make librem5_defconfig + $ make flash.bin + +Burn the flash.bin +------------------ + +Use uuu to burn flash.bin. Power on the phone while holding vol+ to get it +into uuu mode. + +.. code-block:: bash + + $ git clone https://source.puri.sm/Librem5/librem5-devkit-tools.git + $ cd librem5-devkit-tools + $ cp $(builddir)/flash.bin files/ + $ uuu uuu_scripts/u-boot_flash_librem5.lst + +Reboot the phone. diff --git a/include/configs/librem5.h b/include/configs/librem5.h new file mode 100644 index 0000000000..aca157d6dc --- /dev/null +++ b/include/configs/librem5.h @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2017 NXP + * Copyright 2018 Emcraft Systems + * Copyright 2019 Purism + * + */ + +#ifndef __LIBREM5_H +#define __LIBREM5_H + +/* #define DEBUG */ + +#include <version.h> +#include <linux/sizes.h> +#include <asm/arch/imx-regs.h> + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_CSF_SIZE 0x2000 /* 8K region */ +#endif + +#define CONFIG_SPL_MAX_SIZE (148 * 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_SPL_THERM_SUPPORT +#define CONFIG_SPL_WATCHDOG_SUPPORT +#define CONFIG_SPL_DRIVERS_MISC_SUPPORT +#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv8/u-boot-spl.lds" +#define CONFIG_SPL_STACK 0x187FF0 +#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_SPL_STACK_R_ADDR 0x42300000 +#define CONFIG_SPL_STACK_R +#define CONFIG_SYS_SPL_MALLOC_START 0x42200000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x80000 /* 512 KB */ +#define CONFIG_SYS_ICACHE_OFF +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_MALLOC_F_ADDR 0x182000 /* malloc f used before GD_FLG_FULL_MALLOC_INIT */ + +#define CONFIG_SPL_ABORT_ON_RAW_IMAGE /* For RAW image gives a error info not panic */ + +#undef CONFIG_SPL_DM_PMIC +#undef CONFIG_SPL_DM_I2C +#undef CONFIG_SPL_DM_PMIC_BD71837 +#undef CONFIG_DM_USB +#undef CONFIG_SPL_DM_USB +#undef CONFIG_USB_DWC3_GENERIC +#undef CONFIG_DEVRES + +#define CONFIG_SYS_I2C + +#define CONFIG_POWER_BD71837 +#define CONFIG_POWER_BD71837_I2C_BUS 0 +#define CONFIG_POWER_BD71837_I2C_ADDR 0x4B + +#define CONFIG_SPL_DMA_SUPPORT + +#define CONFIG_SYS_FSL_USDHC_NUM 1 + +#else /* CONFIG_SPL_BUILD*/ + +#define CONFIG_SYS_FSL_USDHC_NUM 2 + +#define CONFIG_USB_MAX_CONTROLLER_COUNT 1 + +#define CONFIG_USBD_HS + +#define CONFIG_USB_GADGET_VBUS_DRAW 2 + +#endif /* CONFIG_SPL_BUILD*/ + +#define CONSOLE_ON_UART1 +#define CONFIG_BAUDRATE 115200 + +#ifdef CONSOLE_ON_UART1 +#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR +#define CONSOLE_UART_CLK 0 +#define CONSOLE "ttymxc0" +#elif defined(CONSOLE_ON_UART2) +#define CONFIG_MXC_UART_BASE UART2_BASE_ADDR +#define CONSOLE_UART_CLK 1 +#define CONSOLE "ttymxc1" +#elif defined(CONSOLE_ON_UART3) +#define CONFIG_MXC_UART_BASE UART3_BASE_ADDR +#define CONSOLE_UART_CLK 2 +#define CONSOLE "ttymxc2" +#elif defined(CONSOLE_ON_UART4) +#define CONFIG_MXC_UART_BASE UART4_BASE_ADDR +#define CONSOLE_UART_CLK 3 +#define CONSOLE "ttymxc3" +#else +#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR +#define CONSOLE_UART_CLK 0 +#define CONSOLE "ttymxc0" +#endif + +#define CONFIG_REMAKE_ELF + +#define CONFIG_BOARD_POSTCLK_INIT + +/* Flat Device Tree Definitions */ +#define CONFIG_OF_BOARD_SETUP + +#ifndef CONFIG_SPL_BUILD +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 0) \ + func(MMC, mmc, 1) \ + func(USB, usb, 0) \ + func(PXE, pxe, na) \ + func(DHCP, dhcp, na) +#include <config_distro_bootcmd.h> +#else +#define BOOTENV +#endif + +/* Initial environment variables */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "scriptaddr=0x80000000\0" \ + "pxefile_addr_r=0x80100000\0" \ + "kernel_addr_r=0x80800000\0" \ + "fdt_addr_r=0x83000000\0" \ + "ramdisk_addr_r=0x83800000\0" \ + "console=" CONSOLE ",115200\0" \ + "bootargs=u_boot_version=" PLAIN_VERSION "\0" \ + "stdin=nc,serial\0" \ + "stdout=nc,serial\0" \ + "stderr=nc,serial\0" \ + BOOTENV + +/* Link Definitions */ +#define CONFIG_SYS_TEXT_BASE 0x40200000 + +#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_MMCROOT "/dev/mmcblk0p2" /* USDHC1 */ + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define PHYS_SDRAM 0x40000000 +#define PHYS_SDRAM_SIZE 0xc0000000 /* 3GB LPDDR4 one Rank */ + +#define CONFIG_SYS_ALT_MEMTEST + +/* Monitor Command Prompt */ +#undef CONFIG_SYS_PROMPT +#define CONFIG_SYS_PROMPT "u-boot=> " +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#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_SYS_FSL_ESDHC_ADDR 0 + +#define CONFIG_SYS_MMC_IMG_LOAD_PART 1 + +#ifdef CONFIG_CMD_SF +#define CONFIG_SF_DEFAULT_BUS 0 +#define CONFIG_SF_DEFAULT_CS 0 +#endif +#endif
participants (1)
-
Angus Ainslie