[PATCH v3 2/2] imx: Support i.MX91 11x11 FRDM board

Francesco Valla francesco at valla.it
Tue Dec 9 22:37:51 CET 2025


Hello Joseph,

On Tue, Dec 09, 2025 at 12:17:49PM +0900, Joseph Guo wrote:
> Add i.MX91 11x11 FRDM Board support.
>  - Four ddr scripts included w/o inline ecc feature. Support
>    both 1gb and 2gb DDR
>  - SDHC/EQOS/I2C/UART supported
>  - PCA9451 supported, default nominal drive mode
>  - Documentation added.
> 
> Signed-off-by: Joseph Guo <qijian.guo at nxp.com>
> ---
> Changes in v2:
> - correct commit message 'EVK' to 'FRDM'
> - use #include in ecc config file
> - add ecc description in README
> - drop extraneous includes
> - rename 'imx91_frdm.rst' to 'imx91_11x11_frdm.rst'
> - drop IMX91_FRDM_LPDDR4 symbol
> - drop bootph- property
> 
> Changes in v3:
> - drop usdhc2 in uboot dts
> - add workaround to clear ptn5110 alert in board init
> - /s/EFI_HAVE_CAPSULE_SUPPORT/ENV_IS_IN_MMC
> - drop fec and ethphy1 in u-boot in uboot dts
> - drop spi flash related config
> - drop m-core enviroment variable
> - change PHYS_SDRAM_SIZE macro to SZ_2G
> ---
>  arch/arm/dts/imx91-11x11-frdm-u-boot.dtsi          |   34 +
>  arch/arm/mach-imx/imx9/Kconfig                     |    9 +
>  board/freescale/imx91_frdm/Kconfig                 |   12 +
>  board/freescale/imx91_frdm/MAINTAINERS             |    7 +
>  board/freescale/imx91_frdm/Makefile                |   16 +
>  board/freescale/imx91_frdm/imx91_frdm.c            |   74 +
>  board/freescale/imx91_frdm/imx91_frdm.env          |   87 +
>  .../imx91_frdm/lpddr4_2400mts_1gb_timing.c         | 1996 ++++++++++++++++++++
>  .../imx91_frdm/lpddr4_2400mts_2gb_timing.c         | 1996 ++++++++++++++++++++
>  .../imx91_frdm/lpddr4_2400mts_ecc_1gb_timing.c     | 1996 ++++++++++++++++++++
>  .../imx91_frdm/lpddr4_2400mts_ecc_2gb_timing.c     | 1996 ++++++++++++++++++++
>  board/freescale/imx91_frdm/lpddr4_timing.h         |   12 +
>  board/freescale/imx91_frdm/spl.c                   |  193 ++
>  configs/imx91_11x11_frdm_defconfig                 |  138 ++
>  configs/imx91_11x11_frdm_inline_ecc_defconfig      |    3 +
>  doc/board/nxp/imx91_11x11_frdm.rst                 |  100 +
>  doc/board/nxp/index.rst                            |    1 +
>  include/configs/imx91_frdm.h                       |   25 +
>  18 files changed, 8695 insertions(+)
> 

[snip]

