imx: Support i.MX91 11x11 FRDM board

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@nxp.com>
This commit is contained in:
Joseph Guo
2025-12-12 15:20:21 +09:00
committed by Fabio Estevam
parent e71d109e7b
commit e4eccb860a
18 changed files with 8707 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2025 NXP
*/
#include "imx91-u-boot.dtsi"
/ {
wdt-reboot {
compatible = "wdt-reboot";
wdt = <&wdog3>;
bootph-pre-ram;
bootph-some-ram;
};
firmware {
optee {
compatible = "linaro,optee-tz";
method = "smc";
};
};
};
&s4muap {
bootph-pre-ram;
bootph-some-ram;
status = "okay";
};
&clk {
/delete-property/ assigned-clocks;
/delete-property/ assigned-clock-rates;
/delete-property/ assigned-clock-parents;
};

View File

@@ -61,6 +61,14 @@ config TARGET_IMX91_11X11_EVK
imply BOOTSTD_FULL
imply BOOTSTD_BOOTCOMMAND
config TARGET_IMX91_11X11_FRDM
bool "imx91_11x11_frdm"
select OF_BOARD_FIXUP
select IMX91
select IMX9_LPDDR4X
imply BOOTSTD_FULL
imply BOOTSTD_BOOTCOMMAND
config TARGET_IMX93_9X9_QSB
bool "imx93_qsb"
select OF_BOARD_FIXUP
@@ -148,6 +156,7 @@ config TARGET_TORADEX_SMARC_IMX95
endchoice
source "board/freescale/imx91_evk/Kconfig"
source "board/freescale/imx91_frdm/Kconfig"
source "board/freescale/imx93_evk/Kconfig"
source "board/freescale/imx93_frdm/Kconfig"
source "board/freescale/imx93_qsb/Kconfig"

View File

@@ -0,0 +1,12 @@
if TARGET_IMX91_11X11_FRDM
config SYS_BOARD
default "imx91_frdm"
config SYS_VENDOR
default "freescale"
config SYS_CONFIG_NAME
default "imx91_frdm"
endif

View File

@@ -0,0 +1,7 @@
FRDM-IMX91 BOARD
M: Joseph Guo <qijian.guo@nxp.com>
S: Maintained
F: board/freescale/imx91_frdm/
F: include/configs/imx91_frdm.h
F: configs/imx91_11x11_frdm_defconfig
F: configs/imx91_11x11_frdm_inline_ecc_defconfig

View File

@@ -0,0 +1,16 @@
#
# Copyright 2025 NXP
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += imx91_frdm.o
ifdef CONFIG_SPL_BUILD
obj-y += spl.o
ifdef CONFIG_IMX9_DRAM_INLINE_ECC
obj-y += lpddr4_2400mts_ecc_1gb_timing.o lpddr4_2400mts_ecc_2gb_timing.o
else
obj-y += lpddr4_2400mts_1gb_timing.o lpddr4_2400mts_2gb_timing.o
endif
endif

View File

@@ -0,0 +1,84 @@
// 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
/*
* Since tcpc driver is not upstream. PTN5110 interrupt will cause
* kernel panic because nobody cares the interrupt. So add workaround here.
* Clear PTN5110 USB Power Delivery controller alert status by
* masking interrupts and clearing pending alerts via I2C communication.
* This is typically called during board initialization to ensure the USB PD
* controller starts in a clean state without any stale alert conditions.
*/
static int clear_pd_alert(void)
{
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);
return ret;
}
/* 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 ret;
}
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 ret;
}
ret = dm_i2c_write(i2c_dev, TCPC_ALERT, buffer_1, 2);
if (ret) {
printf("%s dm_i2c_write failed: %d\n", __func__, ret);
return ret;
}
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;
}

View File

@@ -0,0 +1,89 @@
/* 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}
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
bootscript=echo Running bootscript from mmc ...; source
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
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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2025 NXP
*/
#ifndef __LPDDR4_TIMING_H__
#define __LPDDR4_TIMING_H__
extern struct dram_timing_info dram_timing_1GB;
extern struct dram_timing_info dram_timing_2GB;
#endif /* __LPDDR4_TIMING_H__ */

View File

