From 765ec2edd9a27f6337b51d6d38ceb5f9f8755ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Thu, 23 Jul 2026 15:56:28 -0300 Subject: [PATCH 01/37] board: purism: Add support for the Librem5 devkit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although it has similar naming the Librem 5 Devkit is a completely different design from the Librem 5 phone. It uses an imx8mq SOM from Emcraft, a separate HDMI port instead of DisplayPort, different USB-C chip, panel, etc. This is based on a Emcraft's SOM documentation, Purism's downstream fork and the available schematics of the devkit. Link: https://developer.puri.sm/Librem5/Development_Environment/Boards/imx8.html Link: https://source.puri.sm/Librem5/dvk-mx8m-bsb Co-authored-by: Angus Ainslie Co-authored-by: Manuel Traut Signed-off-by: Manuel Traut Tested-by: Manuel Traut Signed-off-by: Guido Günther [fabio: Removed the arch/arm/dts/Makefile entry that does not apply and it is not needed as the board uses OF_UPSTREAM] Signed-off-by: Fabio Estevam --- .../arm/dts/imx8mq-librem5-devkit-u-boot.dtsi | 11 + arch/arm/mach-imx/imx8m/Kconfig | 7 + board/purism/librem5-devkit/Kconfig | 18 + board/purism/librem5-devkit/MAINTAINERS | 8 + board/purism/librem5-devkit/Makefile | 13 + .../librem5-devkit/imximage-8mq-lpddr4.cfg | 9 + board/purism/librem5-devkit/librem5-devkit.c | 77 ++ .../purism/librem5-devkit/librem5-devkit.env | 20 + board/purism/librem5-devkit/lpddr4_timing.c | 931 ++++++++++++++++++ .../purism/librem5-devkit/lpddr4_timing_b0.c | 794 +++++++++++++++ board/purism/librem5-devkit/spl.c | 371 +++++++ configs/librem5-devkit_defconfig | 183 ++++ doc/board/purism/index.rst | 1 + doc/board/purism/librem5-devkit.rst | 56 ++ include/configs/librem5-devkit.h | 36 + 15 files changed, 2535 insertions(+) create mode 100644 arch/arm/dts/imx8mq-librem5-devkit-u-boot.dtsi create mode 100644 board/purism/librem5-devkit/Kconfig create mode 100644 board/purism/librem5-devkit/MAINTAINERS create mode 100644 board/purism/librem5-devkit/Makefile create mode 100644 board/purism/librem5-devkit/imximage-8mq-lpddr4.cfg create mode 100644 board/purism/librem5-devkit/librem5-devkit.c create mode 100644 board/purism/librem5-devkit/librem5-devkit.env create mode 100644 board/purism/librem5-devkit/lpddr4_timing.c create mode 100644 board/purism/librem5-devkit/lpddr4_timing_b0.c create mode 100644 board/purism/librem5-devkit/spl.c create mode 100644 configs/librem5-devkit_defconfig create mode 100644 doc/board/purism/librem5-devkit.rst create mode 100644 include/configs/librem5-devkit.h diff --git a/arch/arm/dts/imx8mq-librem5-devkit-u-boot.dtsi b/arch/arm/dts/imx8mq-librem5-devkit-u-boot.dtsi new file mode 100644 index 00000000000..46a4dfe4e8a --- /dev/null +++ b/arch/arm/dts/imx8mq-librem5-devkit-u-boot.dtsi @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +#include "imx8mq-u-boot.dtsi" + +&pinctrl_uart1 { + bootph-pre-ram; +}; + +&uart1 { /* console */ + bootph-pre-ram; +}; diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig index 5f7d7e4c66e..c03c4e72101 100644 --- a/arch/arm/mach-imx/imx8m/Kconfig +++ b/arch/arm/mach-imx/imx8m/Kconfig @@ -437,6 +437,12 @@ config TARGET_LIBREM5 select IMX8M_LPDDR4 imply OF_UPSTREAM +config TARGET_LIBREM5_DEVKIT + bool "Purism Librem5 Devkit" + select IMX8MQ + select SUPPORT_SPL + select IMX8M_LPDDR4 + endchoice source "board/advantech/imx8mp_rsb3720a1/Kconfig" @@ -469,6 +475,7 @@ source "board/phytec/phycore_imx8mm/Kconfig" source "board/phytec/phycore_imx8mp/Kconfig" source "board/polyhex/imx8mp_debix_model_a/Kconfig" source "board/purism/librem5/Kconfig" +source "board/purism/librem5-devkit/Kconfig" source "board/ronetix/imx8mq-cm/Kconfig" source "board/technexion/pico-imx8mq/Kconfig" source "board/variscite/imx8mn_var_som/Kconfig" diff --git a/board/purism/librem5-devkit/Kconfig b/board/purism/librem5-devkit/Kconfig new file mode 100644 index 00000000000..3e069690142 --- /dev/null +++ b/board/purism/librem5-devkit/Kconfig @@ -0,0 +1,18 @@ +if TARGET_LIBREM5_DEVKIT + +config SYS_BOARD + default "librem5-devkit" + +config SYS_VENDOR + default "purism" + +config SYS_CONFIG_NAME + default "librem5-devkit" + +config ENV_SOURCE_FILE + default "librem5-devkit" + +config IMX_CONFIG + default "board/purism/librem5-devkit/imximage-8mq-lpddr4.cfg" + +endif diff --git a/board/purism/librem5-devkit/MAINTAINERS b/board/purism/librem5-devkit/MAINTAINERS new file mode 100644 index 00000000000..95bdc17cc8f --- /dev/null +++ b/board/purism/librem5-devkit/MAINTAINERS @@ -0,0 +1,8 @@ +PURISM LIBREM5 DEVKIT +M: Guido Günther +R: team@phosh.mobi +S: Supported +F: arch/arm/dts/imx8mq-librem5-devkit-u-boot.dtsi +F: board/purism/librem5-devkit/ +F: configs/librem5-devkit_defconfig +F: include/configs/librem5-devkit.h diff --git a/board/purism/librem5-devkit/Makefile b/board/purism/librem5-devkit/Makefile new file mode 100644 index 00000000000..95044811186 --- /dev/null +++ b/board/purism/librem5-devkit/Makefile @@ -0,0 +1,13 @@ +# +# Copyright 2017 NXP +# Copyright 2026 Phosh.mobi e.V. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += librem5-devkit.o + +ifdef CONFIG_XPL_BUILD +obj-y += spl.o +obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4_timing.o lpddr4_timing_b0.o +endif diff --git a/board/purism/librem5-devkit/imximage-8mq-lpddr4.cfg b/board/purism/librem5-devkit/imximage-8mq-lpddr4.cfg new file mode 100644 index 00000000000..d102e70a954 --- /dev/null +++ b/board/purism/librem5-devkit/imximage-8mq-lpddr4.cfg @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2021 NXP + */ + +FIT +BOOT_FROM sd +SIGNED_HDMI signed_hdmi_imx8m.bin +LOADER u-boot-spl-ddr.bin 0x7E1000 diff --git a/board/purism/librem5-devkit/librem5-devkit.c b/board/purism/librem5-devkit/librem5-devkit.c new file mode 100644 index 00000000000..bbafd392187 --- /dev/null +++ b/board/purism/librem5-devkit/librem5-devkit.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + * 2026 Phosh.mobi e.V. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int board_early_init_f(void) +{ + return 0; +} + +#if IS_ENABLED(CONFIG_FEC_MXC) +int board_phy_config(struct phy_device *phydev) +{ + /* enable rgmii rxc skew and phy mode select to RGMII copper */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); + + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); + + if (phydev->drv->config) + phydev->drv->config(phydev); + return 0; +} +#endif + +#if IS_ENABLED(CONFIG_LOAD_ENV_FROM_MMC_BOOT_PARTITION) +uint board_mmc_get_env_part(struct mmc *mmc) +{ + uint part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config); + + if (part == EMMC_BOOT_PART_USER) + part = EMMC_HWPART_DEFAULT; + return part; +} +#endif + +int board_init(void) +{ + return 0; +} + +int board_late_init(void) +{ + if (IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)) { + char fdt_str[50]; + + env_set("board_name", "librem5-devkit"); + /* Shipped boards have PCB rev. 0.1.2 */ + env_set("board_rev", "0"); + printf("Board name: %s\n", env_get("board_name")); + printf("Board rev: %s\n", env_get("board_rev")); + + sprintf(fdt_str, "freescale/imx8mq-librem5-devkit.dtb"); + env_set("fdtfile", fdt_str); + } + + if (is_usb_boot()) { + puts("USB Boot\n"); + env_set("bootcmd", "fastboot 0"); + } + + return 0; +} diff --git a/board/purism/librem5-devkit/librem5-devkit.env b/board/purism/librem5-devkit/librem5-devkit.env new file mode 100644 index 00000000000..2acec768c06 --- /dev/null +++ b/board/purism/librem5-devkit/librem5-devkit.env @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ + +boot_targets=mmc0 dhcp +bootmeths=efi extlinux script +bootm_size=0x10000000 +console=ttymxc0,115200 +fdt_addr_r=0x43000000 +fdtfile=DEFAULT_FDT_FILE +initrd_addr=0x43800000 +image=Image +kernel_addr_r=CONFIG_SYS_LOAD_ADDR +loadaddr=CONFIG_SYS_LOAD_ADDR +mmcautodetect=yes +mmcdev=CONFIG_ENV_MMC_DEVICE_INDEX +mmcpart=1 +mmcroot=/dev/mmcblk0p1 +scriptaddr=CONFIG_SYS_LOAD_ADDR +mmcargs=setenv bootargs console=${console} root=${mmcroot} rootwait rw +loadimage=load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image} +loadfdt=load mmc ${mmcdev}:${mmcpart} ${fdt_addr_r} ${fdtfile} diff --git a/board/purism/librem5-devkit/lpddr4_timing.c b/board/purism/librem5-devkit/lpddr4_timing.c new file mode 100644 index 00000000000..17867319c55 --- /dev/null +++ b/board/purism/librem5-devkit/lpddr4_timing.c @@ -0,0 +1,931 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include +#include +#include + +#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-devkit/lpddr4_timing_b0.c b/board/purism/librem5-devkit/lpddr4_timing_b0.c new file mode 100644 index 00000000000..89ab6e082e8 --- /dev/null +++ b/board/purism/librem5-devkit/lpddr4_timing_b0.c @@ -0,0 +1,794 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include +#include +#include + +#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-devkit/spl.c b/board/purism/librem5-devkit/spl.c new file mode 100644 index 00000000000..26e01ed6ba4 --- /dev/null +++ b/board/purism/librem5-devkit/spl.c @@ -0,0 +1,371 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + * 2021 Purism + * 2026 Phosh.mobi e.V. + * + * Author: Guido Günther + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct dram_timing_info dram_timing_b0; + +void spl_dram_init(void) +{ + /* ddr init, the default SOM uses B0 */ + if ((get_cpu_rev() & 0xfff) == CHIP_REV_2_1) + ddr_init(&dram_timing); + else + ddr_init(&dram_timing_b0); +} + +#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; + return ret; + } + + return 1; +} + +#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 }, + { USDHC2_BASE_ADDR, 0, 4 }, +}; + +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 < CFG_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) + +#define I2C_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS) +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) +struct i2c_pads_info i2c_pad_info1 = { + .scl = { + .i2c_mode = IMX8MQ_PAD_I2C1_SCL__I2C1_SCL | PC, + .gpio_mode = IMX8MQ_PAD_I2C1_SCL__GPIO5_IO14 | PC, + .gp = IMX_GPIO_NR(5, 14), + }, + .sda = { + .i2c_mode = IMX8MQ_PAD_I2C1_SDA__I2C1_SDA | PC, + .gpio_mode = IMX8MQ_PAD_I2C1_SDA__GPIO5_IO15 | PC, + .gp = IMX_GPIO_NR(5, 15), + }, +}; + +#define I2C_PMIC 0 +#define POWER_BD71837_I2C_BUS 0 +#define POWER_BD71837_I2C_ADDR 0x4B + +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 = POWER_BD71837_I2C_ADDR; + p->hw.i2c.tx_num = 1; + p->bus = bus; + + return 0; +} + +#define PWR_EN IMX_GPIO_NR(1, 8) +#define HAPTIC_nEN IMX_GPIO_NR(5, 4) +#define IMU_INT IMX_GPIO_NR(3, 19) +#define TS_INT IMX_GPIO_NR(3, 0) +static const iomux_v3_cfg_t pwr_en_pads[] = { + IMX8MQ_PAD_GPIO1_IO08__GPIO1_IO8 | + MUX_PAD_CTRL(PAD_CTL_DSE6 | PAD_CTL_FSEL0), + IMX8MQ_PAD_SPDIF_RX__GPIO5_IO4 | + MUX_PAD_CTRL(PAD_CTL_DSE6 | PAD_CTL_FSEL1), + IMX8MQ_PAD_SAI5_RXFS__GPIO3_IO19 | MUX_PAD_CTRL(PAD_CTL_ODE), + IMX8MQ_PAD_NAND_ALE__GPIO3_IO0 | MUX_PAD_CTRL(PAD_CTL_ODE), +}; + +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(POWER_BD71837_I2C_BUS); + if (rv) { + log_err("%s: power_bd71837_init(%d) error %d\n", __func__, + 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); + } + + imx_iomux_v3_setup_multiple_pads(pwr_en_pads, ARRAY_SIZE(pwr_en_pads)); + + /* set IMU_INT as input */ + gpio_request(IMU_INT, "imu_int"); + gpio_direction_input(IMU_INT); + + /* set TS_INT as input */ + gpio_request(TS_INT, "ts_int"); + gpio_direction_output(TS_INT, 0); + + /* disable the haptic motor */ + gpio_request(HAPTIC_nEN, "haptic_en"); + gpio_direction_output(HAPTIC_nEN, 1); + + gpio_request(PWR_EN, "pwr_en"); + gpio_direction_output(PWR_EN, 1); + + udelay(500); + + rv = 0; +out: + return 0; +} + +void spl_board_init(void) +{ +} + +/* + * set some safe defaults for the battery charger + */ +int init_charger_bq25896(void) +{ + int ret; + u8 val; + + ret = i2c_set_bus_num(0); + if (ret < 0) + log_err("Failed to set i2c bus 0: %d", ret); + + /* limit the charge current to 1.6A */ + i2c_reg_write(0x6b, 0x12, 0x20); + + /* set the max voltage to 4.192V */ + val = i2c_reg_read(0x6b, 0x6); + val = (val & 0xFC) | 0x16 << 2; + i2c_reg_write(0x6b, 0x6, val); + + return 0; +} + +#define SPEAKER_PAD_MUTE_CTRL PAD_CTL_HYS | PAD_CTL_DSE1 +#define SPEAKER_MUTE_GPIO IMX_GPIO_NR(5, 3) +static const iomux_v3_cfg_t speaker_pad = IMX8MQ_PAD_SPDIF_TX__GPIO5_IO3 | + MUX_PAD_CTRL(SPEAKER_PAD_MUTE_CTRL); + +static void mute_speaker(void) +{ + imx_iomux_v3_setup_pad(speaker_pad); + gpio_request(SPEAKER_MUTE_GPIO, "speaker_mute"); + gpio_direction_output(SPEAKER_MUTE_GPIO, 0); +} + +void board_init_f(ulong dummy) +{ + int ret; + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + arch_cpu_init(); + + init_uart_clk(0); + + board_early_init_f(); + + timer_init(); + + ret = spl_early_init(); + if (ret) { + log_err("spl_early_init() failed: %d\n", ret); + hang(); + } + preloader_console_init(); + + enable_tzc380(); + + /* PMIC initialization */ + power_init_board(); + init_charger_bq25896(); + + mute_speaker(); + + /* DDR initialization */ + printf("Initializing DRAM\n"); + spl_dram_init(); + + init_clk_usdhc(0); + init_clk_usdhc(1); + + log_debug("Board init\n"); + board_init_r(NULL, 0); +} diff --git a/configs/librem5-devkit_defconfig b/configs/librem5-devkit_defconfig new file mode 100644 index 00000000000..a911b618113 --- /dev/null +++ b/configs/librem5-devkit_defconfig @@ -0,0 +1,183 @@ +CONFIG_ARM=y +CONFIG_ARCH_IMX8M=y +CONFIG_TEXT_BASE=0x40200000 +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_ENV_SIZE=0x2000 +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="freescale/imx8mq-librem5-devkit" +CONFIG_TARGET_LIBREM5_DEVKIT=y +CONFIG_DM_RESET=y +CONFIG_SYS_MONITOR_LEN=524288 +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_STACK=0x187ff0 +CONFIG_SPL_TEXT_BASE=0x7E1000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x180000 +CONFIG_SPL_BSS_MAX_SIZE=0x2000 +CONFIG_SYS_LOAD_ADDR=0x40600000 +CONFIG_SPL=y +CONFIG_IMX_BOOTAUX=y +CONFIG_REMAKE_ELF=y +CONFIG_EFI_SECURE_BOOT=y +CONFIG_EFI_RT_VOLATILE_STORE=y +CONFIG_EFI_IP4_CONFIG2_PROTOCOL=y +CONFIG_EFI_HTTP_PROTOCOL=y +CONFIG_EFI_LOADER_BOUNCE_BUFFER=y +CONFIG_EFI_HTTP_BOOT=y +# CONFIG_ANDROID_BOOT_IMAGE is not set +CONFIG_FIT=y +CONFIG_FIT_EXTERNAL_OFFSET=0x3000 +CONFIG_FIT_SIGNATURE=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_BOOTSTD_FULL=y +# CONFIG_BOOTSTD_BOOTCOMMAND is not set +# CONFIG_BOOTMETH_VBE is not set +CONFIG_LEGACY_IMAGE_FORMAT=y +CONFIG_SD_BOOT=y +CONFIG_SD_BOOT_QSPI=y +CONFIG_BOOTDELAY=3 +CONFIG_OF_SYSTEM_SETUP=y +CONFIG_SYS_PBSIZE=1050 +CONFIG_SYS_CONSOLE_IS_IN_ENV=y +# CONFIG_SYS_DEVICE_NULLDEV is not set +CONFIG_BOARD_LATE_INIT=y +CONFIG_SPL_MAX_SIZE=0x25000 +CONFIG_SPL_BOARD_INIT=y +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_HAVE_INIT_STACK=y +CONFIG_SPL_SYS_MALLOC=y +CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y +CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x42200000 +CONFIG_SPL_SYS_MALLOC_SIZE=0x80000 +CONFIG_SPL_SYS_MMCSD_RAW_MODE=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x300 +CONFIG_SPL_I2C=y +CONFIG_SPL_POWER=y +CONFIG_SPL_WATCHDOG=y +CONFIG_SYS_PROMPT="u-boot=> " +# CONFIG_CMD_BOOTDEV is not set +# CONFIG_CMD_BOOTMETH is not set +CONFIG_CMD_NVEDIT_EFI=y +CONFIG_CMD_MEMTEST=y +CONFIG_SYS_ALT_MEMTEST=y +CONFIG_CMD_CLK=y +CONFIG_CMD_FUSE=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_SDP=y +CONFIG_CMD_WRITE=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_EFIDEBUG=y +CONFIG_CMD_SYSBOOT=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_UPSTREAM=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_FAT=y +CONFIG_ENV_FAT_DEVICE_AND_PART="1:1" +CONFIG_ENV_RELOC_GD_ENV_ADDR=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_LWIP=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPL_DM=y +# CONFIG_SPL_BLK is not set +CONFIG_EFI_MEDIA=y +CONFIG_BUTTON=y +CONFIG_BUTTON_GPIO=y +CONFIG_SAVED_DRAM_TIMING_BASE=0x40000000 +CONFIG_DMA=y +CONFIG_DMA_CHANNELS=y +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_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_PWRSEQ=y +CONFIG_MMC_BROKEN_CD=y +# CONFIG_SPL_DM_MMC is not set +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y +CONFIG_MMC_HS400_ES_SUPPORT=y +CONFIG_MMC_HS400_SUPPORT=y +CONFIG_FSL_USDHC=y +CONFIG_MTD=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_PHY_GIGE=y +CONFIG_FEC_MXC=y +CONFIG_RGMII=y +CONFIG_MII=y +CONFIG_PHYLIB=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_SERIAL=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_SPL_DM_USB_GADGET=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_SPL_USB_DWC3_GENERIC=y +CONFIG_USB_GADGET=y +CONFIG_SPL_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Purism" +CONFIG_USB_GADGET_VENDOR_NUM=0x0525 +CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 +CONFIG_SDP_LOADADDR=0x40400000 +CONFIG_USB_FUNCTION_ACM=y +CONFIG_SPL_USB_SDP_SUPPORT=y +CONFIG_FS_EXFAT=y +CONFIG_FS_FAT_HANDLE_SECTOR_SIZE_MISMATCH=y +CONFIG_SPL_CRC8=y +# CONFIG_HEXDUMP is not set diff --git a/doc/board/purism/index.rst b/doc/board/purism/index.rst index a9cdc312d46..0225aa7f3aa 100644 --- a/doc/board/purism/index.rst +++ b/doc/board/purism/index.rst @@ -7,3 +7,4 @@ Purism SPC :maxdepth: 2 librem5 + librem5-devkit diff --git a/doc/board/purism/librem5-devkit.rst b/doc/board/purism/librem5-devkit.rst new file mode 100644 index 00000000000..4a6dba45a9c --- /dev/null +++ b/doc/board/purism/librem5-devkit.rst @@ -0,0 +1,56 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Librem5 +======= + +U-Boot for the Purism Librem 5 development kit + +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 CROSS_COMPILE=aarch64-linux-gnu- bl31 + $ cp build/imx8mq/release/bl31.bin $(builddir) + +Get the ddr and display port firmware +------------------------------------- + +.. code-block:: bash + + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.15.bin + $ chmod +x firmware-imx-8.15.bin + $ ./firmware-imx-8.15.bin + $ cp firmware-imx-8.15/firmware/hdmi/cadence/signed_hdmi_imx8m.bin $(builddir) + $ cp firmware-imx-8.15/firmware/ddr/synopsys/lpddr4*.bin $(builddir) + +Build U-Boot +------------ + +.. code-block:: bash + + $ export CROSS_COMPILE=aarch64-linux-gnu- + $ make librem5_devkit_defconfig + $ make ARCH=arm + +Burn the flash.bin +------------------ + +Write the flash.bin to the eMMC at offset 32KB: + +.. code-block:: bash + + $ sudo dd if=flash.bin of=/dev/mmc0 bs=1024 seek=32 conv=notrunc + +Reboot the devkit. diff --git a/include/configs/librem5-devkit.h b/include/configs/librem5-devkit.h new file mode 100644 index 00000000000..9ba6a70d58e --- /dev/null +++ b/include/configs/librem5-devkit.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2017 NXP + * 2018 Emcraft Systems + * 2022 Purism + * 2026 Phosh.mobi e.V. + */ + +#ifndef __LIBREM5_DEVKIT_H +#define __LIBREM5_DEVKIT_H + +/* #define DEBUG */ + +#include +#include +#include + +#define CFG_SYS_FSL_USDHC_NUM 2 + +/* UART */ +#define CFG_MXC_UART_BASE UART1_BASE_ADDR + +/* Link Definitions */ + +#define CFG_SYS_INIT_RAM_ADDR 0x40000000 +#define CFG_SYS_INIT_RAM_SIZE 0x80000 + +#define CFG_SYS_SDRAM_BASE 0x40000000 +#define PHYS_SDRAM 0x40000000 +#define PHYS_SDRAM_SIZE 0xc0000000 /* 3GB LPDDR4 one Rank */ + +/* Monitor Command Prompt */ + +#define CFG_SYS_FSL_ESDHC_ADDR 0 + +#endif From 0d61a1fda618964b1eaea5ab3a1f89d45c01ab91 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 27 Jul 2026 11:18:06 -0300 Subject: [PATCH 02/37] imx9: bootaux: Support authenticate signed Mcore container image Add new command bootaux_cntr to replace bootaux in secure boot (CONFIG_AHAB_BOOT=y) to authenticate signed M33 core image. The M33 image must be packed in container format and signed. bootaux_cntr supports Mcore image loaded to TCM or run as FlexSPI NOR XIP. Signed-off-by: Ye Li [fabio: Adapted to use gd->dram[i]] Signed-off-by: Fabio Estevam --- arch/arm/include/asm/arch-imx9/imx-regs.h | 12 ++ arch/arm/mach-imx/imx9/imx_bootaux.c | 215 ++++++++++++++++++++++ 2 files changed, 227 insertions(+) diff --git a/arch/arm/include/asm/arch-imx9/imx-regs.h b/arch/arm/include/asm/arch-imx9/imx-regs.h index fbf2e6a2b01..47d6ae9b559 100644 --- a/arch/arm/include/asm/arch-imx9/imx-regs.h +++ b/arch/arm/include/asm/arch-imx9/imx-regs.h @@ -47,6 +47,18 @@ #define SRC_MEDIA_RBASE (SRC_IPS_BASE_ADDR + 0x2400) #define SRC_M33P_RBASE (SRC_IPS_BASE_ADDR + 0x2800) +#define TCML_BASE_ADDR (0x201E0000UL) +#define TCML_BASE_MCORE_SEC_ADDR (0x1FFE0000UL) +#define TCML_BASE_MCORE_NSEC_ADDR (0x0FFE0000UL) +#define TCML_SIZE (0x20000U) +#define TCMU_BASE_ADDR (0x20200000UL) +#define TCMU_BASE_MCORE_SEC_ADDR (0x30000000UL) +#define TCMU_BASE_MCORE_NSEC_ADDR (0x20000000UL) +#define TCMU_SIZE (0x20000U) + +#define FLEXSPI_AHB_ADDR (0x28000000UL) +#define FLEXSPI_AHB_SIZE (0x8000000UL) + #define SRC_MIX_SLICE_FUNC_STAT_PSW_STAT BIT(0) #define SRC_MIX_SLICE_FUNC_STAT_RST_STAT BIT(2) #define SRC_MIX_SLICE_FUNC_STAT_ISO_STAT BIT(4) diff --git a/arch/arm/mach-imx/imx9/imx_bootaux.c b/arch/arm/mach-imx/imx9/imx_bootaux.c index 73f2e72263d..c49f80e84dd 100644 --- a/arch/arm/mach-imx/imx9/imx_bootaux.c +++ b/arch/arm/mach-imx/imx9/imx_bootaux.c @@ -9,6 +9,12 @@ #include #include #include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; int arch_auxiliary_core_check_up(u32 core_id) { @@ -47,6 +53,197 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr) return 0; } +static inline bool check_in_ddr(ulong addr) +{ + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { + if (gd->dram[i].size) { + if (addr >= gd->dram[i].start && + addr < (gd->dram[i].start + gd->dram[i].size)) + return true; + } + } + + return false; +} + +static inline bool check_in_tcm(ulong addr, bool mcore_view) +{ + if (mcore_view) { + if ((addr >= TCML_BASE_MCORE_SEC_ADDR && + addr < TCML_BASE_MCORE_SEC_ADDR + TCML_SIZE) || + (addr >= TCMU_BASE_MCORE_SEC_ADDR && + addr < TCMU_BASE_MCORE_SEC_ADDR + TCMU_SIZE)) + return true; + + if ((addr >= TCML_BASE_MCORE_NSEC_ADDR && + addr < TCML_BASE_MCORE_NSEC_ADDR + TCML_SIZE) || + (addr >= TCMU_BASE_MCORE_NSEC_ADDR && + addr < TCMU_BASE_MCORE_NSEC_ADDR + TCMU_SIZE)) + return true; + } else { + if ((addr >= TCML_BASE_ADDR && + addr < TCML_BASE_ADDR + TCML_SIZE) || + (addr >= TCMU_BASE_ADDR && + addr < TCMU_BASE_ADDR + TCMU_SIZE)) + return true; + } + return false; +} + +static inline bool check_in_flexspi(ulong addr) +{ + if (addr >= FLEXSPI_AHB_ADDR && addr < FLEXSPI_AHB_ADDR + FLEXSPI_AHB_SIZE) + return true; + + return false; +} + +#if IS_ENABLED(CONFIG_AHAB_BOOT) +static int authenticate_auxcore_container(ulong addr, ulong *entry) +{ + struct container_hdr *phdr; + int i, ret = 0; + u16 length; + struct boot_img_t *img; + unsigned long s, e; + + if (addr % 4) { + printf("Error: Image's address is not 4 byte aligned\n"); + return -EINVAL; + } + + if (!check_in_ddr(addr) && !check_in_tcm(addr, false) && !check_in_flexspi(addr)) { + printf("Error: Container's address is invalid\n"); + return -EINVAL; + } + + phdr = (struct container_hdr *)addr; + if (!valid_container_hdr(phdr)) { + printf("Error: Wrong container header\n"); + return -EFAULT; + } + + if (!phdr->num_images) { + printf("Error: Wrong container, no image found\n"); + return -EFAULT; + } + + length = phdr->length_lsb + (phdr->length_msb << 8); + + debug("container length %u\n", length); + + phdr = ahab_auth_cntr_hdr(phdr, length); + if (!phdr) { + ret = -EIO; + goto exit; + } + + /* Copy images to dest address */ + for (i = 0; i < phdr->num_images; i++) { + img = (struct boot_img_t *)((ulong)phdr + + sizeof(struct container_hdr) + + i * sizeof(struct boot_img_t)); + + /* Check Core ID of M core */ + if ((img->meta & 0xff) != 0) { + printf("Error: Wrong Image core ID, meta = 0x%x\n", img->meta); + ret = -EFAULT; + break; + } + + debug("img %d, dst 0x%x, src 0x%lx, size 0x%x\n", + i, (uint32_t)img->dst, img->offset + addr, img->size); + + if (check_in_flexspi(img->dst)) { + if (img->dst != img->offset + addr) { + printf("Error: Wrong Image[%u] load address 0x%llx\n", i, img->dst); + ret = -EFAULT; + break; + } + } else { + if (!check_in_ddr(img->dst) && !check_in_tcm(img->dst, false)) { + printf("Error: Invalid Image[%u] load address 0x%llx\n", + i, img->dst); + ret = -EFAULT; + break; + } + + memcpy((void *)img->dst, (const void *)(img->offset + addr), img->size); + + s = img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1); + e = ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1; + + flush_dcache_range(s, e); + } + + ret = ahab_verify_cntr_image(img, i); + if (ret) + goto exit; + + /* If the image is type of executable, set entry */ + if (entry && (img->hab_flags & 0xf) == 0x3) + *entry = img->entry; + } + +exit: + debug("ahab_auth_release, 0x%x\n", ret); + ahab_auth_release(); + + return ret; +} + +static int do_bootaux_cntr(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + ulong addr, entry; + int ret, up; + u32 core = 0; + u32 stop = 0; + + if (argc < 2) + return CMD_RET_USAGE; + + if (argc > 2) + core = simple_strtoul(argv[2], NULL, 10); + + if (argc > 3) + stop = simple_strtoul(argv[3], NULL, 10); + + up = arch_auxiliary_core_check_up(core); + if (up) { + printf("## Auxiliary core is already up\n"); + return CMD_RET_SUCCESS; + } + + addr = simple_strtoul(argv[1], NULL, 16); + + if (!addr) + return CMD_RET_FAILURE; + + printf("Authenticate auxcore container at 0x%lx\n", addr); + + ret = authenticate_auxcore_container(addr, &entry); + if (ret) { + printf("Authenticate container failed %d\n", ret); + return CMD_RET_FAILURE; + } + + if (!check_in_ddr(entry) && !check_in_tcm(entry, true) && + !check_in_flexspi(entry)) { + printf("Error: Image's entry 0x%lx is invalid\n", entry); + return CMD_RET_FAILURE; + } + + ret = arch_auxiliary_core_up(core, entry); + if (ret) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} +#else + /* * To i.MX6SX and i.MX7D, the image supported by bootaux needs * the reset vector at the head for the image, with SP and PC @@ -88,12 +285,20 @@ static int do_bootaux(struct cmd_tbl *cmdtp, int flag, int argc, if (!addr) return CMD_RET_FAILURE; + if (!check_in_ddr(addr) && !check_in_tcm(addr, true) && !check_in_flexspi(addr)) { + printf("Error: Image's address 0x%lx is invalid\n", addr); + printf(" Address should be memory from M core view,\n" + " For example: 0x1ffe0000 for TCML in secure\n"); + return CMD_RET_FAILURE; + } + ret = arch_auxiliary_core_up(core, addr); if (ret) return CMD_RET_FAILURE; return CMD_RET_SUCCESS; } +#endif static int do_stopaux(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) @@ -121,6 +326,15 @@ U_BOOT_CMD( " at address
\n" ); +#if IS_ENABLED(CONFIG_AHAB_BOOT) +U_BOOT_CMD( + bootaux_cntr, CONFIG_SYS_MAXARGS, 1, do_bootaux_cntr, + "Start auxiliary core", + " []\n" + " - start auxiliary core [] (default 0),\n" + " with signed container image at address
in A core view\n" +); +#else U_BOOT_CMD( bootaux, CONFIG_SYS_MAXARGS, 1, do_bootaux, "Start auxiliary core", @@ -128,3 +342,4 @@ U_BOOT_CMD( " - start auxiliary core [] (default 0),\n" " at address
of auxiliary core view\n" ); +#endif From bc92fd3aec26601ecc59e441098af6c657efd5b0 Mon Sep 17 00:00:00 2001 From: Alice Guo Date: Wed, 17 Jun 2026 22:14:44 +0800 Subject: [PATCH 03/37] imx9: bootaux: Support booting CM70, CM71 and CM33 sync cores Support booting CM70, CM71 and CM33 sync core image by bootaux command on iMX95, iMX94 and iMX952. (iMX95 and iMX952 only supports CM70). Each core uses different core id which is defined by SM and passed in SIP call. - CM33: 0 - CM70: 1 - CM71: 7 - CM33S: 8 Prior to run bootaux to start core, prepaux is needed before loading image. Below is example for booting CM70 TCM image on iMX95. =>fatload mmc 1:1 0x90000000 rpmsg.bin =>prepaux 1 =>cp.b 0x90000000 0x203c0000 ${filesize} =>bootaux 0 1 Signed-off-by: Alice Guo Signed-off-by: Ye Li Signed-off-by: Peng Fan Signed-off-by: Jacky Bai --- arch/arm/include/asm/arch-imx9/imx-regs.h | 18 +++ arch/arm/mach-imx/imx9/imx_bootaux.c | 186 ++++++++++++++++++---- arch/arm/mach-imx/imx9/scmi/soc.c | 33 +++- include/imx_sip.h | 2 + 4 files changed, 205 insertions(+), 34 deletions(-) diff --git a/arch/arm/include/asm/arch-imx9/imx-regs.h b/arch/arm/include/asm/arch-imx9/imx-regs.h index 47d6ae9b559..55f4f34e1bc 100644 --- a/arch/arm/include/asm/arch-imx9/imx-regs.h +++ b/arch/arm/include/asm/arch-imx9/imx-regs.h @@ -47,6 +47,16 @@ #define SRC_MEDIA_RBASE (SRC_IPS_BASE_ADDR + 0x2400) #define SRC_M33P_RBASE (SRC_IPS_BASE_ADDR + 0x2800) +#ifdef CONFIG_IMX94 +#define TCML_BASE_ADDR (0x209C0000UL) +#define TCML_BASE_MCORE_SEC_ADDR (0x1FFC0000UL) +#define TCML_BASE_MCORE_NSEC_ADDR (0x0FFC0000UL) +#define TCML_SIZE (0x40000U) +#define TCMU_BASE_ADDR (0x20A00000UL) +#define TCMU_BASE_MCORE_SEC_ADDR (0x30000000UL) +#define TCMU_BASE_MCORE_NSEC_ADDR (0x20000000UL) +#define TCMU_SIZE (0x40000U) +#else #define TCML_BASE_ADDR (0x201E0000UL) #define TCML_BASE_MCORE_SEC_ADDR (0x1FFE0000UL) #define TCML_BASE_MCORE_NSEC_ADDR (0x0FFE0000UL) @@ -55,6 +65,14 @@ #define TCMU_BASE_MCORE_SEC_ADDR (0x30000000UL) #define TCMU_BASE_MCORE_NSEC_ADDR (0x20000000UL) #define TCMU_SIZE (0x20000U) +#endif + +#define M7_TCML_BASE_ADDR (0x20380000UL) +#define M7_TCML_BASE_MCORE_ADDR (0x0UL) +#define M7_TCML_MAX_SIZE (0x80000U) /* Could configure to 512KB TCML */ +#define M71_TCML_BASE_ADDR (0x20280000UL) +#define M71_TCML_BASE_MCORE_ADDR (0x0UL) +#define M71_TCML_MAX_SIZE (0x80000U) /* Could configure to 512KB TCML */ #define FLEXSPI_AHB_ADDR (0x28000000UL) #define FLEXSPI_AHB_SIZE (0x8000000UL) diff --git a/arch/arm/mach-imx/imx9/imx_bootaux.c b/arch/arm/mach-imx/imx9/imx_bootaux.c index c49f80e84dd..5b94d71fda5 100644 --- a/arch/arm/mach-imx/imx9/imx_bootaux.c +++ b/arch/arm/mach-imx/imx9/imx_bootaux.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2022 NXP + * Copyright 2022, 2026 NXP */ #include @@ -16,11 +16,16 @@ DECLARE_GLOBAL_DATA_PTR; +#define CORE_CM33 0 +#define CORE_CM7 1 +#define CORE_CM71 7 +#define CORE_CM33S 8 + int arch_auxiliary_core_check_up(u32 core_id) { struct arm_smccc_res res; - arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STARTED, 0, 0, + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STARTED, 0, core_id, 0, 0, 0, 0, &res); return res.a0; @@ -32,7 +37,7 @@ int arch_auxiliary_core_down(u32 core_id) printf("## Stopping auxiliary core\n"); - arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STOP, 0, 0, + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STOP, 0, core_id, 0, 0, 0, 0, &res); return 0; @@ -42,17 +47,48 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr) { struct arm_smccc_res res; - if (!addr) - return -EINVAL; - printf("## Starting auxiliary core addr = 0x%08lX...\n", addr); - arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_START, addr, 0, + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_START, addr, core_id, 0, 0, 0, 0, &res); return 0; } +#if IS_ENABLED(CONFIG_SCMI_FIRMWARE) +int arch_auxiliary_core_prepare(u32 core_id) +{ + struct arm_smccc_res res; + + printf("## Preparing auxiliary core: %d\n", core_id); + + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_PREP, 0, core_id, + 0, 0, 0, 0, &res); + + return res.a0; +} + +int arch_auxiliary_core_prepared(u32 core_id) +{ + struct arm_smccc_res res; + + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_PREPED, 0, core_id, + 0, 0, 0, 0, &res); + + return res.a0; +} +#else +int arch_auxiliary_core_prepare(u32 core_id) +{ + return 0; +} + +bool arch_auxiliary_core_prepared(u32 core_id) +{ + return true; +} +#endif + static inline bool check_in_ddr(ulong addr) { int i; @@ -68,26 +104,42 @@ static inline bool check_in_ddr(ulong addr) return false; } -static inline bool check_in_tcm(ulong addr, bool mcore_view) +static inline bool check_in_tcm(u32 core_id, ulong addr, bool mcore_view) { if (mcore_view) { - if ((addr >= TCML_BASE_MCORE_SEC_ADDR && - addr < TCML_BASE_MCORE_SEC_ADDR + TCML_SIZE) || - (addr >= TCMU_BASE_MCORE_SEC_ADDR && - addr < TCMU_BASE_MCORE_SEC_ADDR + TCMU_SIZE)) - return true; + if (core_id == CORE_CM33 || core_id == CORE_CM33S) { + if ((addr >= TCML_BASE_MCORE_SEC_ADDR && + addr < TCML_BASE_MCORE_SEC_ADDR + TCML_SIZE) || + (addr >= TCMU_BASE_MCORE_SEC_ADDR && + addr < TCMU_BASE_MCORE_SEC_ADDR + TCMU_SIZE)) + return true; - if ((addr >= TCML_BASE_MCORE_NSEC_ADDR && - addr < TCML_BASE_MCORE_NSEC_ADDR + TCML_SIZE) || - (addr >= TCMU_BASE_MCORE_NSEC_ADDR && - addr < TCMU_BASE_MCORE_NSEC_ADDR + TCMU_SIZE)) - return true; + if ((addr >= TCML_BASE_MCORE_NSEC_ADDR && + addr < TCML_BASE_MCORE_NSEC_ADDR + TCML_SIZE) || + (addr >= TCMU_BASE_MCORE_NSEC_ADDR && + addr < TCMU_BASE_MCORE_NSEC_ADDR + TCMU_SIZE)) + return true; + } else if (core_id == CORE_CM7 || core_id == CORE_CM71) { + if (addr >= M7_TCML_BASE_MCORE_ADDR && + addr < M7_TCML_BASE_MCORE_ADDR + M7_TCML_MAX_SIZE) + return true; + } } else { - if ((addr >= TCML_BASE_ADDR && - addr < TCML_BASE_ADDR + TCML_SIZE) || - (addr >= TCMU_BASE_ADDR && - addr < TCMU_BASE_ADDR + TCMU_SIZE)) - return true; + if (core_id == CORE_CM33 || core_id == CORE_CM33S) { + if ((addr >= TCML_BASE_ADDR && + addr < TCML_BASE_ADDR + TCML_SIZE) || + (addr >= TCMU_BASE_ADDR && + addr < TCMU_BASE_ADDR + TCMU_SIZE)) + return true; + } else if (core_id == CORE_CM7) { + if (addr >= M7_TCML_BASE_ADDR && + addr < M7_TCML_BASE_ADDR + M7_TCML_MAX_SIZE) + return true; + } else if (core_id == CORE_CM71) { + if (addr >= M71_TCML_BASE_ADDR && + addr < M71_TCML_BASE_ADDR + M7_TCML_MAX_SIZE) + return true; + } } return false; } @@ -101,7 +153,7 @@ static inline bool check_in_flexspi(ulong addr) } #if IS_ENABLED(CONFIG_AHAB_BOOT) -static int authenticate_auxcore_container(ulong addr, ulong *entry) +static int authenticate_auxcore_container(u32 core_id, ulong addr, ulong *entry) { struct container_hdr *phdr; int i, ret = 0; @@ -114,7 +166,8 @@ static int authenticate_auxcore_container(ulong addr, ulong *entry) return -EINVAL; } - if (!check_in_ddr(addr) && !check_in_tcm(addr, false) && !check_in_flexspi(addr)) { + if (!check_in_ddr(addr) && !check_in_tcm(core_id, addr, false) && + !check_in_flexspi(addr)) { printf("Error: Container's address is invalid\n"); return -EINVAL; } @@ -147,7 +200,7 @@ static int authenticate_auxcore_container(ulong addr, ulong *entry) i * sizeof(struct boot_img_t)); /* Check Core ID of M core */ - if ((img->meta & 0xff) != 0) { + if ((img->meta & 0xff) != core_id) { printf("Error: Wrong Image core ID, meta = 0x%x\n", img->meta); ret = -EFAULT; break; @@ -163,7 +216,8 @@ static int authenticate_auxcore_container(ulong addr, ulong *entry) break; } } else { - if (!check_in_ddr(img->dst) && !check_in_tcm(img->dst, false)) { + if (!check_in_ddr(img->dst) && + !check_in_tcm(core_id, img->dst, false)) { printf("Error: Invalid Image[%u] load address 0x%llx\n", i, img->dst); ret = -EFAULT; @@ -217,6 +271,12 @@ static int do_bootaux_cntr(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_SUCCESS; } + up = arch_auxiliary_core_prepared(core); + if (!up) { + printf("## Not prepared, run 'prepaux [coreid]' first\n"); + return CMD_RET_FAILURE; + } + addr = simple_strtoul(argv[1], NULL, 16); if (!addr) @@ -224,13 +284,13 @@ static int do_bootaux_cntr(struct cmd_tbl *cmdtp, int flag, int argc, printf("Authenticate auxcore container at 0x%lx\n", addr); - ret = authenticate_auxcore_container(addr, &entry); + ret = authenticate_auxcore_container(core, addr, &entry); if (ret) { printf("Authenticate container failed %d\n", ret); return CMD_RET_FAILURE; } - if (!check_in_ddr(entry) && !check_in_tcm(entry, true) && + if (!check_in_ddr(entry) && !check_in_tcm(core, entry, true) && !check_in_flexspi(entry)) { printf("Error: Image's entry 0x%lx is invalid\n", entry); return CMD_RET_FAILURE; @@ -280,12 +340,20 @@ static int do_bootaux(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_SUCCESS; } + up = arch_auxiliary_core_prepared(core); + if (!up) { + printf("## Not prepared, run 'prepaux [coreid]' first\n"); + return CMD_RET_FAILURE; + } + addr = simple_strtoul(argv[1], NULL, 16); - if (!addr) + if ((core != CORE_CM7 && core != CORE_CM71) && !addr) { + printf("Invalid address 0x%lx for core: %d\n", addr, core); return CMD_RET_FAILURE; + } - if (!check_in_ddr(addr) && !check_in_tcm(addr, true) && !check_in_flexspi(addr)) { + if (!check_in_ddr(addr) && !check_in_tcm(core, addr, true) && !check_in_flexspi(addr)) { printf("Error: Image's address 0x%lx is invalid\n", addr); printf(" Address should be memory from M core view,\n" " For example: 0x1ffe0000 for TCML in secure\n"); @@ -304,14 +372,21 @@ static int do_stopaux(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { int ret, up; + u32 core = 0; - up = arch_auxiliary_core_check_up(0); + if (argc < 2) + return CMD_RET_USAGE; + + if (argc > 2) + core = simple_strtoul(argv[2], NULL, 10); + + up = arch_auxiliary_core_check_up(core); if (!up) { printf("## Auxiliary core is already down\n"); return CMD_RET_SUCCESS; } - ret = arch_auxiliary_core_down(0); + ret = arch_auxiliary_core_down(core); if (ret) return CMD_RET_FAILURE; @@ -324,6 +399,41 @@ U_BOOT_CMD( "
[]\n" " - start auxiliary core [] (default 0),\n" " at address
\n" + " :\n" + " 0 - CM33\n" + " 1 - CM70\n" + " 7 - CM71\n" + " 8 - CM33 Sync\n" +); + +static int do_prepaux(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + u32 core = 0; + + if (argc != 2) + return CMD_RET_USAGE; + + core = simple_strtoul(argv[1], NULL, 10); + + ret = arch_auxiliary_core_prepare(core); + if (ret) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + prepaux, CONFIG_SYS_MAXARGS, 1, do_prepaux, + "prepare auxiliary core", + "[]\n" + " - prep auxiliary core [] (default 0),\n" + " :\n" + " 0 - CM33\n" + " 1 - CM70\n" + " 7 - CM71\n" + " 8 - CM33 Sync\n" ); #if IS_ENABLED(CONFIG_AHAB_BOOT) @@ -333,6 +443,11 @@ U_BOOT_CMD( " []\n" " - start auxiliary core [] (default 0),\n" " with signed container image at address
in A core view\n" + " :\n" + " 0 - CM33\n" + " 1 - CM70\n" + " 7 - CM71\n" + " 8 - CM33 Sync\n" ); #else U_BOOT_CMD( @@ -341,5 +456,10 @@ U_BOOT_CMD( "
[]\n" " - start auxiliary core [] (default 0),\n" " at address
of auxiliary core view\n" + " :\n" + " 0 - CM33\n" + " 1 - CM70\n" + " 7 - CM71\n" + " 8 - CM33 Sync\n" ); #endif diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c index 18d00355999..dc78d73251c 100644 --- a/arch/arm/mach-imx/imx9/scmi/soc.c +++ b/arch/arm/mach-imx/imx9/scmi/soc.c @@ -248,7 +248,38 @@ static struct mm_region imx9_mem_map[] = { .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { + }, +#if IS_ENABLED(CONFIG_IMX94) + { + /* M71 TCM */ + .virt = 0x202c0000UL, + .phys = 0x202c0000UL, + .size = 0x80000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, + { + /* M33S TCM */ + .virt = 0x209c0000UL, + .phys = 0x209c0000UL, + .size = 0x80000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, + /* 644K netc ocram for rpmsg buffer */ + { + /* M33S NETC OCRAM */ + .virt = 0x20800000UL, + .phys = 0x20800000UL, + .size = 0xa1000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, +#endif + { /* OCRAM */ .virt = 0x20480000UL, .phys = 0x20480000UL, diff --git a/include/imx_sip.h b/include/imx_sip.h index 8a5ca34f393..478cbd3fdaf 100644 --- a/include/imx_sip.h +++ b/include/imx_sip.h @@ -16,5 +16,7 @@ #define IMX_SIP_SRC_MCU_START 0x00 #define IMX_SIP_SRC_MCU_STARTED 0x01 #define IMX_SIP_SRC_MCU_STOP 0x02 +#define IMX_SIP_SRC_MCU_PREP 0x04 +#define IMX_SIP_SRC_MCU_PREPED 0x05 #endif From 047ed967843af5eb5f24f78910635b61b3c378a1 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 27 Jul 2026 11:21:12 -0300 Subject: [PATCH 04/37] imx9{4, 5, 52}_evk: power on mcore according to SM config When working with SM config mx9{4,5,52}evkrpmsg, mcores are not booted by ROM. Hence, power on the mcore and initialize TCM ECC in u-boot for subsequent mcore booting. Signed-off-by: Ye Li [fabio: Adapted to mainline context] Signed-off-by: Fabio Estevam --- arch/arm/include/asm/arch-imx9/sys_proto.h | 2 + arch/arm/mach-imx/imx9/scmi/soc.c | 98 ++++++++++++++++++++++ board/nxp/imx94_evk/imx94_evk.c | 3 + board/nxp/imx952_evk/imx952_evk.c | 3 + board/nxp/imx95_evk/imx95_evk.c | 8 ++ configs/imx95_evk.config | 2 +- include/scmi_nxp_protocols.h | 11 +++ 7 files changed, 126 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/arch-imx9/sys_proto.h b/arch/arm/include/asm/arch-imx9/sys_proto.h index d43e54e72aa..bdcc5796e5b 100644 --- a/arch/arm/include/asm/arch-imx9/sys_proto.h +++ b/arch/arm/include/asm/arch-imx9/sys_proto.h @@ -28,6 +28,8 @@ int scmi_get_boot_device_offset(unsigned long *img_off); int scmi_get_boot_stage(u8 *stage); u8 scmi_get_imgset_sel(void); +int power_on_mcore(const char *sm_cfgname); + #define is_voltage_mode(mode) (soc_target_voltage_mode() == (mode)) #endif diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c index dc78d73251c..0cba2d92abb 100644 --- a/arch/arm/mach-imx/imx9/scmi/soc.c +++ b/arch/arm/mach-imx/imx9/scmi/soc.c @@ -58,6 +58,43 @@ uint32_t scmi_get_rom_data(rom_passover_t *rom_data) return 0; } +int scmi_misc_cfginfo(u32 *msel, char *cfgname) +{ + struct scmi_imx_misc_cfg_info_out out = {}; + struct scmi_msg msg = { + .protocol_id = SCMI_PROTOCOL_ID_IMX_MISC, + .message_id = SCMI_IMX_MISC_CFG_INFO, + .in_msg = (u8 *)NULL, + .in_msg_sz = 0, + .out_msg = (u8 *)&out, + .out_msg_sz = sizeof(out), + }; + int ret; + struct udevice *dev; + + if (!msel || !cfgname) + return -EINVAL; + + ret = uclass_get_device_by_name(UCLASS_CLK, "protocol@14", &dev); + if (ret) + return ret; + + ret = devm_scmi_process_msg(dev, &msg); + if (ret) + return ret; + + if (out.status) { + printf("Failed to get cfg name, scmi_err = %d\n", + out.status); + return scmi_to_linux_errno(out.status); + } + + *msel = out.msel; + strcpy(cfgname, (const char *)out.cfgname); + + return 0; +} + int scmi_misc_ddrinfo(u32 ddrc_id, struct scmi_ddr_info_out *out) { u32 in = ddrc_id; @@ -860,6 +897,67 @@ const char *get_cpu_variant_type_name(u32 type) return NULL; } +int power_on_mcore(const char *sm_cfgname) +{ + char cfgname[MISC_MAX_CFGNAME]; + u32 msel; + int ret; + struct udevice *dev; + + ret = scmi_misc_cfginfo(&msel, cfgname); + if (ret) + return ret; + + if (strncmp(cfgname, sm_cfgname, MISC_MAX_CFGNAME)) + return -EINVAL; + + printf("power on mcore for %s\n", sm_cfgname); + + ret = uclass_get_device_by_name(UCLASS_CLK, "protocol@14", &dev); + if (ret) + return ret; + + if (!arch_auxiliary_core_check_up(1)) { + /* Power up M7MIX */ + ret = scmi_pwd_state_set(dev, 0, SCMI_PD(M70), 0); + if (ret) { + printf("Power M7 failed\n"); + return -EIO; + } + + /* In case OEI not init ECC, do it here */ + memset_io((void *)0x203c0000, 0, 0x40000); + memset_io((void *)0x20400000, 0, 0x40000); + } + +#if IS_ENABLED(CONFIG_IMX94) + if (!arch_auxiliary_core_check_up(7)) { + ret = scmi_pwd_state_set(dev, 0, SCMI_PD(M71), 0); + if (ret) { + printf("Power M71 failed\n"); + return -EIO; + } + + memset_io((void *)0x202c0000, 0, 0x40000); + memset_io((void *)0x20300000, 0, 0x40000); + } + + if (!arch_auxiliary_core_check_up(8)) { + ret = scmi_pwd_state_set(dev, 0, SCMI_PD(NETC), 0); + if (ret) { + printf("Power M33S failed\n"); + return -EIO; + } + + memset_io((void *)0x209c0000, 0, 0x40000); + memset_io((void *)0x20A00000, 0, 0x40000); + memset_io((void *)0x20800000, 0, 0xa1000); + } +#endif + + return 0; +} + void build_info(void) { u32 fw_version, sha1, res = 0, status; diff --git a/board/nxp/imx94_evk/imx94_evk.c b/board/nxp/imx94_evk/imx94_evk.c index 02149afae87..94fa135c759 100644 --- a/board/nxp/imx94_evk/imx94_evk.c +++ b/board/nxp/imx94_evk/imx94_evk.c @@ -11,6 +11,9 @@ int board_init(void) { + /* Power on mcores when using rpmsg cfg */ + power_on_mcore("mx94evkrpmsg"); + return 0; } diff --git a/board/nxp/imx952_evk/imx952_evk.c b/board/nxp/imx952_evk/imx952_evk.c index b5c2da032a8..171bd029f76 100644 --- a/board/nxp/imx952_evk/imx952_evk.c +++ b/board/nxp/imx952_evk/imx952_evk.c @@ -9,6 +9,9 @@ int board_init(void) { + /* Power on mcores when using rpmsg cfg */ + power_on_mcore("mx952evkrpmsg"); + return 0; } diff --git a/board/nxp/imx95_evk/imx95_evk.c b/board/nxp/imx95_evk/imx95_evk.c index 394d6fd459c..8cc61800edc 100644 --- a/board/nxp/imx95_evk/imx95_evk.c +++ b/board/nxp/imx95_evk/imx95_evk.c @@ -7,6 +7,14 @@ #include #include +int board_init(void) +{ + /* Power on mcores when using rpmsg cfg */ + power_on_mcore("mx95evkrpmsg"); + + return 0; +} + int board_late_init(void) { if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC)) diff --git a/configs/imx95_evk.config b/configs/imx95_evk.config index 743778d9554..7c429fe0bfe 100644 --- a/configs/imx95_evk.config +++ b/configs/imx95_evk.config @@ -37,7 +37,7 @@ CONFIG_BOOTCOMMAND="bootflow scan -l; run bsp_bootcmd" CONFIG_DEFAULT_FDT_FILE="imx95-19x19-evk.dtb" CONFIG_SYS_CBSIZE=2048 CONFIG_SYS_PBSIZE=2074 -# CONFIG_BOARD_INIT is not set +CONFIG_BOARD_INIT=y CONFIG_BOARD_LATE_INIT=y CONFIG_PCI_INIT_R=y CONFIG_SPL_MAX_SIZE=0x20000 diff --git a/include/scmi_nxp_protocols.h b/include/scmi_nxp_protocols.h index c17f3663eba..184dcc1e04b 100644 --- a/include/scmi_nxp_protocols.h +++ b/include/scmi_nxp_protocols.h @@ -18,6 +18,7 @@ #define SCMI_ARRAY(X, Y) ((SCMI_PAYLOAD_LEN - (X)) / sizeof(Y)) #define SCMI_IMX_MISC_RESET_REASON 0xA +#define SCMI_IMX_MISC_CFG_INFO 0xC struct scmi_imx_misc_reset_reason_in { #define MISC_REASON_FLAG_SYSTEM BIT(0) @@ -119,4 +120,14 @@ static inline int scmi_imx_cpu_start(struct udevice *dev, u32 cpuid, bool start) return -EOPNOTSUPP; } #endif + +struct scmi_imx_misc_cfg_info_out { + s32 status; + /* Mode selector value */ + u32 msel; +#define MISC_MAX_CFGNAME 16 + /* Config (cfg) file basename */ + char cfgname[MISC_MAX_CFGNAME]; +}; + #endif From ae31cc745bcb4775b7d8e17a73a3d09f137c9d22 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 17 Jun 2026 22:14:46 +0800 Subject: [PATCH 05/37] imx9: scmi: reset GPIO2 according its node status Check the GPIO2 dts node status to determine reset it or not. On iMX952 single SPL/U-Boot image is shared for both mx952evk and mx952evkrpmsg SM configs. GPIO2 is assigned to M7 domain in mx952evkrpmsg, and there is no active user of GPIO2 for mx952evk and mx952evkrpmsg in SPL/U-Boot, so it is disabled in DTS. Otherwise, reset GPIO2 will meet hang when working with mx952evkrpmsg SM. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx9/scmi/soc.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c index 0cba2d92abb..6561de205d0 100644 --- a/arch/arm/mach-imx/imx9/scmi/soc.c +++ b/arch/arm/mach-imx/imx9/scmi/soc.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -1051,6 +1052,22 @@ static void gpio_reset(ulong gpio_base) writel(0, gpio_base + 0x1c); } +static int gpio_available(const char *nodes_path) +{ + ofnode gpio_node = ofnode_path(nodes_path); + const char *status; + + if (!ofnode_valid(gpio_node)) + return false; + + status = ofnode_read_string(gpio_node, "status"); + + if (status && !strcmp(status, "disabled")) + return false; + + return true; +} + int arch_cpu_init(void) { if (IS_ENABLED(CONFIG_SPL_BUILD)) { @@ -1066,7 +1083,9 @@ int arch_cpu_init(void) disable_wdog((void __iomem *)base); } - gpio_reset(GPIO2_BASE_ADDR); + if (gpio_available("/soc/gpio@43810000")) + gpio_reset(GPIO2_BASE_ADDR); + gpio_reset(GPIO3_BASE_ADDR); gpio_reset(GPIO4_BASE_ADDR); gpio_reset(GPIO5_BASE_ADDR); From 573b03317aab3529bd813ef5259cd84c98edb52d Mon Sep 17 00:00:00 2001 From: Ye Li Date: Thu, 18 Jun 2026 09:19:36 +0800 Subject: [PATCH 06/37] arm: dts: imx943-evk: Add label for gpio expander devices Because the i2c address of some gpio expander devices are same, so in dts they have same node name which lead to same gpio device name. Users can't get the GPIO through GPIO API or GPIO command. Add the label to each gpio expander node, hence give unique name. Signed-off-by: Ye Li Reviewed-by: Peng Fan --- arch/arm/dts/imx943-evk-u-boot.dtsi | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm/dts/imx943-evk-u-boot.dtsi b/arch/arm/dts/imx943-evk-u-boot.dtsi index 3b3619d2232..635a3042fdd 100644 --- a/arch/arm/dts/imx943-evk-u-boot.dtsi +++ b/arch/arm/dts/imx943-evk-u-boot.dtsi @@ -272,3 +272,31 @@ &pinctrl_usdhc2_gpio { bootph-pre-ram; }; + +&pcal6416_i2c3_u46 { + label = "u46"; +}; + +&pcal6416_i2c3_u171 { + label = "u171"; +}; + +&pcal6416_i2c3_u48 { + label = "u48"; +}; + +&pcal6408_i2c3_u172 { + label = "u172"; +}; + +&pcal6416_i2c6_u50 { + label = "u50"; +}; + +&pcal6408_i2c6_u170 { + label = "u170"; +}; + +&pcal6416_i2c6_u44 { + label = "u44"; +}; From cec2f200b4bfcc466e4a83196ed5fdd54678c1c7 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 25 Jun 2026 16:17:29 +0200 Subject: [PATCH 07/37] mx6: ddr: Subtract half a cycle instead of three quarters of a cycle after DQS gating calibration The current DRAM calibration sequence is implemented based on NXP AN4467 Rev.2 03/2015, which in chapter "12.3.2 Calibration Sequence Setup with Predefined Data Content" states: " 9. For each of the DQSx: - Read the HW_DG_UPx value from the MMDC0/1_MPDGHWSTx, subtract the value of 0xc0 (3/4 cycle). " However, the i.MX 6Solo/6DualLite Applications Processor Reference Manual, Rev. 5, 05/2020, chapter "45.11.3.1.2 Hardware DQS Calibration with pre-defined value" states: " 35. Set (MPDGHWSTn[HW_DG_UPn][10:7] - 1) to MPDGCTRLn[DG_HC_DELn]. (We set the DQS gating value to be the upper limit value minus 1 half cycle) " The i.MX 6Dual/6Quad Applications Processor Reference Manual, Rev. 6, 05/2020, chapter 44.11.3.1.2 Hardware DQS Calibration with pre-defined value lists the same information. So do the following manuals: - i.MX 6DualPlus/6QuadPlus Applications Processor Reference Manual, Rev. 3, 05/2020 chapter 46.11.3.1.2 Hardware DQS Calibration with pre-defined value - i.MX 6SoloX Applications Processor Reference Manual, Rev. 4, 05/2020 chapter 40.11.3.1.2 Hardware DQS Calibration with pre-defined value - i.MX 6UltraLite Applications Processor Reference Manual, Rev. 2, 03/2017 chapter 33.11.3.1.2 Hardware DQS Calibration with pre-defined value - i.MX 6ULL Applications Processor Reference Manual, Rev. 1, 11/2017 chapter 35.11.3.1.2 Hardware DQS Calibration with pre-defined value - i.MX 6ULZ Applications Processor Reference Manual, Rev. 0, 10/2018 chapter 29.11.3.1.2 Hardware DQS Calibration with pre-defined value The NXP MMDC DDR Stress Test (3.0.0) tool seems to be have the same way as the later document rather than the AN4467 application note, and produces values similar to the values with subtracted 1/2 cycle. Adjust the behavior to match the more recent Reference Manual and the MMDC calibration tool. Winbond W634GU6RB does show sporadic signs of instability without this correction. Signed-off-by: Marek Vasut Tested-by: Christoph Niedermaier --- arch/arm/mach-imx/mx6/ddr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/mx6/ddr.c b/arch/arm/mach-imx/mx6/ddr.c index 5a1258e002d..2447698cfe4 100644 --- a/arch/arm/mach-imx/mx6/ddr.c +++ b/arch/arm/mach-imx/mx6/ddr.c @@ -71,13 +71,13 @@ static void modify_dg_result(u32 *reg_st0, u32 *reg_st1, u32 *reg_ctrl) val_ctrl = readl(reg_ctrl); val_ctrl &= 0xf0000000; - dg_tmp_val = ((readl(reg_st0) & 0x07ff0000) >> 16) - 0xc0; + dg_tmp_val = ((readl(reg_st0) & 0x07ff0000) >> 16) - 0x80; dg_dl_abs_offset = dg_tmp_val & 0x7f; dg_hc_del = (dg_tmp_val & 0x780) << 1; val_ctrl |= dg_dl_abs_offset + dg_hc_del; - dg_tmp_val = ((readl(reg_st1) & 0x07ff0000) >> 16) - 0xc0; + dg_tmp_val = ((readl(reg_st1) & 0x07ff0000) >> 16) - 0x80; dg_dl_abs_offset = dg_tmp_val & 0x7f; dg_hc_del = (dg_tmp_val & 0x780) << 1; From 3dcbac87a2cc784bcd27a925e246e8192788ce09 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 30 Jun 2026 18:08:56 +0200 Subject: [PATCH 08/37] arm64: dts: imx8m: Reinstate TEE ifdeffery Since b57ed147939c ("dts: imx8m{m,n,p,q}: Make optee packaging optional") the TEE node is always present in U-Boot proper fitImage, even if the CONFIG_OPTEE is disabled because the u-boot.itb should not contain any tee.bin. This is wasteful, and produces the following warning which is also confusing to users: " Image 'image' is missing optional external blobs but is still functional: tee-os /binman/section/fit/images/tee/tee-os (tee.bin): See the documentation for your board. You may need to build Open Portable Trusted Execution Environment (OP-TEE) and build with TEE=/path/to/tee.bin " Reinstate the CONFIG_OPTEE ifdeffery to mitigate the problem, but retain the binman "optional" keyword at tee.bin . Before: " $ mkimage -l u-boot.itb FIT description: Configuration to load ATF before U-Boot Created: Tue Jun 30 17:23:54 2026 Image 0 (uboot) ... Image 2 (tee) <------------------------------ bogus empty image entry Description: OP-TEE | Created: Tue Jun 30 17:23:54 2026 | Type: Trusted Execution Environment Image | Compression: uncompressed | Data Size: 0 Bytes = 0.00 KiB = 0.00 MiB <--------' Image 3 (fdt-1) ... " After: " $ mkimage -l u-boot.itb FIT description: Configuration to load ATF before U-Boot Created: Tue Jun 30 17:58:15 2026 Image 0 (uboot) ... Image 1 (atf) ... Image 2 (fdt-1) ... " Fixes: b57ed147939c ("dts: imx8m{m,n,p,q}: Make optee packaging optional") Signed-off-by: Marek Vasut Reviewed-by: Peng Fan --- arch/arm/dts/imx8mm-u-boot.dtsi | 6 ++++++ arch/arm/dts/imx8mn-u-boot.dtsi | 6 ++++++ arch/arm/dts/imx8mp-u-boot.dtsi | 6 ++++++ arch/arm/dts/imx8mq-u-boot.dtsi | 6 ++++++ 4 files changed, 24 insertions(+) diff --git a/arch/arm/dts/imx8mm-u-boot.dtsi b/arch/arm/dts/imx8mm-u-boot.dtsi index 50ecb6cad39..c3d9b4f4237 100644 --- a/arch/arm/dts/imx8mm-u-boot.dtsi +++ b/arch/arm/dts/imx8mm-u-boot.dtsi @@ -165,6 +165,7 @@ }; #endif +#ifdef CONFIG_OPTEE tee: tee { description = "OP-TEE"; type = "tee"; @@ -179,6 +180,7 @@ optional; }; }; +#endif binman_fip: fip { arch = "arm64"; @@ -208,7 +210,11 @@ fdt = "fdt-SEQ"; firmware = "uboot"; #ifndef CONFIG_ARMV8_PSCI +#ifdef CONFIG_OPTEE loadables = "atf", "tee"; +#else + loadables = "atf"; +#endif #endif }; }; diff --git a/arch/arm/dts/imx8mn-u-boot.dtsi b/arch/arm/dts/imx8mn-u-boot.dtsi index 690f56e65bb..f9cbfd03f99 100644 --- a/arch/arm/dts/imx8mn-u-boot.dtsi +++ b/arch/arm/dts/imx8mn-u-boot.dtsi @@ -241,6 +241,7 @@ }; #endif +#ifdef CONFIG_OPTEE tee: tee { description = "OP-TEE"; type = "tee"; @@ -255,6 +256,7 @@ optional; }; }; +#endif binman_fip: fip { arch = "arm64"; @@ -284,7 +286,11 @@ fdt = "fdt-SEQ"; firmware = "uboot"; #ifndef CONFIG_ARMV8_PSCI +#ifdef CONFIG_OPTEE loadables = "atf", "tee"; +#else + loadables = "atf"; +#endif #endif }; }; diff --git a/arch/arm/dts/imx8mp-u-boot.dtsi b/arch/arm/dts/imx8mp-u-boot.dtsi index d9d220c70db..58b6863f003 100644 --- a/arch/arm/dts/imx8mp-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-u-boot.dtsi @@ -189,6 +189,7 @@ }; #endif +#ifdef CONFIG_OPTEE tee: tee { description = "OP-TEE"; type = "tee"; @@ -203,6 +204,7 @@ optional; }; }; +#endif @fdt-SEQ { description = "NAME"; @@ -223,7 +225,11 @@ fdt = "fdt-SEQ"; firmware = "uboot"; #ifndef CONFIG_ARMV8_PSCI +#ifdef CONFIG_OPTEE loadables = "atf", "tee"; +#else + loadables = "atf"; +#endif #endif }; }; diff --git a/arch/arm/dts/imx8mq-u-boot.dtsi b/arch/arm/dts/imx8mq-u-boot.dtsi index b4deaa92160..c6947401750 100644 --- a/arch/arm/dts/imx8mq-u-boot.dtsi +++ b/arch/arm/dts/imx8mq-u-boot.dtsi @@ -173,6 +173,7 @@ }; #endif +#ifdef CONFIG_OPTEE tee: tee { description = "OP-TEE"; type = "tee"; @@ -187,6 +188,7 @@ optional; }; }; +#endif fdt { compression = "none"; @@ -208,7 +210,11 @@ fdt = "fdt"; firmware = "uboot"; #ifndef CONFIG_ARMV8_PSCI +#ifdef CONFIG_OPTEE loadables = "atf", "tee"; +#else + loadables = "atf"; +#endif #endif }; }; From beae2cdf2fbde7fb4b0b64f5d92834378129aac4 Mon Sep 17 00:00:00 2001 From: Max Merchel Date: Wed, 1 Jul 2026 11:11:16 +0200 Subject: [PATCH 09/37] sysinfo: tq_eeprom: select NVMEM The SYSINFO_TQ_EEPROM driver requires NVMEM to access the SoM EEPROM. Signed-off-by: Max Merchel --- drivers/sysinfo/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/sysinfo/Kconfig b/drivers/sysinfo/Kconfig index 6922dac9170..adcf1aed8a8 100644 --- a/drivers/sysinfo/Kconfig +++ b/drivers/sysinfo/Kconfig @@ -63,6 +63,7 @@ config SYSINFO_TQ_EEPROM bool "Enable TQ-Systems EEPROM sysinfo driver" depends on I2C_EEPROM depends on SPL_I2C_EEPROM || !SPL_SYSINFO + select NVMEM help Support querying EEPROM of TQ-Systems SOMs to determine board information. From 1786f0e16e8f5e2cab97865d04bbbf9ae75584ba Mon Sep 17 00:00:00 2001 From: Max Merchel Date: Wed, 1 Jul 2026 11:11:17 +0200 Subject: [PATCH 10/37] arm: dts: tqma6ul: add eeprom nvmem-layout TQMa6UL has board-information located in EEPROM at offset 0x20. Add necessary nodes and properties for nvmem-cells. Revert this commit once the upstream linux device trees are accepted and synchronized. Signed-off-by: Max Merchel --- arch/arm/dts/imx6ul-tqma6ul-common-u-boot.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/dts/imx6ul-tqma6ul-common-u-boot.dtsi b/arch/arm/dts/imx6ul-tqma6ul-common-u-boot.dtsi index 09f94f23074..1ed44c57f59 100644 --- a/arch/arm/dts/imx6ul-tqma6ul-common-u-boot.dtsi +++ b/arch/arm/dts/imx6ul-tqma6ul-common-u-boot.dtsi @@ -24,6 +24,18 @@ bootph-pre-ram; }; +&m24c64_50 { + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + module_info: module-info@20 { + reg = <0x20 0x60>; + }; + }; +}; + &osc { bootph-pre-ram; }; From e643d211f55f1c6cdba548565df71ec6c288096a Mon Sep 17 00:00:00 2001 From: Max Merchel Date: Wed, 1 Jul 2026 11:11:18 +0200 Subject: [PATCH 11/37] arm: dts: tqma6ul: integrate tq,eeprom sysinfo driver Add sysinfo node for tq,eeprom sysinfo driver. Signed-off-by: Max Merchel --- arch/arm/dts/imx6ul-tqma6ul-common-u-boot.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/dts/imx6ul-tqma6ul-common-u-boot.dtsi b/arch/arm/dts/imx6ul-tqma6ul-common-u-boot.dtsi index 1ed44c57f59..c9e6cef38a2 100644 --- a/arch/arm/dts/imx6ul-tqma6ul-common-u-boot.dtsi +++ b/arch/arm/dts/imx6ul-tqma6ul-common-u-boot.dtsi @@ -14,6 +14,12 @@ u-boot,mmc-env-offset = <0x100000>; u-boot,mmc-env-offset-redundant = <0x110000>; }; + + sysinfo: sysinfo { + compatible = "tq,eeprom-sysinfo"; + nvmem-cells = <&module_info>; + nvmem-cell-names = "device_info"; + }; }; &clks { From 141b9cab273d88272fec454f8e244ae31b5dd99f Mon Sep 17 00:00:00 2001 From: Max Merchel Date: Wed, 1 Jul 2026 11:11:19 +0200 Subject: [PATCH 12/37] boards: tqma6ul: select TQ_COMMON_SYSINFO Select TQ_COMMON_SYSINFO to use the tq_eeprom sysinfo driver to read and print module EEPROM data. Signed-off-by: Max Merchel --- arch/arm/mach-imx/mx6/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/mx6/Kconfig b/arch/arm/mach-imx/mx6/Kconfig index a38adfed02b..ffcc05e8683 100644 --- a/arch/arm/mach-imx/mx6/Kconfig +++ b/arch/arm/mach-imx/mx6/Kconfig @@ -637,6 +637,7 @@ config TARGET_TQMA6UL bool "TQ-Systems TQMa6UL[L]x" depends on MX6UL || MX6ULL select TQ_COMMON_SOM + select TQ_COMMON_SYSINFO select BOARD_EARLY_INIT_F select BOARD_LATE_INIT select OF_SYSTEM_SETUP From d2d005a32b97173d41ac99bfd19d7c9b73184d3a Mon Sep 17 00:00:00 2001 From: Md Shofiqul Islam Date: Sun, 5 Jul 2026 13:08:41 +0300 Subject: [PATCH 13/37] ge: common: vpd_reader: fix errloc array size in verify_bch() errloc stores bit positions of errors returned by decode_bch(). The maximum number of correctable errors is ecc_bits, so errloc must have ecc_bits entries. The array was allocated with data_length entries instead, which is the number of EEPROM data bytes -- orders of magnitude larger than needed and incorrect. Fixes: b418dfe16e62 ("board: ge: make VPD code common") Signed-off-by: Md Shofiqul Islam --- board/ge/common/vpd_reader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/ge/common/vpd_reader.c b/board/ge/common/vpd_reader.c index 2422db38013..b3f9e96615d 100644 --- a/board/ge/common/vpd_reader.c +++ b/board/ge/common/vpd_reader.c @@ -66,7 +66,7 @@ static int verify_bch(int ecc_bits, unsigned int prim_poly, u8 *data, return -1; } - unsigned int *errloc = (unsigned int *)calloc(data_length, + unsigned int *errloc = (unsigned int *)calloc(ecc_bits, sizeof(unsigned int)); int errors = decode_bch(bch, data, data_length, ecc, NULL, NULL, errloc); From c62cdff89cc5d9efdc2f522abb82fa08e9fb00aa Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 5 Jul 2026 23:19:05 +0200 Subject: [PATCH 14/37] binman: imx8mimage: Generate FSPI header in binman instead of mkimage Stop depending on the current mkimage method of generating the FSPI header, instead generate the FSPI header within binman itself. This is more flexible, as the FSPI header properties can be configured from within the board-specific DT instead of being hard-coded in mkimage at build time. Acked-by: Peng Fan Signed-off-by: Marek Vasut Reviewed-by: Simon Glass --- tools/binman/etype/nxp_imx8mimage.py | 95 +++++++++++++++++-- tools/binman/ftest.py | 23 ++--- tools/binman/test/vendor/nxp_imx8m_fspi.dts | 1 - .../nxp_imx8m_fspi_fail_columnadresswidth.dts | 19 ++++ ...dts => nxp_imx8m_fspi_fail_devicetype.dts} | 3 +- .../nxp_imx8m_fspi_fail_flashpadtype.dts | 19 ++++ .../nxp_imx8m_fspi_fail_readsampleclksrc.dts | 19 ++++ .../nxp_imx8m_fspi_fail_serialclkfreq.dts | 19 ++++ .../test/vendor/nxp_imx8m_fspi_pass.dts | 1 - 9 files changed, 178 insertions(+), 21 deletions(-) create mode 100644 tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts rename tools/binman/test/vendor/{nxp_imx8m_fspi_fail.dts => nxp_imx8m_fspi_fail_devicetype.dts} (83%) create mode 100644 tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts create mode 100644 tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts create mode 100644 tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts diff --git a/tools/binman/etype/nxp_imx8mimage.py b/tools/binman/etype/nxp_imx8mimage.py index 25c43438a87..38d31b1bc09 100644 --- a/tools/binman/etype/nxp_imx8mimage.py +++ b/tools/binman/etype/nxp_imx8mimage.py @@ -7,7 +7,7 @@ # configuration file and input data. # -import os +import struct from collections import OrderedDict @@ -25,8 +25,26 @@ class Entry_nxp_imx8mimage(Entry_mkimage): - nxp,boot-from - device to boot from (e.g. 'sd') - nxp,loader-address - loader address (SPL text base) - nxp,rom-version - BootROM version ('2' for i.MX8M Nano and Plus) - - nxp,fspi-header-filename - FSPI header file name (CONFIG_FSPI_CONF_FILE). - Used only if 'nxp,boot-from == "fspi"' . + + Properties / Entry arguments for FSPI boot mode (nxp,boot-from = "fspi"): + - nxp,fspi-columnaddresswidth - FSPI column address width + (3 - HyperFlash, 12/13 - Serial NAND, 0 - Otherwise (default)) + - nxp,fspi-controllermisc-diffclk - FSPI differential clock enable (default off) + - nxp,fspi-controllermisc-wordaddr - FSPI word addressable enable (default off) + - nxp,fspi-controllermisc-safecfg - FSPI safe configuration frequency (default off) + - nxp,fspi-controllermisc-padovr - FSPI pad setting override (default off) + - nxp,fspi-controllermisc-ddrmode - FSPI DDR mode (default off) + - nxp,fspi-lutcustomseq - FSPI use LUT sequence parameters (default off) + - nxp,fspi-devicetype - FSPI device type + (1 - SPI NOR (default), 2 - Serial NAND) + - nxp,fspi-flasha1size - FSPI device size (default 0x10000000) + - nxp,fspi-flashpadtype - FSPI flash pad type + (1 - Single pad (default), 2 - Dual pads, 4 - Quad pads, 8 - Octal pads) + - nxp,fspi-readsampleclksrc - FSPI clock source + (0 - Internal loopback (default), 1 - loopback from DQS pad, 3 - Flash provided DQS). + - nxp,fspi-serialclkfreq - FSPI clock frequency + (1 - 30 MHz, 2 - 50 MHz (default), 3 - 60 MHz, 4 - 75 MHz, 5 - 80 MHz, + 6 - 100 MHz, 7 - 133 MHz, 8 - 166 MHz). """ def __init__(self, section, etype, node): @@ -37,9 +55,30 @@ class Entry_nxp_imx8mimage(Entry_mkimage): def ReadNode(self): super().ReadNode() self.boot_from = fdt_util.GetString(self._node, 'nxp,boot-from') - self.fspi_header = fdt_util.GetString(self._node, 'nxp,fspi-header-filename', 'fspi_header.bin') + self.fspi_columnadresswidth = fdt_util.GetInt(self._node, 'nxp,fspi-columnaddresswidth', 0) + self.fspi_controllermisc_diffclk = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-diffclk') + self.fspi_controllermisc_wordaddr = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-wordaddr') + self.fspi_controllermisc_safecfg = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-safecfg') + self.fspi_controllermisc_padovr = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-padovr') + self.fspi_controllermisc_ddrmode = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-ddrmode') + self.fspi_devicetype = fdt_util.GetInt(self._node, 'nxp,fspi-devicetype', 1) + self.fspi_flasha1size = fdt_util.GetInt(self._node, 'nxp,fspi-flasha1size', 0x10000000) + self.fspi_flashpadtype = fdt_util.GetInt(self._node, 'nxp,fspi-flashpadtype', 1) + self.fspi_lutcustomseq = fdt_util.GetBool(self._node, 'nxp,fspi-lutcustomseq') + self.fspi_readsampleclksrc = fdt_util.GetInt(self._node, 'nxp,fspi-readsampleclksrc', 0) + self.fspi_serialclkfreq = fdt_util.GetInt(self._node, 'nxp,fspi-serialclkfreq', 2) self.loader_address = fdt_util.GetInt(self._node, 'nxp,loader-address') self.rom_version = fdt_util.GetInt(self._node, 'nxp,rom-version') + if not self.fspi_columnadresswidth in [ 0, 3, 12, 13 ]: + self.Raise('nxp,fspi-columnaddresswidth can be 0, 3, 12, 13 only.') + if not self.fspi_devicetype in [ 1, 2 ]: + self.Raise('nxp,fspi-devicetype can be 1, 2 only.') + if not self.fspi_flashpadtype in [ 1, 2, 4, 8 ]: + self.Raise('nxp,fspi-flashpadtype can be 1, 2, 4, 8 only.') + if not self.fspi_readsampleclksrc in [ 0, 1, 3 ]: + self.Raise('nxp,fspi-readsampleclksrc can be 0, 1, 3 only.') + if not self.fspi_serialclkfreq in [ 1, 2, 3, 4, 5, 6, 7, 8 ]: + self.Raise('nxp,fspi-serialclkfreq can be 1..8 only.') self.ReadEntries() def BuildSectionData(self, required): @@ -59,9 +98,51 @@ class Entry_nxp_imx8mimage(Entry_mkimage): if self.mkimage.run_cmd(*args) is not None: outdata = tools.read_file(output_fname) if self.boot_from == 'fspi': - spidata = tools.read_file(os.path.join(tools.get_output_dir(), self.fspi_header)) - if len(spidata) != 448: - raise ValueError("FSPI header is not 448 Bytes long") + # 0x00 ... Tag + spidata = struct.pack('; nxp,loader-address = <0x10>; }; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts new file mode 100644 index 00000000000..95efa33b5bf --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mimage { + args; /* TODO: Needed by mkimage etype superclass */ + nxp,boot-from = "fspi"; + nxp,rom-version = <2>; + nxp,loader-address = <0x10>; + /* Bogus value */ + nxp,fspi-columnaddresswidth = <1>; + }; + }; +}; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_devicetype.dts similarity index 83% rename from tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts rename to tools/binman/test/vendor/nxp_imx8m_fspi_fail_devicetype.dts index 5a0d758e5a3..f3b343f942f 100644 --- a/tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_devicetype.dts @@ -10,9 +10,10 @@ nxp-imx8mimage { args; /* TODO: Needed by mkimage etype superclass */ nxp,boot-from = "fspi"; - nxp,fspi-header-filename = "fspi_header_fail.bin"; nxp,rom-version = <2>; nxp,loader-address = <0x10>; + /* Bogus value */ + nxp,fspi-devicetype = <3>; }; }; }; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts new file mode 100644 index 00000000000..515f81ba9f4 --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mimage { + args; /* TODO: Needed by mkimage etype superclass */ + nxp,boot-from = "fspi"; + nxp,rom-version = <2>; + nxp,loader-address = <0x10>; + /* Bogus value */ + nxp,fspi-flashpadtype = <9>; + }; + }; +}; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts new file mode 100644 index 00000000000..b409a6099a3 --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mimage { + args; /* TODO: Needed by mkimage etype superclass */ + nxp,boot-from = "fspi"; + nxp,rom-version = <2>; + nxp,loader-address = <0x10>; + /* Bogus value */ + nxp,fspi-readsampleclksrc = <2>; + }; + }; +}; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts new file mode 100644 index 00000000000..a71522838e8 --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mimage { + args; /* TODO: Needed by mkimage etype superclass */ + nxp,boot-from = "fspi"; + nxp,rom-version = <2>; + nxp,loader-address = <0x10>; + /* Bogus value */ + nxp,fspi-serialclkfreq = <9>; + }; + }; +}; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts index 448d93d277a..1545cf6e44c 100644 --- a/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts @@ -10,7 +10,6 @@ nxp-imx8mimage { args; /* TODO: Needed by mkimage etype superclass */ nxp,boot-from = "fspi"; - /* Default nxp,fspi-header-filename = "fspi_header.bin"; */ nxp,rom-version = <2>; nxp,loader-address = <0x10>; }; From 3f7a074d83a5792667145f0f414b09a9e79918e4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 5 Jul 2026 23:19:06 +0200 Subject: [PATCH 15/37] arm64: dts: imx8mm: Drop nxp,fspi-header-filename The FSPI header is now generated purely using binman, drop no longer supported nxp,fspi-header-filename property. Acked-by: Peng Fan Reviewed-by: Simon Glass Signed-off-by: Marek Vasut --- arch/arm/dts/imx8mm-u-boot.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/dts/imx8mm-u-boot.dtsi b/arch/arm/dts/imx8mm-u-boot.dtsi index c3d9b4f4237..d5a5681c23f 100644 --- a/arch/arm/dts/imx8mm-u-boot.dtsi +++ b/arch/arm/dts/imx8mm-u-boot.dtsi @@ -62,7 +62,6 @@ filename = "u-boot-spl-mkimage.bin"; #ifdef CONFIG_FSPI_CONF_HEADER nxp,boot-from = "fspi"; - nxp,fspi-header-filename = CONFIG_FSPI_CONF_FILE; #else nxp,boot-from = "sd"; #endif From ba1a95aef3ed972a411ac8e03a547b758c931a1e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 5 Jul 2026 23:19:07 +0200 Subject: [PATCH 16/37] arm64: dts: imx8mn: Drop nxp,fspi-header-filename The FSPI header is now generated purely using binman, drop no longer supported nxp,fspi-header-filename property. Acked-by: Peng Fan Reviewed-by: Simon Glass Signed-off-by: Marek Vasut --- arch/arm/dts/imx8mn-u-boot.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/dts/imx8mn-u-boot.dtsi b/arch/arm/dts/imx8mn-u-boot.dtsi index f9cbfd03f99..9a5afa7c807 100644 --- a/arch/arm/dts/imx8mn-u-boot.dtsi +++ b/arch/arm/dts/imx8mn-u-boot.dtsi @@ -116,7 +116,6 @@ filename = "u-boot-spl-mkimage.bin"; #ifdef CONFIG_FSPI_CONF_HEADER nxp,boot-from = "fspi"; - nxp,fspi-header-filename = CONFIG_FSPI_CONF_FILE; #else nxp,boot-from = "sd"; #endif From 099fc6eda5448dc9c112cbb0f5c78a858a6b1180 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois-Briand Date: Mon, 6 Jul 2026 14:34:01 +0200 Subject: [PATCH 17/37] imx93_frdm: Add OP-TEE device tree node Add missing firmware/optee node, so is can be both used and copied into Linux device tree by optee_copy_firmware_node(). This is consistent with other i.MX93 boards. Signed-off-by: Mathieu Dubois-Briand --- arch/arm/dts/imx93-11x11-frdm-u-boot.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/dts/imx93-11x11-frdm-u-boot.dtsi b/arch/arm/dts/imx93-11x11-frdm-u-boot.dtsi index 41111b1a95a..2ce9f46b2ad 100644 --- a/arch/arm/dts/imx93-11x11-frdm-u-boot.dtsi +++ b/arch/arm/dts/imx93-11x11-frdm-u-boot.dtsi @@ -12,6 +12,13 @@ bootph-pre-ram; bootph-some-ram; }; + + firmware { + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; }; &A55_0 { From bb4b0925d48c51c2e5241e3d058aae3d3f486e9c Mon Sep 17 00:00:00 2001 From: Ye Li Date: Fri, 10 Jul 2026 18:27:21 +0800 Subject: [PATCH 18/37] imx9: scmi: Update get mac from fuse for iMX952 Since iMX952 only has 2 pf and 2 vf, update the imx_get_mac_from_fuse to adapt this layout. Signed-off-by: Ye Li --- arch/arm/mach-imx/imx9/scmi/soc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c index 6561de205d0..e8f739920be 100644 --- a/arch/arm/mach-imx/imx9/scmi/soc.c +++ b/arch/arm/mach-imx/imx9/scmi/soc.c @@ -662,6 +662,18 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) eth_addr_add(mac, 8); /* enetc1 */ if (dev_id == 2) eth_addr_add(mac, 9); /* enetc2 */ + } else if (is_imx952()) { + /* + * i.MX952 uses the following mac address offset list: + * | No. | Mac address user | + * |-----|----------------------| + * | 0 | enetc mac pf0 | + * | 1 | enetc mac vf0 | + * | 2 | enetc mac pf1 | + * | 3 | enetc mac vf1 | + */ + if (dev_id == 1) + eth_addr_add(mac, 2); } else { if (dev_id == 1) eth_addr_add(mac, 3); From 1f829fcc2adebef777a77b9d6cbdc3139aff2728 Mon Sep 17 00:00:00 2001 From: Emanuele Ghidoli Date: Fri, 10 Jul 2026 15:39:08 +0200 Subject: [PATCH 19/37] board: toradex: smarc-imx95: detect RAM sizes Use alias-based RAM probing to detect different memory configurations on Toradex SMARC iMX95. The address wrap-around is not linear: address bits above the module capacity alias back with some low address bits XORed (bit 32 -> XOR 0xc000), as measured on 4GB and 8GB modules. During probing, skip the first 256MB, since that region is reserved. Signed-off-by: Emanuele Ghidoli --- board/toradex/smarc-imx95/smarc-imx95.c | 23 ++++++++++++++++++++++- include/configs/toradex-smarc-imx95.h | 15 +++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/board/toradex/smarc-imx95/smarc-imx95.c b/board/toradex/smarc-imx95/smarc-imx95.c index 6040c49975a..d09ce8a52ab 100644 --- a/board/toradex/smarc-imx95/smarc-imx95.c +++ b/board/toradex/smarc-imx95/smarc-imx95.c @@ -3,14 +3,35 @@ #include #include +#include #include #include #include "../common/tdx-cfg-block.h" +/* + * The address wrap-around is not linear: address bits above the module + * capacity alias back to the base with some low address bits XORed, as + * measured on 4GB and 8GB modules (bit 32 -> XOR 0xc000, bit 33 -> XOR + * 0x2000). + */ +static const struct ram_alias_check ram_alias_checks[] = { + { (void *)((uintptr_t)PHYS_SDRAM + SZ_4G), (void *)((uintptr_t)PHYS_SDRAM + 0xc000), SZ_8G }, + { (void *)((uintptr_t)PHYS_SDRAM + SZ_2G), (void *)(PHYS_SDRAM), SZ_4G }, + { NULL } +}; + int board_phys_sdram_size(phys_size_t *size) { - *size = PHYS_SDRAM_SIZE + PHYS_SDRAM_2_SIZE; + phys_size_t sz; + + sz = probe_ram_size_by_alias(ram_alias_checks); + if (!sz) { + puts("## WARNING: Less than 4GB RAM detected\n"); + return -EINVAL; + } + + *size = sz - PHYS_SDRAM_FW_RSVD; return 0; } diff --git a/include/configs/toradex-smarc-imx95.h b/include/configs/toradex-smarc-imx95.h index 8a880b96503..97e3322ac28 100644 --- a/include/configs/toradex-smarc-imx95.h +++ b/include/configs/toradex-smarc-imx95.h @@ -7,16 +7,19 @@ #include #include -/* module has 8GB, 2GB from 0x80000000..0xffffffff, 6GB above */ +/* module has 8GB, 2GB from 0x80000000..0xffffffff, 6GB above. + * Actual size is determined at runtime. + */ #define SZ_6G _AC(0x180000000, ULL) -/* first 256MB reserved for firmware */ -#define CFG_SYS_INIT_RAM_ADDR 0x90000000 +/* The first 256MB of SDRAM is reserved for firmware (Cortex M7) */ +#define PHYS_SDRAM_FW_RSVD SZ_256M +#define CFG_SYS_INIT_RAM_ADDR PHYS_SDRAM #define CFG_SYS_INIT_RAM_SIZE SZ_2M -#define CFG_SYS_SDRAM_BASE 0x90000000 -#define PHYS_SDRAM 0x90000000 -#define PHYS_SDRAM_SIZE (SZ_2G - SZ_256M) +#define CFG_SYS_SDRAM_BASE PHYS_SDRAM +#define PHYS_SDRAM (0x80000000 + PHYS_SDRAM_FW_RSVD) +#define PHYS_SDRAM_SIZE (SZ_2G - PHYS_SDRAM_FW_RSVD) #define PHYS_SDRAM_2_SIZE SZ_6G #endif From 3685450a81185af9b12f2330088f7197bbfd69a0 Mon Sep 17 00:00:00 2001 From: Emanuele Ghidoli Date: Fri, 10 Jul 2026 15:39:09 +0200 Subject: [PATCH 20/37] board: toradex: aquila-imx95: detect RAM sizes Use alias-based RAM probing to detect different memory configurations on Toradex Aquila iMX95. The address wrap-around is not linear: address bits above the module capacity alias back with some low address bits XORed (bit 32 -> XOR 0xc000), as measured on 4GB and 8GB modules. During probing, skip the first 256MB, since that region is reserved. Signed-off-by: Emanuele Ghidoli --- board/toradex/aquila-imx95/aquila-imx95.c | 23 ++++++++++++++++++++++- include/configs/aquila-imx95.h | 15 +++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/board/toradex/aquila-imx95/aquila-imx95.c b/board/toradex/aquila-imx95/aquila-imx95.c index 0c6473e4b3a..a5b26ef3dc3 100644 --- a/board/toradex/aquila-imx95/aquila-imx95.c +++ b/board/toradex/aquila-imx95/aquila-imx95.c @@ -3,14 +3,35 @@ #include #include +#include #include #include #include "../common/tdx-cfg-block.h" +/* + * The address wrap-around is not linear: address bits above the module + * capacity alias back to the base with some low address bits XORed, as + * measured on 4GB and 8GB modules (bit 32 -> XOR 0xc000, bit 33 -> XOR + * 0x2000). + */ +static const struct ram_alias_check ram_alias_checks[] = { + { (void *)((uintptr_t)PHYS_SDRAM + SZ_4G), (void *)((uintptr_t)PHYS_SDRAM + 0xc000), SZ_8G }, + { (void *)((uintptr_t)PHYS_SDRAM + SZ_2G), (void *)(PHYS_SDRAM), SZ_4G }, + { NULL } +}; + int board_phys_sdram_size(phys_size_t *size) { - *size = PHYS_SDRAM_SIZE + PHYS_SDRAM_2_SIZE; + phys_size_t sz; + + sz = probe_ram_size_by_alias(ram_alias_checks); + if (!sz) { + puts("## WARNING: Less than 4GB RAM detected\n"); + return -EINVAL; + } + + *size = sz - PHYS_SDRAM_FW_RSVD; return 0; } diff --git a/include/configs/aquila-imx95.h b/include/configs/aquila-imx95.h index 07d09d138cb..96c11ff2d5b 100644 --- a/include/configs/aquila-imx95.h +++ b/include/configs/aquila-imx95.h @@ -10,16 +10,19 @@ #define CFG_SYS_UBOOT_BASE \ (QSPI0_AMBA_BASE + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512) -/* module has 8GB, 2GB from 0x80000000..0xffffffff, 6GB above */ +/* module has 8GB, 2GB from 0x80000000..0xffffffff, 6GB above. + * Actual size is determined at runtime. + */ #define SZ_6G _AC(0x180000000, ULL) -/* first 256MB reserved for firmware */ -#define CFG_SYS_INIT_RAM_ADDR 0x90000000 +/* The first 256MB of SDRAM is reserved for firmware (Cortex M7) */ +#define PHYS_SDRAM_FW_RSVD SZ_256M +#define CFG_SYS_INIT_RAM_ADDR PHYS_SDRAM #define CFG_SYS_INIT_RAM_SIZE SZ_2M -#define CFG_SYS_SDRAM_BASE 0x90000000 -#define PHYS_SDRAM 0x90000000 -#define PHYS_SDRAM_SIZE (SZ_2G - SZ_256M) +#define CFG_SYS_SDRAM_BASE PHYS_SDRAM +#define PHYS_SDRAM (0x80000000 + PHYS_SDRAM_FW_RSVD) +#define PHYS_SDRAM_SIZE (SZ_2G - PHYS_SDRAM_FW_RSVD) #define PHYS_SDRAM_2_SIZE SZ_6G #define CFG_SYS_SECURE_SDRAM_BASE 0x8A000000 /* Secure DDR region for A55, SPL could use first 2MB */ From f7d1cb673de0c483f82c6abec86ff2cbf7133025 Mon Sep 17 00:00:00 2001 From: Vitor Soares Date: Fri, 10 Jul 2026 15:32:59 +0100 Subject: [PATCH 21/37] toradex: tdx-cfg-block: Add smarc imx95 0229 pid4 Add the new 0229 PID4 to config block handling: - 0229 SMARC iMX95 Hexa 4GB IT Signed-off-by: Vitor Soares --- board/toradex/common/tdx-cfg-block.c | 1 + board/toradex/common/tdx-cfg-block.h | 1 + 2 files changed, 2 insertions(+) diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index 896a0d3bd12..c46dd46ca98 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -190,6 +190,7 @@ const struct toradex_som toradex_modules[] = { { VERDIN_IMX95H_4G_WB_IT, "Verdin iMX95 Hexa 4GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX95) }, { VERDIN_IMX95H_4G_ET, "Verdin iMX95 Hexa 4GB ET", TARGET_IS_ENABLED(VERDIN_IMX95) }, { VERDIN_IMX95H_16G_IT, "Verdin iMX95 Hexa 16GB IT", TARGET_IS_ENABLED(VERDIN_IMX95) }, + { SMARC_IMX95_HEXA_4GB_IT, "SMARC iMX95 Hexa 4GB IT", TARGET_IS_ENABLED(TORADEX_SMARC_IMX95) }, }; struct pid4list { diff --git a/board/toradex/common/tdx-cfg-block.h b/board/toradex/common/tdx-cfg-block.h index 9a96bddfbe1..3ff7c2b6376 100644 --- a/board/toradex/common/tdx-cfg-block.h +++ b/board/toradex/common/tdx-cfg-block.h @@ -153,6 +153,7 @@ enum { VERDIN_IMX95H_4G_WB_IT = 226, VERDIN_IMX95H_4G_ET, VERDIN_IMX95H_16G_IT, + SMARC_IMX95_HEXA_4GB_IT, }; enum { From 9d42978d91a1721781aa0f7ae08a2d95d972d762 Mon Sep 17 00:00:00 2001 From: Vitor Soares Date: Fri, 10 Jul 2026 15:33:00 +0100 Subject: [PATCH 22/37] toradex: tdx-cfg-block: Add aquila tda4 0230 pid4 Add the new 0230 PID4 to config block handling: - 0230 Aquila TDA4 Octa 8GB IT Signed-off-by: Vitor Soares --- board/toradex/common/tdx-cfg-block.c | 1 + board/toradex/common/tdx-cfg-block.h | 1 + 2 files changed, 2 insertions(+) diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index c46dd46ca98..3ac253e69ea 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -191,6 +191,7 @@ const struct toradex_som toradex_modules[] = { { VERDIN_IMX95H_4G_ET, "Verdin iMX95 Hexa 4GB ET", TARGET_IS_ENABLED(VERDIN_IMX95) }, { VERDIN_IMX95H_16G_IT, "Verdin iMX95 Hexa 16GB IT", TARGET_IS_ENABLED(VERDIN_IMX95) }, { SMARC_IMX95_HEXA_4GB_IT, "SMARC iMX95 Hexa 4GB IT", TARGET_IS_ENABLED(TORADEX_SMARC_IMX95) }, + { AQUILA_TDA4O_8GB_IT, "Aquila TDA4 Octa 8GB IT", TARGET_IS_ENABLED(AQUILA_AM69_A72) }, }; struct pid4list { diff --git a/board/toradex/common/tdx-cfg-block.h b/board/toradex/common/tdx-cfg-block.h index 3ff7c2b6376..8fe76640c46 100644 --- a/board/toradex/common/tdx-cfg-block.h +++ b/board/toradex/common/tdx-cfg-block.h @@ -154,6 +154,7 @@ enum { VERDIN_IMX95H_4G_ET, VERDIN_IMX95H_16G_IT, SMARC_IMX95_HEXA_4GB_IT, + AQUILA_TDA4O_8GB_IT, /* 230 */ }; enum { From 6c00fdf583e59829cf9f1792d8b46774eb6e5225 Mon Sep 17 00:00:00 2001 From: Vitor Soares Date: Fri, 10 Jul 2026 15:33:01 +0100 Subject: [PATCH 23/37] toradex: tdx-cfg-block: Add apalis imx8qm 64gb emmc pid4s Add the new Apalis iMX8QM 64GB eMMC PID4s to config block handling: - 0233 Apalis iMX8QM 4GB WB IT - 0234 Apalis iMX8QM 4GB IT - 0235 Apalis iMX8QM 8GB WB IT Signed-off-by: Vitor Soares --- board/toradex/common/tdx-cfg-block.c | 3 +++ board/toradex/common/tdx-cfg-block.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index 3ac253e69ea..21baa810f2f 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -192,6 +192,9 @@ const struct toradex_som toradex_modules[] = { { VERDIN_IMX95H_16G_IT, "Verdin iMX95 Hexa 16GB IT", TARGET_IS_ENABLED(VERDIN_IMX95) }, { SMARC_IMX95_HEXA_4GB_IT, "SMARC iMX95 Hexa 4GB IT", TARGET_IS_ENABLED(TORADEX_SMARC_IMX95) }, { AQUILA_TDA4O_8GB_IT, "Aquila TDA4 Octa 8GB IT", TARGET_IS_ENABLED(AQUILA_AM69_A72) }, + { APALIS_IMX8QM_4GB_WIFI_BT_IT_64G, "Apalis iMX8QM 4GB WB IT", TARGET_IS_ENABLED(APALIS_IMX8) }, + { APALIS_IMX8QM_4GB_IT_64G, "Apalis iMX8QM 4GB IT", TARGET_IS_ENABLED(APALIS_IMX8) }, + { APALIS_IMX8QM_8GB_WIFI_BT_IT_64G, "Apalis iMX8QM 8GB WB IT", TARGET_IS_ENABLED(APALIS_IMX8) }, }; struct pid4list { diff --git a/board/toradex/common/tdx-cfg-block.h b/board/toradex/common/tdx-cfg-block.h index 8fe76640c46..e6e726f381c 100644 --- a/board/toradex/common/tdx-cfg-block.h +++ b/board/toradex/common/tdx-cfg-block.h @@ -155,6 +155,9 @@ enum { VERDIN_IMX95H_16G_IT, SMARC_IMX95_HEXA_4GB_IT, AQUILA_TDA4O_8GB_IT, /* 230 */ + APALIS_IMX8QM_4GB_WIFI_BT_IT_64G = 233, + APALIS_IMX8QM_4GB_IT_64G, + APALIS_IMX8QM_8GB_WIFI_BT_IT_64G, /* 235 */ }; enum { From 30586348b87b99ea83a80a89b0a7996dc4ebc787 Mon Sep 17 00:00:00 2001 From: Vitor Soares Date: Fri, 10 Jul 2026 15:33:02 +0100 Subject: [PATCH 24/37] toradex: tdx-cfg-block: Add verdin imx8mp 64gb emmc pid4s Add the new Verdin iMX8M Plus 64GB eMMC PID4s to config block handling: - 0236 Verdin iMX8M Plus Quad 4GB WB IT - 0237 Verdin iMX8M Plus Quad 4GB IT - 0238 Verdin iMX8M Plus Quad 8GB WB IT Update the board-specific variant selection to use the Wi-Fi variant for the new WB SKUs. Signed-off-by: Vitor Soares --- board/toradex/common/tdx-cfg-block.c | 3 +++ board/toradex/common/tdx-cfg-block.h | 3 +++ board/toradex/verdin-imx8mp/verdin-imx8mp.c | 4 +++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index 21baa810f2f..8b4698e92e1 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -195,6 +195,9 @@ const struct toradex_som toradex_modules[] = { { APALIS_IMX8QM_4GB_WIFI_BT_IT_64G, "Apalis iMX8QM 4GB WB IT", TARGET_IS_ENABLED(APALIS_IMX8) }, { APALIS_IMX8QM_4GB_IT_64G, "Apalis iMX8QM 4GB IT", TARGET_IS_ENABLED(APALIS_IMX8) }, { APALIS_IMX8QM_8GB_WIFI_BT_IT_64G, "Apalis iMX8QM 8GB WB IT", TARGET_IS_ENABLED(APALIS_IMX8) }, + { VERDIN_IMX8MPQ_4GB_WIFI_BT_IT_64G, "Verdin iMX8M Plus Quad 4GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) }, + { VERDIN_IMX8MPQ_4GB_IT_64G, "Verdin iMX8M Plus Quad 4GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) }, + { VERDIN_IMX8MPQ_8GB_WIFI_BT_IT_64G, "Verdin iMX8M Plus Quad 8GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) }, }; struct pid4list { diff --git a/board/toradex/common/tdx-cfg-block.h b/board/toradex/common/tdx-cfg-block.h index e6e726f381c..4bf4f2e6843 100644 --- a/board/toradex/common/tdx-cfg-block.h +++ b/board/toradex/common/tdx-cfg-block.h @@ -158,6 +158,9 @@ enum { APALIS_IMX8QM_4GB_WIFI_BT_IT_64G = 233, APALIS_IMX8QM_4GB_IT_64G, APALIS_IMX8QM_8GB_WIFI_BT_IT_64G, /* 235 */ + VERDIN_IMX8MPQ_4GB_WIFI_BT_IT_64G, + VERDIN_IMX8MPQ_4GB_IT_64G, + VERDIN_IMX8MPQ_8GB_WIFI_BT_IT_64G, }; enum { diff --git a/board/toradex/verdin-imx8mp/verdin-imx8mp.c b/board/toradex/verdin-imx8mp/verdin-imx8mp.c index 69c3408fbba..1209da593f8 100644 --- a/board/toradex/verdin-imx8mp/verdin-imx8mp.c +++ b/board/toradex/verdin-imx8mp/verdin-imx8mp.c @@ -79,7 +79,9 @@ static void select_dt_from_module_version(void) is_wifi = (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_WIFI_BT_IT) || (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_2GB_WIFI_BT_IT) || (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_8GB_WIFI_BT) || - (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_8GB_WIFI_BT_IT); + (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_8GB_WIFI_BT_IT) || + (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_4GB_WIFI_BT_IT_64G) || + (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_8GB_WIFI_BT_IT_64G); } if (is_wifi) From 96a52d11aea6f893c3b1b4787c934d6cf7dfce60 Mon Sep 17 00:00:00 2001 From: Vitor Soares Date: Fri, 10 Jul 2026 15:33:03 +0100 Subject: [PATCH 25/37] toradex: tdx-cfg-block: Add verdin imx8mm 0239 pid4 Add the new 0239 PID4 to config block handling: - 0239 Verdin iMX8M Mini Quad 2GB WB IT Update the board-specific variant selection to use the Wi-Fi variant for the new WB SKU. Signed-off-by: Vitor Soares --- board/toradex/common/tdx-cfg-block.c | 1 + board/toradex/common/tdx-cfg-block.h | 1 + board/toradex/verdin-imx8mm/verdin-imx8mm.c | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index 8b4698e92e1..cdeb2e4b4de 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -198,6 +198,7 @@ const struct toradex_som toradex_modules[] = { { VERDIN_IMX8MPQ_4GB_WIFI_BT_IT_64G, "Verdin iMX8M Plus Quad 4GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) }, { VERDIN_IMX8MPQ_4GB_IT_64G, "Verdin iMX8M Plus Quad 4GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) }, { VERDIN_IMX8MPQ_8GB_WIFI_BT_IT_64G, "Verdin iMX8M Plus Quad 8GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) }, + { VERDIN_IMX8MMQ_2G_WIFI_BT_IT_64G, "Verdin iMX8M Mini Quad 2GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) }, }; struct pid4list { diff --git a/board/toradex/common/tdx-cfg-block.h b/board/toradex/common/tdx-cfg-block.h index 4bf4f2e6843..3b32fbb0610 100644 --- a/board/toradex/common/tdx-cfg-block.h +++ b/board/toradex/common/tdx-cfg-block.h @@ -161,6 +161,7 @@ enum { VERDIN_IMX8MPQ_4GB_WIFI_BT_IT_64G, VERDIN_IMX8MPQ_4GB_IT_64G, VERDIN_IMX8MPQ_8GB_WIFI_BT_IT_64G, + VERDIN_IMX8MMQ_2G_WIFI_BT_IT_64G, }; enum { diff --git a/board/toradex/verdin-imx8mm/verdin-imx8mm.c b/board/toradex/verdin-imx8mm/verdin-imx8mm.c index b56f5bf30a8..4e308084968 100644 --- a/board/toradex/verdin-imx8mm/verdin-imx8mm.c +++ b/board/toradex/verdin-imx8mm/verdin-imx8mm.c @@ -83,7 +83,8 @@ static void select_dt_from_module_version(void) (tdx_hw_tag.prodid == VERDIN_IMX8MMDL_WIFI_BT_IT) || (tdx_hw_tag.prodid == VERDIN_IMX8MMQ_WIFI_BT_IT_NO_CAN) || (tdx_hw_tag.prodid == VERDIN_IMX8MMQ_4G_WIFI_BT_ET) || - (tdx_hw_tag.prodid == VERDIN_IMX8MMQ_WB_IT_64G); + (tdx_hw_tag.prodid == VERDIN_IMX8MMQ_WB_IT_64G) || + (tdx_hw_tag.prodid == VERDIN_IMX8MMQ_2G_WIFI_BT_IT_64G); } switch (get_pcb_revision()) { From 815de583703a1e9fd6d1e24c3292927f4b7506d4 Mon Sep 17 00:00:00 2001 From: Vitor Soares Date: Fri, 10 Jul 2026 15:33:04 +0100 Subject: [PATCH 26/37] toradex: tdx-cfg-block: Add smarc imx8mp 0240 pid4 Add the new 0240 PID4 to config block handling: - 0240 SMARC iMX8M Plus Quad 4GB WB IT Signed-off-by: Vitor Soares --- board/toradex/common/tdx-cfg-block.c | 1 + board/toradex/common/tdx-cfg-block.h | 1 + 2 files changed, 2 insertions(+) diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index cdeb2e4b4de..465254ac2bf 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -199,6 +199,7 @@ const struct toradex_som toradex_modules[] = { { VERDIN_IMX8MPQ_4GB_IT_64G, "Verdin iMX8M Plus Quad 4GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) }, { VERDIN_IMX8MPQ_8GB_WIFI_BT_IT_64G, "Verdin iMX8M Plus Quad 8GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) }, { VERDIN_IMX8MMQ_2G_WIFI_BT_IT_64G, "Verdin iMX8M Mini Quad 2GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) }, + { SMARC_IMX8MPQ_4GB_WB_IT_64G, "SMARC iMX8M Plus Quad 4GB WB IT", TARGET_IS_ENABLED(TORADEX_SMARC_IMX8MP) }, }; struct pid4list { diff --git a/board/toradex/common/tdx-cfg-block.h b/board/toradex/common/tdx-cfg-block.h index 3b32fbb0610..2d038a67a1b 100644 --- a/board/toradex/common/tdx-cfg-block.h +++ b/board/toradex/common/tdx-cfg-block.h @@ -162,6 +162,7 @@ enum { VERDIN_IMX8MPQ_4GB_IT_64G, VERDIN_IMX8MPQ_8GB_WIFI_BT_IT_64G, VERDIN_IMX8MMQ_2G_WIFI_BT_IT_64G, + SMARC_IMX8MPQ_4GB_WB_IT_64G, /* 240 */ }; enum { From 2e49ea72ff5f77bfe3c4a6c0752b99eb57db8801 Mon Sep 17 00:00:00 2001 From: Vitor Soares Date: Fri, 10 Jul 2026 15:33:05 +0100 Subject: [PATCH 27/37] toradex: tdx-cfg-block: Add verdin am62 0242 pid4 Add the new 0242 PID4 to config block handling: - 0242 Verdin AM62 Dual 1GB WB ET Update the board-specific variant selection to use the Wi-Fi variant for the new WB SKU. Signed-off-by: Vitor Soares --- board/toradex/common/tdx-cfg-block.c | 1 + board/toradex/common/tdx-cfg-block.h | 1 + board/toradex/verdin-am62/verdin-am62.c | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index 465254ac2bf..1998411ebde 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -200,6 +200,7 @@ const struct toradex_som toradex_modules[] = { { VERDIN_IMX8MPQ_8GB_WIFI_BT_IT_64G, "Verdin iMX8M Plus Quad 8GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) }, { VERDIN_IMX8MMQ_2G_WIFI_BT_IT_64G, "Verdin iMX8M Mini Quad 2GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) }, { SMARC_IMX8MPQ_4GB_WB_IT_64G, "SMARC iMX8M Plus Quad 4GB WB IT", TARGET_IS_ENABLED(TORADEX_SMARC_IMX8MP) }, + { VERDIN_AM62D_1G_WIFI_BT_ET, "Verdin AM62 Dual 1GB WB ET", TARGET_IS_ENABLED(VERDIN_AM62_A53) }, }; struct pid4list { diff --git a/board/toradex/common/tdx-cfg-block.h b/board/toradex/common/tdx-cfg-block.h index 2d038a67a1b..bf6a0861378 100644 --- a/board/toradex/common/tdx-cfg-block.h +++ b/board/toradex/common/tdx-cfg-block.h @@ -163,6 +163,7 @@ enum { VERDIN_IMX8MPQ_8GB_WIFI_BT_IT_64G, VERDIN_IMX8MMQ_2G_WIFI_BT_IT_64G, SMARC_IMX8MPQ_4GB_WB_IT_64G, /* 240 */ + VERDIN_AM62D_1G_WIFI_BT_ET = 242, }; enum { diff --git a/board/toradex/verdin-am62/verdin-am62.c b/board/toradex/verdin-am62/verdin-am62.c index a174cc43ade..6d55638b44b 100644 --- a/board/toradex/verdin-am62/verdin-am62.c +++ b/board/toradex/verdin-am62/verdin-am62.c @@ -84,7 +84,8 @@ static void select_dt_from_module_version(void) is_wifi = (tdx_hw_tag.prodid == VERDIN_AM62Q_WIFI_BT_IT) || (tdx_hw_tag.prodid == VERDIN_AM62S_512MB_WIFI_BT_IT) || (tdx_hw_tag.prodid == VERDIN_AM62D_1G_WIFI_BT_IT) || - (tdx_hw_tag.prodid == VERDIN_AM62Q_2G_WIFI_BT_IT); + (tdx_hw_tag.prodid == VERDIN_AM62Q_2G_WIFI_BT_IT) || + (tdx_hw_tag.prodid == VERDIN_AM62D_1G_WIFI_BT_ET); } if (is_wifi) From 771dca9677df6405be1598682fae46356b9a3484 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 11 Jul 2026 00:39:50 +0200 Subject: [PATCH 28/37] arm64: imx: Handle both MMC2 and SD2 boot devices on Data Modul i.MX8M Mini eDM SBC Handle both MMC2 and SD2 boot devices as SDMMC device 1 on Data Modul i.MX8M Mini eDM SBC. In case the system boots from a microSD card, the BootROM reports boot device as SD2_BOOT instead of MMC2_BOOT. Continue booting from that SDMMC device instead of falling back to SDP. Note that SDMMC device 1 is the microSD slot on this device, SDMMC device 2 is the eMMC, but BootROM reports the numbers the other way around, hence the potential confusion in this commit message. Fixes: 0b97a394f6b7 ("ARM: imx: Replace YModem with SDP on Data Modul i.MX8M Mini eDM SBC SPL") Signed-off-by: Marek Vasut Reviewed-by: Peng Fan --- board/data_modul/imx8mm_edm_sbc/spl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/data_modul/imx8mm_edm_sbc/spl.c b/board/data_modul/imx8mm_edm_sbc/spl.c index c6a5740c7a7..6071fb405a7 100644 --- a/board/data_modul/imx8mm_edm_sbc/spl.c +++ b/board/data_modul/imx8mm_edm_sbc/spl.c @@ -59,7 +59,7 @@ int spl_board_boot_device(enum boot_device boot_dev_spl) { if (boot_dev_spl == MMC3_BOOT) return BOOT_DEVICE_MMC2; /* eMMC */ - else if (boot_dev_spl == MMC2_BOOT) + else if (boot_dev_spl == MMC2_BOOT || boot_dev_spl == SD2_BOOT) return BOOT_DEVICE_MMC1; /* SD */ else return BOOT_DEVICE_BOARD; From 5c2fc4acc4ef160bbf527cc1818f13fdda9bf7e9 Mon Sep 17 00:00:00 2001 From: Alexander Koch Date: Sat, 11 Jul 2026 15:39:33 +0200 Subject: [PATCH 29/37] rtc: snvs: Add i.MX SNVS RTC driver Add simple driver for i.MX SNVS RTC IP present in NXP i.MX SoCs. Signed-off-by: Alexander Koch Signed-off-by: Marek Vasut --- drivers/rtc/Kconfig | 7 +++ drivers/rtc/Makefile | 1 + drivers/rtc/snvs-rtc.c | 118 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 drivers/rtc/snvs-rtc.c diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6fb3019a644..5b44cc99c97 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -296,6 +296,13 @@ config SPL_RTC_SANDBOX emulator and is used to test the RTC uclasses and associated code, as well as the I2C subsystem. +config RTC_SNVS + bool "Enable i.MX SNVS RTC driver" + depends on DM_RTC + help + Enable i.MX RTC driver. This driver supports the RTC that is present + on various NXP i.MX SoCs. + config RTC_STM32 bool "Enable STM32 RTC driver" depends on DM_RTC diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 782f5a3bc3d..742481ce185 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_RTC_RV8803) += rv8803.o obj-$(CONFIG_RTC_RX8025) += rx8025.o obj-$(CONFIG_RTC_RX8010SJ) += rx8010sj.o obj-$(CONFIG_RTC_S35392A) += s35392a.o +obj-$(CONFIG_RTC_SNVS) += snvs-rtc.o obj-$(CONFIG_RTC_STM32) += stm32_rtc.o obj-$(CONFIG_$(PHASE_)RTC_SANDBOX) += sandbox_rtc.o obj-$(CONFIG_RTC_ABX80X) += abx80x.o diff --git a/drivers/rtc/snvs-rtc.c b/drivers/rtc/snvs-rtc.c new file mode 100644 index 00000000000..c1b4fa0f8da --- /dev/null +++ b/drivers/rtc/snvs-rtc.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018-2026 INIT GmbH, Alexander Koch + */ + +#include +#include +#include +#include +#include +#include + +#define SNVS_LPSRTCMR 0x1c +#define SNVS_LPSRTCLR 0x20 +#define SNVS_LPCR 0x04 +#define SNVS_LPCR_SRTC_ENV BIT(0) +#define CNTR_TO_SECS_SH 15 + +struct snvs_rtc_priv { + fdt_addr_t base; +}; + +static int snvs_rtc_enable(struct udevice *dev) +{ + struct snvs_rtc_priv *priv = dev_get_priv(dev); + u32 val; + + setbits_le32(priv->base + SNVS_LPCR, SNVS_LPCR_SRTC_ENV); + + return readl_poll_timeout(priv->base + SNVS_LPCR, val, + (val & SNVS_LPCR_SRTC_ENV), 1000); +} + +static int snvs_rtc_disable(struct udevice *dev) +{ + struct snvs_rtc_priv *priv = dev_get_priv(dev); + u32 val; + + clrbits_le32(priv->base + SNVS_LPCR, SNVS_LPCR_SRTC_ENV); + + return readl_poll_timeout(priv->base + SNVS_LPCR, val, + !(val & SNVS_LPCR_SRTC_ENV), 1000); +} + +static int snvs_rtc_get(struct udevice *dev, struct rtc_time *tm) +{ + struct snvs_rtc_priv *priv = dev_get_priv(dev); + u64 read1, read2; + + /* Require two identical consecutive reads as stated in manual */ + do { + read1 = (u64)readl(priv->base + SNVS_LPSRTCMR) << 32ULL; + read1 |= readl(priv->base + SNVS_LPSRTCLR); + + read2 = (u64)readl(priv->base + SNVS_LPSRTCMR) << 32ULL; + read2 |= readl(priv->base + SNVS_LPSRTCLR); + } while (read1 != read2); + + /* Convert 47-bit counter to 32-bit raw second count */ + rtc_to_tm((time_t)(read1 >> CNTR_TO_SECS_SH), tm); + + return 0; +} + +static int snvs_rtc_set(struct udevice *dev, const struct rtc_time *tm) +{ + struct snvs_rtc_priv *priv = dev_get_priv(dev); + u32 time = rtc_mktime(tm); + int ret; + + ret = snvs_rtc_disable(dev); + if (ret) + return ret; + + /* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */ + writel(time << CNTR_TO_SECS_SH, priv->base + SNVS_LPSRTCLR); + writel(time >> (32 - CNTR_TO_SECS_SH), priv->base + SNVS_LPSRTCMR); + + return snvs_rtc_enable(dev); +} + +static const struct rtc_ops snvs_rtc_ops = { + .get = snvs_rtc_get, + .set = snvs_rtc_set, +}; + +static int snvs_rtc_probe(struct udevice *dev) +{ + struct snvs_rtc_priv *priv = dev_get_priv(dev); + u32 offset; + int ret; + + priv->base = dev_read_addr(dev->parent); + if (priv->base == FDT_ADDR_T_NONE) + return -EINVAL; + + ret = dev_read_u32(dev, "offset", &offset); + if (ret) + return ret; + + priv->base += offset; + + return snvs_rtc_enable(dev); +} + +static const struct udevice_id snvs_rtc_ids[] = { + { .compatible = "fsl,sec-v4.0-mon-rtc-lp" }, + { } +}; + +U_BOOT_DRIVER(rtc_snvs) = { + .name = "rtc-snvs", + .id = UCLASS_RTC, + .probe = snvs_rtc_probe, + .of_match = snvs_rtc_ids, + .ops = &snvs_rtc_ops, + .priv_auto = sizeof(struct snvs_rtc_priv), +}; From 2484741fec39eece54824012e348c2bdbf9ff0f7 Mon Sep 17 00:00:00 2001 From: Markus Niebel Date: Mon, 13 Jul 2026 15:01:01 +0200 Subject: [PATCH 30/37] board: tqma6: change U-Boot device tree fragments We will need GPIO to distinguish between SOM variants with / without workaround for ENET errata. This is necessary to implement the appropriate solution and remove code intended for the non-DM use case. To support reuse, split them in SOM and baseboard specific parts. Prepare fragments for use with SPL. Signed-off-by: Markus Niebel Signed-off-by: Max Merchel --- arch/arm/dts/imx6dl-mba6a-u-boot.dtsi | 8 ++++++ arch/arm/dts/imx6dl-mba6b-u-boot.dtsi | 7 ++++- arch/arm/dts/imx6q-mba6a-u-boot.dtsi | 8 ++++++ arch/arm/dts/imx6q-mba6b-u-boot.dtsi | 7 ++++- arch/arm/dts/imx6qdl-mba6-u-boot.dtsi | 37 +++++-------------------- arch/arm/dts/imx6qdl-tqma6-u-boot.dtsi | 18 ++++++++++++ arch/arm/dts/imx6qdl-tqma6a-u-boot.dtsi | 10 +++++++ arch/arm/dts/imx6qdl-tqma6b-u-boot.dtsi | 10 +++++++ 8 files changed, 73 insertions(+), 32 deletions(-) create mode 100644 arch/arm/dts/imx6dl-mba6a-u-boot.dtsi create mode 100644 arch/arm/dts/imx6q-mba6a-u-boot.dtsi create mode 100644 arch/arm/dts/imx6qdl-tqma6-u-boot.dtsi create mode 100644 arch/arm/dts/imx6qdl-tqma6a-u-boot.dtsi create mode 100644 arch/arm/dts/imx6qdl-tqma6b-u-boot.dtsi diff --git a/arch/arm/dts/imx6dl-mba6a-u-boot.dtsi b/arch/arm/dts/imx6dl-mba6a-u-boot.dtsi new file mode 100644 index 00000000000..d484a5dda00 --- /dev/null +++ b/arch/arm/dts/imx6dl-mba6a-u-boot.dtsi @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Markus Niebel + */ + +#include "imx6qdl-mba6-u-boot.dtsi" diff --git a/arch/arm/dts/imx6dl-mba6b-u-boot.dtsi b/arch/arm/dts/imx6dl-mba6b-u-boot.dtsi index bb17ba9b424..d484a5dda00 100644 --- a/arch/arm/dts/imx6dl-mba6b-u-boot.dtsi +++ b/arch/arm/dts/imx6dl-mba6b-u-boot.dtsi @@ -1,3 +1,8 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Markus Niebel + */ #include "imx6qdl-mba6-u-boot.dtsi" diff --git a/arch/arm/dts/imx6q-mba6a-u-boot.dtsi b/arch/arm/dts/imx6q-mba6a-u-boot.dtsi new file mode 100644 index 00000000000..d484a5dda00 --- /dev/null +++ b/arch/arm/dts/imx6q-mba6a-u-boot.dtsi @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Markus Niebel + */ + +#include "imx6qdl-mba6-u-boot.dtsi" diff --git a/arch/arm/dts/imx6q-mba6b-u-boot.dtsi b/arch/arm/dts/imx6q-mba6b-u-boot.dtsi index bb17ba9b424..d484a5dda00 100644 --- a/arch/arm/dts/imx6q-mba6b-u-boot.dtsi +++ b/arch/arm/dts/imx6q-mba6b-u-boot.dtsi @@ -1,3 +1,8 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Markus Niebel + */ #include "imx6qdl-mba6-u-boot.dtsi" diff --git a/arch/arm/dts/imx6qdl-mba6-u-boot.dtsi b/arch/arm/dts/imx6qdl-mba6-u-boot.dtsi index c8c0fc1fba7..535fd0c5e48 100644 --- a/arch/arm/dts/imx6qdl-mba6-u-boot.dtsi +++ b/arch/arm/dts/imx6qdl-mba6-u-boot.dtsi @@ -1,31 +1,8 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Markus Niebel + */ -#include "imx6qdl-u-boot.dtsi" - -/ { - wdt-reboot { - compatible = "wdt-reboot"; - wdt = <&wdog1>; - bootph-pre-ram; - }; -}; - -&aips2 { - bootph-all; -}; - -&pinctrl_uart2 { - bootph-all; -}; - -&soc { - bootph-all; -}; - -&uart2 { - bootph-all; -}; - -&wdog1 { - bootph-pre-ram; -}; +#include "imx6qdl-tqma6-u-boot.dtsi" diff --git a/arch/arm/dts/imx6qdl-tqma6-u-boot.dtsi b/arch/arm/dts/imx6qdl-tqma6-u-boot.dtsi new file mode 100644 index 00000000000..5b1a65583cf --- /dev/null +++ b/arch/arm/dts/imx6qdl-tqma6-u-boot.dtsi @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Markus Niebel + */ + +/* SOC specific U-Boot DT adjustments */ + +#include "imx6qdl-u-boot.dtsi" + +/ { + wdt-reboot { + compatible = "wdt-reboot"; + wdt = <&wdog1>; + bootph-pre-ram; + }; +}; diff --git a/arch/arm/dts/imx6qdl-tqma6a-u-boot.dtsi b/arch/arm/dts/imx6qdl-tqma6a-u-boot.dtsi new file mode 100644 index 00000000000..cb3f68e859b --- /dev/null +++ b/arch/arm/dts/imx6qdl-tqma6a-u-boot.dtsi @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Markus Niebel + */ + +/* SOC specific U-Boot DT adjustments */ + +#include "imx6qdl-tqma6-u-boot.dtsi" diff --git a/arch/arm/dts/imx6qdl-tqma6b-u-boot.dtsi b/arch/arm/dts/imx6qdl-tqma6b-u-boot.dtsi new file mode 100644 index 00000000000..cb3f68e859b --- /dev/null +++ b/arch/arm/dts/imx6qdl-tqma6b-u-boot.dtsi @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Markus Niebel + */ + +/* SOC specific U-Boot DT adjustments */ + +#include "imx6qdl-tqma6-u-boot.dtsi" From c644dec64af5182b8fbb142dbf62484f1583d5b1 Mon Sep 17 00:00:00 2001 From: Max Merchel Date: Mon, 13 Jul 2026 15:01:02 +0200 Subject: [PATCH 31/37] ARM: dts: tqma6: add boot phase properties Add boot phase properties from U-Boot device tree. This commit can be reverted if changes are integrated in upstreem device trees and synced with U-Boot. Signed-off-by: Max Merchel --- arch/arm/dts/imx6qdl-mba6-u-boot.dtsi | 32 ++++++++++++++++++++++ arch/arm/dts/imx6qdl-tqma6-u-boot.dtsi | 36 +++++++++++++++++++++++++ arch/arm/dts/imx6qdl-tqma6a-u-boot.dtsi | 4 +++ arch/arm/dts/imx6qdl-tqma6b-u-boot.dtsi | 8 ++++++ 4 files changed, 80 insertions(+) diff --git a/arch/arm/dts/imx6qdl-mba6-u-boot.dtsi b/arch/arm/dts/imx6qdl-mba6-u-boot.dtsi index 535fd0c5e48..22f67c6f966 100644 --- a/arch/arm/dts/imx6qdl-mba6-u-boot.dtsi +++ b/arch/arm/dts/imx6qdl-mba6-u-boot.dtsi @@ -6,3 +6,35 @@ */ #include "imx6qdl-tqma6-u-boot.dtsi" + +&gpio1 { + bootph-pre-ram; +}; + +&i2c1 { + bootph-pre-ram; +}; + +&pinctrl_uart2 { + bootph-pre-ram; +}; + +&pinctrl_usdhc2 { + bootph-pre-ram; +}; + +&pinctrl_wdog1{ + bootph-pre-ram; +}; + +&uart2 { + bootph-pre-ram; +}; + +&usdhc2 { + bootph-pre-ram; +}; + +&wdog1 { + bootph-pre-ram; +}; diff --git a/arch/arm/dts/imx6qdl-tqma6-u-boot.dtsi b/arch/arm/dts/imx6qdl-tqma6-u-boot.dtsi index 5b1a65583cf..b5269748058 100644 --- a/arch/arm/dts/imx6qdl-tqma6-u-boot.dtsi +++ b/arch/arm/dts/imx6qdl-tqma6-u-boot.dtsi @@ -16,3 +16,39 @@ bootph-pre-ram; }; }; + +&aips1 { + bootph-pre-ram; +}; + +&aips2 { + bootph-pre-ram; +}; + +&ecspi1 { + bootph-pre-ram; +}; + +&gpio3 { + bootph-pre-ram; +}; + +&m25p80 { + bootph-pre-ram; +}; + +&pinctrl_ecspi1 { + bootph-pre-ram; +}; + +&pinctrl_i2c1 { + bootph-pre-ram; +}; + +&pinctrl_usdhc3 { + bootph-pre-ram; +}; + +&usdhc3 { + bootph-pre-ram; +}; diff --git a/arch/arm/dts/imx6qdl-tqma6a-u-boot.dtsi b/arch/arm/dts/imx6qdl-tqma6a-u-boot.dtsi index cb3f68e859b..af72ac77a79 100644 --- a/arch/arm/dts/imx6qdl-tqma6a-u-boot.dtsi +++ b/arch/arm/dts/imx6qdl-tqma6a-u-boot.dtsi @@ -8,3 +8,7 @@ /* SOC specific U-Boot DT adjustments */ #include "imx6qdl-tqma6-u-boot.dtsi" + +&i2c1 { + bootph-pre-ram; +}; diff --git a/arch/arm/dts/imx6qdl-tqma6b-u-boot.dtsi b/arch/arm/dts/imx6qdl-tqma6b-u-boot.dtsi index cb3f68e859b..8ae7f2900f3 100644 --- a/arch/arm/dts/imx6qdl-tqma6b-u-boot.dtsi +++ b/arch/arm/dts/imx6qdl-tqma6b-u-boot.dtsi @@ -8,3 +8,11 @@ /* SOC specific U-Boot DT adjustments */ #include "imx6qdl-tqma6-u-boot.dtsi" + +&i2c3 { + bootph-pre-ram; +}; + +&pinctrl_i2c3 { + bootph-pre-ram; +}; From 2416b2a21cf1289b2c5232d49146964322412bc9 Mon Sep 17 00:00:00 2001 From: Max Merchel Date: Mon, 13 Jul 2026 15:01:03 +0200 Subject: [PATCH 32/37] dts: tqma6: mba6: remove old device trees No longer required due to the use of upstream device trees. Signed-off-by: Max Merchel --- arch/arm/dts/imx6dl-mba6.dtsi | 22 -- arch/arm/dts/imx6dl-mba6a.dts | 21 -- arch/arm/dts/imx6q-mba6.dtsi | 44 --- arch/arm/dts/imx6q-mba6a.dts | 20 -- arch/arm/dts/imx6qdl-mba6.dtsi | 535 -------------------------------- arch/arm/dts/imx6qdl-mba6a.dtsi | 30 -- arch/arm/dts/imx6qdl-mba6b.dtsi | 49 --- 7 files changed, 721 deletions(-) delete mode 100644 arch/arm/dts/imx6dl-mba6.dtsi delete mode 100644 arch/arm/dts/imx6dl-mba6a.dts delete mode 100644 arch/arm/dts/imx6q-mba6.dtsi delete mode 100644 arch/arm/dts/imx6q-mba6a.dts delete mode 100644 arch/arm/dts/imx6qdl-mba6.dtsi delete mode 100644 arch/arm/dts/imx6qdl-mba6a.dtsi delete mode 100644 arch/arm/dts/imx6qdl-mba6b.dtsi diff --git a/arch/arm/dts/imx6dl-mba6.dtsi b/arch/arm/dts/imx6dl-mba6.dtsi deleted file mode 100644 index b749b424bbd..00000000000 --- a/arch/arm/dts/imx6dl-mba6.dtsi +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2013 Sascha Hauer, Pengutronix - * - * Copyright 2013-2021 TQ-Systems GmbH - * Author: Markus Niebel - */ - -ðphy { - rxdv-skew-ps = <180>; - txen-skew-ps = <0>; - rxd3-skew-ps = <180>; - rxd2-skew-ps = <180>; - rxd1-skew-ps = <180>; - rxd0-skew-ps = <180>; - txd3-skew-ps = <120>; - txd2-skew-ps = <0>; - txd1-skew-ps = <300>; - txd0-skew-ps = <120>; - txc-skew-ps = <1860>; - rxc-skew-ps = <1860>; -}; diff --git a/arch/arm/dts/imx6dl-mba6a.dts b/arch/arm/dts/imx6dl-mba6a.dts deleted file mode 100644 index df0a96b28af..00000000000 --- a/arch/arm/dts/imx6dl-mba6a.dts +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2013 Sascha Hauer, Pengutronix - * - * Copyright 2013-2021 TQ-Systems GmbH - * Author: Markus Niebel - */ - -/dts-v1/; - -#include -#include "imx6dl-tqma6a.dtsi" -#include "imx6qdl-mba6.dtsi" -#include "imx6qdl-mba6a.dtsi" -#include "imx6dl-mba6.dtsi" - -/ { - model = "TQ TQMa6S/DL on MBa6x"; - compatible = "tq,imx6dl-mba6x-a", "tq,mba6a", - "tq,imx6dl-tqma6dl-a", "fsl,imx6dl"; -}; diff --git a/arch/arm/dts/imx6q-mba6.dtsi b/arch/arm/dts/imx6q-mba6.dtsi deleted file mode 100644 index 0d7be456729..00000000000 --- a/arch/arm/dts/imx6q-mba6.dtsi +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2013 Sascha Hauer, Pengutronix - * - * Copyright 2013-2021 TQ-Systems GmbH - * Author: Markus Niebel - */ - -&ecspi5 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_ecspi5_mba6x>; - cs-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; -}; - -ðphy { - rxdv-skew-ps = <180>; - txen-skew-ps = <120>; - rxd3-skew-ps = <180>; - rxd2-skew-ps = <180>; - rxd1-skew-ps = <180>; - rxd0-skew-ps = <180>; - txd3-skew-ps = <120>; - txd2-skew-ps = <0>; - txd1-skew-ps = <180>; - txd0-skew-ps = <360>; - txc-skew-ps = <1860>; - rxc-skew-ps = <1860>; -}; - -&sata { - status = "okay"; -}; - -&iomuxc { - pinctrl_ecspi5_mba6x: ecspi5grp-mba6x { - fsl,pins = < - /* HYS, SPEED = MED, 100k up, DSE = 011, SRE_FAST */ - MX6QDL_PAD_SD1_DAT0__ECSPI5_MISO 0x1b099 - MX6QDL_PAD_SD1_CMD__ECSPI5_MOSI 0xb099 - MX6QDL_PAD_SD1_CLK__ECSPI5_SCLK 0xb099 - MX6QDL_PAD_SD1_DAT1__GPIO1_IO17 0xb099 /* eCSPI5 SS0 */ - >; - }; -}; diff --git a/arch/arm/dts/imx6q-mba6a.dts b/arch/arm/dts/imx6q-mba6a.dts deleted file mode 100644 index 349a08605a5..00000000000 --- a/arch/arm/dts/imx6q-mba6a.dts +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2013 Sascha Hauer, Pengutronix - * - * Copyright 2013-2021 TQ-Systems GmbH - * Author: Markus Niebel - */ - -/dts-v1/; - -#include "imx6q-tqma6a.dtsi" -#include "imx6qdl-mba6.dtsi" -#include "imx6qdl-mba6a.dtsi" -#include "imx6q-mba6.dtsi" - -/ { - model = "TQ TQMa6Q on MBa6x"; - compatible = "tq,imx6q-mba6x-a", "tq,mba6a", - "tq,imx6q-tqma6q-a", "fsl,imx6q"; -}; diff --git a/arch/arm/dts/imx6qdl-mba6.dtsi b/arch/arm/dts/imx6qdl-mba6.dtsi deleted file mode 100644 index 78555a61885..00000000000 --- a/arch/arm/dts/imx6qdl-mba6.dtsi +++ /dev/null @@ -1,535 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2013 Sascha Hauer, Pengutronix - * - * Copyright 2013-2021 TQ-Systems GmbH - * Author: Markus Niebel - */ - -#include -#include -#include -#include - -/ { - aliases { - mmc0 = &usdhc3; - mmc1 = &usdhc2; - /delete-property/ mmc2; - /delete-property/ mmc3; - rtc0 = &rtc0; - }; - - chosen { - stdout-path = &uart2; - }; - - beeper: gpio-beeper { - compatible = "gpio-beeper"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpiobeeper>; - gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; - }; - - gpio_buttons: gpio-buttons { - compatible = "gpio-keys"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpiobuttons>; - - button1 { - label = "s6"; - linux,code = ; - gpios = <&gpio7 13 GPIO_ACTIVE_LOW>; - wakeup-source; - }; - - button2 { - label = "s7"; - linux,code = ; - gpios = <&gpio7 12 GPIO_ACTIVE_LOW>; - wakeup-source; - }; - - button3 { - label = "s8"; - linux,code = ; - gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; - wakeup-source; - }; - }; - - gpio-leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpioled>; - - led1 { - label = "led1"; - gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-on"; - }; - - led2 { - label = "led2"; - gpios = <&gpio6 31 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; - }; - }; - - reg_mba6_3p3v: regulator-mba6-3p3v { - compatible = "regulator-fixed"; - regulator-name = "supply-mba6-3p3v"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - - reg_pcie: regulator-pcie { - compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_regpcie>; - regulator-name = "supply-pcie"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - /* PCIE.PWR_EN */ - gpio = <&gpio2 0 GPIO_ACTIVE_HIGH>; - enable-active-high; - regulator-always-on; - vin-supply = <®_mba6_3p3v>; - }; - - reg_vcc3v3_audio: regulator-vcc3v3-audio { - compatible = "regulator-fixed"; - regulator-name = "vcc3v3-audio"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <®_mba6_3p3v>; - }; - - sound { - compatible = "fsl,imx-audio-tlv320aic32x4"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_audmux>; - model = "imx-audio-tlv320aic32x4"; - ssi-controller = <&ssi1>; - audio-codec = <&tlv320aic32x4>; - audio-asrc = <&asrc>; - audio-routing = - "IN3_L", "Mic Jack", - "Mic Jack", "Mic Bias", - "IN1_L", "Line In Jack", - "IN1_R", "Line In Jack", - "Line Out Jack", "LOL", - "Line Out Jack", "LOR"; - mux-int-port = <1>; - mux-ext-port = <3>; - }; -}; - -&audmux { - status = "okay"; - - ssi0 { - fsl,audmux-port = ; - fsl,port-config = < - (IMX_AUDMUX_V2_PTCR_SYN | - IMX_AUDMUX_V2_PTCR_TFSDIR | - IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT3_SSI_PINS_3) | - IMX_AUDMUX_V2_PTCR_TCLKDIR | - IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT3_SSI_PINS_3)) - IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT3_SSI_PINS_3) - >; - }; - - aud3 { - fsl,audmux-port = ; - fsl,port-config = < - IMX_AUDMUX_V2_PTCR_SYN - IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0) - >; - }; -}; - -&can1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_can1>; - status = "okay"; -}; - -&can2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_can2>; - status = "okay"; -}; - -&ecspi1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_ecspi1>, <&pinctrl_ecspi1_mba6>; - cs-gpios = <&gpio3 19 0>, <&gpio3 24 0>; -}; - -&fec { - phy-mode = "rgmii-id"; - phy-handle = <ðphy>; - mac-address = [00 00 00 00 00 00]; - status = "okay"; - - mdio { - #address-cells = <1>; - #size-cells = <0>; - - ethphy: ethernet-phy@3 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <3>; - interrupt-parent = <&gpio1>; - interrupts = <28 IRQ_TYPE_LEVEL_LOW>; - reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; - reset-assert-us = <1000>; - reset-deassert-us = <100000>; - micrel,force-master; - max-speed = <1000>; - }; - }; -}; - -&i2c1 { - tlv320aic32x4: audio-codec@18 { - compatible = "ti,tlv320aic32x4"; - reg = <0x18>; - clocks = <&clks IMX6QDL_CLK_CKO>; - clock-names = "mclk"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_codec>; - ldoin-supply = <®_vcc3v3_audio>; - iov-supply = <®_mba6_3p3v>; - }; -}; - -&pcie { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pcie>; - reset-gpio = <&gpio6 7 GPIO_ACTIVE_LOW>; - status = "okay"; -}; - -&pwm1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm1>; - status = "okay"; -}; - -&pwm3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm3>; - status = "okay"; -}; - -&pwm4 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm4>; - status = "okay"; -}; - -&snvs_poweroff { - status = "okay"; -}; - -&ssi1 { - status = "okay"; -}; - -&uart2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart2>; - status = "okay"; -}; - -&uart3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart3>; - uart-has-rtscts; - status = "okay"; -}; - -&uart4 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart4>; - uart-has-rtscts; - linux,rs485-enabled-at-boot-time; - rs485-rts-active-low; - rs485-rx-during-tx; - status = "okay"; -}; - -&uart5 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart5>; - uart-has-rtscts; - status = "okay"; -}; - -&usbh1 { - disable-over-current; - status = "okay"; -}; - -&usbotg { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usbotg>; - power-active-high; - over-current-active-low; - srp-disable; - hnp-disable; - adp-disable; - dr_mode = "otg"; - status = "okay"; -}; - -/* SD card slot */ -&usdhc2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc2>; - vmmc-supply = <®_mba6_3p3v>; - bus-width = <4>; - no-1-8-v; - no-mmc; - no-sdio; - cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; - wp-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; - status = "okay"; -}; - -&wdog1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_wdog1>; - /* does not work on unmodified starter kit */ - /* fsl,ext-reset-output; */ - status = "okay"; -}; - -&iomuxc { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_hog>; - - pinctrl_audmux: audmuxgrp { - fsl,pins = < - MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x1b0b0 - MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x1b0b0 - MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x1b0b0 - MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x1b0b0 - >; - }; - - pinctrl_can1: can1grp { - fsl,pins = < - MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0xb099 - MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0xb099 - >; - }; - - pinctrl_can2: can2grp { - fsl,pins = < - MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0xb099 - MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0xb099 - >; - }; - - pinctrl_codec: codecgrp { - fsl,pins = < - MX6QDL_PAD_CSI0_MCLK__CCM_CLKO1 0xb0 /* CLK */ - >; - }; - - pinctrl_ecspi1_mba6: ecspimba6grp { - fsl,pins = < - MX6QDL_PAD_EIM_D24__GPIO3_IO24 0xb099 /* eCSPI1 SS2 */ - >; - }; - - pinctrl_enet: enetgrp { - fsl,pins = < - /* FEC phy IRQ */ - MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x00011008 - /* FEC phy reset */ - MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1b099 - /* DSE = 100, 100k up, SPEED = MED */ - MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0xb0a0 - MX6QDL_PAD_ENET_MDC__ENET_MDC 0xb0a0 - /* DSE = 111, pull 100k up */ - MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0xb038 - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0xb038 - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0xb038 - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0xb038 - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0xb038 - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0xb038 - /* DSE = 111, pull external */ - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x0038 - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x0038 - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x0038 - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x0038 - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x0038 - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x0038 - /* HYS = 1, DSE = 111, 100k up, SPEED = HIGH */ - MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0f0 - >; - }; - - pinctrl_gpiobeeper: gpiobeepergrp { - fsl,pins = < - MX6QDL_PAD_SD1_DAT3__GPIO1_IO21 0xb099 - >; - }; - - pinctrl_gpiobuttons: gpiobuttongrp { - fsl,pins = < - MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x0001b099 - MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x0001b099 - MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x0001b099 - >; - }; - - pinctrl_gpioled: gpioledgrp { - fsl,pins = < - MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0xb099 /* LED V15 */ - MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0xb099 /* LED V16 */ - >; - }; - - pinctrl_hog: hoggrp { - fsl,pins = < - MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x0001b099 - - MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x0001b099 - MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x0001b099 - MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x0001b099 - - MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x0001b099 - MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x0001b099 - MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x0001b099 - MX6QDL_PAD_SD4_DAT0__GPIO2_IO08 0x0001b099 - MX6QDL_PAD_EIM_CS0__GPIO2_IO23 0x0001b099 - MX6QDL_PAD_EIM_CS1__GPIO2_IO24 0x0001b099 - MX6QDL_PAD_EIM_OE__GPIO2_IO25 0x0001b099 - - MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x0001b099 - MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x0001b099 - MX6QDL_PAD_EIM_D27__GPIO3_IO27 0x0001b099 - MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x0001b099 - MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x0001b099 - - MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x0001b099 - MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x0001b099 - MX6QDL_PAD_KEY_COL1__GPIO4_IO08 0x0001b099 - MX6QDL_PAD_KEY_ROW1__GPIO4_IO09 0x0001b099 - - MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18 0x0001b099 - MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x0001b099 - MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x0001b099 - - MX6QDL_PAD_NANDF_ALE__GPIO6_IO08 0x0001b099 - MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x0001b099 - >; - }; - - pinctrl_pcie: pciegrp { - fsl,pins = < - /* HYS = 1, DSE = 110, 100k up, SPEED = HIGH (11)*/ - MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x001b0f0 /* #PCIE.WAKE */ - MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x001b0f0 /* #PCIE.RST */ - MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x001b0f0 /* #PCIE.DIS */ - >; - }; - - pinctrl_pwm1: pwm1grp { - fsl,pins = < - /* 100 k PD, DSE 120 OHM, SPPEED LO */ - MX6QDL_PAD_GPIO_9__PWM1_OUT 0x00003050 - >; - }; - - pinctrl_pwm3: pwm3grp { - fsl,pins = < - /* 100 k PD, DSE 120 OHM, SPPEED LO */ - MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x00003050 - >; - }; - - pinctrl_pwm4: pwm4grp { - fsl,pins = < - /* 100 k PD, DSE 120 OHM, SPPEED LO */ - MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x00003050 - >; - }; - - pinctrl_regpcie: regpciegrp { - fsl,pins = < - /* HYS = 1, DSE = 110, PUE+PKE, SPEED = HIGH (11)*/ - MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x00130f0 /* PCIE.PWR_EN */ - >; - }; - - pinctrl_uart2: uart2grp { - fsl,pins = < - MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b099 - MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b099 - >; - }; - - pinctrl_uart3: uart3grp { - fsl,pins = < - MX6QDL_PAD_SD4_CLK__UART3_RX_DATA 0x1b0b1 - MX6QDL_PAD_SD4_CMD__UART3_TX_DATA 0x1b0b1 - MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x1b0b1 - MX6QDL_PAD_EIM_D31__UART3_RTS_B 0x1b0b1 - >; - }; - - pinctrl_uart4: uart4grp { - fsl,pins = < - MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1 - MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1 - MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B 0x1b0b1 - MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B 0x1b0b1 - >; - }; - - pinctrl_uart5: uart5grp { - fsl,pins = < - MX6QDL_PAD_CSI0_DAT14__UART5_TX_DATA 0x1b0b1 - MX6QDL_PAD_CSI0_DAT15__UART5_RX_DATA 0x1b0b1 - MX6QDL_PAD_CSI0_DAT18__UART5_RTS_B 0x1b0b1 - MX6QDL_PAD_CSI0_DAT19__UART5_CTS_B 0x1b0b1 - >; - }; - - pinctrl_usdhc2: usdhc2grp { - fsl,pins = < - /* CLK: 47k Pup SPD_LOW DSE 40Ohm SRE_FAST HYS */ - MX6QDL_PAD_SD2_CLK__SD2_CLK 0x00017071 - /* SD2: 47k Pup SPD_LOW DSE 80Ohm SRE_FAST HYS */ - MX6QDL_PAD_SD2_CMD__SD2_CMD 0x00017059 - MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x00017059 - MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x00017059 - MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x00017059 - MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x00017059 - - MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x0001b099 /* usdhc2 CD */ - MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x0001b099 /* usdhc2 WP */ - >; - }; - - pinctrl_usbotg: usbotggrp { - fsl,pins = < - MX6QDL_PAD_EIM_D21__USB_OTG_OC 0x0001b0b0 - MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x00017059 - MX6QDL_PAD_EIM_D22__USB_OTG_PWR 0x0001b099 - >; - }; - - pinctrl_wdog1: wdog1grp { - fsl,pins = < - /* Watchdog out */ - MX6QDL_PAD_SD1_DAT2__WDOG1_B 0x0000b099 - >; - }; -}; diff --git a/arch/arm/dts/imx6qdl-mba6a.dtsi b/arch/arm/dts/imx6qdl-mba6a.dtsi deleted file mode 100644 index df8fa169e9f..00000000000 --- a/arch/arm/dts/imx6qdl-mba6a.dtsi +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2013 Sascha Hauer, Pengutronix - * - * Copyright 2013-2021 TQ-Systems GmbH - * Author: Markus Niebel - */ - -&fec { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_enet>, <&pinctrl_enet_fix>; -}; - -&i2c1 { - lm75: temperature-sensor@49 { - compatible = "national,lm75"; - reg = <0x49>; - }; - - m24c64_57: eeprom@57 { - compatible = "atmel,24c64"; - reg = <0x57>; - pagesize = <32>; - }; - - rtc0: rtc@68 { - compatible = "dallas,ds1339"; - reg = <0x68>; - }; -}; diff --git a/arch/arm/dts/imx6qdl-mba6b.dtsi b/arch/arm/dts/imx6qdl-mba6b.dtsi deleted file mode 100644 index 7d1cd7454c7..00000000000 --- a/arch/arm/dts/imx6qdl-mba6b.dtsi +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2013 Sascha Hauer, Pengutronix - * - * Copyright 2013-2021 TQ-Systems GmbH - * Author: Markus Niebel - */ - -&fec { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_enet>; -}; - -&i2c1 { - clock-frequency = <100000>; - pinctrl-names = "default", "gpio"; - pinctrl-0 = <&pinctrl_i2c1>; - pinctrl-1 = <&pinctrl_i2c1_recovery>; - scl-gpios = <&gpio5 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; - sda-gpios = <&gpio5 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; - status = "okay"; -}; - -&i2c3 { - lm75: temperature-sensor@49 { - compatible = "national,lm75"; - reg = <0x49>; - }; - - m24c64_57: eeprom@57 { - compatible = "atmel,24c64"; - reg = <0x57>; - pagesize = <32>; - }; - - rtc0: rtc@68 { - compatible = "dallas,ds1339"; - reg = <0x68>; - }; -}; - -&iomuxc { - pinctrl_i2c1: i2c1grp { - fsl,pins = < - MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b899 - MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b899 - >; - }; -}; From c6bf5b6a14e32196b889ff4b27611f883ae3f448 Mon Sep 17 00:00:00 2001 From: Max Merchel Date: Mon, 13 Jul 2026 15:01:04 +0200 Subject: [PATCH 33/37] board: tqma6: use runtime SoC detection in enet setup Select the appropriate iomux settings based on the CPU type during ethernet configuration. Signed-off-by: Paul Gerber Signed-off-by: Max Merchel --- board/tq/tqma6/tqma6_mba6.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/board/tq/tqma6/tqma6_mba6.c b/board/tq/tqma6/tqma6_mba6.c index 32aeb1b07c8..8cc5857b06f 100644 --- a/board/tq/tqma6/tqma6_mba6.c +++ b/board/tq/tqma6/tqma6_mba6.c @@ -33,21 +33,11 @@ #include "../common/tq_bb.h" -#if defined(CONFIG_TQMA6Q) +#define TQMA6Q_IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII 0x02e0790 +#define TQMA6Q_IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM 0x02e07ac -#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII 0x02e0790 -#define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM 0x02e07ac - -#elif defined(CONFIG_TQMA6S) || defined(CONFIG_TQMA6DL) - -#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII 0x02e0768 -#define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM 0x02e0788 - -#else - -#error "need to select module" - -#endif +#define TQMA6DL_IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII 0x02e0768 +#define TQMA6DL_IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM 0x02e0788 /* disable on die termination for RGMII */ #define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE 0x00000000 @@ -63,10 +53,17 @@ static void mba6_setup_iomuxc_enet(void) /* clear gpr1[ENET_CLK_SEL] for externel clock */ clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK); - __raw_writel(IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE, - (void *)IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM); - __raw_writel(IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V, - (void *)IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII); + if (is_mx6sdl()) { + __raw_writel(IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE, + (void *)TQMA6DL_IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM); + __raw_writel(IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V, + (void *)TQMA6DL_IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII); + } else if (is_mx6dq()) { + __raw_writel(IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE, + (void *)TQMA6Q_IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM); + __raw_writel(IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V, + (void *)TQMA6Q_IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII); + } } int board_mmc_get_env_dev(int devno) From 17abea6ca04921bf13d6c4f199e6baa83b0e9fb6 Mon Sep 17 00:00:00 2001 From: Markus Niebel Date: Mon, 13 Jul 2026 15:01:05 +0200 Subject: [PATCH 34/37] board: tqma6: implement ENET errata workaround detection TQMa6 SOM beginning with hardware rev. 0200 comes in two flavours: With and without a hardware workaround for ENET errata err006687. Therefore we need two flavours of device tree. To be able to detect the presence of the workaround we need to check GPIO1_6 is connected to I2C bus or not. If the I2C bus is detected, the workaround is not used and separate I2C buses are used for the SoM and the baseboard. Later on this detection will be used to select the correct devicetree at runtime. Signed-off-by: Markus Niebel Signed-off-by: Max Merchel --- board/tq/tqma6/tqma6.c | 58 ++++++++++++++++++++++++++++++++++++++++++ board/tq/tqma6/tqma6.h | 13 ++++++++++ 2 files changed, 71 insertions(+) create mode 100644 board/tq/tqma6/tqma6.h diff --git a/board/tq/tqma6/tqma6.c b/board/tq/tqma6/tqma6.c index 005f08c4e5f..b740ac7d5b1 100644 --- a/board/tq/tqma6/tqma6.c +++ b/board/tq/tqma6/tqma6.c @@ -31,6 +31,18 @@ DECLARE_GLOBAL_DATA_PTR; +/* + * Rev. 0200 and newer optionally implements GIGE errata fix. + * Use a global var to signal presence of the fix. This should be checked + * early. If fix is present, system I2C is I2C1 - otherwise I2C3 + */ +static int has_enet_workaround = -1; + +int tqma6_has_enet_workaround(void) +{ + return has_enet_workaround; +} + int dram_init(void) { gd->ram_size = imx_ddr_size(); @@ -38,6 +50,36 @@ int dram_init(void) return 0; } +#define GPIO_REVDET_PAD_CTRL (PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_LOW | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +static const iomux_v3_cfg_t tqma6_revdet_pads[] = { + MX6_PAD_GPIO_6__GPIO1_IO06 | MUX_PAD_CTRL(GPIO_REVDET_PAD_CTRL), +}; + +void tqma6_detect_enet_workaround(void) +{ + int ret; + struct gpio_desc desc; + + imx_iomux_v3_setup_multiple_pads(tqma6_revdet_pads, + ARRAY_SIZE(tqma6_revdet_pads)); + + ret = dm_gpio_lookup_name("GPIO1_6", &desc); + if (ret) { + pr_err("error: gpio lookup for enet workaround %d\n", ret); + return; + } + + ret = dm_gpio_get_value(&desc); + if (ret == 0) + has_enet_workaround = 1; + else if (ret > 0) + has_enet_workaround = 0; + + dm_gpio_free(NULL, &desc); +} + int board_early_init_f(void) { return tq_bb_board_early_init_f(); @@ -99,11 +141,27 @@ int board_late_init(void) { env_set("board_name", tqma6_get_boardname()); + tqma6_detect_enet_workaround(); + tq_bb_board_late_init(); printf("Board: %s on a %s\n", tqma6_get_boardname(), tq_bb_get_boardname()); + puts("Enet workaround: "); + switch (tqma6_has_enet_workaround()) { + case 0: + puts("absent"); + break; + case 1: + puts("implemented"); + break; + default: + puts("Unknown"); + break; + }; + puts("\n"); + return tq_bb_checkboard(); } diff --git a/board/tq/tqma6/tqma6.h b/board/tq/tqma6/tqma6.h new file mode 100644 index 00000000000..0cf38a4d1e3 --- /dev/null +++ b/board/tq/tqma6/tqma6.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Paul Gerber + */ + +#ifndef __TQMA6_H +#define __TQMA6_H + +int tqma6_has_enet_workaround(void); + +#endif /* __TQMA6_H */ From 1aae8d914dee7311ea063682379308dd277b2c69 Mon Sep 17 00:00:00 2001 From: Paul Gerber Date: Mon, 13 Jul 2026 15:01:06 +0200 Subject: [PATCH 35/37] board: tqma6: add kernel device tree handling for environment Set the environment variable 'fdtfile' depending on ENET workaround detection. The function tqma6_get_fdt_configuration is implemented to be reusable for configuration detection in multi-DTB FIT image and therefore returns the devicetree name without the '.dtb' ending. Set fdtfile only if CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG is enabled and it is currently unset. The model string is loaded from the device tree variant. Therefore, the overriding of the model string is being removed. Signed-off-by: Paul Gerber Signed-off-by: Markus Niebel Signed-off-by: Max Merchel --- board/tq/tqma6/tqma6.c | 28 +++++++++++++++++++++++----- board/tq/tqma6/tqma6.h | 1 + 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/board/tq/tqma6/tqma6.c b/board/tq/tqma6/tqma6.c index b740ac7d5b1..f4cd9915185 100644 --- a/board/tq/tqma6/tqma6.c +++ b/board/tq/tqma6/tqma6.c @@ -117,6 +117,16 @@ static const char *tqma6_get_boardname(void) }; } +const char *tqma6_get_fdt_configuration(void) +{ + if (is_mx6dq()) + return !tqma6_has_enet_workaround() ? "imx6q-mba6b" : "imx6q-mba6a"; + if (is_mx6sdl()) + return !tqma6_has_enet_workaround() ? "imx6dl-mba6b" : "imx6dl-mba6a"; + + return NULL; +} + #if CONFIG_IS_ENABLED(DM_PMIC) /* setup board specific PMIC */ int power_init_board(void) @@ -137,12 +147,25 @@ int power_init_board(void) } #endif +#define FDTFILE_STRLEN 32u int board_late_init(void) { + char fdtfile[FDTFILE_STRLEN]; + const char *config = tqma6_get_fdt_configuration(); + env_set("board_name", tqma6_get_boardname()); tqma6_detect_enet_workaround(); + if (!env_get("fdtfile")) { + if (config) { + snprintf(fdtfile, FDTFILE_STRLEN, "%s.dtb", config); + env_set_runtime("fdtfile", fdtfile); + } else { + pr_err("ENV: Could not set kernel devicetree, ${fdtfile} remains unset\n"); + } + } + tq_bb_board_late_init(); printf("Board: %s on a %s\n", tqma6_get_boardname(), @@ -169,15 +192,10 @@ int board_late_init(void) * Device Tree Support */ #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) -#define MODELSTRLEN 32u int ft_board_setup(void *blob, struct bd_info *bd) { struct mmc *mmc = find_mmc_device(0); - char modelstr[MODELSTRLEN]; - snprintf(modelstr, MODELSTRLEN, "TQ %s on %s", tqma6_get_boardname(), - tq_bb_get_boardname()); - do_fixup_by_path_string(blob, "/", "model", modelstr); fdt_fixup_memory(blob, (u64)PHYS_SDRAM, (u64)gd->ram_size); /* bring in eMMC dsr settings if needed */ diff --git a/board/tq/tqma6/tqma6.h b/board/tq/tqma6/tqma6.h index 0cf38a4d1e3..bc09087e3df 100644 --- a/board/tq/tqma6/tqma6.h +++ b/board/tq/tqma6/tqma6.h @@ -8,6 +8,7 @@ #ifndef __TQMA6_H #define __TQMA6_H +const char *tqma6_get_fdt_configuration(void); int tqma6_has_enet_workaround(void); #endif /* __TQMA6_H */ From 0f662df68899293ff36bd2eb5437a54aeea24ee1 Mon Sep 17 00:00:00 2001 From: Alexander Feilke Date: Wed, 15 Jul 2026 08:46:15 +0200 Subject: [PATCH 36/37] configs: tqma6ul: add support for redundant environment Activate the redundant environment and set the required offset. Signed-off-by: Alexander Feilke Signed-off-by: Max Merchel --- configs/tqma6ul_common.config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/tqma6ul_common.config b/configs/tqma6ul_common.config index c076fb5d295..6b1fecb9071 100644 --- a/configs/tqma6ul_common.config +++ b/configs/tqma6ul_common.config @@ -18,6 +18,7 @@ CONFIG_SPL_SERIAL=y CONFIG_SPL_STACK_R_ADDR=0x88000000 CONFIG_SPL_STACK_R=y CONFIG_SPL=y +CONFIG_ENV_OFFSET_REDUND=0x110000 CONFIG_IMX_MODULE_FUSE=y CONFIG_SYS_MEMTEST_START=0x82000000 CONFIG_SYS_MEMTEST_END=0x83000000 @@ -76,6 +77,7 @@ CONFIG_MULTI_DTB_FIT_LZO=y CONFIG_MULTI_DTB_FIT=y CONFIG_SPL_MULTI_DTB_FIT=y CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_REDUNDANT=y CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_USE_ROOTPATH=y CONFIG_ROOTPATH="/srv/nfs" From ce5793d777fd1f5bb6b0448c6366ba989c4a3509 Mon Sep 17 00:00:00 2001 From: Christopher Kleiner Date: Thu, 16 Jul 2026 20:06:44 -0400 Subject: [PATCH 37/37] board: gateworks: fsa: bound FSA EEPROM gpio descriptor count fsa_user_info.gpios[] is a fixed 20-element array, but the number of descriptors iterated and indexed comes from the FSA add-on board EEPROM: board_info.sockgpios and board_info.ioexpgpios are u8 fields (up to 255 each) read via dm_i2c_read() with no upper bound. fsa_config_gpios(), invoked automatically at boot from fsa_init(), loops over info->gpios[i] for i < sockgpios + ioexpgpios, reading past the 20-element array (an out-of-bounds stack read whose contents are then used to configure GPIOs and build names). do_fsa_gpio() validates the console-supplied index only against the same EEPROM counts, so "fsa gpio ..." can memcpy() a descriptor to user_info.gpios[i] for i up to 254 -- an out-of-bounds stack write that is then written back to the EEPROM. A malicious or swapped FSA add-on board EEPROM (only a valid checksum is required, which the attacker can compute) thus yields OOB accesses on the boot path and via the console command. Clamp the descriptor count to ARRAY_SIZE(info->gpios) before iterating, and reject any console index outside the array. Fixes: da9e2218afc2 ("board: venice: add FSA support") Signed-off-by: Christopher Kleiner --- board/gateworks/fsa.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/board/gateworks/fsa.c b/board/gateworks/fsa.c index 1af8021057c..126a897ee28 100644 --- a/board/gateworks/fsa.c +++ b/board/gateworks/fsa.c @@ -140,6 +140,9 @@ static int fsa_config_gpios(int fsa, struct fsa_user_info *info, int gpios, stru int i, ret, flags; char name[32]; + /* clamp EEPROM-supplied descriptor count to the array size */ + if (gpios > ARRAY_SIZE(info->gpios)) + gpios = ARRAY_SIZE(info->gpios); /* configure GPIO's */ for (i = 0; i < gpios; i++) { desc = &info->gpios[i]; @@ -637,6 +640,11 @@ static int do_fsa_gpio(struct cmd_tbl *cmdtp, int flag, int argc, char * const a memset(&desc, 0, sizeof(desc)); i = simple_strtoul(argv[0], NULL, 10); + if (i < 0 || i >= (int)ARRAY_SIZE(user_info.gpios)) { + printf("invalid index %d", i); + return CMD_RET_FAILURE; + } + if (i >= 0 && i < board_info.sockgpios) { desc.offset = i; desc.source = 0xff;