> diff --git a/board/freescale/imx91_frdm/imx91_frdm.c b/board/freescale/imx91_frdm/imx91_frdm.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..453f19e7f5f1d06e9ac453933ea80c66e6368c81
> --- /dev/null
> +++ b/board/freescale/imx91_frdm/imx91_frdm.c
> @@ -0,0 +1,74 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2025 NXP
> + */
> +
> +#include <env.h>
> +#include <asm/arch/sys_proto.h>
> +#include <i2c.h>
> +#include <dm.h>
> +
> +#define TCPC_ALERT 0x10
> +#define TCPC_ALERT_MASK 0x12
> +#define TCPC_FAULT_STATUS_MASK 0x15
> +#define USB_I2C_BUS 2
> +#define USB_I2C_ADDR 0x50
> +
> +static int clear_pd_alert(void)
> +{

Given this is a workaround, maybe a comment explaining why this is
needed would be useful.

> +	struct udevice *bus;
> +	struct udevice *i2c_dev = NULL;
> +	int ret;
> +	u8 buffer_0[2] = {0, 0};
> +	u8 buffer_1[2] = {0xff, 0xff};
> +
> +	ret = uclass_get_device_by_seq(UCLASS_I2C, USB_I2C_BUS, &bus);
> +	if (ret) {
> +		printf("Failed to get I2C bus %d\n", USB_I2C_BUS);
> +		return ret;
> +	}
> +
> +		ret = dm_i2c_probe(bus, USB_I2C_ADDR, 0, &i2c_dev);
> +		if (ret)
> +			printf("Can't find USB PD device at 0x%02x\n", USB_I2C_ADDR);
> +
> +		/* Mask all alert status*/
> +		ret = dm_i2c_write(i2c_dev, TCPC_ALERT_MASK, buffer_0, 2);
> +		if (ret) {
> +			printf("%s dm_i2c_write failed: %d\n", __func__, ret);
> +			return 0;
> +		}
> +
> +		ret = dm_i2c_write(i2c_dev, TCPC_FAULT_STATUS_MASK, buffer_0, 2);
> +		if (ret) {
> +			printf("%s dm_i2c_write failed: %d\n", __func__, ret);
> +			return 0;
> +		}
> +
> +		ret = dm_i2c_write(i2c_dev, TCPC_ALERT, buffer_1, 2);
> +		if (ret) {
> +			printf("%s dm_i2c_write failed: %d\n", __func__, ret);
> +			return 0;
> +		}
> +

Indentation is off here.

> +	return 0;
> +}
> +
> +int board_late_init(void)
> +{
> +	if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC))
> +		board_late_mmc_env_init();
> +
> +	env_set("sec_boot", "no");
> +
> +	if (IS_ENABLED(CONFIG_AHAB_BOOT))
> +		env_set("sec_boot", "yes");
> +
> +	if (IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)) {
> +		env_set("board_name", "11X11_FRDM");
> +		env_set("board_rev", "iMX91");
> +	}
> +
> +	clear_pd_alert();
> +	return 0;
> +}
> diff --git a/board/freescale/imx91_frdm/imx91_frdm.env b/board/freescale/imx91_frdm/imx91_frdm.env
> new file mode 100644
> index 0000000000000000000000000000000000000000..fa5e22f0508f3deb676ed1919146c3c4997a3c97
> --- /dev/null
> +++ b/board/freescale/imx91_frdm/imx91_frdm.env
> @@ -0,0 +1,87 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
> +
> +boot_targets=mmc0 mmc1
> +boot_fit=no
> +bootm_size=0x10000000
> +cntr_addr=0x98000000
> +cntr_file=os_cntr_signed.bin
> +console=ttyLP0,115200 earlycon
> +fdt_addr_r=0x83000000
> +fdt_addr=0x83000000
> +fdtfile=CONFIG_DEFAULT_FDT_FILE
> +image=Image
> +mmcdev=CONFIG_ENV_MMC_DEVICE_INDEX
> +mmcpart=1
> +mmcroot=/dev/mmcblk1p2 rootwait rw
> +mmcautodetect=yes
> +mmcargs=setenv bootargs ${jh_clk} ${mcore_clk} console=${console} root=${mmcroot}
> +loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
> +loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr_r} ${fdtfile}
> +loadcntr=fatload mmc ${mmcdev}:${mmcpart} ${cntr_addr} ${cntr_file}
> +auth_os=auth_cntr ${cntr_addr}
> +sec_boot=no
> +boot_os=booti ${loadaddr} - ${fdt_addr_r}
> +mmcboot=
> +	echo Booting from mmc ...;
> +	run mmcargs;
> +	if test ${sec_boot} = yes; then
> +		if run true; then
> +			run boot_os;
> +		else
> +			echo ERR: failed to authenticate;
> +		fi;
> +	else
> +		if run loadfdt; then
> +			run boot_os;
> +		else
> +			echo WARN: Cannot load the DT;
> +		fi;
> +	fi;
> +netargs=setenv bootargs ${jh_clk} ${mcore_clk} console=${console} root=/dev/nfs
> +	ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
> +netboot=
> +	echo Booting from net ...;
> +	run netargs;
> +	if test ${ip_dyn} = yes; then
> +		setenv get_cmd dhcp;
> +	else
> +		setenv get_cmd tftp;
> +	fi;
> +	if test ${sec_boot} = yes; then
> +		${get_cmd} ${cntr_addr} ${cntr_file};
> +		if true; then
> +			run boot_os;
> +		else
> +			echo ERR: failed to authenticate;
> +		fi;
> +	else
> +		${get_cmd} ${loadaddr} ${image};
> +		if ${get_cmd} ${fdt_addr_r} ${fdtfile}; then
> +			run boot_os;
> +		else
> +			echo WARN: Cannot load the DT;
> +		fi;
> +	fi;
> +bsp_bootcmd=
> +	echo Running BSP bootcmd ...;
> +	mmc dev ${mmcdev};
> +	if mmc rescan; then
> +		if run loadbootscript; then
> +			run bootscript;
> +		else

Neither loadbootscript nor bootscript are defined; this leads to the
following error on startup:

    ## Error: "loadbootscript" not defined

I saw that this is shared by several other i.MX boards, but maybe it's
worth fixing.

> +			if test ${sec_boot} = yes; then
> +				if run loadcntr; then
> +					run mmcboot;
> +				else
> +					run netboot;
> +				fi;
> +			else
> +				if run loadimage; then
> +					run mmcboot;
> +				else
> +					run netboot;
> +				fi;
> +			fi;
> +		fi;
> +	fi;
> +scriptaddr=0x83500000


I also get on startup:

    Failed to update cpu-thermal trip(s)

But this is probably due to lack of thermal support at Linux kernel side
and needs a fix there?


Thank you

Regards,
Francesco



More information about the U-Boot mailing list