@@ -0,0 +1,193 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2025 NXP
*/
#include "lpddr4_timing.h"
#include <init.h>
#include <spl.h>
#include <asm/arch/clock.h>
#include <asm/arch/ddr.h>
#include <asm/arch/mu.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/trdc.h>
#include <asm/mach-imx/boot_mode.h>
#include <asm/mach-imx/ele_api.h>
#include <asm/global_data.h>
#include <asm/sections.h>
#include <dm/device.h>
#include <dm/device-internal.h>
#include <dm/uclass.h>
#include <dm/uclass-internal.h>
#include <linux/delay.h>
#include <power/pca9450.h>
#include <power/pmic.h>
DECLARE_GLOBAL_DATA_PTR;
#define SRC_DDRC_SW_CTRL (0x44461020)
#define SRC_DDRPHY_SINGLE_RESET_SW_CTRL (0x44461424)
static struct _drams {
u8 mr8;
struct dram_timing_info *pdram_timing;
char *name;
} frdm_drams[2] = {
{0x10, &dram_timing_1GB, "1GB DRAM" },
{0x18, &dram_timing_2GB, "2GB DRAM" },
};
int spl_board_boot_device(enum boot_device boot_dev_spl)
{
return BOOT_DEVICE_BOOTROM;
}
void spl_board_init(void)
{
int ret;
ret = ele_start_rng();
if (ret)
printf("Fail to start RNG: %d\n", ret);
puts("Normal Boot\n");
}
void spl_dram_init(void)
{
int i;
int ret;
for (i = 0; i < ARRAY_SIZE(frdm_drams); i++) {
struct dram_timing_info *ptiming = frdm_drams[i].pdram_timing;
printf("DDR: %uMTS\n", ptiming->fsp_msg[0].drate);
ret = ddr_init(ptiming);
if (ret == 0) {
if (lpddr4_mr_read(1, 8) == frdm_drams[i].mr8) {
printf("found DRAM %s matched\n", frdm_drams[i].name);
break;
}
/* Power down and Power up DDR Mixer */
/* Clear PwrOkIn via DDRMIX register */
setbits_32(SRC_DDRPHY_SINGLE_RESET_SW_CTRL, BIT(0));
/* Power off the DDRMIX */
setbits_32(SRC_DDRC_SW_CTRL, BIT(31));
udelay(50);
/* Power up the DDRMIX */
clrbits_32(SRC_DDRC_SW_CTRL, BIT(31));
setbits_32(SRC_DDRC_SW_CTRL, BIT(0));
udelay(10);
clrbits_32(SRC_DDRC_SW_CTRL, BIT(0));
udelay(10);
}
}
}
#if CONFIG_IS_ENABLED(DM_PMIC_PCA9450)
int power_init_board(void)
{
struct udevice *dev;
int ret;
unsigned int val = 0, buck_val;
ret = pmic_get("pmic@25", &dev);
if (ret == -ENODEV) {
puts("ERROR: Get PMIC PCA9451A failed!\n");
return ret;
}
if (ret != 0)
return ret;
/* BUCKxOUT_DVS0/1 control BUCK123 output */
pmic_reg_write(dev, PCA9450_BUCK123_DVS, 0x29);
/* enable DVS control through PMIC_STBY_REQ */
pmic_reg_write(dev, PCA9450_BUCK1CTRL, 0x59);
ret = pmic_reg_read(dev, PCA9450_PWR_CTRL);
if (ret < 0)
return ret;
val = ret;
if (is_voltage_mode(VOLT_LOW_DRIVE)) {
buck_val = 0x0c; /* 0.8V for Low drive mode */
printf("PMIC: Low Drive Voltage Mode\n");
} else if (is_voltage_mode(VOLT_NOMINAL_DRIVE)) {
buck_val = 0x10; /* 0.85V for Nominal drive mode */
printf("PMIC: Nominal Voltage Mode\n");
} else {
buck_val = 0x14; /* 0.9V for Over drive mode */
printf("PMIC: Over Drive Voltage Mode\n");
}
if (val & PCA9450_REG_PWRCTRL_TOFF_DEB) {
pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS0, buck_val);
pmic_reg_write(dev, PCA9450_BUCK3OUT_DVS0, buck_val);
} else {
pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS0, buck_val + 0x4);
pmic_reg_write(dev, PCA9450_BUCK3OUT_DVS0, buck_val + 0x4);
}
/* Set VDDQ to 1.1V from buck2 (buck2 not used for iMX91 EVK) */
pmic_reg_write(dev, PCA9450_BUCK2OUT_DVS0, 0x28);
/* set standby voltage to 0.65V */
if (val & PCA9450_REG_PWRCTRL_TOFF_DEB)
pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS1, 0x0);
else
pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS1, 0x4);
/* I2C_LT_EN*/
pmic_reg_write(dev, 0xa, 0x3);
return 0;
}
#endif
void board_init_f(ulong dummy)
{
int ret;
/* Clear the BSS. */
memset(__bss_start, 0, __bss_end - __bss_start);
timer_init();
arch_cpu_init();
spl_early_init();
preloader_console_init();
ret = imx9_probe_mu();
if (ret) {
printf("Fail to init ELE API\n");
} else {
debug("SOC: 0x%x\n", gd->arch.soc_rev);
debug("LC: 0x%x\n", gd->arch.lifecycle);
}
clock_init_late();
power_init_board();
if (!is_voltage_mode(VOLT_LOW_DRIVE))
set_arm_clk(get_cpu_speed_grade_hz());
/* Init power of mix */
soc_power_init();
/* Setup TRDC for DDR access */
trdc_init();
/* DDR initialization */
spl_dram_init();
board_init_r(NULL, 0);
}

View File

@@ -0,0 +1,138 @@
CONFIG_ARM=y
CONFIG_ARCH_IMX9=y
CONFIG_TEXT_BASE=0x80200000
CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x18000
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_NR_DRAM_BANKS=2
CONFIG_SF_DEFAULT_SPEED=40000000
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_OFFSET=0x700000
CONFIG_IMX_CONFIG="arch/arm/mach-imx/imx9/imximage.cfg"
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="imx91-11x11-frdm"
CONFIG_TARGET_IMX91_11X11_FRDM=y
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_SYS_MONITOR_LEN=524288
CONFIG_SPL_SERIAL=y
CONFIG_SPL_DRIVERS_MISC=y
CONFIG_SPL_STACK=0x204E0000
CONFIG_SPL_SYS_MALLOC_F_LEN=0x2000
CONFIG_SPL_TEXT_BASE=0x204A0000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x20498000
CONFIG_SPL_BSS_MAX_SIZE=0x2000
CONFIG_SYS_LOAD_ADDR=0x80400000
CONFIG_SPL=y
CONFIG_CMD_DEKBLOB=y
CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x88000000
CONFIG_SYS_MEMTEST_START=0x80000000
CONFIG_SYS_MEMTEST_END=0x90000000
CONFIG_REMAKE_ELF=y
CONFIG_OF_SYSTEM_SETUP=y
CONFIG_BOOTCOMMAND="bootflow scan -lb; run bsp_bootcmd"
CONFIG_DEFAULT_FDT_FILE="imx91-11x11-frdm.dtb"
CONFIG_SYS_CBSIZE=2048
CONFIG_SYS_PBSIZE=2074
# CONFIG_BOARD_INIT is not set
CONFIG_BOARD_LATE_INIT=y
CONFIG_SPL_MAX_SIZE=0x26000
CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_BOOTROM_SUPPORT=y
CONFIG_SPL_LOAD_IMX_CONTAINER=y
CONFIG_IMX_CONTAINER_CFG="arch/arm/mach-imx/imx9/container.cfg"
# 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=0x83200000
CONFIG_SPL_SYS_MALLOC_SIZE=0x80000
CONFIG_SPL_I2C=y
CONFIG_SPL_POWER=y
CONFIG_SPL_WATCHDOG=y
CONFIG_SYS_PROMPT="u-boot=> "
CONFIG_CMD_CPU=y
CONFIG_CMD_ERASEENV=y
CONFIG_CMD_NVEDIT_EFI=y
CONFIG_CRC32_VERIFY=y
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_CLK=y
CONFIG_CMD_DFU=y
CONFIG_CMD_FUSE=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_POWEROFF=y
CONFIG_CMD_SNTP=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_EFIDEBUG=y
CONFIG_CMD_RTC=y
CONFIG_CMD_TIME=y
CONFIG_CMD_GETTIME=y
CONFIG_CMD_TIMER=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_HASH=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_MMC_DEVICE_INDEX=1
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_USE_ETHPRIME=y
CONFIG_ETHPRIME="eth1"
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_ADC=y
CONFIG_ADC_IMX93=y
CONFIG_CLK_IMX93=y
CONFIG_SAVED_DRAM_TIMING_BASE=0x2049C000
CONFIG_IMX_RGPIO2P=y
CONFIG_DM_PCA953X=y
CONFIG_ADP5585_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_IMX_LPI2C=y
CONFIG_SUPPORT_EMMC_RPMB=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_IO_VOLTAGE=y
CONFIG_MMC_UHS_SUPPORT=y
CONFIG_MMC_HS400_ES_SUPPORT=y
CONFIG_MMC_HS400_SUPPORT=y
CONFIG_FSL_USDHC=y
CONFIG_MTD=y
CONFIG_PHY_ANEG_TIMEOUT=20000
CONFIG_PHY_MOTORCOMM=y
CONFIG_DM_ETH_PHY=y
CONFIG_PHY_GIGE=y
CONFIG_DWC_ETH_QOS=y
CONFIG_DWC_ETH_QOS_IMX=y
CONFIG_MII=y
CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_IMX93=y
CONFIG_POWER_DOMAIN=y
CONFIG_DM_PMIC=y
CONFIG_DM_PMIC_PCA9450=y
CONFIG_SPL_DM_PMIC_PCA9450=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_PCA9450=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_DM_RTC=y
CONFIG_RTC_EMULATION=y
CONFIG_DM_SERIAL=y
CONFIG_FSL_LPUART=y
CONFIG_SYSRESET=y
CONFIG_SYSRESET_CMD_POWEROFF=y
CONFIG_SYSRESET_PSCI=y
CONFIG_ULP_WATCHDOG=y
CONFIG_WDT=y
CONFIG_SHA384=y
CONFIG_LZO=y
CONFIG_BZIP2=y

View File

@@ -0,0 +1,3 @@
#include <configs/imx91_11x11_frdm_defconfig>
CONFIG_IMX9_DRAM_INLINE_ECC=y

View File

@@ -0,0 +1,100 @@
.. SPDX-License-Identifier: GPL-2.0+
imx91_frdm
=======================
U-Boot for the NXP i.MX91 11x11 FRDM Board
Quick Start
-----------
- Get and Build the ARM Trusted firmware
- Get the DDR firmware
- Get ahab-container.img
- Build U-Boot
- Boot from the SD card
- Boot using USB serial download (uuu)
Get and Build the ARM Trusted firmware
--------------------------------------
Note: srctree is U-Boot source directory
Get ATF from: https://github.com/nxp-imx/imx-atf/
branch: lf_v2.10
.. code-block:: bash
$ unset LDFLAGS
$ make PLAT=imx91 bl31
$ cp build/imx91/release/bl31.bin $(srctree)
Get the DDR firmware
--------------------
.. code-block:: bash
$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.21.bin
$ chmod +x firmware-imx-8.21.bin
$ ./firmware-imx-8.21.bin
$ cp firmware-imx-8.21/firmware/ddr/synopsys/lpddr4*.bin $(srctree)
Get ahab-container.img
---------------------------------------
.. code-block:: bash
$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-ele-imx-1.3.0-17945fc.bin
$ chmod +x firmware-ele-imx-1.3.0-17945fc.bin
$ ./firmware-ele-imx-1.3.0-17945fc.bin
$ cp firmware-ele-imx-1.3.0-17945fc/mx91a0-ahab-container.img $(srctree)
Build U-Boot
------------
.. code-block:: bash
$ export CROSS_COMPILE=aarch64-poky-linux-
$ make imx91_11x11_frdm_defconfig or imx91_11x11_frdm_inline_ecc_defconfig
$ make
- Inline ECC is to enable DDR ECC feature with imx91_11x11_frdm_inline_ecc_defconfig
Enable ECC will reduce DDR size by 1/8. For 1GB DRAM, available size will be 896MB.
Burn the flash.bin to MicroSD card offset 32KB:
.. code-block:: bash
$ dd if=flash.bin of=/dev/sd[x] bs=1k seek=32; sync
Boot from the SD card
---------------------
- Configure SW1 boot switches to SD boot mode:
0011 SW1[3:0] - ("USDHC2 4-bit SD3.0" Boot Mode)
- Insert the SD card in the SD slot (P13) of the board.
- Connect a USB Type-C cable into the P16 Debug USB Port and connect
using a terminal emulator at 115200 bps, 8n1. The console will show up
at /dev/ttyACM0.
- Power on the board by connecting a USB Type-C cable into the P1
Power USB Port.
Boot using USB serial download (uuu)
------------------------------------
- Configure SW1 boot switches to serial download boot mode:
0001 SW1[3:0] - ("Serial downloader (USB)" Boot Mode)
- Plug USB Type-C cable into the P2 device port.
- Connect a USB Type-C cable into the P16 Debug USB Port and connect
using a terminal emulator at 115200 bps, 8n1. The console will show up
at /dev/ttyACM0.
- Power on the board by connecting a USB Type-C cable into the P1
Power USB Port.
- Use NXP Universal Update Utility `NXP Universal Update Utility`_ to boot or
flash the device. E.g. following command can be used to flash an image onto
the eMMC storage:
.. code-block:: bash
$ uuu -V -b emmc_all <image file>
.. _`NXP Universal Update Utility`: https://github.com/nxp-imx/mfgtools

View File

@@ -13,6 +13,7 @@ NXP Semiconductors
imx8qxp_mek
imx8ulp_evk
imx91_11x11_evk
imx91_11x11_frdm
imx93_9x9_qsb
imx93_11x11_evk
imx93_frdm

View File

@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2025 NXP
*/
#ifndef __IMX91_FRDM_H
#define __IMX91_FRDM_H
#include <linux/sizes.h>
#include <linux/stringify.h>
#include <asm/arch/imx-regs.h>
#define CFG_SYS_UBOOT_BASE \
(QSPI0_AMBA_BASE + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512)
#define CFG_SYS_INIT_RAM_ADDR 0x80000000
#define CFG_SYS_INIT_RAM_SIZE 0x200000
#define CFG_SYS_SDRAM_BASE 0x80000000
#define PHYS_SDRAM 0x80000000
#define PHYS_SDRAM_SIZE SZ_2G /* 2GB DDR */
#define WDOG_BASE_ADDR WDG3_BASE_ADDR
#endif