From dffae7d2a6311a4249ba51d61f1c890aba7656e8 Mon Sep 17 00:00:00 2001 From: Simona Toaca Date: Thu, 30 Apr 2026 11:33:33 +0300 Subject: doc: board: nxp: Add Quickboot documentation Add instructions on how to use U-Boot to save DDR training data to NVM and explain the saving process. Signed-off-by: Simona Toaca --- doc/board/nxp/index.rst | 1 + doc/board/nxp/quickboot.rst | 59 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 doc/board/nxp/quickboot.rst (limited to 'doc') diff --git a/doc/board/nxp/index.rst b/doc/board/nxp/index.rst index 8cd24aecf33..52c8e85fa5b 100644 --- a/doc/board/nxp/index.rst +++ b/doc/board/nxp/index.rst @@ -30,3 +30,4 @@ NXP Semiconductors mx6ullevk rproc psb + quickboot diff --git a/doc/board/nxp/quickboot.rst b/doc/board/nxp/quickboot.rst new file mode 100644 index 00000000000..0fd72b4e13b --- /dev/null +++ b/doc/board/nxp/quickboot.rst @@ -0,0 +1,59 @@ +.. SPDX-License-Identifier: GPL-2.0+ + Copyright 2026 NXP + +DDR QuickBoot flow +------------------ + +Some NXP SoCs (which use OEI - iMX943, iMX95, iMX952 etc.) support saving +DDR training data (collected by OEI during Training flow) from volatile +to non-volatile memory, which is then available to OEI at next cold reboot. +OEI uses the saved data to run Quickboot flow and avoid training the DDR again. +This significantly reduces the boot time. + +The location of the quickboot data in NVM is a space left in the bootloader by +mkimage, with the size of 64K. The qb command searches for this space to +save the data. Thus, the NVM should also be a boot device and contain +the bootloader at the time of the saving. + +U-Boot provides no authentication for quickboot data, only its integrity +is verified via the CRC32. The authentication is done in OEI. With +the exception of iMX95 A0/A1, which use CRC32 as well for verifying +the data, the rest of the SoCs use ELE to verify the MAC stored +in the ddrphy_qb_state structure. + +If the quickboot data in memory is not valid (CRC32 check fails), +U-Boot does not save it to NVM. So, if OEI runs Quickboot flow -> no +data is written to volatile memory -> invalid data -> no saving happens +(qb save fails during qb check). + +After successful saving, U-Boot clears the data in volatile memory so +that qb check fails at next reboot and the NVM isn't accessed again. + +There are 2 ways to save this data, both can be enabled: + +1. automatically, in SPL (by enabling CONFIG_SPL_IMX_QB) + +- this will save the data on the current boot device (e.g. SD) +- other configs specific to the boot device need to be enabled (CONFIG_SPL_MMC_WRITE for saving to eMMC/SD) +- use for: automating qb save / saving quickboot data if using Falcon mode (skipping U-Boot proper) + +2. using qb command in U-Boot console (by enabling CONFIG_CMD_IMX_QB) + +- supports saving on the current boot device, or on another, specified device. +- supports specifying the hwpartition for eMMC (for booting from boot0/boot1) +- if flashing via uuu, the command can be added in an uuu script (boot device needs to be specified) +- use 'qb erase' to force DDR re-training +- use for: saving quickboot data during flashing / controlling the NVM to save to / forcing re-training + +:: + + # To save/erase on current boot device + # For eMMC boot1, mmc 0:2 has to be specified explicitly + => qb save/erase + + # To save/erase on other boot device + => qb save/erase mmc 0 # eMMC boot0 + => qb save/erase mmc 0:1 # eMMC boot0 + => qb save/erase mmc 0:2 # eMMC boot1 + => qb save/erase mmc 1 # SD + => qb save/erase spi # NOR SPI -- cgit v1.3.1 From 5e41a5deb4b843808f3c892f2f54f1b9c76b3da1 Mon Sep 17 00:00:00 2001 From: James Hilliard Date: Mon, 11 May 2026 12:20:25 -0600 Subject: env: migrate static flags list to Kconfig Environment callbacks can already be configured from Kconfig with CONFIG_ENV_CALLBACK_LIST_STATIC, but static environment flags still require board headers to define CFG_ENV_FLAGS_LIST_STATIC. Add CONFIG_ENV_FLAGS_LIST_STATIC and use it as the only board-provided static environment flags list. Convert the remaining default-config users from CFG_ENV_FLAGS_LIST_STATIC to defconfig settings and drop the legacy header macro from ENV_FLAGS_LIST_STATIC. Move the environment flags format documentation out of README and into the developer environment documentation. Include the format in the Kconfig help as well. This lets boards configure writeable-list policy and type validation from defconfig without adding a config header solely for env flags. This preserves the behavior of default configs. Header-only cases that were inactive in upstream defconfigs are not converted into defconfig entries: iot2050 can add its list when enabling ENV_WRITEABLE_LIST, and smegw01 can add mmcdev:dw support if the unlocked SYS_BOOT_LOCKED=n configuration is needed. Signed-off-by: James Hilliard Reviewed-by: Tom Rini Reviewed-by: Simon Glass Reviewed-by: Alexander Sverdlin Reviewed-by: Walter Schweizer --- README | 45 +----------------------------------- configs/aristainetos2c_defconfig | 1 + configs/aristainetos2ccslb_defconfig | 1 + configs/hmibsc_defconfig | 1 + configs/imx6q_bosch_acc_defconfig | 1 + configs/imx8qxp_capricorn.config | 1 + configs/smegw01_defconfig | 1 + configs/socrates_defconfig | 1 + doc/develop/environment.rst | 40 ++++++++++++++++++++++++++++++++ env/Kconfig | 23 ++++++++++++++++++ include/configs/aristainetos2.h | 3 --- include/configs/capricorn-common.h | 13 ----------- include/configs/hmibsc.h | 4 ---- include/configs/imx6q-bosch-acc.h | 12 ---------- include/configs/iot2050.h | 8 ------- include/configs/smegw01.h | 15 ------------ include/configs/socrates.h | 2 -- include/env_flags.h | 6 +---- 18 files changed, 72 insertions(+), 106 deletions(-) (limited to 'doc') diff --git a/README b/README index 6836a917c79..664d88a5505 100644 --- a/README +++ b/README @@ -799,7 +799,7 @@ The following options need to be configured: The same can be accomplished in a more flexible way for any variable by configuring the type of access to allow for those variables in the ".flags" variable - or define CFG_ENV_FLAGS_LIST_STATIC. + or by setting CONFIG_ENV_FLAGS_LIST_STATIC. - Protected RAM: CFG_PRAM @@ -1106,49 +1106,6 @@ Configuration Settings: - CONFIG_SYS_FLASH_USE_BUFFER_WRITE Use buffered writes to flash. -- CONFIG_ENV_FLAGS_LIST_DEFAULT -- CFG_ENV_FLAGS_LIST_STATIC - Enable validation of the values given to environment variables when - calling env set. Variables can be restricted to only decimal, - hexadecimal, or boolean. If CONFIG_CMD_NET is also defined, - the variables can also be restricted to IP address or MAC address. - - The format of the list is: - type_attribute = [s|d|x|b|i|m] - access_attribute = [a|r|o|c] - attributes = type_attribute[access_attribute] - entry = variable_name[:attributes] - list = entry[,list] - - The type attributes are: - s - String (default) - d - Decimal - x - Hexadecimal - b - Boolean ([1yYtT|0nNfF]) - i - IP address - m - MAC address - - The access attributes are: - a - Any (default) - r - Read-only - o - Write-once - c - Change-default - - - CONFIG_ENV_FLAGS_LIST_DEFAULT - Define this to a list (string) to define the ".flags" - environment variable in the default or embedded environment. - - - CFG_ENV_FLAGS_LIST_STATIC - Define this to a list (string) to define validation that - should be done if an entry is not found in the ".flags" - environment variable. To override a setting in the static - list, simply add an entry for the same variable name to the - ".flags" variable. - - If CONFIG_REGEX is defined, the variable_name above is evaluated as a - regular expression. This allows multiple variables to define the same - flags without explicitly listing them for each variable. - The following definitions that deal with the placement and management of environment data (variable area); in general, we support the following configurations: diff --git a/configs/aristainetos2c_defconfig b/configs/aristainetos2c_defconfig index 6923d27f79a..6c44e670cbc 100644 --- a/configs/aristainetos2c_defconfig +++ b/configs/aristainetos2c_defconfig @@ -56,6 +56,7 @@ CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y +CONFIG_ENV_FLAGS_LIST_STATIC="ethaddr:mw,serial#:sw,board_type:sw,sysnum:dw,panel:sw,ipaddr:iw,serverip:iw" CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_ENV_SPI_EARLY=y diff --git a/configs/aristainetos2ccslb_defconfig b/configs/aristainetos2ccslb_defconfig index 3ffebb15375..5016646ef87 100644 --- a/configs/aristainetos2ccslb_defconfig +++ b/configs/aristainetos2ccslb_defconfig @@ -56,6 +56,7 @@ CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y +CONFIG_ENV_FLAGS_LIST_STATIC="ethaddr:mw,serial#:sw,board_type:sw,sysnum:dw,panel:sw,ipaddr:iw,serverip:iw" CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_ENV_SPI_EARLY=y diff --git a/configs/hmibsc_defconfig b/configs/hmibsc_defconfig index 1e3d744193d..c8fad154e31 100644 --- a/configs/hmibsc_defconfig +++ b/configs/hmibsc_defconfig @@ -41,6 +41,7 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y # CONFIG_OF_UPSTREAM is not set +CONFIG_ENV_FLAGS_LIST_STATIC="BOOT_A_LEFT:dw,BOOT_B_LEFT:dw,BOOT_ORDER:sw" CONFIG_ENV_IS_IN_MMC=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_ENV_MMC_EMMC_HW_PARTITION=2 diff --git a/configs/imx6q_bosch_acc_defconfig b/configs/imx6q_bosch_acc_defconfig index 6f0ef2eaee3..87cf676ed4c 100644 --- a/configs/imx6q_bosch_acc_defconfig +++ b/configs/imx6q_bosch_acc_defconfig @@ -74,6 +74,7 @@ CONFIG_EFI_PARTITION=y CONFIG_SPL_OF_CONTROL=y CONFIG_MULTI_DTB_FIT=y CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clocks clock-names interrupt-parent" +CONFIG_ENV_FLAGS_LIST_STATIC="bootset:bw,clone_pending:bw,endurance_test:bw,env_persisted:bw,factory_reset:bw,fdtcontroladdr:xw,fitpart:dw,mmcpart:dw,production:bw,ustate:dw" CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_MMC=y CONFIG_ENV_REDUNDANT=y diff --git a/configs/imx8qxp_capricorn.config b/configs/imx8qxp_capricorn.config index 2bae5b1a862..91da5554db0 100644 --- a/configs/imx8qxp_capricorn.config +++ b/configs/imx8qxp_capricorn.config @@ -92,6 +92,7 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_SPL_OF_CONTROL=y +CONFIG_ENV_FLAGS_LIST_STATIC="bootcount:dw,bootdelay:sw,bootlimit:dw,partitionset_active:sw,rastate:dw,sig_a:sw,sig_b:sw,target_env:sw,upgrade_available:dw,ustate:dw" CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_MMC=y diff --git a/configs/smegw01_defconfig b/configs/smegw01_defconfig index 529836e7bdd..e5d4014d640 100644 --- a/configs/smegw01_defconfig +++ b/configs/smegw01_defconfig @@ -48,6 +48,7 @@ CONFIG_CMD_FAT=y CONFIG_CMD_SQUASHFS=y CONFIG_CMD_FS_GENERIC=y CONFIG_OF_CONTROL=y +CONFIG_ENV_FLAGS_LIST_STATIC="mmcpart:dw,mmcpart_committed:dw,ustate:dw,bootcount:dw,bootlimit:dw,upgrade_available:dw" CONFIG_ENV_OVERWRITE=y CONFIG_ENV_REDUNDANT=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y diff --git a/configs/socrates_defconfig b/configs/socrates_defconfig index 217141cceda..79e40268c6b 100644 --- a/configs/socrates_defconfig +++ b/configs/socrates_defconfig @@ -66,6 +66,7 @@ CONFIG_MTDIDS_DEFAULT="nor0=fe000000.nor_flash,nand0=socrates_nand" CONFIG_MTDPARTS_DEFAULT="mtdparts=fe000000.nor_flash:13312k(system1),13312k(system2),5120k(data),128k(env),128k(env-red),768k(u-boot);socrates_nand:256M(ubi-data1),-(ubi-data2)" # CONFIG_CMD_IRQ is not set CONFIG_OF_CONTROL=y +CONFIG_ENV_FLAGS_LIST_STATIC="ethaddr:mw,eth1addr:mw,system1_addr:xw,serial#:sw,ethact:sw,ethprime:sw" CONFIG_ENV_IS_IN_FLASH=y CONFIG_ENV_REDUNDANT=y CONFIG_ENV_ADDR_REDUND=0xFFF00000 diff --git a/doc/develop/environment.rst b/doc/develop/environment.rst index e46cd39d601..a7ed4aab0a5 100644 --- a/doc/develop/environment.rst +++ b/doc/develop/environment.rst @@ -49,3 +49,43 @@ The signature of the callback functions is:: include/search.h The return value is 0 if the variable change is accepted and 1 otherwise. + +Flags for environment variables +------------------------------- + +Environment flags validate the values given to environment variables and +restrict how environment variables can be changed. + +The static list is configured with CONFIG_ENV_FLAGS_LIST_STATIC. The list +must be in the following format:: + + type_attribute = [s|d|x|b|i|m] + access_attribute = [a|r|o|c|w] + attributes = type_attribute[access_attribute] + entry = variable_name[:attributes] + list = entry[,list] + +The type attributes are: + +* s - String (default) +* d - Decimal +* x - Hexadecimal +* b - Boolean ([1yYtT|0nNfF]) +* i - IP address, if networking is enabled +* m - MAC address, if networking is enabled + +The access attributes are: + +* a - Any (default) +* r - Read-only +* o - Write-once +* c - Change-default +* w - Writeable, if CONFIG_ENV_WRITEABLE_LIST is enabled + +CONFIG_ENV_FLAGS_LIST_DEFAULT defines the ``.flags`` variable in the +default or embedded environment. Any association in ``.flags`` overrides +an association in the static list. + +If CONFIG_REGEX is defined, the variable name is evaluated as a regular +expression. This allows multiple variables to define the same flags without +explicitly listing them all. diff --git a/env/Kconfig b/env/Kconfig index 7abd82ab6f3..3c9aaeb1f16 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -34,6 +34,29 @@ config ENV_CALLBACK_LIST_STATIC If the callback name is not specified, then the callback is deleted. Spaces are also allowed anywhere in the list. +config ENV_FLAGS_LIST_STATIC + string "Static flags list" + default "" + help + The environment flags are associated with variables in a static + list. Define this list in the following format: + + type_attribute = [s|d|x|b|i|m] + access_attribute = [a|r|o|c|w] + attributes = type_attribute[access_attribute] + entry = variable_name[:attributes] + list = entry[,list] + + The type attributes are s for string, d for decimal, x for + hexadecimal and b for boolean. If networking is enabled, i can + be used for IP addresses and m for MAC addresses. + + The access attributes are a for any, r for read-only, o for + write-once and c for change-default. When CONFIG_ENV_WRITEABLE_LIST + is enabled, w can be used to mark variables as writable. + + Spaces are also allowed anywhere in the list. + config SAVEENV def_bool y if CMD_SAVEENV diff --git a/include/configs/aristainetos2.h b/include/configs/aristainetos2.h index 8a66b1275df..c0e5c72764e 100644 --- a/include/configs/aristainetos2.h +++ b/include/configs/aristainetos2.h @@ -413,7 +413,4 @@ /* UBI support */ -#define CFG_ENV_FLAGS_LIST_STATIC "ethaddr:mw,serial#:sw,board_type:sw," \ - "sysnum:dw,panel:sw,ipaddr:iw,serverip:iw" - #endif /* __ARISTAINETOS2_CONFIG_H */ diff --git a/include/configs/capricorn-common.h b/include/configs/capricorn-common.h index ee13d2ab950..7120a44d186 100644 --- a/include/configs/capricorn-common.h +++ b/include/configs/capricorn-common.h @@ -38,19 +38,6 @@ #define CFG_EXTRA_ENV_SETTINGS \ AHAB_ENV -#ifdef CONFIG_ENV_WRITEABLE_LIST -#define CFG_ENV_FLAGS_LIST_STATIC \ - "bootcount:dw," \ - "bootdelay:sw," \ - "bootlimit:dw," \ - "partitionset_active:sw," \ - "rastate:dw," \ - "sig_a:sw,sig_b:sw," \ - "target_env:sw," \ - "upgrade_available:dw," \ - "ustate:dw" -#endif - /* Default location for tftp and bootm */ /* On CCP board, USDHC1 is for eMMC */ diff --git a/include/configs/hmibsc.h b/include/configs/hmibsc.h index 950ec8b190d..ea9762ee448 100644 --- a/include/configs/hmibsc.h +++ b/include/configs/hmibsc.h @@ -8,8 +8,4 @@ #ifndef __CONFIGS_HMIBSC_H #define __CONFIGS_HMIBSC_H -/* PHY needs a longer aneg time */ - -#define CFG_ENV_FLAGS_LIST_STATIC "BOOT_A_LEFT:dw,BOOT_B_LEFT:dw,BOOT_ORDER:sw" - #endif diff --git a/include/configs/imx6q-bosch-acc.h b/include/configs/imx6q-bosch-acc.h index 84da8250684..e00cddfdac0 100644 --- a/include/configs/imx6q-bosch-acc.h +++ b/include/configs/imx6q-bosch-acc.h @@ -44,18 +44,6 @@ "then env set env_persisted 1; run save_env; fi;\0" \ "save_env=env save; env save\0" -#define CFG_ENV_FLAGS_LIST_STATIC \ - "bootset:bw," \ - "clone_pending:bw," \ - "endurance_test:bw," \ - "env_persisted:bw," \ - "factory_reset:bw," \ - "fdtcontroladdr:xw," \ - "fitpart:dw," \ - "mmcpart:dw," \ - "production:bw," \ - "ustate:dw" - #else /* SD Card boot */ #define ENV_EXTRA \ diff --git a/include/configs/iot2050.h b/include/configs/iot2050.h index 5c58c7bbaab..fac4bbcd4ed 100644 --- a/include/configs/iot2050.h +++ b/include/configs/iot2050.h @@ -38,12 +38,4 @@ func(MMC, mmc, 0) \ BOOT_TARGET_USB(func) -#ifdef CONFIG_ENV_WRITEABLE_LIST -#define CFG_ENV_FLAGS_LIST_STATIC \ - "board_uuid:sw,board_name:sw,board_serial:sw,board_a5e:sw," \ - "mlfb:sw,fw_version:sw,seboot_version:sw," \ - "m2_manual_config:sw," \ - "eth1addr:mw,eth2addr:mw,watchdog_timeout_ms:dw,boot_targets:sw" -#endif - #endif /* __CONFIG_IOT2050_H */ diff --git a/include/configs/smegw01.h b/include/configs/smegw01.h index 0aa25f9e2ea..c0ca5a7db2f 100644 --- a/include/configs/smegw01.h +++ b/include/configs/smegw01.h @@ -22,21 +22,6 @@ #define EXTRA_BOOTPARAMS #endif -#ifdef CONFIG_SYS_BOOT_LOCKED -#define EXTRA_ENV_FLAGS -#else -#define EXTRA_ENV_FLAGS "mmcdev:dw," -#endif - -#define CFG_ENV_FLAGS_LIST_STATIC \ - "mmcpart:dw," \ - "mmcpart_committed:dw," \ - "ustate:dw," \ - "bootcount:dw," \ - "bootlimit:dw," \ - "upgrade_available:dw," \ - EXTRA_ENV_FLAGS - /* Physical Memory Map */ #define PHYS_SDRAM MMDC0_ARB_BASE_ADDR diff --git a/include/configs/socrates.h b/include/configs/socrates.h index 006d649f6ed..68d177d4ca3 100644 --- a/include/configs/socrates.h +++ b/include/configs/socrates.h @@ -108,8 +108,6 @@ */ #define CFG_SYS_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ -#define CFG_ENV_FLAGS_LIST_STATIC "ethaddr:mw,eth1addr:mw,system1_addr:xw,serial#:sw,ethact:sw,ethprime:sw" - /* pass open firmware flat tree */ #endif /* __CONFIG_H */ diff --git a/include/env_flags.h b/include/env_flags.h index 123fdbcb0ba..245dfdbd564 100644 --- a/include/env_flags.h +++ b/include/env_flags.h @@ -37,10 +37,6 @@ enum env_flags_varaccess { #define ENV_FLAGS_VARTYPE_LOC 0 #define ENV_FLAGS_VARACCESS_LOC 1 -#ifndef CFG_ENV_FLAGS_LIST_STATIC -#define CFG_ENV_FLAGS_LIST_STATIC "" -#endif - #if CONFIG_IS_ENABLED(NET) #ifdef CONFIG_REGEX #define ETHADDR_WILDCARD "\\d*" @@ -89,7 +85,7 @@ enum env_flags_varaccess { NET_FLAGS \ NET6_FLAGS \ SERIAL_FLAGS \ - CFG_ENV_FLAGS_LIST_STATIC + CONFIG_ENV_FLAGS_LIST_STATIC #ifdef CONFIG_CMD_ENV_FLAGS /* -- cgit v1.3.1 From f34597790e655baf25ff3081da654f7fc725b56b Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 16 May 2026 00:38:16 +0100 Subject: doc: fit: add dm-verity boot parameter documentation Add documentation for CONFIG_FIT_VERITY which allows U-Boot to construct dm-mod.create= and dm-mod.waitfor= kernel command-line parameters from dm-verity metadata embedded in FIT filesystem sub-images. The new document covers the relationship between FIT loadable indices and the /dev/fitN block devices that the Linux uImage.FIT block driver creates, provides a complete .its example with a dm-verity-protected SquashFS root filesystem, describes all required and optional dm-verity subnode properties and explains how mkimage generates the verity metadata automatically. dm-verity is only supported for external-data FIT images (mkimage -E); mkimage aborts with an error if the flag is omitted. Signed-off-by: Daniel Golle Reviewed-by: Simon Glass --- doc/usage/fit/dm-verity.rst | 304 ++++++++++++++++++++++++++++++++++++++++++++ doc/usage/fit/index.rst | 1 + 2 files changed, 305 insertions(+) create mode 100644 doc/usage/fit/dm-verity.rst (limited to 'doc') diff --git a/doc/usage/fit/dm-verity.rst b/doc/usage/fit/dm-verity.rst new file mode 100644 index 00000000000..800a18fceae --- /dev/null +++ b/doc/usage/fit/dm-verity.rst @@ -0,0 +1,304 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +FIT dm-verity Boot Parameters +============================= + +Introduction +------------ + +Linux's dm-verity device-mapper target provides transparent integrity +checking of block devices using a Merkle tree. It is commonly used to +protect read-only root filesystems such as SquashFS images. + +When a FIT image packages the root filesystem as a loadable sub-image of +type ``filesystem`` (``IH_TYPE_FILESYSTEM``), the verity metadata can be +stored alongside the image data in a ``dm-verity`` subnode. U-Boot reads +this metadata at boot time and generates the kernel command-line parameters +that Linux needs to activate the verity target, eliminating the need for +an initramfs or userspace helper to set up dm-verity. + +This feature is enabled by ``CONFIG_FIT_VERITY`` (see ``boot/Kconfig``). + +Prerequisites +------------- + +* **Linux uImage.FIT block driver** – the kernel must include the FIT block + driver that exposes loadable sub-images as ``/dev/fit0``, ``/dev/fit1``, + etc. The driver assigns device numbers in the order loadables appear in + the FIT configuration. + +* **dm-verity support in the kernel** – ``CONFIG_DM_VERITY`` must be + enabled so the kernel can process the ``dm-mod.create=`` parameter. + +* **CONFIG_FIT_VERITY** enabled in U-Boot. + +How it works +------------ + +The implementation is split into a **build** phase and an **apply** phase, +both of which run automatically within the ``bootm`` state machine. No boot +method needs to call verity functions explicitly. + +**Build phase** (``BOOTM_STATE_FINDOTHER`` → ``boot_get_loadable()``) + +1. After all loadable sub-images have been loaded, + ``fit_verity_build_cmdline()`` iterates the configuration's + ``loadables`` list. + +2. For each loadable that is an ``IH_TYPE_FILESYSTEM`` image **and** + contains a ``dm-verity`` child node, a dm-verity target specification is + built by the helper ``fit_verity_build_target()``. + +3. The dm-verity target references ``/dev/fitN``, where *N* is the + zero-based index of the loadable in the configuration. This matches the + numbering used by the Linux FIT block driver. + +4. The resulting fragments are stored in ``struct bootm_headers``: + + ``images->dm_mod_create`` + The full dm-verity target table. Multiple targets are separated by ``;``. + + ``images->dm_mod_waitfor`` + Comma-separated list of ``/dev/fitN`` devices so the kernel waits for + the underlying FIT block devices to appear before activating + device-mapper. + +**Apply phase** (``BOOTM_STATE_OS_PREP``) + +5. Just before ``bootm_process_cmdline_env()`` processes the ``bootargs`` + environment variable, ``fit_verity_apply_bootargs()`` appends the + ``dm-mod.create=`` and ``dm-mod.waitfor=`` parameters. + +**Bootmeth integration** + + Because the fragments are stored in ``struct bootm_headers``, a boot + method can check ``fit_verity_active(images)`` between bootm state + invocations. A typical pattern splits ``bootm_run_states()`` into two + calls -- one for ``START|FINDOS|FINDOTHER|LOADOS`` and one for + ``OS_PREP|OS_GO`` -- and inspects ``fit_verity_active()`` in + between to decide whether to add a ``root=`` parameter pointing at the + dm-verity device. + +FIT image source (.its) example +------------------------------- + +Below is a minimal ``.its`` file showing a kernel and a dm-verity-protected +root filesystem packaged as a FIT. Only the three user-provided properties +(``algo``, ``data-block-size``, ``hash-block-size``) are included; ``mkimage`` +computes and fills in ``digest``, ``salt``, ``num-data-blocks``, and +``hash-start-block`` automatically (see `Generating verity metadata`_ below):: + + /dts-v1/; + + / { + description = "Kernel + dm-verity rootfs"; + #address-cells = <1>; + + images { + kernel { + description = "Linux kernel"; + data = /incbin/("./Image.gz"); + type = "kernel"; + arch = "arm64"; + os = "linux"; + compression = "gzip"; + load = <0x44000000>; + entry = <0x44000000>; + hash-1 { + algo = "sha256"; + }; + }; + + fdt { + description = "Device tree blob"; + data = /incbin/("./board.dtb"); + type = "flat_dt"; + arch = "arm64"; + compression = "none"; + hash-1 { + algo = "sha256"; + }; + }; + + rootfs { + description = "SquashFS root filesystem"; + data = /incbin/("./rootfs.squashfs"); + type = "filesystem"; + arch = "arm64"; + compression = "none"; + hash-1 { + algo = "sha256"; + }; + + dm-verity { + algo = "sha256"; + data-block-size = <4096>; + hash-block-size = <4096>; + }; + }; + }; + + configurations { + default = "config-1"; + config-1 { + description = "Boot with dm-verity rootfs"; + kernel = "kernel"; + fdt = "fdt"; + loadables = "rootfs"; + }; + }; + }; + +With this configuration U-Boot produces a kernel command line similar to:: + + dm-mod.create="rootfs,,, ro,0 verity 1 \ + /dev/fit0 /dev/fit0 4096 4096 3762 3762 sha256 \ + 8e6791637f93cbb81fc45299e203cbe85ca2e47a38f5051bddeece92d7b1c9f9 \ + aa7b11f8db8fe2e5bfd4eca1d18a22b5de7ea39d2e1b93bb7272ce0c6ca3cc8e" \ + dm-mod.waitfor=/dev/fit0 + +dm-verity subnode properties +---------------------------- + +User-provided properties (required in the ``.its``): + +.. list-table:: + :header-rows: 1 + :widths: 20 15 65 + + * - Property + - Type + - Description + * - ``algo`` + - string + - Hash algorithm name, e.g. ``"sha256"``. + * - ``data-block-size`` + - u32 + - Data block size in bytes (>= 512, typically 4096). + * - ``hash-block-size`` + - u32 + - Hash block size in bytes (>= 512, typically 4096). + +Computed properties (filled in by ``mkimage``): + +.. list-table:: + :header-rows: 1 + :widths: 20 15 65 + + * - Property + - Type + - Description + * - ``num-data-blocks`` + - u32 + - Number of data blocks in the filesystem image (computed from the + image size and ``data-block-size``). + * - ``hash-start-block`` + - u32 + - Offset in ``hash-block-size``-sized blocks from the start of the + sub-image to the root block of the hash tree. + * - ``digest`` + - byte array + - Root hash of the Merkle tree, stored as raw bytes. Length must match + the output size of ``algo``. + * - ``salt`` + - byte array + - Salt used when computing the Merkle tree, stored as raw bytes. + +These values are the same ones produced by ``veritysetup format`` and can +typically be obtained from its output. +The ``digest`` and ``salt`` byte arrays correspond to the hex-encoded +``Root hash`` and ``Salt`` printed by ``veritysetup format``. + +Optional boolean properties (when present, they are collected and appended +as dm-verity optional parameters with hyphens converted to underscores): + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Property + - Description + * - ``restart-on-corruption`` + - Restart the system on data corruption. + * - ``panic-on-corruption`` + - Panic the system on data corruption. + * - ``restart-on-error`` + - Restart the system on I/O error. + * - ``panic-on-error`` + - Panic the system on I/O error. + * - ``check-at-most-once`` + - Verify data blocks only on first read. + + +Generating verity metadata +-------------------------- + +``mkimage`` automates the entire process. When it encounters a +``dm-verity`` subnode, it: + +1. Writes the embedded image data to a temporary file. +2. Runs ``veritysetup format`` with the user-supplied algorithm and + block sizes. +3. Parses ``Root hash`` and ``Salt`` from ``veritysetup`` stdout. +4. Reads the expanded content (original data + Merkle hash tree) back + into an in-memory buffer and removes the temporary file. The + external-data section written to the .itb file uses this buffer in + place of the original ``data`` property. +5. Writes the computed ``digest``, ``salt``, ``num-data-blocks``, and + ``hash-start-block`` properties into the ``dm-verity`` subnode. + +Images with ``dm-verity`` subnodes **must** use external data layout +(``mkimage -E``). ``mkimage`` will abort with an error if ``-E`` is +not specified. + +Usage:: + + # Create the filesystem image + mksquashfs rootfs/ rootfs.squashfs -comp xz + + # Build the FIT (dm-verity is computed automatically); align each + # external-data section to the block size of the underlying storage + # (see the alignment note below). + mkimage -E -B 0x1000 -f image.its image.itb + +``veritysetup`` (from the cryptsetup_ package) must be installed on +the build host. + +.. _cryptsetup: https://gitlab.com/cryptsetup/cryptsetup + +.. note:: + + ``veritysetup format`` is invoked with ``--no-superblock``, so no + on-disk superblock is written between the data and hash regions. + The Merkle hash tree is appended directly to the image data within + the FIT external data section. ``hash-start-block`` is therefore + computed as ``data_size / hash-block-size`` (the offset of the hash + region in units of ``hash-block-size``). When ``data-block-size`` + equals ``hash-block-size`` this happens to equal ``num-data-blocks``. + +.. note:: + + The Linux ``fitblk`` driver currently requires each ``filesystem`` + sub-image to start and end on block boundaries of the underlying + block device (typically 512 bytes, sometimes 4 KiB for eMMC or NVMe + with 4 KiB native sectors). Use ``mkimage -B `` to pad + external-data sections to that boundary; ``-B 0x1000`` is a safe + default for the storage in common use. + + This alignment requirement comes from the kernel-side ``fitblk`` + driver to avoid unaligned-access fix-up overhead in block I/O, and + is **independent** of the dm-verity ``data-block-size`` and + ``hash-block-size`` properties -- those describe the block sizes + used by the device-mapper verity target itself, not storage + alignment. + +Kconfig +------- + +``CONFIG_FIT_VERITY`` + Depends on ``CONFIG_FIT`` and ``CONFIG_OF_LIBFDT``. + When enabled, ``fit_verity_build_cmdline()`` and + ``fit_verity_apply_bootargs()`` are compiled into the boot path. + When disabled, the functions are static inlines returning 0, so there + is no code-size impact. Works with both the ``bootm`` command and + BOOTSTD boot methods. diff --git a/doc/usage/fit/index.rst b/doc/usage/fit/index.rst index 6c78d8584ed..d17582b1d64 100644 --- a/doc/usage/fit/index.rst +++ b/doc/usage/fit/index.rst @@ -11,6 +11,7 @@ images that it reads and boots. Documentation about FIT is available in :maxdepth: 1 beaglebone_vboot + dm-verity howto kernel_fdt kernel_fdts_compressed -- cgit v1.3.1 From 86f4f05ad871e8af0f021c3614802875d6521f3e Mon Sep 17 00:00:00 2001 From: Wadim Egorov Date: Wed, 13 May 2026 09:19:03 +0200 Subject: doc: board: phytec: Fix typos and copy-paste errors in K3 docs A handful of small inaccuracies had crept into the phyCORE-AM6x docs. Mostly typos and formatting Issues. Fix them. While at it, update the am62a board to use the correct product link. Signed-off-by: Wadim Egorov --- doc/board/phytec/phycore-am62ax.rst | 8 ++++---- doc/board/phytec/phycore-am62x.rst | 2 +- doc/board/phytec/phycore-am64x.rst | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'doc') diff --git a/doc/board/phytec/phycore-am62ax.rst b/doc/board/phytec/phycore-am62ax.rst index e1f741011e7..aa3518a07ff 100644 --- a/doc/board/phytec/phycore-am62ax.rst +++ b/doc/board/phytec/phycore-am62ax.rst @@ -9,7 +9,7 @@ SoM (System on Module) featuring TI's AM62Ax SoC. It can be used in combination with different carrier boards. This module can come with different sizes and models for DDR, eMMC, SPI NOR Flash and various SoCs from the AM62Ax family. -A development Kit, called `phyBOARD-Lyra `_ +A development Kit, called `phyBOARD-Lyra `_ is used as a carrier board reference design around the AM62Ax SoM. Quickstart @@ -57,10 +57,10 @@ Set the variables corresponding to this platform: $ export UBOOT_CFG_CORTEXR=phycore_am62ax_r5_defconfig $ export UBOOT_CFG_CORTEXA=phycore_am62ax_a53_defconfig $ export TFA_BOARD=lite - $ # we dont use any extra TFA parameters + $ # we don't use any extra TFA parameters $ unset TFA_EXTRA_ARGS $ export OPTEE_PLATFORM=k3-am62ax - $ # we dont use any extra OPTEE parameters + $ # we don't use any extra OPTEE parameters $ unset OPTEE_EXTRA_ARGS 1. Trusted Firmware-A: @@ -147,7 +147,7 @@ the main domain serial port: Boot Modes ---------- -The phyCORE-AM62x development kit supports booting from many different +The phyCORE-AM62Ax development kit supports booting from many different interfaces. By default, the development kit is set to boot from the micro-SD card. To change the boot device, DIP switches S5 and S6 can be used. Boot switches should be changed with power off. diff --git a/doc/board/phytec/phycore-am62x.rst b/doc/board/phytec/phycore-am62x.rst index bd61d0c16cf..f5a0d51240a 100644 --- a/doc/board/phytec/phycore-am62x.rst +++ b/doc/board/phytec/phycore-am62x.rst @@ -60,7 +60,7 @@ Set the variables corresponding to this platform: $ # we don't use any extra TFA parameters $ unset TFA_EXTRA_ARGS $ export OPTEE_PLATFORM=k3-am62x - $ # we dont use any extra OPTEE parameters + $ # we don't use any extra OPTEE parameters $ unset OPTEE_EXTRA_ARGS .. include:: ../ti/am62x_sk.rst diff --git a/doc/board/phytec/phycore-am64x.rst b/doc/board/phytec/phycore-am64x.rst index 71f1fd7b404..c6677f6a440 100644 --- a/doc/board/phytec/phycore-am64x.rst +++ b/doc/board/phytec/phycore-am64x.rst @@ -60,8 +60,8 @@ Set the variables corresponding to this platform: $ # we don't use any extra TFA parameters $ unset TFA_EXTRA_ARGS $ export OPTEE_PLATFORM=k3-am64x - # we don't use any extra OPTEE parameters - unset OPTEE_EXTRA_ARGS + $ # we don't use any extra OPTEE parameters + $ unset OPTEE_EXTRA_ARGS .. include:: ../ti/am62x_sk.rst :start-after: .. am62x_evm_rst_include_start_build_steps @@ -148,7 +148,7 @@ Boot Modes The phyCORE-AM64x development kit supports booting from many different interfaces. By default, the development kit is set to boot from the micro-SD -card. To change the boot device, DIP switches S5 and S6 can be used. +card. To change the boot device, DIP switches SW3 and SW4 can be used. Boot switches should be changed with power off. .. list-table:: Boot Modes -- cgit v1.3.1 From 14ba26ebdda6bf003eac5b18d59ccd3808345fa5 Mon Sep 17 00:00:00 2001 From: Wadim Egorov Date: Wed, 13 May 2026 09:19:04 +0200 Subject: doc: board: phytec: k3: Document boot flow and watchdog Add two short sections to the common K3 phyCORE docs. Describe the default boot flow and its deprecated version. And write down the use of the watchdog. Signed-off-by: Wadim Egorov --- doc/board/phytec/k3-common.rst | 47 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'doc') diff --git a/doc/board/phytec/k3-common.rst b/doc/board/phytec/k3-common.rst index ffb50b51ad6..3adb176ea8a 100644 --- a/doc/board/phytec/k3-common.rst +++ b/doc/board/phytec/k3-common.rst @@ -1,6 +1,53 @@ .. SPDX-License-Identifier: GPL-2.0+ .. sectionauthor:: Wadim Egorov +Boot Flow +--------- + +The default `bootcmd` performs three steps: + +.. code-block:: + + run start_watchdog; bootflow scan -lb; run ${boot}boot + +Boot devices are scanned in the order given by `boot_targets`: + +.. code-block:: + + mmc1 mmc0 spi_flash dhcp + +For each device, U-Boot tries the boot methods listed in `bootmeths`: + +.. code-block:: + + [rauc] script efi extlinux pxe + +The `rauc` bootmeth is only present when `CONFIG_BOOTMETH_RAUC=y` is set in +the A53 defconfig. RAUC slot selection is handled entirely by the bootmeth; +no environment-side configuration is required. + +The legacy `${boot}boot` chain (`mmcboot`, `spiboot`, `netboot`) is kept for +backwards compatibility and prints a deprecation warning when run. New +deployments should rely on the standard boot mechanism (`bootflow`) only. + + +Watchdog +-------- + +`bootcmd` runs `start_watchdog` before starting the boot flow. When +`CONFIG_WATCHDOG_TIMEOUT_MSECS` is set to a non-zero value and the +`watchdog` environment variable points to a watchdog device, U-Boot enables +the watchdog with that timeout. + +After this point the OS is responsible for servicing the watchdog. If it +does not feed the watchdog before the timeout expires, the SoC will reset. +Make sure the watchdog driver is enabled and configured in the kernel and +userspace before relying on this. + +To skip the watchdog start, either build with `CONFIG_WATCHDOG_TIMEOUT_MSECS=0` +or set `watchdog_timeout_ms=0` in the environment. + + Environment ----------- -- cgit v1.3.1 From 6e8d82b9e9bd3418614a884a1cbc2dbda6ca4e64 Mon Sep 17 00:00:00 2001 From: Wadim Egorov Date: Wed, 13 May 2026 09:19:05 +0200 Subject: doc: board: phytec: Document DDR size override Kconfigs The phyCORE-AM62x and phyCORE-AM64x R5 SPL detects the populated DDR size from the SoM EEPROM and falls back to 2 GB if detection fails. For boards without a populated EEPROM or if no detection needed, the detection can be bypassed via CONFIG_PHYCORE_AM6{2,4}X_RAM_SIZE_FIX and one of the CONFIG_PHYCORE_AM6{2,4}X_RAM_SIZE_ choices. Add a "DDR RAM Size" section to both board docs describing this behaviour and listing the available size options (1/2/4 GB for AM62x, 1/2 GB for AM64x). Signed-off-by: Wadim Egorov --- doc/board/phytec/phycore-am62x.rst | 19 +++++++++++++++++++ doc/board/phytec/phycore-am64x.rst | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) (limited to 'doc') diff --git a/doc/board/phytec/phycore-am62x.rst b/doc/board/phytec/phycore-am62x.rst index f5a0d51240a..5349ba429d4 100644 --- a/doc/board/phytec/phycore-am62x.rst +++ b/doc/board/phytec/phycore-am62x.rst @@ -177,6 +177,25 @@ Boot switches should be changed with power off. - 11001010 - 00100000 +DDR RAM Size +------------ + +By default, the R5 SPL detects the populated DDR size by reading the SoM +EEPROM and configures the DDR controller and the U-Boot device-tree memory +node accordingly. The phyCORE-AM62x is available with 1 GB, 2 GB, or 4 GB of +DDR. If the EEPROM cannot be read or is invalid, the SPL falls back to a +2 GB configuration. + +EEPROM-based detection can be bypassed by enabling +`CONFIG_PHYCORE_AM62X_RAM_SIZE_FIX` in the R5 defconfig and selecting one of: + +* `CONFIG_PHYCORE_AM62X_RAM_SIZE_1GB` +* `CONFIG_PHYCORE_AM62X_RAM_SIZE_2GB` +* `CONFIG_PHYCORE_AM62X_RAM_SIZE_4GB` + +This is mainly useful if no detection is needed or for boards without a +populated SoM EEPROM. + .. include:: k3-common.rst Further Information diff --git a/doc/board/phytec/phycore-am64x.rst b/doc/board/phytec/phycore-am64x.rst index c6677f6a440..20887d443a9 100644 --- a/doc/board/phytec/phycore-am64x.rst +++ b/doc/board/phytec/phycore-am64x.rst @@ -175,6 +175,24 @@ Boot switches should be changed with power off. - 11011100 - 00000000 +DDR RAM Size +------------ + +By default, the R5 SPL detects the populated DDR size by reading the SoM +EEPROM and configures the DDR controller and the U-Boot device-tree memory +node accordingly. The phyCORE-AM64x is available with 1 GB or 2 GB of DDR. +If the EEPROM cannot be read or is invalid, the SPL falls back to a 2 GB +configuration. + +EEPROM-based detection can be bypassed by enabling +`CONFIG_PHYCORE_AM64X_RAM_SIZE_FIX` in the R5 defconfig and selecting one of: + +* `CONFIG_PHYCORE_AM64X_RAM_SIZE_1GB` +* `CONFIG_PHYCORE_AM64X_RAM_SIZE_2GB` + +This is mainly useful if no detection is needed or for boards without a +populated SoM EEPROM. + .. include:: k3-common.rst Further Information -- cgit v1.3.1 From 87ea6e67959099804faf4eb85d93a41f18db71c9 Mon Sep 17 00:00:00 2001 From: Caleb Ethridge Date: Thu, 21 May 2026 09:53:20 -0400 Subject: mach-sc5xx: sc573: Rename EZKIT board to EZLITE Rename the SC573 EZKIT board to EZLITE across the device tree, defconfig, board file, and related Kconfig/Makefile entries to match with release naming. EZKIT was used internally before the official product release. Signed-off-by: Caleb Ethridge Reviewed-by: Simon Glass --- arch/arm/dts/Makefile | 2 +- arch/arm/dts/sc573-ezkit.dts | 253 ------------------------ arch/arm/dts/sc573-ezlite.dts | 253 ++++++++++++++++++++++++ arch/arm/mach-sc5xx/Kconfig | 8 +- arch/arm/mach-sc5xx/init/dmcinit.c | 2 +- board/adi/sc573-ezkit/Kconfig | 116 ----------- board/adi/sc573-ezkit/Makefile | 6 - board/adi/sc573-ezkit/sc573-ezkit.c | 21 -- board/adi/sc573-ezkit/sc573-ezkit.env | 15 -- board/adi/sc573-ezlite/Kconfig | 116 +++++++++++ board/adi/sc573-ezlite/Makefile | 6 + board/adi/sc573-ezlite/sc573-ezlite.c | 21 ++ board/adi/sc573-ezlite/sc573-ezlite.env | 15 ++ configs/sc573-ezkit_defconfig | 85 -------- configs/sc573-ezlite_defconfig | 85 ++++++++ doc/device-tree-bindings/arm/adi/adi,sc5xx.yaml | 2 +- include/configs/sc573-ezkit.h | 18 -- include/configs/sc573-ezlite.h | 18 ++ 18 files changed, 521 insertions(+), 521 deletions(-) delete mode 100644 arch/arm/dts/sc573-ezkit.dts create mode 100644 arch/arm/dts/sc573-ezlite.dts delete mode 100644 board/adi/sc573-ezkit/Kconfig delete mode 100644 board/adi/sc573-ezkit/Makefile delete mode 100644 board/adi/sc573-ezkit/sc573-ezkit.c delete mode 100644 board/adi/sc573-ezkit/sc573-ezkit.env create mode 100644 board/adi/sc573-ezlite/Kconfig create mode 100644 board/adi/sc573-ezlite/Makefile create mode 100644 board/adi/sc573-ezlite/sc573-ezlite.c create mode 100644 board/adi/sc573-ezlite/sc573-ezlite.env delete mode 100644 configs/sc573-ezkit_defconfig create mode 100644 configs/sc573-ezlite_defconfig delete mode 100644 include/configs/sc573-ezkit.h create mode 100644 include/configs/sc573-ezlite.h (limited to 'doc') diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index d5dd0867622..1e8676284b7 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1178,7 +1178,7 @@ dtb-$(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) += imx8mm-cl-iot-gate-optee.dtb \ imx8mm-cl-iot-gate-ied-tpm0.dtbo \ imx8mm-cl-iot-gate-ied-tpm1.dtbo -dtb-$(CONFIG_TARGET_SC573_EZKIT) += sc573-ezkit.dtb +dtb-$(CONFIG_TARGET_SC573_EZLITE) += sc573-ezlite.dtb dtb-$(CONFIG_TARGET_SC584_EZKIT) += sc584-ezkit.dtb dtb-$(CONFIG_TARGET_SC589_MINI) += sc589-mini.dtb dtb-$(CONFIG_TARGET_SC589_EZKIT) += sc589-ezkit.dtb diff --git a/arch/arm/dts/sc573-ezkit.dts b/arch/arm/dts/sc573-ezkit.dts deleted file mode 100644 index 4a3d1ed5c56..00000000000 --- a/arch/arm/dts/sc573-ezkit.dts +++ /dev/null @@ -1,253 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * (C) Copyright 2024 - Analog Devices, Inc. - */ - -/dts-v1/; - -#include "sc5xx.dtsi" -#include "sc57x.dtsi" - -/ { - model = "ADI SC573-EZKIT"; - compatible = "adi,sc573-ezkit", "adi,sc57x"; -}; - -&i2c0 { - gpio_expander0: mcp23017@21 { - compatible = "microchip,mcp23017"; - reg = <0x21>; - gpio-controller; - #gpio-cells = <2>; - bootph-pre-ram; - - eeprom { - gpio-hog; - gpios = <0 GPIO_ACTIVE_LOW>; - output-low; - line-name = "eeprom-en"; - bootph-pre-ram; - }; - - uart0-flow-en { - gpio-hog; - gpios = <1 GPIO_ACTIVE_LOW>; - output-low; - line-name = "uart0-flow-en"; - bootph-pre-ram; - }; - - mlb { - gpio-hog; - gpios = <5 GPIO_ACTIVE_LOW>; - output-low; - line-name = "mlb-en"; - bootph-pre-ram; - }; - - can0 { - gpio-hog; - gpios = <6 GPIO_ACTIVE_LOW>; - output-low; - line-name = "can0-en"; - bootph-pre-ram; - }; - - can1 { - gpio-hog; - gpios = <7 GPIO_ACTIVE_LOW>; - output-low; - line-name = "can1-en"; - bootph-pre-ram; - }; - - adau1962 { - gpio-hog; - gpios = <8 GPIO_ACTIVE_LOW>; - output-high; - line-name = "adau1962-en"; - bootph-pre-ram; - }; - - adau1979 { - gpio-hog; - gpios = <9 GPIO_ACTIVE_LOW>; - output-high; - line-name = "adau1979-en"; - bootph-pre-ram; - }; - - sd-wp-en { - gpio-hog; - gpios = <11 GPIO_ACTIVE_LOW>; - output-low; - line-name = "sd-wp-en"; - bootph-pre-ram; - }; - - spi2flash-cs { - gpio-hog; - gpios = <12 GPIO_ACTIVE_LOW>; - output-high; - line-name = "spi2flash-cs"; - bootph-pre-ram; - }; - - spi2d2-d3 { - gpio-hog; - gpios = <13 GPIO_ACTIVE_LOW>; - output-high; - line-name = "spi2d2-d3-en"; - bootph-pre-ram; - }; - - spdif-opt { - gpio-hog; - gpios = <14 GPIO_ACTIVE_LOW>; - output-low; - line-name = "spdif-optical-en"; - bootph-pre-ram; - }; - - spdif-dig { - gpio-hog; - gpios = <15 GPIO_ACTIVE_LOW>; - output-low; - line-name = "spdif-digital-en"; - bootph-pre-ram; - }; - }; - - gpio_expander1: mcp23017@22 { - compatible = "microchip,mcp23017"; - reg = <0x22>; - gpio-controller; - #gpio-cells = <2>; - bootph-pre-ram; - - pushbutton3 { - gpio-hog; - gpios = <0 GPIO_ACTIVE_LOW>; - output-low; - line-name = "pushbutton3-en"; - bootph-pre-ram; - }; - - pushbutton2 { - gpio-hog; - gpios = <1 GPIO_ACTIVE_LOW>; - output-low; - line-name = "pushbutton2-en"; - bootph-pre-ram; - }; - - pushbutton1 { - gpio-hog; - gpios = <2 GPIO_ACTIVE_LOW>; - output-low; - line-name = "pushbutton1-en"; - bootph-pre-ram; - }; - - leds { - gpio-hog; - gpios = <3 GPIO_ACTIVE_LOW>; - output-low; - line-name = "leds-en"; - bootph-pre-ram; - }; - - flg0 { - gpio-hog; - gpios = <4 GPIO_ACTIVE_LOW>; - output-low; - line-name = "flg0_loop"; - bootph-pre-ram; - }; - - flg1 { - gpio-hog; - gpios = <5 GPIO_ACTIVE_LOW>; - output-low; - line-name = "flg1_loop"; - bootph-pre-ram; - }; - - flg2 { - gpio-hog; - gpios = <6 GPIO_ACTIVE_LOW>; - output-low; - line-name = "flg2_loop"; - bootph-pre-ram; - }; - - flg3 { - gpio-hog; - gpios = <7 GPIO_ACTIVE_LOW>; - output-low; - line-name = "flg3_loop"; - bootph-pre-ram; - }; - - adau1977 { - gpio-hog; - gpios = <8 GPIO_ACTIVE_LOW>; - output-low; - line-name = "adau1977_en"; - bootph-pre-ram; - }; - - adau1977_fault_rst { - gpio-hog; - gpios = <9 GPIO_ACTIVE_LOW>; - output-low; - line-name = "adau1977_fault_rst_en"; - bootph-pre-ram; - }; - - thumbwheel { - gpio-hog; - gpios = <10 GPIO_ACTIVE_LOW>; - output-low; - line-name = "thumbwheel_oe"; - bootph-pre-ram; - }; - - engine_rpm { - gpio-hog; - gpios = <11 GPIO_ACTIVE_LOW>; - output-low; - line-name = "engine_rpm_oe"; - bootph-pre-ram; - }; - }; -}; - -ð0 { - snps,reset-gpio = <&gpio0 ADI_ADSP_PIN('A', 5) GPIO_ACTIVE_LOW>; -}; - -&gpio0 { - emac0_phy_pwdn { - gpio-hog; - output-high; - gpios = ; - }; -}; - -&mmc { - status = "okay"; -}; - -&spi2 { - flash1: is25lp512@1 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "jedec,spi-nor", "is25lp512"; - reg = <1>; - spi-tx-bus-width = <4>; - spi-rx-bus-width = <4>; - spi-max-frequency = <10000000>; - bootph-pre-ram; - }; -}; diff --git a/arch/arm/dts/sc573-ezlite.dts b/arch/arm/dts/sc573-ezlite.dts new file mode 100644 index 00000000000..57604d707f7 --- /dev/null +++ b/arch/arm/dts/sc573-ezlite.dts @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2024 - Analog Devices, Inc. + */ + +/dts-v1/; + +#include "sc5xx.dtsi" +#include "sc57x.dtsi" + +/ { + model = "ADI SC573-EZLITE"; + compatible = "adi,sc573-ezlite", "adi,sc57x"; +}; + +&i2c0 { + gpio_expander0: mcp23017@21 { + compatible = "microchip,mcp23017"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + bootph-pre-ram; + + eeprom { + gpio-hog; + gpios = <0 GPIO_ACTIVE_LOW>; + output-low; + line-name = "eeprom-en"; + bootph-pre-ram; + }; + + uart0-flow-en { + gpio-hog; + gpios = <1 GPIO_ACTIVE_LOW>; + output-low; + line-name = "uart0-flow-en"; + bootph-pre-ram; + }; + + mlb { + gpio-hog; + gpios = <5 GPIO_ACTIVE_LOW>; + output-low; + line-name = "mlb-en"; + bootph-pre-ram; + }; + + can0 { + gpio-hog; + gpios = <6 GPIO_ACTIVE_LOW>; + output-low; + line-name = "can0-en"; + bootph-pre-ram; + }; + + can1 { + gpio-hog; + gpios = <7 GPIO_ACTIVE_LOW>; + output-low; + line-name = "can1-en"; + bootph-pre-ram; + }; + + adau1962 { + gpio-hog; + gpios = <8 GPIO_ACTIVE_LOW>; + output-high; + line-name = "adau1962-en"; + bootph-pre-ram; + }; + + adau1979 { + gpio-hog; + gpios = <9 GPIO_ACTIVE_LOW>; + output-high; + line-name = "adau1979-en"; + bootph-pre-ram; + }; + + sd-wp-en { + gpio-hog; + gpios = <11 GPIO_ACTIVE_LOW>; + output-low; + line-name = "sd-wp-en"; + bootph-pre-ram; + }; + + spi2flash-cs { + gpio-hog; + gpios = <12 GPIO_ACTIVE_LOW>; + output-high; + line-name = "spi2flash-cs"; + bootph-pre-ram; + }; + + spi2d2-d3 { + gpio-hog; + gpios = <13 GPIO_ACTIVE_LOW>; + output-high; + line-name = "spi2d2-d3-en"; + bootph-pre-ram; + }; + + spdif-opt { + gpio-hog; + gpios = <14 GPIO_ACTIVE_LOW>; + output-low; + line-name = "spdif-optical-en"; + bootph-pre-ram; + }; + + spdif-dig { + gpio-hog; + gpios = <15 GPIO_ACTIVE_LOW>; + output-low; + line-name = "spdif-digital-en"; + bootph-pre-ram; + }; + }; + + gpio_expander1: mcp23017@22 { + compatible = "microchip,mcp23017"; + reg = <0x22>; + gpio-controller; + #gpio-cells = <2>; + bootph-pre-ram; + + pushbutton3 { + gpio-hog; + gpios = <0 GPIO_ACTIVE_LOW>; + output-low; + line-name = "pushbutton3-en"; + bootph-pre-ram; + }; + + pushbutton2 { + gpio-hog; + gpios = <1 GPIO_ACTIVE_LOW>; + output-low; + line-name = "pushbutton2-en"; + bootph-pre-ram; + }; + + pushbutton1 { + gpio-hog; + gpios = <2 GPIO_ACTIVE_LOW>; + output-low; + line-name = "pushbutton1-en"; + bootph-pre-ram; + }; + + leds { + gpio-hog; + gpios = <3 GPIO_ACTIVE_LOW>; + output-low; + line-name = "leds-en"; + bootph-pre-ram; + }; + + flg0 { + gpio-hog; + gpios = <4 GPIO_ACTIVE_LOW>; + output-low; + line-name = "flg0_loop"; + bootph-pre-ram; + }; + + flg1 { + gpio-hog; + gpios = <5 GPIO_ACTIVE_LOW>; + output-low; + line-name = "flg1_loop"; + bootph-pre-ram; + }; + + flg2 { + gpio-hog; + gpios = <6 GPIO_ACTIVE_LOW>; + output-low; + line-name = "flg2_loop"; + bootph-pre-ram; + }; + + flg3 { + gpio-hog; + gpios = <7 GPIO_ACTIVE_LOW>; + output-low; + line-name = "flg3_loop"; + bootph-pre-ram; + }; + + adau1977 { + gpio-hog; + gpios = <8 GPIO_ACTIVE_LOW>; + output-low; + line-name = "adau1977_en"; + bootph-pre-ram; + }; + + adau1977_fault_rst { + gpio-hog; + gpios = <9 GPIO_ACTIVE_LOW>; + output-low; + line-name = "adau1977_fault_rst_en"; + bootph-pre-ram; + }; + + thumbwheel { + gpio-hog; + gpios = <10 GPIO_ACTIVE_LOW>; + output-low; + line-name = "thumbwheel_oe"; + bootph-pre-ram; + }; + + engine_rpm { + gpio-hog; + gpios = <11 GPIO_ACTIVE_LOW>; + output-low; + line-name = "engine_rpm_oe"; + bootph-pre-ram; + }; + }; +}; + +ð0 { + snps,reset-gpio = <&gpio0 ADI_ADSP_PIN('A', 5) GPIO_ACTIVE_LOW>; +}; + +&gpio0 { + emac0_phy_pwdn { + gpio-hog; + output-high; + gpios = ; + }; +}; + +&mmc { + status = "okay"; +}; + +&spi2 { + flash1: is25lp512@1 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor", "is25lp512"; + reg = <1>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <10000000>; + bootph-pre-ram; + }; +}; diff --git a/arch/arm/mach-sc5xx/Kconfig b/arch/arm/mach-sc5xx/Kconfig index 70fab57fb3c..e311a8adf9a 100644 --- a/arch/arm/mach-sc5xx/Kconfig +++ b/arch/arm/mach-sc5xx/Kconfig @@ -25,7 +25,7 @@ config SC57X bool "SC57x series" select COMMON_CLK_ADI_SC57X select CPU_V7A - select TARGET_SC573_EZKIT + select TARGET_SC573_EZLITE config SC58X bool "SC58x series" @@ -51,8 +51,8 @@ endchoice if SC57X -config TARGET_SC573_EZKIT - bool "Support SC573-EZKIT" +config TARGET_SC573_EZLITE + bool "Support SC573-EZLITE" endif @@ -600,6 +600,6 @@ source "board/adi/sc594-som-ezlite/Kconfig" source "board/adi/sc589-ezkit/Kconfig" source "board/adi/sc589-mini/Kconfig" source "board/adi/sc584-ezkit/Kconfig" -source "board/adi/sc573-ezkit/Kconfig" +source "board/adi/sc573-ezlite/Kconfig" endif diff --git a/arch/arm/mach-sc5xx/init/dmcinit.c b/arch/arm/mach-sc5xx/init/dmcinit.c index 12052613feb..2026735cc21 100644 --- a/arch/arm/mach-sc5xx/init/dmcinit.c +++ b/arch/arm/mach-sc5xx/init/dmcinit.c @@ -101,7 +101,7 @@ #ifdef CONFIG_TARGET_SC584_EZKIT #define DMC_PADCTL2_VALUE 0x0078283C -#elif CONFIG_TARGET_SC573_EZKIT +#elif CONFIG_TARGET_SC573_EZLITE #define DMC_PADCTL2_VALUE 0x00782828 #elif CONFIG_TARGET_SC589_MINI || CONFIG_TARGET_SC589_EZKIT #define DMC_PADCTL2_VALUE 0x00783C3C diff --git a/board/adi/sc573-ezkit/Kconfig b/board/adi/sc573-ezkit/Kconfig deleted file mode 100644 index 328563c1296..00000000000 --- a/board/adi/sc573-ezkit/Kconfig +++ /dev/null @@ -1,116 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# -# (C) Copyright 2024 - Analog Devices, Inc. - -if TARGET_SC573_EZKIT - -config SYS_BOARD - default "sc573-ezkit" - -config SYS_CONFIG_NAME - default "sc573-ezkit" - -config LDR_CPU - default "ADSP-SC573-0.0" - -config DEFAULT_DEVICE_TREE - default "sc573-ezkit" - -config ADI_IMAGE - default "tiny" - -config CUSTOM_SYS_INIT_SP_ADDR - default 0x8203f000 - -# SPI Flash - -config SF_DEFAULT_BUS - default 2 - -config SF_DEFAULT_CS - default 1 - -config SF_DEFAULT_SPEED - default 10000000 - -# Clocks - -config CGU0_DF_DIV - default 0 - -config CGU0_VCO_MULT - default 18 - -config CGU0_CCLK_DIV - default 1 - -config CGU0_SCLK_DIV - default 2 - -config CGU0_SCLK0_DIV - default 2 - -config CGU0_SCLK1_DIV - default 2 - -config CGU0_DCLK_DIV - default 2 - -config CGU0_OCLK_DIV - default 3 - -config CGU1_VCO_MULT - default 5 - -config CGU1_DF_DIV - default 0 - -config CGU1_CCLK_DIV - default 1 - -config CGU1_SCLK_DIV - default 2 - -config CGU1_SCLK0_DIV - default 2 - -config CGU1_SCLK1_DIV - default 2 - -config CGU1_DCLK_DIV - default 2 - -config CGU1_OCLK_DIV - default 3 - -config CDU0_CLKO0 - default 1 - -config CDU0_CLKO1 - default 1 - -config CDU0_CLKO2 - default 1 - -config CDU0_CLKO3 - default 1 - -config CDU0_CLKO4 - default 1 - -config CDU0_CLKO5 - default 1 - -config CDU0_CLKO6 - default 1 - -config CDU0_CLKO7 - default 5 - -config CDU0_CLKO8 - default 1 - -config CDU0_CLKO9 - default 1 - -endif diff --git a/board/adi/sc573-ezkit/Makefile b/board/adi/sc573-ezkit/Makefile deleted file mode 100644 index 0ea725b992b..00000000000 --- a/board/adi/sc573-ezkit/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# -# (C) Copyright 2025 - Analog Devices, Inc. -# - -obj-y += sc573-ezkit.o diff --git a/board/adi/sc573-ezkit/sc573-ezkit.c b/board/adi/sc573-ezkit/sc573-ezkit.c deleted file mode 100644 index 464142b27a5..00000000000 --- a/board/adi/sc573-ezkit/sc573-ezkit.c +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * (C) Copyright 2025 - Analog Devices, Inc. - */ - -#include -#include -#include -#include - -int board_phy_config(struct phy_device *phydev) -{ - fixup_dp83867_phy(phydev); - return 0; -} - -int board_init(void) -{ - sc5xx_enable_rgmii(); - return 0; -} diff --git a/board/adi/sc573-ezkit/sc573-ezkit.env b/board/adi/sc573-ezkit/sc573-ezkit.env deleted file mode 100644 index e1ad4f3716f..00000000000 --- a/board/adi/sc573-ezkit/sc573-ezkit.env +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later+ */ -/* - * (C) Copyright 2024 - Analog Devices, Inc. - */ - -adi_image_offset=0xe0000 -loadaddr=CONFIG_SC5XX_LOADADDR - -#define USE_NFS -#define USE_SPI -#define USE_RAM -#define USE_MMC -#define USE_USB - -#include diff --git a/board/adi/sc573-ezlite/Kconfig b/board/adi/sc573-ezlite/Kconfig new file mode 100644 index 00000000000..f3b848ef0f7 --- /dev/null +++ b/board/adi/sc573-ezlite/Kconfig @@ -0,0 +1,116 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# (C) Copyright 2024 - Analog Devices, Inc. + +if TARGET_SC573_EZLITE + +config SYS_BOARD + default "sc573-ezlite" + +config SYS_CONFIG_NAME + default "sc573-ezlite" + +config LDR_CPU + default "ADSP-SC573-0.0" + +config DEFAULT_DEVICE_TREE + default "sc573-ezlite" + +config ADI_IMAGE + default "tiny" + +config CUSTOM_SYS_INIT_SP_ADDR + default 0x8203f000 + +# SPI Flash + +config SF_DEFAULT_BUS + default 2 + +config SF_DEFAULT_CS + default 1 + +config SF_DEFAULT_SPEED + default 10000000 + +# Clocks + +config CGU0_DF_DIV + default 0 + +config CGU0_VCO_MULT + default 18 + +config CGU0_CCLK_DIV + default 1 + +config CGU0_SCLK_DIV + default 2 + +config CGU0_SCLK0_DIV + default 2 + +config CGU0_SCLK1_DIV + default 2 + +config CGU0_DCLK_DIV + default 2 + +config CGU0_OCLK_DIV + default 3 + +config CGU1_VCO_MULT + default 5 + +config CGU1_DF_DIV + default 0 + +config CGU1_CCLK_DIV + default 1 + +config CGU1_SCLK_DIV + default 2 + +config CGU1_SCLK0_DIV + default 2 + +config CGU1_SCLK1_DIV + default 2 + +config CGU1_DCLK_DIV + default 2 + +config CGU1_OCLK_DIV + default 3 + +config CDU0_CLKO0 + default 1 + +config CDU0_CLKO1 + default 1 + +config CDU0_CLKO2 + default 1 + +config CDU0_CLKO3 + default 1 + +config CDU0_CLKO4 + default 1 + +config CDU0_CLKO5 + default 1 + +config CDU0_CLKO6 + default 1 + +config CDU0_CLKO7 + default 5 + +config CDU0_CLKO8 + default 1 + +config CDU0_CLKO9 + default 1 + +endif diff --git a/board/adi/sc573-ezlite/Makefile b/board/adi/sc573-ezlite/Makefile new file mode 100644 index 00000000000..77c55af6240 --- /dev/null +++ b/board/adi/sc573-ezlite/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# (C) Copyright 2025 - Analog Devices, Inc. +# + +obj-y += sc573-ezlite.o diff --git a/board/adi/sc573-ezlite/sc573-ezlite.c b/board/adi/sc573-ezlite/sc573-ezlite.c new file mode 100644 index 00000000000..464142b27a5 --- /dev/null +++ b/board/adi/sc573-ezlite/sc573-ezlite.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2025 - Analog Devices, Inc. + */ + +#include +#include +#include +#include + +int board_phy_config(struct phy_device *phydev) +{ + fixup_dp83867_phy(phydev); + return 0; +} + +int board_init(void) +{ + sc5xx_enable_rgmii(); + return 0; +} diff --git a/board/adi/sc573-ezlite/sc573-ezlite.env b/board/adi/sc573-ezlite/sc573-ezlite.env new file mode 100644 index 00000000000..e1ad4f3716f --- /dev/null +++ b/board/adi/sc573-ezlite/sc573-ezlite.env @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later+ */ +/* + * (C) Copyright 2024 - Analog Devices, Inc. + */ + +adi_image_offset=0xe0000 +loadaddr=CONFIG_SC5XX_LOADADDR + +#define USE_NFS +#define USE_SPI +#define USE_RAM +#define USE_MMC +#define USE_USB + +#include diff --git a/configs/sc573-ezkit_defconfig b/configs/sc573-ezkit_defconfig deleted file mode 100644 index 4320c73fd39..00000000000 --- a/configs/sc573-ezkit_defconfig +++ /dev/null @@ -1,85 +0,0 @@ -CONFIG_ARM=y -CONFIG_SYS_ARM_CACHE_WRITETHROUGH=y -CONFIG_ARCH_SC5XX=y -CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SPL_GPIO=y -CONFIG_DM_GPIO=y -CONFIG_SPL_SYS_MALLOC_F_LEN=0x10000 -CONFIG_SPL_SERIAL=y -CONFIG_SC5XX_LOADADDR=0x83000000 -CONFIG_WATCHDOG_TIMEOUT_MSECS=60000 -CONFIG_CGU0_CLKOUTSEL=7 -# CONFIG_EFI_LOADER is not set -CONFIG_FIT=y -CONFIG_FIT_SIGNATURE=y -CONFIG_LEGACY_IMAGE_FORMAT=y -CONFIG_USE_BOOTCOMMAND=y -CONFIG_BOOTCOMMAND="run ramboot" -CONFIG_SYS_CBSIZE=512 -# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -CONFIG_SPL_I2C=y -CONFIG_CMD_BOOTZ=y -# CONFIG_BOOTM_PLAN9 is not set -# CONFIG_BOOTM_RTEMS is not set -# CONFIG_BOOTM_VXWORKS is not set -# CONFIG_CMD_ELF is not set -CONFIG_CMD_DM=y -CONFIG_CMD_GPIO=y -CONFIG_CMD_GPT=y -CONFIG_CMD_I2C=y -CONFIG_CMD_MMC=y -CONFIG_CMD_MTD=y -# CONFIG_CMD_PINMUX is not set -CONFIG_CMD_SPI=y -CONFIG_CMD_USB=y -CONFIG_SYS_DISABLE_AUTOLOAD=y -CONFIG_CMD_DHCP=y -CONFIG_CMD_DNS=y -CONFIG_CMD_MII=y -# CONFIG_CMD_MDIO is not set -CONFIG_CMD_PING=y -CONFIG_CMD_WGET=y -CONFIG_CMD_EXT4=y -CONFIG_CMD_EXT4_WRITE=y -CONFIG_CMD_FAT=y -CONFIG_CMD_FS_GENERIC=y -CONFIG_SPL_OF_CONTROL=y -CONFIG_OF_EMBED=y -CONFIG_ENV_OVERWRITE=y -CONFIG_USE_HOSTNAME=y -CONFIG_HOSTNAME="sc573-ezkit" -CONFIG_NET_RETRY_COUNT=20 -CONFIG_IP_DEFRAG=y -CONFIG_SPL_CLK=y -CONFIG_SPL_CLK_CCF=y -CONFIG_GPIO_HOG=y -CONFIG_SPL_GPIO_HOG=y -CONFIG_DM_GPIO_LOOKUP_LABEL=y -CONFIG_SPL_DM_GPIO_LOOKUP_LABEL=y -CONFIG_MCP230XX_GPIO=y -CONFIG_DM_I2C=y -CONFIG_DM_I2C_GPIO=y -CONFIG_SYS_I2C_ADI=y -CONFIG_MMC_DW=y -CONFIG_MMC_DW_SNPS=y -CONFIG_MTD=y -CONFIG_DM_SPI_FLASH=y -CONFIG_SPI_FLASH_WINBOND=y -CONFIG_ETH_DESIGNWARE=y -CONFIG_DW_ALTDESCRIPTOR=y -CONFIG_PINCTRL=y -# CONFIG_PINCTRL_GENERIC is not set -CONFIG_SPL_PINCTRL=y -# CONFIG_SPL_PINCTRL_GENERIC is not set -CONFIG_SPECIFY_CONSOLE_INDEX=y -CONFIG_SPI=y -CONFIG_DM_SPI=y -CONFIG_ADI_SPI3=y -CONFIG_SPL_TIMER=y -CONFIG_USB=y -CONFIG_USB_MUSB_HOST=y -CONFIG_USB_MUSB_SC5XX=y -CONFIG_USB_MUSB_PIO_ONLY=y -CONFIG_USB_STORAGE=y -CONFIG_FAT_WRITE=y -# CONFIG_REGEX is not set diff --git a/configs/sc573-ezlite_defconfig b/configs/sc573-ezlite_defconfig new file mode 100644 index 00000000000..f6305451c27 --- /dev/null +++ b/configs/sc573-ezlite_defconfig @@ -0,0 +1,85 @@ +CONFIG_ARM=y +CONFIG_SYS_ARM_CACHE_WRITETHROUGH=y +CONFIG_ARCH_SC5XX=y +CONFIG_SYS_MALLOC_LEN=0x100000 +CONFIG_SPL_GPIO=y +CONFIG_DM_GPIO=y +CONFIG_SPL_SYS_MALLOC_F_LEN=0x10000 +CONFIG_SPL_SERIAL=y +CONFIG_SC5XX_LOADADDR=0x83000000 +CONFIG_WATCHDOG_TIMEOUT_MSECS=60000 +CONFIG_CGU0_CLKOUTSEL=7 +# CONFIG_EFI_LOADER is not set +CONFIG_FIT=y +CONFIG_FIT_SIGNATURE=y +CONFIG_LEGACY_IMAGE_FORMAT=y +CONFIG_USE_BOOTCOMMAND=y +CONFIG_BOOTCOMMAND="run ramboot" +CONFIG_SYS_CBSIZE=512 +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +CONFIG_SPL_I2C=y +CONFIG_CMD_BOOTZ=y +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +CONFIG_CMD_DM=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y +# CONFIG_CMD_PINMUX is not set +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +CONFIG_SYS_DISABLE_AUTOLOAD=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_DNS=y +CONFIG_CMD_MII=y +# CONFIG_CMD_MDIO is not set +CONFIG_CMD_PING=y +CONFIG_CMD_WGET=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_EMBED=y +CONFIG_ENV_OVERWRITE=y +CONFIG_USE_HOSTNAME=y +CONFIG_HOSTNAME="sc573-ezlite" +CONFIG_NET_RETRY_COUNT=20 +CONFIG_IP_DEFRAG=y +CONFIG_SPL_CLK=y +CONFIG_SPL_CLK_CCF=y +CONFIG_GPIO_HOG=y +CONFIG_SPL_GPIO_HOG=y +CONFIG_DM_GPIO_LOOKUP_LABEL=y +CONFIG_SPL_DM_GPIO_LOOKUP_LABEL=y +CONFIG_MCP230XX_GPIO=y +CONFIG_DM_I2C=y +CONFIG_DM_I2C_GPIO=y +CONFIG_SYS_I2C_ADI=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_SNPS=y +CONFIG_MTD=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_DW_ALTDESCRIPTOR=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_SPECIFY_CONSOLE_INDEX=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_ADI_SPI3=y +CONFIG_SPL_TIMER=y +CONFIG_USB=y +CONFIG_USB_MUSB_HOST=y +CONFIG_USB_MUSB_SC5XX=y +CONFIG_USB_MUSB_PIO_ONLY=y +CONFIG_USB_STORAGE=y +CONFIG_FAT_WRITE=y +# CONFIG_REGEX is not set diff --git a/doc/device-tree-bindings/arm/adi/adi,sc5xx.yaml b/doc/device-tree-bindings/arm/adi/adi,sc5xx.yaml index df976c7ae73..ae3b5e6092a 100644 --- a/doc/device-tree-bindings/arm/adi/adi,sc5xx.yaml +++ b/doc/device-tree-bindings/arm/adi/adi,sc5xx.yaml @@ -18,7 +18,7 @@ properties: oneOf: - description: SC57X Series Boards items: - - const: adi,sc573-ezkit + - const: adi,sc573-ezlite - const: adi,sc57x - description: SC58X Series Boards diff --git a/include/configs/sc573-ezkit.h b/include/configs/sc573-ezkit.h deleted file mode 100644 index 42e42f8150b..00000000000 --- a/include/configs/sc573-ezkit.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * (C) Copyright 2024 - Analog Devices, Inc. - */ - -#ifndef __CONFIG_SC573_EZKIT_H -#define __CONFIG_SC573_EZKIT_H - -/* - * Memory Settings - */ -#define MEM_MT41K128M16JT -#define MEM_DMC0 - -#define CFG_SYS_SDRAM_BASE 0x82000000 -#define CFG_SYS_SDRAM_SIZE 0xe000000 - -#endif diff --git a/include/configs/sc573-ezlite.h b/include/configs/sc573-ezlite.h new file mode 100644 index 00000000000..590a8f06fb5 --- /dev/null +++ b/include/configs/sc573-ezlite.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * (C) Copyright 2024 - Analog Devices, Inc. + */ + +#ifndef __CONFIG_SC573_EZLITE_H +#define __CONFIG_SC573_EZLITE_H + +/* + * Memory Settings + */ +#define MEM_MT41K128M16JT +#define MEM_DMC0 + +#define CFG_SYS_SDRAM_BASE 0x82000000 +#define CFG_SYS_SDRAM_SIZE 0xe000000 + +#endif -- cgit v1.3.1 From 0b9897e7a41cb6d035956b5c7ca004be84feaa17 Mon Sep 17 00:00:00 2001 From: Nora Schiffer Date: Tue, 19 May 2026 14:24:06 +0200 Subject: board: tq: add TQMa6UL[L]x[L] SOM and MBa6ULx baseboard The TQMa6UL[L]x is a family of SoMs based on the i.MX6UL[L] SoCs. They are available either with board connectors or as LGA packages with solder balls. Add Support for the SoM and its combination with our MBa6ULx carrier board. For use with the MBa6ULx carrier board, the LGA variant is soldered onto an adapter board. Signed-off-by: Nora Schiffer Signed-off-by: Max Merchel --- arch/arm/mach-imx/mx6/Kconfig | 21 ++++ board/tq/MAINTAINERS | 2 +- board/tq/tqma6ul/Kconfig | 114 ++++++++++++++++++++ board/tq/tqma6ul/Makefile | 16 +++ board/tq/tqma6ul/spl.c | 128 +++++++++++++++++++++++ board/tq/tqma6ul/spl_mba6ul.c | 177 +++++++++++++++++++++++++++++++ board/tq/tqma6ul/spl_tqma6ul_ram.c | 209 +++++++++++++++++++++++++++++++++++++ board/tq/tqma6ul/tqma6ul.c | 184 ++++++++++++++++++++++++++++++++ board/tq/tqma6ul/tqma6ul.cfg | 23 ++++ board/tq/tqma6ul/tqma6ul.env | 47 +++++++++ board/tq/tqma6ul/tqma6ul.h | 25 +++++ board/tq/tqma6ul/tqma6ul_mba6ul.c | 138 ++++++++++++++++++++++++ doc/board/tq/index.rst | 1 + doc/board/tq/tqma6ul.rst | 105 +++++++++++++++++++ include/configs/tqma6ul.h | 53 ++++++++++ include/configs/tqma6ul_mba6ul.h | 19 ++++ 16 files changed, 1261 insertions(+), 1 deletion(-) create mode 100644 board/tq/tqma6ul/Kconfig create mode 100644 board/tq/tqma6ul/Makefile create mode 100644 board/tq/tqma6ul/spl.c create mode 100644 board/tq/tqma6ul/spl_mba6ul.c create mode 100644 board/tq/tqma6ul/spl_tqma6ul_ram.c create mode 100644 board/tq/tqma6ul/tqma6ul.c create mode 100644 board/tq/tqma6ul/tqma6ul.cfg create mode 100644 board/tq/tqma6ul/tqma6ul.env create mode 100644 board/tq/tqma6ul/tqma6ul.h create mode 100644 board/tq/tqma6ul/tqma6ul_mba6ul.c create mode 100644 doc/board/tq/tqma6ul.rst create mode 100644 include/configs/tqma6ul.h create mode 100644 include/configs/tqma6ul_mba6ul.h (limited to 'doc') diff --git a/arch/arm/mach-imx/mx6/Kconfig b/arch/arm/mach-imx/mx6/Kconfig index d198d9932f4..7ed4b24b751 100644 --- a/arch/arm/mach-imx/mx6/Kconfig +++ b/arch/arm/mach-imx/mx6/Kconfig @@ -633,6 +633,26 @@ config TARGET_TQMA6 imply CMD_SF imply CMD_DM +config TARGET_TQMA6UL + bool "TQ-Systems TQMa6UL[L]x" + depends on MX6UL || MX6ULL + select TQ_COMMON_SOM + select BOARD_EARLY_INIT_F + select BOARD_LATE_INIT + select OF_SYSTEM_SETUP + select DM + select DM_I2C + select SUPPORT_SPL + select SPL_SEPARATE_BSS if SPL + imply DM_GPIO + imply DM_MMC + imply DM_SPI if SPI + imply DM_SPI_FLASH if SPI + imply SPI + help + TQMa6UL[L]x is a TQ SoM with i.MX6UL/i.MX6ULL CPU + The SoM can be used on various baseboards. + config TARGET_UDOO bool "udoo" depends on MX6QDL @@ -739,6 +759,7 @@ source "board/technexion/pico-imx6/Kconfig" source "board/technexion/pico-imx6ul/Kconfig" source "board/tbs/tbs2910/Kconfig" source "board/tq/tqma6/Kconfig" +source "board/tq/tqma6ul/Kconfig" source "board/toradex/apalis_imx6/Kconfig" source "board/toradex/colibri_imx6/Kconfig" source "board/toradex/colibri-imx6ull/Kconfig" diff --git a/board/tq/MAINTAINERS b/board/tq/MAINTAINERS index b31c5793432..a04a36ba415 100644 --- a/board/tq/MAINTAINERS +++ b/board/tq/MAINTAINERS @@ -1,4 +1,4 @@ -TQMA6 +TQMA6 / TQMA6UL / TQMA6ULxL / TQMA6ULL / TQMA6ULLxL M: Max Merchel L: u-boot@ew.tq-group.com S: Maintained diff --git a/board/tq/tqma6ul/Kconfig b/board/tq/tqma6ul/Kconfig new file mode 100644 index 00000000000..5d85c68b359 --- /dev/null +++ b/board/tq/tqma6ul/Kconfig @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (c) 2016-2026 TQ-Systems GmbH , +# D-82229 Seefeld, Germany. +# Author: Marco Felsch, Markus Niebel, Max Merchel +# + +if TARGET_TQMA6UL + +config SYS_BOARD + default "tqma6ul" + +config SYS_VENDOR + default "tq" + +config SYS_CONFIG_NAME + default "tqma6ul_mba6ul" if MBA6UL + +choice + prompt "TQMa6UL module variant" + default TQMA6UL_VARIANT_STANDARD + help + Select the variant of the TQMa6UL SoM module being used. + By default, the variant with board-to-board connectors is used. + +config TQMA6UL_VARIANT_STANDARD + bool "standard module with board connector" + help + Select for SoM variant connector + with board to board connectors + +config TQMA6UL_VARIANT_LGA + bool "LGA module with solder balls" + help + Select for SoM variant LGA + with solder balls + +endchoice + +config TQMA6UL_RAM_256M + bool + +config TQMA6UL_RAM_512M + bool + +choice + prompt "TQMa6UL RAM configuration" + default TQMA6UL_RAM_MULTI + help + Select RAM configuration. Normally use default here but for + specific setup it is possible to use a single RAM size. + +config TQMA6UL_RAM_MULTI + bool "TQMa6ULx with 256/512 MB RAM - Single image" + select TQMA6UL_RAM_256M + select TQMA6UL_RAM_512M + help + Build a single U-Boot solely for variants + with 256/512 MB RAM. + +config TQMA6UL_RAM_SINGLE_256M + bool "TQMa6UL with 256 MB RAM" + select TQMA6UL_RAM_256M + help + Build U-Boot solely for variants + with 256 MB RAM. + +config TQMA6UL_RAM_SINGLE_512M + bool "TQMa6UL with 512 MB RAM" + select TQMA6UL_RAM_512M + help + Build U-Boot solely for variants + with 512 MB RAM. + +endchoice + +choice + prompt "TQMa6UL base board variant" + default MBA6UL + help + Select the baseboard variant for the TQMa6UL module. + By default the MBA6UL starterkit is used. + +config MBA6UL + bool "TQMa6UL on MBa6ULx Starterkit" + select TQ_COMMON_BB + select TQ_COMMON_SDMMC + select SYSINFO + select SYSINFO_TQ_EEPROM + select I2C_EEPROM + select MISC + select MXC_UART + imply DM_ETH + imply DM_GPIO + imply DM_MMC + imply DM_SERIAL + imply DM_SPI + imply OF_UPSTREAM + imply PHYLIB + imply PHY_SMSC + imply USB + imply USB_STORAGE + help + Select the MBa6ULx starterkit. + This is the default base board. + +endchoice + +config IMX_CONFIG + default "board/tq/tqma6ul/tqma6ul.cfg" + +source "board/tq/common/Kconfig" + +endif diff --git a/board/tq/tqma6ul/Makefile b/board/tq/tqma6ul/Makefile new file mode 100644 index 00000000000..f45ed4a15f6 --- /dev/null +++ b/board/tq/tqma6ul/Makefile @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (c) 2021-2026 TQ-Systems GmbH , +# D-82229 Seefeld, Germany. +# Author: Markus Niebel, Matthias Schiffer, Max Merchel +# + +obj-y := tqma6ul.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +obj-y += spl_tqma6ul_ram.o +obj-$(CONFIG_MBA6UL) += spl_mba6ul.o +else +obj-$(CONFIG_MBA6UL) += tqma6ul_mba6ul.o +endif diff --git a/board/tq/tqma6ul/spl.c b/board/tq/tqma6ul/spl.c new file mode 100644 index 00000000000..71c5134c4f6 --- /dev/null +++ b/board/tq/tqma6ul/spl.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Max Merchel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../common/tq_bb.h" +#include "../common/tq_som.h" + +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + writel(0xFFFFFFFF, &ccm->CCGR0); + writel(0xFFFFFFFF, &ccm->CCGR1); + writel(0xFFFFFFFF, &ccm->CCGR2); + writel(0xFFFFFFFF, &ccm->CCGR3); + writel(0xFFFFFFFF, &ccm->CCGR4); + writel(0xFFFFFFFF, &ccm->CCGR5); + writel(0xFFFFFFFF, &ccm->CCGR6); +} + +#define USDHC_CLK_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \ + PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +/* eMMC on USDHC2 */ +static const iomux_v3_cfg_t tqma6ul_usdhc2_pads[] = { + MX6_PAD_NAND_DATA00__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NAND_DATA01__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NAND_DATA02__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NAND_DATA03__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NAND_DATA04__USDHC2_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NAND_DATA05__USDHC2_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NAND_DATA06__USDHC2_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NAND_DATA07__USDHC2_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NAND_ALE__USDHC2_RESET_B | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NAND_RE_B__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NAND_WE_B__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; + +static struct fsl_esdhc_cfg tqma6ul_usdhc2_cfg = { + .esdhc_base = USDHC2_BASE_ADDR, + .max_bus_width = 8, +}; + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + if (cfg->esdhc_base == USDHC2_BASE_ADDR) + /* eMMC/uSDHC2 is always present */ + ret = 1; + else + ret = tq_bb_board_mmc_getcd(mmc); + + return ret; +} + +int board_mmc_getwp(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + if (cfg->esdhc_base == USDHC2_BASE_ADDR) + /* eMMC/uSDHC2 is never WP */ + ret = 0; + else + ret = tq_bb_board_mmc_getwp(mmc); + + return ret; +} + +int board_mmc_init(struct bd_info *bis) +{ + imx_iomux_v3_setup_multiple_pads(tqma6ul_usdhc2_pads, + ARRAY_SIZE(tqma6ul_usdhc2_pads)); + tqma6ul_usdhc2_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + + if (fsl_esdhc_initialize(bis, &tqma6ul_usdhc2_cfg)) + printf("Warning: failed to initialize eMMC dev\n"); + + tq_bb_board_mmc_init(bis); + + return 0; +} + +void board_init_f(ulong dummy) +{ + /* setup clock gating */ + ccgr_init(); + + /* setup AIPS and disable watchdog */ + arch_cpu_init(); + + /* setup AXI */ + gpr_init(); + + /* iomux and setup of i2c */ + board_early_init_f(); + + /* Setup GP timer */ + timer_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* DDR initialization */ + tq_som_ram_init(); +} diff --git a/board/tq/tqma6ul/spl_mba6ul.c b/board/tq/tqma6ul/spl_mba6ul.c new file mode 100644 index 00000000000..55beeac8fc9 --- /dev/null +++ b/board/tq/tqma6ul/spl_mba6ul.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Max Merchel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../common/tq_bb.h" +#include "tqma6ul.h" + +#define GPIO_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +#define USDHC_CLK_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | \ + PAD_CTL_HYS) + +#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \ + PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +static const iomux_v3_cfg_t mba6ul_uart_pads[] = { + NEW_PAD_CTRL(MX6_PAD_UART1_TX_DATA__UART1_DCE_TX, UART_PAD_CTRL), + NEW_PAD_CTRL(MX6_PAD_UART1_RX_DATA__UART1_DCE_RX, UART_PAD_CTRL), +}; + +static void mba6ul_setup_iomuxc_uart(void) +{ + imx_iomux_v3_setup_multiple_pads(mba6ul_uart_pads, + ARRAY_SIZE(mba6ul_uart_pads)); +} + +/* SD card on USDHC1 */ +static const iomux_v3_cfg_t mba6ul_usdhc1_pads[] = { + MX6_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_CLK_PAD_CTRL), + MX6_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + /* WP */ + MX6_PAD_UART1_CTS_B__GPIO1_IO18 | MUX_PAD_CTRL(GPIO_PAD_CTRL), + /* CD */ + MX6_PAD_UART1_RTS_B__GPIO1_IO19 | MUX_PAD_CTRL(GPIO_PAD_CTRL), +}; + +#define USDHC1_CD_GPIO IMX_GPIO_NR(1, 19) +#define USDHC1_WP_GPIO IMX_GPIO_NR(1, 18) + +static struct fsl_esdhc_cfg mba6ul_usdhc1_cfg = { + .esdhc_base = USDHC1_BASE_ADDR, + .max_bus_width = 4, +}; + +int tq_bb_board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + if (cfg->esdhc_base == USDHC1_BASE_ADDR) + ret = !gpio_get_value(USDHC1_CD_GPIO); + + return ret; +} + +int tq_bb_board_mmc_getwp(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + if (cfg->esdhc_base == USDHC1_BASE_ADDR) + ret = gpio_get_value(USDHC1_WP_GPIO); + + return ret; +} + +int tq_bb_board_mmc_init(struct bd_info *bis) +{ + imx_iomux_v3_setup_multiple_pads(mba6ul_usdhc1_pads, + ARRAY_SIZE(mba6ul_usdhc1_pads)); + gpio_request(USDHC1_CD_GPIO, "usdhc1-cd"); + gpio_request(USDHC1_WP_GPIO, "usdhc1-wp"); + gpio_direction_input(USDHC1_CD_GPIO); + gpio_direction_input(USDHC1_WP_GPIO); + + mba6ul_usdhc1_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + if (fsl_esdhc_initialize(bis, &mba6ul_usdhc1_cfg)) + puts("Warning: failed to initialize SD card\n"); + + return 0; +} + +int board_early_init_f(void) +{ + tq_bb_board_early_init_f(); + + mba6ul_setup_iomuxc_uart(); + + return 0; +} + +/* + * This is done per baseboard to allow different implementations + */ +void board_boot_order(u32 *spl_boot_list) +{ + u32 bmode = imx6_src_get_boot_mode(); + u8 imx6_bmode = (bmode & IMX6_BMODE_MASK) >> IMX6_BMODE_SHIFT; + + /* USB boot */ + if (spl_boot_device() == BOOT_DEVICE_BOARD) { + printf("USB\n"); + spl_boot_list[0] = BOOT_DEVICE_BOARD; + return; + } + + switch (imx6_bmode) { + case IMX6_BMODE_SD: + case IMX6_BMODE_ESD: + /* SD/eSD - BOOT_DEVICE_MMC2 */ + printf("SD\n"); + spl_boot_list[0] = BOOT_DEVICE_MMC2; + break; + case IMX6_BMODE_MMC: + case IMX6_BMODE_EMMC: + /* MMC/eMMC - BOOT_DEVICE_MMC1 */ + printf("eMMC\n"); + spl_boot_list[0] = BOOT_DEVICE_MMC1; + break; + case IMX6_BMODE_QSPI: + /* QSPI - BOOT_DEVICE_SPI */ + printf("QSPI\n"); + spl_boot_list[0] = BOOT_DEVICE_NOR; + break; + case IMX6_BMODE_SERIAL_ROM: + /* SERIAL_ROM - BOOT_DEVICE_BOARD */ + printf("Serial ROM\n"); + spl_boot_list[0] = BOOT_DEVICE_BOARD; + break; + default: + printf("WARNING: unknown boot device, fallback to eMMC\n"); + spl_boot_list[0] = BOOT_DEVICE_MMC1; + break; + } +} + +int board_fit_config_name_match(const char *name) +{ + /* Longest FDT name */ + char dt[] = "imx6ull-tqma6ull2l-mba6ulx"; + enum tqma6ul_som_type somtype; + + somtype = set_tqma6ul_dt_name(dt, sizeof(dt), "mba6ulx"); + if (somtype == tqma6ul_som_type_unknown) + return -EINVAL; + + if (!strcmp(name, dt)) + return -EINVAL; + + printf("Device tree: %s\n", name); + return 0; +} diff --git a/board/tq/tqma6ul/spl_tqma6ul_ram.c b/board/tq/tqma6ul/spl_tqma6ul_ram.c new file mode 100644 index 00000000000..c5d50890702 --- /dev/null +++ b/board/tq/tqma6ul/spl_tqma6ul_ram.c @@ -0,0 +1,209 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Max Merchel + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../common/tq_som.h" + +static void tqma6ul_init_ddr_controller(u32 size) +{ + /* TQMa6ul DDR config */ + + /* reset DDR via Chip Select 0*/ + tq_som_init_write_reg(MX6_MMDC_P0_MDCTL, 0x03180000); + tq_som_init_write_reg(MX6_MMDC_P0_MDCTL, 0x83180000); + + debug("SPL: tqma6ul ddr iomux ....\n"); + + /* DDR IO TYPE: */ + tq_som_init_write_reg(MX6_IOM_GRP_DDR_TYPE, 0x000C0000); + tq_som_init_write_reg(MX6_IOM_GRP_DDRPKE, 0x00000000); + /* CLOCK: */ + tq_som_init_write_reg(MX6_IOM_DRAM_SDCLK_0, 0x00000030); + /* Control: */ + tq_som_init_write_reg(MX6_IOM_DRAM_CAS, 0x00000030); + tq_som_init_write_reg(MX6_IOM_DRAM_RAS, 0x00000030); + tq_som_init_write_reg(MX6_IOM_GRP_ADDDS, 0x00000030); + tq_som_init_write_reg(MX6_IOM_DRAM_RESET, 0x00000030); + tq_som_init_write_reg(MX6_IOM_DRAM_SDBA2, 0x00000000); + tq_som_init_write_reg(MX6_IOM_DRAM_SDODT0, 0x00000030); + tq_som_init_write_reg(MX6_IOM_DRAM_SDODT1, 0x00000030); + tq_som_init_write_reg(MX6_IOM_GRP_CTLDS, 0x00000030); + /* Data Strobes: */ + tq_som_init_write_reg(MX6_IOM_DDRMODE_CTL, 0x00020000); + tq_som_init_write_reg(MX6_IOM_DRAM_SDQS0, 0x00000030); + tq_som_init_write_reg(MX6_IOM_DRAM_SDQS1, 0x00000030); + /* Data: */ + tq_som_init_write_reg(MX6_IOM_GRP_DDRMODE, 0x00020000); + tq_som_init_write_reg(MX6_IOM_GRP_B0DS, 0x00000030); + tq_som_init_write_reg(MX6_IOM_GRP_B1DS, 0x00000030); + tq_som_init_write_reg(MX6_IOM_DRAM_DQM0, 0x00000030); + tq_som_init_write_reg(MX6_IOM_DRAM_DQM1, 0x00000030); + + debug("tqma6ul ddr controller registers ....\n"); + + /* MMDC_MDSCR - MMDC Core Special Command Register */ + tq_som_init_write_reg(MX6_MMDC_P0_MDSCR, 0x00008000); + + debug("tqma6ul ddr calibrations ....\n"); + + /* DDR_PHY_P0_MPZQHWCTRL , enable both one-time & periodic HW ZQ calibration. */ + tq_som_init_write_reg(MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003); + + switch (size) { + case SZ_512M: + if (IS_ENABLED(CONFIG_MX6UL)) { + debug("tqma6ul ddr calibration standard variant ....\n"); + + tq_som_init_write_reg(MX6_MMDC_P0_MPWLDECTRL0, 0x00000000); + tq_som_init_write_reg(MX6_MMDC_P0_MPDGCTRL0, 0x41580150); + tq_som_init_write_reg(MX6_MMDC_P0_MPRDDLCTL, 0x40404E52); + tq_som_init_write_reg(MX6_MMDC_P0_MPWRDLCTL, 0x40404E4A); + + } else if (IS_ENABLED(CONFIG_MX6ULL)) { + if (IS_ENABLED(CONFIG_TQMA6UL_VARIANT_STANDARD)) { + debug("tqma6ull ddr calibration standard variant ....\n"); + + tq_som_init_write_reg(MX6_MMDC_P0_MPWLDECTRL0, 0x00090009); + tq_som_init_write_reg(MX6_MMDC_P0_MPDGCTRL0, 0x4140013C); + tq_som_init_write_reg(MX6_MMDC_P0_MPRDDLCTL, 0x40403A3E); + tq_som_init_write_reg(MX6_MMDC_P0_MPWRDLCTL, 0x40402E26); + + } else if (IS_ENABLED(CONFIG_TQMA6UL_VARIANT_LGA)) { + debug("tqma6ull ddr calibration lga variant ....\n"); + + tq_som_init_write_reg(MX6_MMDC_P0_MPWLDECTRL0, 0x00050009); + tq_som_init_write_reg(MX6_MMDC_P0_MPDGCTRL0, 0x41340130); + tq_som_init_write_reg(MX6_MMDC_P0_MPRDDLCTL, 0x40403A3E); + tq_som_init_write_reg(MX6_MMDC_P0_MPWRDLCTL, 0x40402E28); + + } else { + pr_err("invalid/unsupported SoM variant ....\n"); + hang(); + } /* IS_ENABLED(CONFIG_TQMA6UL_VARIANT_STANDARD) */ + } else { + pr_err("ERROR: invalid/unsupported CPU variant ....\n"); + hang(); + } /* IS_ENABLED(CONFIG_MX6UL) */ + break; + case SZ_256M: + if (IS_ENABLED(CONFIG_TQMA6UL_VARIANT_STANDARD)) { + debug("tqma6ul ddr calibration standard variant ....\n"); + + tq_som_init_write_reg(MX6_MMDC_P0_MPWLDECTRL0, 0x00000000); + tq_som_init_write_reg(MX6_MMDC_P0_MPDGCTRL0, 0x41480144); + tq_som_init_write_reg(MX6_MMDC_P0_MPRDDLCTL, 0x40404E54); + tq_som_init_write_reg(MX6_MMDC_P0_MPWRDLCTL, 0x40404E48); + + } else if (IS_ENABLED(CONFIG_TQMA6UL_VARIANT_LGA)) { + debug("tqma6ul ddr calibration lga variant ....\n"); + + tq_som_init_write_reg(MX6_MMDC_P0_MPWLDECTRL0, 0x00130003); + tq_som_init_write_reg(MX6_MMDC_P0_MPDGCTRL0, 0x41540154); + tq_som_init_write_reg(MX6_MMDC_P0_MPRDDLCTL, 0x40405050); + tq_som_init_write_reg(MX6_MMDC_P0_MPWRDLCTL, 0x40404E4C); + + } else { + pr_err("ERROR: invalid/unsupported SoM variant ....\n"); + hang(); + } /* IS_ENABLED(CONFIG_TQMA6UL_VARIANT_STANDARD) */ + break; + default: + pr_err("ERROR: invalid/unsupported RAM size ....\n"); + hang(); + break; + } + + tq_som_init_write_reg(MX6_MMDC_P0_MPRDDQBY0DL, 0x33333333); + tq_som_init_write_reg(MX6_MMDC_P0_MPRDDQBY1DL, 0x33333333); + + tq_som_init_write_reg(0x021B082C, 0xf3333333); /* MMDC_MPWRDQBY0DL */ + tq_som_init_write_reg(0x021B0830, 0xf3333333); /* MMDC_MPWRDQBY1DL */ + tq_som_init_write_reg(0x021B08C0, 0x00921012); /* MMDC_MPDCCR */ + + /* + * Complete calibration by forced measurement: + */ + tq_som_init_write_reg(MX6_MMDC_P0_MPMUR0, 0x00000800); + tq_som_init_write_reg(MX6_MMDC_P0_MDPDC, 0x0002002D); + + debug("tqma6ul ddr mmdc ....\n"); + + tq_som_init_write_reg(MX6_MMDC_P0_MDOTC, 0x00333030); + tq_som_init_write_reg(MX6_MMDC_P0_MDCFG0, 0x676B52F3); + tq_som_init_write_reg(MX6_MMDC_P0_MDCFG1, 0xB66D8B63); + tq_som_init_write_reg(MX6_MMDC_P0_MDCFG2, 0x01FF00DB); + tq_som_init_write_reg(MX6_MMDC_P0_MDMISC, 0x00201740); + tq_som_init_write_reg(MX6_MMDC_P0_MDSCR, 0x00008000); + tq_som_init_write_reg(MX6_MMDC_P0_MDRWD, 0x000026D2); + tq_som_init_write_reg(MX6_MMDC_P0_MDOR, 0x006B1023); + + switch (size) { + case SZ_512M: + tq_som_init_write_reg(MX6_MMDC_P0_MDASP, 0x0000004F); + tq_som_init_write_reg(MX6_MMDC_P0_MDCTL, 0x84180000); + break; + case SZ_256M: + tq_som_init_write_reg(MX6_MMDC_P0_MDASP, 0x00000047); + tq_som_init_write_reg(MX6_MMDC_P0_MDCTL, 0x83180000); + break; + default: + hang(); + break; + } + + debug("tqma6ul ddr cs0 ....\n"); + tq_som_init_write_reg(MX6_MMDC_P0_MDSCR, 0x02008032); + tq_som_init_write_reg(MX6_MMDC_P0_MDSCR, 0x00008033); + tq_som_init_write_reg(MX6_MMDC_P0_MDSCR, 0x00048031); + tq_som_init_write_reg(MX6_MMDC_P0_MDSCR, 0x15208030); + tq_som_init_write_reg(MX6_MMDC_P0_MDSCR, 0x04008040); + tq_som_init_write_reg(MX6_MMDC_P0_MDREF, 0x00000800); + tq_som_init_write_reg(MX6_MMDC_P0_MPODTCTRL, 0x00000227); + tq_som_init_write_reg(MX6_MMDC_P0_MDPDC, 0x0002552D); + tq_som_init_write_reg(MX6_MMDC_P0_MAPSR, 0x00011006); + tq_som_init_write_reg(MX6_MMDC_P0_MDSCR, 0x00000000); +} + +void tq_som_ram_init(void) +{ + int i; + /* RAM sizes need to be in descending order */ + static const u32 ram_sizes[] = { +#if IS_ENABLED(CONFIG_TQMA6UL_RAM_512M) + SZ_512M, +#endif +#if IS_ENABLED(CONFIG_TQMA6UL_RAM_256M) + SZ_256M, +#endif + }; + + if (!is_mx6ul() && !is_mx6ull()) { + pr_err("ERROR: Not running on TQMa6UL[L]\n"); + hang(); + } + + for (i = 0; i < ARRAY_SIZE(ram_sizes); i++) { + tqma6ul_init_ddr_controller(ram_sizes[i]); + if (tq_som_ram_check_size(ram_sizes[i])) + break; + } + + if (i < ARRAY_SIZE(ram_sizes)) { + debug("SPL: tqma6ul ddr init done ...\n"); + } else { + pr_err("ERROR: Invalid DDR RAM size\n"); + hang(); + } +} diff --git a/board/tq/tqma6ul/tqma6ul.c b/board/tq/tqma6ul/tqma6ul.c new file mode 100644 index 00000000000..999396f573d --- /dev/null +++ b/board/tq/tqma6ul/tqma6ul.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2016-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Marco Felsch, Nora Schiffer + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../common/tq_bb.h" +#include "tqma6ul.h" + +int tq_bb_board_early_init_f(void) +{ + if (CONFIG_IS_ENABLED(FSL_QSPI)) + enable_qspi_clk(0); + + return 0; +} + +/** + * Checks if CPU (imx6ul or ima6ull) matches the one set for the image. + */ +static const char *check_cpu_variant(void) +{ + const char *cpu; + + if (is_mx6ul()) { + cpu = "ul"; + if (!IS_ENABLED(CONFIG_MX6UL)) + printf("*** ERROR: image not compiled for i.MX6UL!\n"); + } else if (is_mx6ull()) { + cpu = "ull"; + if (!IS_ENABLED(CONFIG_MX6ULL)) + printf("*** ERROR: image not compiled for i.MX6ULL!\n"); + } else { + printf("unknown CPU\n"); + return NULL; + } + + return cpu; +} + +/** + * Checks configuration for TQMa6UL SoM module variant. + */ +enum tqma6ul_som_type check_tqma6ul_variant(void) +{ + if (IS_ENABLED(CONFIG_TQMA6UL_VARIANT_STANDARD)) + return tqma6ul_som_type_ca; + + if (IS_ENABLED(CONFIG_TQMA6UL_VARIANT_LGA)) + return tqma6ul_som_type_lga; + + printf("unknown SoM variant\n"); + + return tqma6ul_som_type_unknown; +} + +/** + * Adjusts device tree name based on CPU variant. + */ +enum tqma6ul_som_type set_tqma6ul_dt_name(char *dt, size_t dtsize, const char *mb) +{ + const char *tqma6ul_cpu, *tqma6ul_variant; + enum tqma6ul_som_type somtype; + u8 mx6ul_variant; + + tqma6ul_cpu = check_cpu_variant(); + if (!tqma6ul_cpu) + return tqma6ul_som_type_unknown; + + /* MX6UL1 vs MX6UL2 */ + mx6ul_variant = check_module_fused(MODULE_ENET2) ? 1 : 2; + + somtype = check_tqma6ul_variant(); + switch (somtype) { + case tqma6ul_som_type_ca: + tqma6ul_variant = ""; + break; + case tqma6ul_som_type_lga: + tqma6ul_variant = "l"; + break; + default: + return tqma6ul_som_type_unknown; + } + + snprintf(dt, dtsize, "imx6%s-tqma6%s%u%s-%s", + tqma6ul_cpu, tqma6ul_cpu, mx6ul_variant, tqma6ul_variant, mb); + + return somtype; +} + +#if !IS_ENABLED(CONFIG_SPL_BUILD) +int dram_init(void) +{ + gd->ram_size = imx_ddr_size(); + + return 0; +} + +const char *tq_som_get_modulename(void) +{ + if (is_mx6ul()) { + if (IS_ENABLED(CONFIG_TQMA6UL_VARIANT_STANDARD)) + return "TQMa6ULx"; + + if (IS_ENABLED(CONFIG_TQMA6UL_VARIANT_LGA)) + return "TQMa6ULxL"; + } + + if (is_mx6ull()) { + if (IS_ENABLED(CONFIG_TQMA6UL_VARIANT_STANDARD)) + return "TQMa6ULLx"; + + if (IS_ENABLED(CONFIG_TQMA6UL_VARIANT_LGA)) + return "TQMa6ULLxL"; + } + + return "Unknown"; +} + +int checkboard(void) +{ + printf("Board: %s on %s\n", tq_som_get_modulename(), + tq_bb_get_boardname()); + + return tq_bb_checkboard(); +} + +#if IS_ENABLED(CONFIG_CMD_BMODE) +static const struct boot_mode tqma6ul_board_boot_modes[] = { + /* 4 bit bus width */ + {"sd", MAKE_CFGVAL(0x42, 0x20, 0x00, 0x00)}, + {"emmc", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)}, + {"qspi", MAKE_CFGVAL(0x10, 0x00, 0x00, 0x00)}, + {NULL, 0}, +}; +#endif + +int tq_bb_board_late_init(void) +{ + if (IS_ENABLED(CONFIG_CMD_BMODE)) + add_board_boot_modes(tqma6ul_board_boot_modes); + + env_set_runtime("board_name", tq_som_get_modulename()); + + return 0; +} + +int tq_bb_checkboard(void) +{ + if (is_mx6ul()) { + if (!IS_ENABLED(CONFIG_MX6UL)) + printf("*** ERROR: image not compiled for i.MX6UL!\n"); + } else if (is_mx6ull()) { + if (!IS_ENABLED(CONFIG_MX6ULL)) + printf("*** ERROR: image not compiled for i.MX6ULL!\n"); + } else { + printf("*** ERROR: unknown CPU variant!\n"); + } + + return 0; +} + +/* + * Device Tree Support + */ +#if IS_ENABLED(CONFIG_OF_BOARD_SETUP) && IS_ENABLED(CONFIG_OF_LIBFDT) +int tq_bb_ft_board_setup(void *blob, struct bd_info *bd) +{ + return 0; +} +#endif /* IS_ENABLED(CONFIG_OF_BOARD_SETUP) && IS_ENABLED(CONFIG_OF_LIBFDT) */ + +#endif /* !IS_ENABLED(CONFIG_SPL_BUILD) */ diff --git a/board/tq/tqma6ul/tqma6ul.cfg b/board/tq/tqma6ul/tqma6ul.cfg new file mode 100644 index 00000000000..42821ae5c7a --- /dev/null +++ b/board/tq/tqma6ul/tqma6ul.cfg @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2024-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Max Merchel + * + */ + +#include + +/* image version */ + +IMAGE_VERSION 2 + +#if IS_ENABLED(CONFIG_QSPI_BOOT) +BOOT_FROM qspi +#else +BOOT_FROM sd +#endif + +#if IS_ENABLED(CONFIG_IMX_HAB) +CSF CONFIG_CSF_SIZE +#endif diff --git a/board/tq/tqma6ul/tqma6ul.env b/board/tq/tqma6ul/tqma6ul.env new file mode 100644 index 00000000000..fa172caca23 --- /dev/null +++ b/board/tq/tqma6ul/tqma6ul.env @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (c) 2016-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Max Merchel + * + * TQMa6UL environment + */ + +#include + +board=tqma6ul +boot_os=bootz "${kernel_addr_r}" - "${fdt_addr_r}" +emmc_bootp_start=TQMA6UL_MMC_UBOOT_SECTOR_START +emmc_dev=0 +fdt_addr_r=TQMA6UL_FDT_ADDRESS +fdtoverlay_addr_r=TQMA6UL_FDT_OVERLAY_ADDR +image=zImage +kernel_addr_r=CONFIG_SYS_LOAD_ADDR +mmcautodetect=yes +mmcblkdev=0 +mmcdev=CONFIG_ENV_MMC_DEVICE_INDEX +netdev=eth1 +pxefile_addr_r=CONFIG_SYS_LOAD_ADDR +ramdisk_addr_r=TQMA6UL_INITRD_ADDRESS +sd_dev=1 +uboot=u-boot-with-spl.imx +uboot_mmc_start=TQMA6UL_MMC_UBOOT_SECTOR_START +uboot_mmc_size=TQMA6UL_MMC_UBOOT_SECTOR_COUNT +uboot_spi_sector_size=TQMA6UL_SPI_FLASH_SECTOR_SIZE +uboot_spi_start=TQMA6UL_SPI_UBOOT_START +uboot_spi_size=TQMA6UL_SPI_UBOOT_SIZE + +#ifdef CONFIG_USB_FUNCTION_FASTBOOT + +/* 0=user 1=boot1 2=boot2 */ +fastboot_mmc_boot_partition = 1 + +fastboot_partition_alias_all=CONFIG_FASTBOOT_FLASH_MMC_DEV :0 + +fastboot_raw_partition_bootloader= + TQMA6UL_MMC_UBOOT_SECTOR_START TQMA6UL_MMC_UBOOT_SECTOR_COUNT mmcpart + "${fastboot_mmc_boot_partition}" + +fastbootcmd=fastboot usb 0 + +#endif /* CONFIG_USB_FUNCTION_FASTBOOT */ diff --git a/board/tq/tqma6ul/tqma6ul.h b/board/tq/tqma6ul/tqma6ul.h new file mode 100644 index 00000000000..595edc89e19 --- /dev/null +++ b/board/tq/tqma6ul/tqma6ul.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Max Merchel + */ + +enum tqma6ul_som_type { + /* unknown */ + tqma6ul_som_type_unknown, + /* connector module */ + tqma6ul_som_type_ca, + /* LGA Variant */ + tqma6ul_som_type_lga, +}; + +/** + * Checks configuration for TQMa6UL SoM module variant + */ +enum tqma6ul_som_type check_tqma6ul_variant(void); + +/** + * Adjusts device tree name based on CPU variant. + */ +enum tqma6ul_som_type set_tqma6ul_dt_name(char *dt, size_t dtsize, const char *mb); diff --git a/board/tq/tqma6ul/tqma6ul_mba6ul.c b/board/tq/tqma6ul/tqma6ul_mba6ul.c new file mode 100644 index 00000000000..be78060cbda --- /dev/null +++ b/board/tq/tqma6ul/tqma6ul_mba6ul.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2016-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Marco Felsch, Nora Schiffer + */ + +#include +#include +#include +#include +#include +#include + +#include "../common/tq_bb.h" +#include "tqma6ul.h" + +const char *tq_bb_get_boardname(void) +{ + return "MBa6ULx"; +} + +int board_early_init_f(void) +{ + return tq_bb_board_early_init_f(); +} + +static void mba6ul_setup_eth(void) +{ + struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; + + if (check_module_fused(MODULE_ENET1)) { + printf("FEC1: disabled by fuses\n"); + } else { + /* + * Use 50M anatop loopback REF_CLK1 for ENET1, + * clear gpr1[13], set gpr1[17] + */ + clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK, + IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK); + + enable_fec_anatop_clock(0, ENET_50MHZ); + } + + if (check_module_fused(MODULE_ENET2)) { + printf("FEC2: disabled by fuses\n"); + } else { + /* + * Use 50M anatop loopback REF_CLK1 for ENET2, + * clear gpr1[14], set gpr1[18] + */ + clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC2_MASK, + IOMUX_GPR1_FEC2_CLOCK_MUX1_SEL_MASK); + + enable_fec_anatop_clock(1, ENET_50MHZ); + } + + enable_enet_clk(1); +} + +int board_init(void) +{ + return 0; +} + +static void mba6ul_set_fdt_file(void) +{ + /* Longest FDT name */ + char dt[] = "imx6ull-tqma6ull2l-mba6ulx.dtb"; + enum tqma6ul_som_type somtype; + + if (!env_get("fdtfile")) { + somtype = set_tqma6ul_dt_name(dt, sizeof(dt), "mba6ulx.dtb"); + if (somtype == tqma6ul_som_type_unknown) + return; + + env_set_runtime("fdtfile", dt); + } +} + +int board_late_init(void) +{ + unsigned int bmode = + (imx6_src_get_boot_mode() & IMX6_BMODE_MASK) >> IMX6_BMODE_SHIFT; + + tq_bb_board_late_init(); + + printf("Boot: "); + + switch (bmode) { + case IMX6_BMODE_MMC: + case IMX6_BMODE_EMMC: + printf("eMMC\n"); + env_set_runtime("boot_dev", "mmc"); + board_late_mmc_env_init(); + break; + case IMX6_BMODE_SD: + case IMX6_BMODE_ESD: + printf("SD\n"); + env_set_runtime("boot_dev", "mmc"); + board_late_mmc_env_init(); + break; + case IMX6_BMODE_QSPI: + case IMX6_BMODE_NOR: + printf("QSPI\n"); + env_set_runtime("boot_dev", "qspi"); + break; + default: + printf("unhandled boot device %u\n", bmode); + } + + mba6ul_set_fdt_file(); + mba6ul_setup_eth(); + + return 0; +} + +int board_mmc_get_env_dev(int devno) +{ + unsigned int port = (imx6_src_get_boot_mode() >> 11) & 0x3; + + switch (port) { + case 0: + /* SDHC1 - SD card on MBa6ULx */ + return 1; + + default: + /* Return eMMC device otherwise */ + return 0; + } +} + +#if IS_ENABLED(CONFIG_OF_BOARD_SETUP) && IS_ENABLED(CONFIG_OF_LIBFDT) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return tq_bb_ft_board_setup(blob, bd); +} +#endif /* IS_ENABLED(CONFIG_OF_BOARD_SETUP) && IS_ENABLED(CONFIG_OF_LIBFDT) */ diff --git a/doc/board/tq/index.rst b/doc/board/tq/index.rst index d6dc6101c2c..775957474e7 100644 --- a/doc/board/tq/index.rst +++ b/doc/board/tq/index.rst @@ -9,4 +9,5 @@ TQ-Systems .. toctree:: :maxdepth: 2 + tqma6ul tqma7 diff --git a/doc/board/tq/tqma6ul.rst b/doc/board/tq/tqma6ul.rst new file mode 100644 index 00000000000..2b346715642 --- /dev/null +++ b/doc/board/tq/tqma6ul.rst @@ -0,0 +1,105 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later or CC-BY-4.0 + +.. Copyright (c) 2017-2025 TQ-Systems GmbH , +.. D-82229 Seefeld, Germany. + +######################################## +U-Boot for the TQ-Systems TQMa6x modules +######################################## + +The following hardware revisions are supported: + +Modules: + ++------------+----------+ +| TQMa6ULx | REV.030x | ++------------+----------+ +| TQMa6ULLx | REV.030x | ++------------+----------+ +| TQMa6ULxL | REV.030x | ++------------+----------+ +| TQMa6ULLxL | REV.030x | ++------------+----------+ + +Mainboards: + ++----------+----------+ +| MBa6ULx | REV.020x | ++----------+----------+ + +Hardware on modules TQMa6ULx, TQMa6ULxL, TQMa6ULLx and TQMa6ULLxL + +- eMMC +- RTC +- PMIC +- SPI-NOR (optional) +- EEPROM +- Temperature sensor +- RAM (256 MiB / 512 MiB) + +Supported hardware on Starterkit MBa6ULx: + +- 2 Ethernet PHY connected to FEC0 / FEC1 (usage depends on CPU) +- SD-card slot +- UART +- USB + +Note: To change the Ethernet port to use for networking functionality, use the +U-Boot generic environment variable ``ethact``. + +.. code-block:: bash + + setenv ethact + +*********** +Boot source +*********** + +- SD/eMMC +- USB/SDP (with NXP UUU tool) +- SPI NOR (functional but requires additional prepended NXP header. + Not supported in U-Boot.) + +******** +Building +******** + +To build U-Boot for the TQ-Systems TQMa6L modules: + +.. code-block:: bash + + make ___defconfig + make + + +**som** is a placeholder for the module base variant: + ++------------+------------+----------------+ +| tqma6ulx | TQMa6ULx | i.MX6UL | ++------------+------------+----------------+ +| tqma6ullx | TQMa6ULLx | i.MX6ULL | ++------------+------------+----------------+ +| tqma6ulxl | TQMa6ULxL | i.MX6UL (lga) | ++------------+------------+----------------+ +| tqma6ullxl | TQMa6ULLxL | i.MX6ULL (lga) | ++------------+------------+----------------+ + +**baseboard** is a placeholder for the mainboard to compile for: + ++----------+----------+ +| mba6ul | MBa6ULx | ++----------+----------+ + +**boot** is a placeholder for the boot device: + ++------+---------+ +| mmc | SD/eMMC | ++------+---------+ +| spi | SPI-NOR | ++------+---------+ + +************ +Support Wiki +************ + +See `TQ Embedded Wiki for TQMa6ulx `_. diff --git a/include/configs/tqma6ul.h b/include/configs/tqma6ul.h new file mode 100644 index 00000000000..89bd8102500 --- /dev/null +++ b/include/configs/tqma6ul.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2016-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Marco Felsch, Nora Schiffer, Max Merchel + * + * Configuration settings for the TQ-Systems TQMa6UL[L]x[L] SOM family. + */ + +#ifndef __TQMA6UL_CONFIG_H +#define __TQMA6UL_CONFIG_H + +#include + +#include "mx6_common.h" + +#define TQMA6UL_MMC_UBOOT_SECTOR_START 0x2 +#define TQMA6UL_MMC_UBOOT_SECTOR_COUNT 0x7fe + +#define TQMA6UL_SPI_FLASH_SECTOR_SIZE SZ_64K +#define TQMA6UL_SPI_UBOOT_START SZ_4K +#define TQMA6UL_SPI_UBOOT_SIZE 0xf0000 + +/* 128 MiB offset as suggested in ARM related Linux docs */ +#define TQMA6UL_FDT_ADDRESS 0x88000000 + +/* 256KiB above TQMA6UL_FDT_ADDRESS (TQMA6UL_FDT_ADDRESS + SZ_256K) */ +#define TQMA6UL_FDT_OVERLAY_ADDR 0x88040000 + +/* 16MiB above TQMA6UL_FDT_ADDRESS (TQMA6UL_FDT_ADDRESS + SZ_16M) */ +#define TQMA6UL_INITRD_ADDRESS 0x89000000 + +#ifndef __ASSEMBLY__ +static_assert(TQMA6UL_FDT_OVERLAY_ADDR == (TQMA6UL_FDT_ADDRESS + SZ_256K)); +static_assert(TQMA6UL_INITRD_ADDRESS == (TQMA6UL_FDT_ADDRESS + SZ_16M)); +#endif + +/* Physical Memory Map */ +#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR + +#define CFG_SYS_SDRAM_BASE PHYS_SDRAM +#define CFG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR +#define CFG_SYS_INIT_RAM_SIZE IRAM_SIZE + +/* u-boot.img base address for SPI-NOR boot */ +#define CFG_SYS_UBOOT_BASE (QSPI0_AMBA_BASE + SZ_4K + CONFIG_SPL_PAD_TO) + +#define CFG_SYS_INIT_SP_OFFSET \ + (CFG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CFG_SYS_INIT_SP_ADDR \ + (CFG_SYS_INIT_RAM_ADDR + CFG_SYS_INIT_SP_OFFSET) + +#endif /* __TQMA6UL_CONFIG_H */ diff --git a/include/configs/tqma6ul_mba6ul.h b/include/configs/tqma6ul_mba6ul.h new file mode 100644 index 00000000000..b7a31b5ce26 --- /dev/null +++ b/include/configs/tqma6ul_mba6ul.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2016-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Markus Niebel, Nora Schiffer, Max Merchel + * + * Configuration settings for the TQ-Systems MBa6ULx carrier board for + * TQMa6UL[L]x[L] SOM family. + */ + +#ifndef __CONFIG_TQMA6UL_MBA6UL_H +#define __CONFIG_TQMA6UL_MBA6UL_H + +#include "tqma6ul.h" + +#define CFG_MXC_UART_BASE UART1_BASE +#define CFG_SYS_FSL_ESDHC_ADDR 0 + +#endif /* __CONFIG_TQMA6UL_MBA6UL_H */ -- cgit v1.3.1 From a30556bc4249b4154f86c9460da740ff86d30807 Mon Sep 17 00:00:00 2001 From: Nora Schiffer Date: Tue, 2 Jun 2026 13:57:51 +0200 Subject: sysinfo: tq_eeprom: new driver Introduce a sysinfo driver that can be instantiated from the device, which will provide information from the EEPROM found on all TQ-Systems SoMs. Signed-off-by: Nora Schiffer Signed-off-by: Max Merchel Reviewed-by: Simon Glass Signed-off-by: Alexander Feilke --- MAINTAINERS | 1 + configs/tqma7_common.config | 1 + .../sysinfo/tq,eeprom-sysinfo.txt | 36 ++++ drivers/sysinfo/Kconfig | 8 + drivers/sysinfo/Makefile | 1 + drivers/sysinfo/tq_eeprom.c | 203 +++++++++++++++++++++ include/sysinfo/tq_eeprom.h | 24 +++ 7 files changed, 274 insertions(+) create mode 100644 doc/device-tree-bindings/sysinfo/tq,eeprom-sysinfo.txt create mode 100644 drivers/sysinfo/tq_eeprom.c create mode 100644 include/sysinfo/tq_eeprom.h (limited to 'doc') diff --git a/MAINTAINERS b/MAINTAINERS index a55742a0baf..ec7217f39f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1865,6 +1865,7 @@ S: Maintained W: https://www.tq-group.com/en/products/tq-embedded/ F: board/tq/* F: doc/board/tq/* +F: drivers/sysinfo/tq_eeprom.c F: include/configs/tq*.h F: include/env/tq/* diff --git a/configs/tqma7_common.config b/configs/tqma7_common.config index 7e5e31a14ab..9b055849ad1 100644 --- a/configs/tqma7_common.config +++ b/configs/tqma7_common.config @@ -77,6 +77,7 @@ CONFIG_I2C_DEFAULT_BUS_NUMBER=0x3 CONFIG_SYS_I2C_MXC=y CONFIG_LED=y CONFIG_LED_GPIO=y +CONFIG_NVMEM=y CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_FSL_USDHC=y CONFIG_MTD=y diff --git a/doc/device-tree-bindings/sysinfo/tq,eeprom-sysinfo.txt b/doc/device-tree-bindings/sysinfo/tq,eeprom-sysinfo.txt new file mode 100644 index 00000000000..678fff0e812 --- /dev/null +++ b/doc/device-tree-bindings/sysinfo/tq,eeprom-sysinfo.txt @@ -0,0 +1,36 @@ +TQ EEPROM Sysinfo Driver +------------------------ + +This binding describes a sysinfo provider which retrieves system +identification information from an I2C EEPROM device. + +Required properties: + +- compatible: "tq,eeprom-sysinfo" +- nvmem-cells: phandle referencing the nvmem cell +- nvmem-cell-names: string, should be "device_info" + +Example: + +&i2c1 { + eeprom@50 { + compatible = "atmel,24c64"; + reg = <0x50>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + module_info: module-info@20 { + reg = <0x20 0x60>; + }; + }; + }; +}; + +sysinfo { + compatible = "tq,eeprom-sysinfo"; + nvmem-cells = <&module_info>; + nvmem-cell-names = "device_info"; +}; diff --git a/drivers/sysinfo/Kconfig b/drivers/sysinfo/Kconfig index df83df69ffb..6922dac9170 100644 --- a/drivers/sysinfo/Kconfig +++ b/drivers/sysinfo/Kconfig @@ -59,4 +59,12 @@ config SYSINFO_GPIO This ternary number is then mapped to a board revision name using device tree properties. +config SYSINFO_TQ_EEPROM + bool "Enable TQ-Systems EEPROM sysinfo driver" + depends on I2C_EEPROM + depends on SPL_I2C_EEPROM || !SPL_SYSINFO + help + Support querying EEPROM of TQ-Systems SOMs to determine board + information. + endif diff --git a/drivers/sysinfo/Makefile b/drivers/sysinfo/Makefile index 26ca3150999..d21fb3c2270 100644 --- a/drivers/sysinfo/Makefile +++ b/drivers/sysinfo/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_SYSINFO_IOT2050) += iot2050.o obj-$(CONFIG_SYSINFO_RCAR3) += rcar3.o obj-$(CONFIG_SYSINFO_SANDBOX) += sandbox.o obj-$(CONFIG_SYSINFO_SMBIOS) += smbios.o +obj-$(CONFIG_SYSINFO_TQ_EEPROM) += tq_eeprom.o diff --git a/drivers/sysinfo/tq_eeprom.c b/drivers/sysinfo/tq_eeprom.c new file mode 100644 index 00000000000..63be07b664e --- /dev/null +++ b/drivers/sysinfo/tq_eeprom.c @@ -0,0 +1,203 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2014-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Nora Schiffer + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TQ_EE_RSV1_BYTES 10 +#define TQ_EE_SERIAL_BYTES 8 +#define TQ_EE_RSV2_BYTES 8 +#define TQ_EE_BDID_BYTES 0x40 + +struct tq_eeprom_data { + u8 mac[ETH_ALEN]; /* 0x20 ... 0x25 */ + u8 rsv1[TQ_EE_RSV1_BYTES]; + u8 serial[TQ_EE_SERIAL_BYTES]; /* 0x30 ... 0x37 */ + u8 rsv2[TQ_EE_RSV2_BYTES]; + u8 id[TQ_EE_BDID_BYTES]; /* 0x40 ... 0x7f */ +}; + +static_assert(sizeof(struct tq_eeprom_data) == 0x60, + "struct tq_eeprom_data has incorrect size"); + +/** + * struct sysinfo_tq_eeprom_priv - sysinfo private data + */ +struct sysinfo_tq_eeprom_priv { + struct nvmem_cell device_info_cell; + + /* Reserve extra space for \0 in id and serial */ + char id[TQ_EE_BDID_BYTES + 1]; + char serial[TQ_EE_SERIAL_BYTES + 1]; + u8 mac[ETH_ALEN]; +}; + +static void tq_eeprom_parse_id(struct udevice *dev, const struct tq_eeprom_data *data) +{ + struct sysinfo_tq_eeprom_priv *priv = dev_get_priv(dev); + int i; + + for (i = 0; i < sizeof(data->id); i++) { + if (!(isprint(data->id[i]) && isascii(data->id[i]))) + break; + } + + if (i == 0) + dev_warn(dev, "no valid model name in EEPROM\n"); + + snprintf(priv->id, sizeof(priv->id), "%.*s", i, data->id); +} + +static int tq_eeprom_serial_len(const struct tq_eeprom_data *data, bool allow_upper) +{ + int i; + + for (i = 0; i < sizeof(data->serial); i++) { + if (!(isdigit(data->serial[i]) || (allow_upper && isupper(data->serial[i])))) + break; + } + + return i; +} + +static void tq_eeprom_parse_serial(struct udevice *dev, const struct tq_eeprom_data *data) +{ + struct sysinfo_tq_eeprom_priv *priv = dev_get_priv(dev); + bool use_new_format; + int len; + + use_new_format = data->serial[0] == 'T' && data->serial[1] == 'Q'; + + len = tq_eeprom_serial_len(data, use_new_format); + + /* For now, only serial numbers with the exact size of the field are accepted */ + if (len != sizeof(data->serial)) { + dev_warn(dev, "no valid serial number in EEPROM\n"); + len = 0; + } + + snprintf(priv->serial, sizeof(priv->serial), "%.*s", len, data->serial); +} + +static int tq_eeprom_dump(const struct sysinfo_tq_eeprom_priv *priv) +{ + printf("TQ EEPROM:\n"); + printf(" ID: %s\n", priv->id[0] ? priv->id : ""); + printf(" SN: %s\n", priv->serial[0] ? priv->serial : ""); + printf(" MAC: "); + if (is_valid_ethaddr(priv->mac)) + printf("%pM\n", priv->mac); + else + printf("\n"); + + return 0; +} + +static int sysinfo_tq_eeprom_detect(struct udevice *dev) +{ + struct sysinfo_tq_eeprom_priv *priv = dev_get_priv(dev); + struct tq_eeprom_data data; + int ret; + + ret = nvmem_cell_read(&priv->device_info_cell, (u8 *)&data, sizeof(data)); + if (ret < 0) { + dev_err(dev, "EEPROM read failed: %d\n", ret); + return ret; + } + + tq_eeprom_parse_id(dev, &data); + tq_eeprom_parse_serial(dev, &data); + memcpy(priv->mac, data.mac, ETH_ALEN); + + if (!IS_ENABLED(CONFIG_SPL_BUILD)) + tq_eeprom_dump(priv); + + return 0; +} + +static int sysinfo_tq_eeprom_get_str(struct udevice *dev, int id, size_t size, char *val) +{ + struct sysinfo_tq_eeprom_priv *priv = dev_get_priv(dev); + + switch (id) { + case SYSID_TQ_MODEL: + if (!priv->id[0]) + return -ENODATA; + + strlcpy(val, priv->id, size); + return 0; + + case SYSID_TQ_SERIAL: + if (!priv->serial[0]) + return -ENODATA; + + strlcpy(val, priv->serial, size); + return 0; + + default: + return -EINVAL; + } +} + +static int sysinfo_tq_eeprom_get_data(struct udevice *dev, int id, void **data, size_t *size) +{ + struct sysinfo_tq_eeprom_priv *priv = dev_get_priv(dev); + + switch (id) { + case SYSID_TQ_MAC_ADDR: + if (!is_valid_ethaddr(priv->mac)) + return -ENODATA; + + *data = priv->mac; + *size = sizeof(priv->mac); + + return 0; + + default: + return -EINVAL; + } +} + +static const struct sysinfo_ops sysinfo_tq_eeprom_ops = { + .detect = sysinfo_tq_eeprom_detect, + .get_str = sysinfo_tq_eeprom_get_str, + .get_data = sysinfo_tq_eeprom_get_data, +}; + +static int sysinfo_tq_eeprom_probe(struct udevice *dev) +{ + struct sysinfo_tq_eeprom_priv *priv = dev_get_priv(dev); + int ret; + + ret = nvmem_cell_get_by_name(dev, "device_info", &priv->device_info_cell); + if (ret) { + dev_err(dev, "device_info not found: %d\n", ret); + return ret; + } + + return 0; +} + +static const struct udevice_id sysinfo_tq_eeprom_ids[] = { + { .compatible = "tq,eeprom-sysinfo" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(sysinfo_tq_eeprom) = { + .name = "sysinfo_tq_eeprom", + .id = UCLASS_SYSINFO, + .of_match = sysinfo_tq_eeprom_ids, + .ops = &sysinfo_tq_eeprom_ops, + .priv_auto = sizeof(struct sysinfo_tq_eeprom_priv), + .probe = sysinfo_tq_eeprom_probe, +}; diff --git a/include/sysinfo/tq_eeprom.h b/include/sysinfo/tq_eeprom.h new file mode 100644 index 00000000000..6b1bddd7ce0 --- /dev/null +++ b/include/sysinfo/tq_eeprom.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023-2026 TQ-Systems GmbH , + * D-82229 Seefeld, Germany. + * Author: Nora Schiffer + */ + +#ifndef __SYSINFO_TQ_EEPROM_H__ +#define __SYSINFO_TQ_EEPROM_H__ + +#include + +enum { + /* Model string of TQ-Systems SOM. This is different from BOARD_MODEL, + * which usually combines SOM and baseboard names for TQ hardware + */ + SYSID_TQ_MODEL = SYSID_USER, + /* SOM serial number */ + SYSID_TQ_SERIAL, + /* MAC address */ + SYSID_TQ_MAC_ADDR, +}; + +#endif /* __SYSINFO_TQ_EEPROM_H__ */ -- cgit v1.3.1 From 3abd953da8c322f5e76b4909b37bd7a9d050d9e9 Mon Sep 17 00:00:00 2001 From: Jonathan GUILLOT Date: Thu, 21 May 2026 21:00:11 +0200 Subject: doc: wdt: fix typo for expire --- doc/usage/cmd/wdt.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/usage/cmd/wdt.rst b/doc/usage/cmd/wdt.rst index 711b74d20da..28abf98def9 100644 --- a/doc/usage/cmd/wdt.rst +++ b/doc/usage/cmd/wdt.rst @@ -16,7 +16,7 @@ Synopsis wdt start [flags] wdt stop wdt reset - wdt expirer [flags] + wdt expire [flags] Description ----------- -- cgit v1.3.1 From 59e13ed8f6d8b030c6aaf7e2af77f073fecc3b30 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Fri, 19 Dec 2025 11:59:36 +1300 Subject: arm: mvebu: Add Allied Telesis x220 Add the Allied Telesis x220 board. There are a number of other variants with the same CPU block that are sold under some different brand names but the x220 was first. The x220 uses the AlleyCat3 switch chip with integrated ARMv7 CPU. Because of this it is reliant on a binary blob for the DDR training. In upstream u-boot this is replaced by an empty file. Signed-off-by: Chris Packham Reviewed-by: Stefan Roese --- arch/arm/dts/Makefile | 1 + arch/arm/dts/armada-xp-atl-x220.dts | 162 +++++++++++++++++++++++++++++++ arch/arm/mach-mvebu/Kconfig | 7 ++ board/alliedtelesis/x220/.gitattributes | 1 + board/alliedtelesis/x220/.gitignore | 1 + board/alliedtelesis/x220/MAINTAINERS | 8 ++ board/alliedtelesis/x220/Makefile | 14 +++ board/alliedtelesis/x220/binary.0 | 11 +++ board/alliedtelesis/x220/kwbimage.cfg.in | 12 +++ board/alliedtelesis/x220/x220.c | 67 +++++++++++++ configs/x220_defconfig | 76 +++++++++++++++ doc/board/alliedtelesis/index.rst | 11 +++ doc/board/alliedtelesis/x220.rst | 39 ++++++++ doc/board/index.rst | 1 + include/configs/x220.h | 20 ++++ 15 files changed, 431 insertions(+) create mode 100644 arch/arm/dts/armada-xp-atl-x220.dts create mode 100644 board/alliedtelesis/x220/.gitattributes create mode 100644 board/alliedtelesis/x220/.gitignore create mode 100644 board/alliedtelesis/x220/MAINTAINERS create mode 100644 board/alliedtelesis/x220/Makefile create mode 100644 board/alliedtelesis/x220/binary.0 create mode 100644 board/alliedtelesis/x220/kwbimage.cfg.in create mode 100644 board/alliedtelesis/x220/x220.c create mode 100644 configs/x220_defconfig create mode 100644 doc/board/alliedtelesis/index.rst create mode 100644 doc/board/alliedtelesis/x220.rst create mode 100644 include/configs/x220.h (limited to 'doc') diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index b75f3ee4386..722a7a662b1 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -137,6 +137,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-388-gp.dtb \ armada-388-helios4.dtb \ armada-38x-controlcenterdc.dtb \ + armada-xp-atl-x220.dtb \ armada-xp-crs305-1g-4s.dtb \ armada-xp-crs305-1g-4s-bit.dtb \ armada-xp-crs326-24g-2s.dtb \ diff --git a/arch/arm/dts/armada-xp-atl-x220.dts b/arch/arm/dts/armada-xp-atl-x220.dts new file mode 100644 index 00000000000..5b3307ed288 --- /dev/null +++ b/arch/arm/dts/armada-xp-atl-x220.dts @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for x220 board + * + * Copyright (C) 2025 Allied Telesis Labs + */ + +/dts-v1/; +#include +#include "armada-xp-98dx3236.dtsi" +#include "mvebu-u-boot.dtsi" + +/ { + model = "x220"; + compatible = "marvell,armadaxp-98dx3236", "marvell,armadaxp-mv78260", + "marvell,armadaxp", "marvell,armada-370-xp"; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs = "console=ttyS0,115200"; + }; + + aliases { + i2c0 = &i2c0; + spi0 = &spi0; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x00000000 0x00000000 0x20000000>; + }; +}; + +&L2 { + arm,parity-enable; + marvell,ecc-enable; +}; + +&devbus_bootcs { + status = "okay"; + + /* Device Bus parameters are required */ + + /* Read parameters */ + devbus,bus-width = <16>; + devbus,turn-off-ps = <60000>; + devbus,badr-skew-ps = <0>; + devbus,acc-first-ps = <124000>; + devbus,acc-next-ps = <248000>; + devbus,rd-setup-ps = <0>; + devbus,rd-hold-ps = <0>; + + /* Write parameters */ + devbus,sync-enable = <0>; + devbus,wr-high-ps = <60000>; + devbus,wr-low-ps = <60000>; + devbus,ale-wr-ps = <60000>; +}; + +&uart0 { + status = "okay"; +}; + +&i2c0 { + clock-frequency = <100000>; + status = "okay"; + + rtc@68 { + compatible = "dallas,ds1340"; + reg = <0x68>; + }; + + adt7476a@2e { + compatible = "adi,adt7476"; + reg = <0x2e>; + }; + + sfpgpio: gpio@27 { + #address-cells = <2>; + #size-cells = <0>; + compatible = "nxp,pca9555"; + reg = <0x27>; + gpio-controller; + #gpio-cells = <2>; + }; + + systemgpio: gpio@25 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nxp,pca9555"; + reg = <0x25>; + gpio-controller; + #gpio-cells = <2>; + + nand-protect { + gpio-hog; + gpios = <6 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "nand-protect"; + }; + + usb-enable { + gpio-hog; + gpios = <9 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "usb-enable"; + }; + + phy-reset { + gpio-hog; + gpios = <5 GPIO_ACTIVE_LOW>; + output-high; + line-name = "phy-reset"; + }; + + led-enable { + gpio-hog; + gpios = <13 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "led-enable"; + }; + }; +}; + +&watchdog { + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash", "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <20000000>; + }; +}; + +&nand_controller { + compatible = "marvell,armada370-nand-controller"; + label = "pxa3xx_nand-0"; + status = "okay"; + nand-rb = <0>; + nand-on-flash-bbt; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; +}; + +&{/} { + boot-board { + compatible = "atl,boot-board"; + present-gpio = <&systemgpio 12 GPIO_ACTIVE_HIGH>; + override-gpio = <&gpio0 31 GPIO_ACTIVE_HIGH>; + }; +}; + diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 4afaee234ea..0b4df8e7be9 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -226,6 +226,10 @@ config TARGET_X240 select ALLEYCAT_5 imply BOOTSTD_DEFAULTS +config TARGET_X220 + bool "Support Allied Telesis x220" + select 98DX3336 + config TARGET_DB_XC3_24G4XG bool "Support DB-XC3-24G4XG" select 98DX3336 @@ -310,6 +314,7 @@ config SYS_BOARD default "x530" if TARGET_X530 default "x250" if TARGET_X250 default "x240" if TARGET_X240 + default "x220" if TARGET_X220 default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG default "crs3xx-98dx3236" if TARGET_CRS3XX_98DX3236 default "mvebu_alleycat-5" if TARGET_MVEBU_ALLEYCAT5 @@ -335,6 +340,7 @@ config SYS_CONFIG_NAME default "x530" if TARGET_X530 default "x250" if TARGET_X250 default "x240" if TARGET_X240 + default "x220" if TARGET_X220 default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG default "crs3xx-98dx3236" if TARGET_CRS3XX_98DX3236 default "mvebu_alleycat-5" if TARGET_MVEBU_ALLEYCAT5 @@ -360,6 +366,7 @@ config SYS_VENDOR default "alliedtelesis" if TARGET_X530 default "alliedtelesis" if TARGET_X250 default "alliedtelesis" if TARGET_X240 + default "alliedtelesis" if TARGET_X220 default "mikrotik" if TARGET_CRS3XX_98DX3236 default "Marvell" if TARGET_MVEBU_ALLEYCAT5 diff --git a/board/alliedtelesis/x220/.gitattributes b/board/alliedtelesis/x220/.gitattributes new file mode 100644 index 00000000000..2aeb4eee641 --- /dev/null +++ b/board/alliedtelesis/x220/.gitattributes @@ -0,0 +1 @@ +binary.0 binary diff --git a/board/alliedtelesis/x220/.gitignore b/board/alliedtelesis/x220/.gitignore new file mode 100644 index 00000000000..775b9346b85 --- /dev/null +++ b/board/alliedtelesis/x220/.gitignore @@ -0,0 +1 @@ +kwbimage.cfg diff --git a/board/alliedtelesis/x220/MAINTAINERS b/board/alliedtelesis/x220/MAINTAINERS new file mode 100644 index 00000000000..63da2725f71 --- /dev/null +++ b/board/alliedtelesis/x220/MAINTAINERS @@ -0,0 +1,8 @@ +x220 BOARD +M: Chris Packham +S: Maintained +F: board/alliedtelesis/x220 +F: include/configs/x220.h +F: configs/x220_defconfig +F: arch/arm/dts/armada-xp-atl-x220.dts +F: doc/board/alliedtelesis/x220.rst diff --git a/board/alliedtelesis/x220/Makefile b/board/alliedtelesis/x220/Makefile new file mode 100644 index 00000000000..a74f0a76948 --- /dev/null +++ b/board/alliedtelesis/x220/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2025 Allied Telesis Labs + +obj-y := x220.o +extra-y := kwbimage.cfg + +quiet_cmd_sed = SED $@ + cmd_sed = sed $(SEDFLAGS_$(@F)) $< >$(dir $@)$(@F) + +SEDFLAGS_kwbimage.cfg =-e "s|^BINARY.*|BINARY $(srctree)/$(@D)/binary.0 0000005b 00000068|" +$(obj)/kwbimage.cfg: $(src)/kwbimage.cfg.in include/autoconf.mk \ + include/config/auto.conf + $(call if_changed,sed) diff --git a/board/alliedtelesis/x220/binary.0 b/board/alliedtelesis/x220/binary.0 new file mode 100644 index 00000000000..8dd687286a0 --- /dev/null +++ b/board/alliedtelesis/x220/binary.0 @@ -0,0 +1,11 @@ +-------- +WARNING: +-------- +This file should contain the bin_hdr generated by the original Marvell +U-Boot implementation. As this is currently not included in this +U-Boot version, we have added this placeholder, so that the U-Boot +image can be generated without errors. + +If you have a known to be working bin_hdr for your board, then you +just need to replace this text file here with the binary header +and recompile U-Boot. diff --git a/board/alliedtelesis/x220/kwbimage.cfg.in b/board/alliedtelesis/x220/kwbimage.cfg.in new file mode 100644 index 00000000000..8beda907ba4 --- /dev/null +++ b/board/alliedtelesis/x220/kwbimage.cfg.in @@ -0,0 +1,12 @@ +# +# Copyright (C) 2025 Allied Telesis Labs +# + +# Armada XP uses version 1 image format +VERSION 1 + +# Boot Media configurations +BOOT_FROM spi + +# Binary Header (bin_hdr) with DDR3 training code +BINARY board/alliedtelesis/x220/binary.0 0000005b 00000068 diff --git a/board/alliedtelesis/x220/x220.c b/board/alliedtelesis/x220/x220.c new file mode 100644 index 00000000000..7c9a73de9a2 --- /dev/null +++ b/board/alliedtelesis/x220/x220.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2025 Allied Telesis Labs + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define X220_GPP_OUT_ENA_LOW (~(BIT(12) | BIT(17) | BIT(18) | BIT(31))) +#define X220_GPP_OUT_ENA_MID (~(0)) +#define X220_GPP_OUT_VAL_LOW (BIT(12) | BIT(18)) +#define X220_GPP_OUT_VAL_MID 0x0 +#define X220_GPP_POL_LOW 0x0 +#define X220_GPP_POL_MID 0x0 + +int board_early_init_f(void) +{ + /* Configure MPP */ + writel(0x44042222, MVEBU_MPP_BASE + 0x00); + writel(0x11000004, MVEBU_MPP_BASE + 0x04); + writel(0x44444004, MVEBU_MPP_BASE + 0x08); + writel(0x04444444, MVEBU_MPP_BASE + 0x0c); + writel(0x00000004, MVEBU_MPP_BASE + 0x10); + + /* Set GPP Out value */ + writel(X220_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00); + writel(X220_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00); + + /* Set GPP Polarity */ + writel(X220_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c); + writel(X220_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c); + + /* Set GPP Out Enable */ + writel(X220_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04); + writel(X220_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04); + + return 0; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100; + + /* Disable MBUS Err Prop - in order to avoid data aborts */ + clrbits_le32(MVEBU_CPU_WIN_BASE + 0x200, (1 << 8)); + + return 0; +} + +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ + puts("Board: Allied Telesis x220\n"); + + return 0; +} +#endif diff --git a/configs/x220_defconfig b/configs/x220_defconfig new file mode 100644 index 00000000000..4318f5e6ef1 --- /dev/null +++ b/configs/x220_defconfig @@ -0,0 +1,76 @@ +CONFIG_ARM=y +CONFIG_ARCH_CPU_INIT=y +CONFIG_ARCH_MVEBU=y +CONFIG_SYS_KWD_CONFIG="board/alliedtelesis/x220/kwbimage.cfg" +CONFIG_TEXT_BASE=0x00800000 +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xff0000 +CONFIG_TARGET_X220=y +CONFIG_ENV_SIZE=0x10000 +CONFIG_ENV_OFFSET=0x100000 +CONFIG_ENV_SECT_SIZE=0x40000 +CONFIG_DEFAULT_DEVICE_TREE="armada-xp-atl-x220" +CONFIG_SYS_LOAD_ADDR=0x800000 +CONFIG_PCI=y +CONFIG_SYS_MEMTEST_START=0x00800000 +CONFIG_SYS_MEMTEST_END=0x00ffffff +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_BEST_MATCH=y +CONFIG_USE_PREBOOT=y +CONFIG_SYS_CONSOLE_INFO_QUIET=y +CONFIG_SYS_MAXARGS=96 +CONFIG_CMD_MEMTEST=y +CONFIG_SYS_ALT_MEMTEST=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_CMD_MTDPARTS=y +CONFIG_MTDIDS_DEFAULT="nand0=nand" +CONFIG_MTDPARTS_DEFAULT="mtdparts=nand:112M(user),8M(errlog),8M(nand-bbt)" +CONFIG_CMD_UBI=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_ENV_RELOC_GD_ENV_ADDR=y +CONFIG_ARP_TIMEOUT=200 +CONFIG_NET_RETRY_COUNT=50 +CONFIG_GPIO_HOG=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_MVTWSI=y +# CONFIG_MMC is not set +CONFIG_MTD_RAW_NAND=y +CONFIG_SYS_NAND_USE_FLASH_BBT=y +CONFIG_NAND_PXA3XX=y +CONFIG_SYS_NAND_ONFI_DETECTION=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_SST=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_PCI_MVEBU=y +CONFIG_SYS_NS16550=y +CONFIG_KIRKWOOD_SPI=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y +CONFIG_USB_ETHER_ASIX88179=y +CONFIG_USB_ETHER_MCS7830=y +CONFIG_USB_ETHER_RTL8152=y +CONFIG_USB_ETHER_SMSC95XX=y +CONFIG_WDT=y +CONFIG_WDT_ORION=y diff --git a/doc/board/alliedtelesis/index.rst b/doc/board/alliedtelesis/index.rst new file mode 100644 index 00000000000..a8de2986609 --- /dev/null +++ b/doc/board/alliedtelesis/index.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. Copyright (C) 2026 Allied Telesis Labs + +Allied Telesis +============== + +.. toctree:: + :maxdepth: 2 + + x220 + diff --git a/doc/board/alliedtelesis/x220.rst b/doc/board/alliedtelesis/x220.rst new file mode 100644 index 00000000000..6ca5f61ec4e --- /dev/null +++ b/doc/board/alliedtelesis/x220.rst @@ -0,0 +1,39 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. Copyright (C) 2026 Allied Telesis Labs + +x220 Platforms +============== + +Introduction +------------ + +The x220 has is a range of L2+ switches using the Marvell AlleyCat3 switch with +integrated ARMv7 CPU. It is also sold under some different brands for different +markets. + +- x220-52GP +- x220-52GT +- x220-28GS +- GS980M/52PS +- GS980M/52 +- x230-52 + +DDR Traning (binhdr) +-------------------- + +The AlleyCat3 uses a binary blob for it's DDR training. This is launched by +the built-in bootloader prior to U-Boot starting. + +To generate binary.0 from Marvell's bin_hdr.elf use the following command + +.. prompt:: bash $ + + arm-softfloat-linux-gnueabi-objcopy -S -O binary bin_hdr.elf \ + board/alliedtelesis/x220/binary.0 + +Alternatively, it is possible to extract the binary.0 from an existing U-Boot +image + +.. prompt:: bash $ + + ./tools/dumpimage -T kwbimage -p 1 -o board/alliedtelesis/x220/binary.0 u-boot.kwb diff --git a/doc/board/index.rst b/doc/board/index.rst index fcb4224bae3..4103fef8d8f 100644 --- a/doc/board/index.rst +++ b/doc/board/index.rst @@ -10,6 +10,7 @@ Board-specific doc actions/index advantech/index andestech/index + alliedtelesis/index allwinner/index amlogic/index anbernic/index diff --git a/include/configs/x220.h b/include/configs/x220.h new file mode 100644 index 00000000000..3022ad491b7 --- /dev/null +++ b/include/configs/x220.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2025 Allied Telesis Labs + */ + +#ifndef _CONFIG_X220_H +#define _CONFIG_X220_H + +/* Keep device tree and initrd in lower memory so the kernel can access them */ +#define CFG_EXTRA_ENV_SETTINGS \ + "fdt_high=0x10000000\0" \ + "initrd_high=0x10000000\0" + +/* + * mv-common.h should be defined after CMD configs since it used them + * to enable certain macros + */ +#include "mv-common.h" + +#endif /* _CONFIG_X220_H */ -- cgit v1.3.1 From a6369b8bb299aff8d5641fd11d2fcd0214103a18 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 2 Jun 2026 23:30:12 +0200 Subject: doc: develop: add section on embedding scripts inside control DTB Add a section that explains how one can embed scripts in the control DTB and run them from the U-Boot shell, the advantages of doing that compared to using a separately built FIT image, and the configuration knob that must be turned on to allow this to work. Reviewed-by: Simon Glass Signed-off-by: Rasmus Villemoes --- doc/develop/devicetree/control.rst | 58 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'doc') diff --git a/doc/develop/devicetree/control.rst b/doc/develop/devicetree/control.rst index 634114af59a..7d6117d5c4b 100644 --- a/doc/develop/devicetree/control.rst +++ b/doc/develop/devicetree/control.rst @@ -232,6 +232,64 @@ outside the U-Boot repository. You can use `DEVICE_TREE_INCLUDES` Kconfig option to specify a list of .dtsi files that will also be included when building .dtb files. +Scripts embedded in control DTB +------------------------------- + +The `DEVICE_TREE_INCLUDES` option can also be used to make the control +DTB serve double duty as a FIT image. By including a `scripts.dtsi` +file containing something like:: + + / { + images { + default = "boot"; + boot { + description = "Bootscript"; + data = /incbin/("boot.sh"); + type = "script"; + compression = "none"; + }; + factory-reset { + description = "Script for performing factory reset"; + data = /incbin/("factory-reset.sh"); + type = "script"; + compression = "none"; + }; + }; + }; + +one can call those scripts using the `source` command in the U-Boot shell:: + + source ${fdtcontroladdr}:boot + +or just ``source ${fdtcontroladdr}`` for invoking the default. + +Since one does not need to separately build a "real" FIT image +containing those scripts, this simplifies both the build process and +the boot logic, as the latter does not need to first load the FIT +image from storage. + +Another advantage is that when the bootloader and boot script must be +updated together, it is easier to achieve a guaranteed atomic update +when the boot script is embedded inside the U-Boot binary, instead of +stored separately. + +For the above to work, one must enable the `CONTROL_DTB_AS_FIT` config +option, which will (when the address passed to the `source` command is +the address of U-Boot's control DTB) elide certain sanity checks that +are normally done: With the above `.dtsi` snippet, the control DTB +does not quite become a "real" FIT image - it lacks `timestamp` and +`description` properties, but more importantly, FIT images cannot +contain nodes with `@` in their names (unit addresses) anywhere, and +the control DTB obviously does have such nodes. + +This is not a security problem, as the control DTB is necessarily +trusted. In any secure boot setup where the bootloader is verified, +that mechanism must also include verification of the control DTB. So +in fact, since the scripts embedded this way are then also +automatically verified, it simplifies implementation of secure +boot. When using a separate FIT image, one must build it with +appropriate signatures, just as when building a FIT image containing a +kernel/dtb/initramfs. Devicetree bindings schema checks --------------------------------- -- cgit v1.3.1 From fb537c85bca0e3d29a62fe119181bf1744b8c91a Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Wed, 17 Jun 2026 10:48:25 +0300 Subject: doc: Add a warning about using RELOC_ADDR_TOP Since devices that can't DMA above 4GiB will misbehave with this option enabled add a warning on the documentation. Reviewed-by: Simon Glass Signed-off-by: Ilias Apalodimas Tested-by: Christophe Leroy (CS GROUP) --- doc/develop/memory.rst | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'doc') diff --git a/doc/develop/memory.rst b/doc/develop/memory.rst index 5177229630d..3da39bb6c66 100644 --- a/doc/develop/memory.rst +++ b/doc/develop/memory.rst @@ -111,6 +111,15 @@ U-Boot Proper Flow This follows the same as in SPL flow. In board_init_f(), a part of memory is reserved at the end of RAM (see reserve_* functions in init_sequence_f) + #. Relocation address + + By default U-Boot will try to relocate below the 4GiB boundary. If + RELOC_ADDR_TOP is enabled U-Boot will look into the dram bank config of + gd->dram[] and try to relocate to the highest available bank. Use this + with caution as devices that can only DMA below 4GiB will misbehave + since their buffers may be allocated above the 32-bit boundary. + Boards can override thre relocation address via board_get_usable_ram_top(). + #. Code Relocation relocate_code() is called which relocates U-Boot code from the current -- cgit v1.3.1 From b6de000aeadc23d7d68f52379dbf30ceec44b8e9 Mon Sep 17 00:00:00 2001 From: Sam Day Date: Fri, 19 Jun 2026 09:55:00 +1000 Subject: cmd: fastboot: Add keyed abort option Works the same as CONFIG_CMD_UMS_ABORT_KEYED does: any keypress will abort fastboot mode (rather than only ctrl-c). Reviewed-by: Mattijs Korpershoek Tested-by: Mattijs Korpershoek Reviewed-by: Casey Connolly Signed-off-by: Sam Day Reviewed-by: Simon Glass Link: https://patch.msgid.link/20260619-fastboot-abort-keyed-v2-1-684e53949a42@samcday.com Signed-off-by: Mattijs Korpershoek --- cmd/Kconfig | 7 +++++++ cmd/fastboot.c | 9 ++++++++- doc/android/fastboot.rst | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) (limited to 'doc') diff --git a/cmd/Kconfig b/cmd/Kconfig index d0fb7397067..ca1039f6a03 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1208,6 +1208,13 @@ config CMD_FASTBOOT See doc/android/fastboot.rst for more information. +config CMD_FASTBOOT_ABORT_KEYED + bool "fastboot abort with any key" + depends on CMD_FASTBOOT && USB_FUNCTION_FASTBOOT + help + Allow interruption of USB fastboot mode by any key presses, + rather than just Ctrl-c. + config CMD_FLASH bool "flinfo, erase, protect" default y diff --git a/cmd/fastboot.c b/cmd/fastboot.c index e71f873527b..f3929f88dfa 100644 --- a/cmd/fastboot.c +++ b/cmd/fastboot.c @@ -103,8 +103,15 @@ static int do_fastboot_usb(int argc, char *const argv[], while (1) { if (g_dnl_detach()) break; - if (ctrlc()) + if (IS_ENABLED(CONFIG_CMD_FASTBOOT_ABORT_KEYED)) { + if (tstc()) { + getchar(); + puts("\rOperation aborted.\n"); + break; + } + } else if (ctrlc()) { break; + } schedule(); dm_usb_gadget_handle_interrupts(udc); } diff --git a/doc/android/fastboot.rst b/doc/android/fastboot.rst index 818b8815ebd..96c544ae11b 100644 --- a/doc/android/fastboot.rst +++ b/doc/android/fastboot.rst @@ -217,6 +217,10 @@ It's possible to interrupt the fastboot command using Ctrl-c:: => fastboot usb 0 Operation aborted. +``CONFIG_CMD_FASTBOOT_ABORT_KEYED`` can be enabled so that *any* keypress +will interrupt the fastboot command, rather than just Ctrl-c. This can be +quite useful on mobile devices which lack a means to input Ctrl-c. + You can also specify a kernel image to boot. You have to either specify the an image in Android format *or* pass a binary kernel and let the fastboot client wrap the Android suite around it. On OMAP for instance you -- cgit v1.3.1 From 3ac3708d168e1f85616817aae077326a6786ab59 Mon Sep 17 00:00:00 2001 From: Franz Schnyder Date: Thu, 11 Jun 2026 15:47:48 +0200 Subject: board: toradex: add initial support for aquila imx95 Add initial U-Boot support for Aquila iMX95 SoM. Link: https://www.toradex.com/computer-on-modules/aquila-arm-family/nxp-imx95 Link: https://www.toradex.com/products/carrier-board/aquila-development-board-kit Signed-off-by: Franz Schnyder Reviewed-by: Francesco Dolcini --- arch/arm/dts/imx95-aquila-dev-u-boot.dtsi | 40 + arch/arm/dts/imx95-aquila-dev.dts | 389 +++++++++ arch/arm/dts/imx95-aquila.dtsi | 1160 +++++++++++++++++++++++++++ arch/arm/mach-imx/imx9/Kconfig | 5 + board/toradex/aquila-imx95/Kconfig | 36 + board/toradex/aquila-imx95/MAINTAINERS | 11 + board/toradex/aquila-imx95/Makefile | 8 + board/toradex/aquila-imx95/aquila-imx95.c | 23 + board/toradex/aquila-imx95/aquila-imx95.env | 20 + board/toradex/aquila-imx95/spl.c | 75 ++ configs/aquila-imx95_defconfig | 186 +++++ doc/board/toradex/aquila-imx95.rst | 175 ++++ doc/board/toradex/index.rst | 1 + include/configs/aquila-imx95.h | 28 + 14 files changed, 2157 insertions(+) create mode 100644 arch/arm/dts/imx95-aquila-dev-u-boot.dtsi create mode 100644 arch/arm/dts/imx95-aquila-dev.dts create mode 100644 arch/arm/dts/imx95-aquila.dtsi create mode 100644 board/toradex/aquila-imx95/Kconfig create mode 100644 board/toradex/aquila-imx95/MAINTAINERS create mode 100644 board/toradex/aquila-imx95/Makefile create mode 100644 board/toradex/aquila-imx95/aquila-imx95.c create mode 100644 board/toradex/aquila-imx95/aquila-imx95.env create mode 100644 board/toradex/aquila-imx95/spl.c create mode 100644 configs/aquila-imx95_defconfig create mode 100644 doc/board/toradex/aquila-imx95.rst create mode 100644 include/configs/aquila-imx95.h (limited to 'doc') diff --git a/arch/arm/dts/imx95-aquila-dev-u-boot.dtsi b/arch/arm/dts/imx95-aquila-dev-u-boot.dtsi new file mode 100644 index 00000000000..92ec0d3efa3 --- /dev/null +++ b/arch/arm/dts/imx95-aquila-dev-u-boot.dtsi @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* Copyright (c) Toradex */ + +#include "imx95-u-boot.dtsi" + +/ { + sysinfo { + compatible = "toradex,sysinfo"; + }; +}; + +&lpuart1 { + bootph-pre-ram; +}; + +&pinctrl_uart1 { + bootph-pre-ram; +}; + +&pinctrl_usdhc1 { + bootph-pre-ram; +}; + +&pinctrl_usdhc1_200mhz { + bootph-pre-ram; +}; + +&usb3 { + bootph-pre-ram; +}; + +&usb3_dwc3 { + bootph-pre-ram; + compatible = "fsl,imx95a-dwc3", "fsl,imx8mq-dwc3", "snps,dwc3"; +}; + +&usdhc1 { + bootph-pre-ram; +}; + diff --git a/arch/arm/dts/imx95-aquila-dev.dts b/arch/arm/dts/imx95-aquila-dev.dts new file mode 100644 index 00000000000..3df17700b63 --- /dev/null +++ b/arch/arm/dts/imx95-aquila-dev.dts @@ -0,0 +1,389 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (c) Toradex + * + * https://www.toradex.com/computer-on-modules/aquila-arm-family/nxp-imx95 + * https://www.toradex.com/products/carrier-board/aquila-development-board-kit + */ + +/dts-v1/; + +#include +#include +#include "imx95-aquila.dtsi" + +/ { + model = "Aquila iMX95 on Aquila Development Board"; + compatible = "toradex,aquila-imx95-dev", + "toradex,aquila-imx95", + "fsl,imx95"; + + aliases { + eeprom1 = &carrier_eeprom; + }; + + dp_1_connector: dp0-connector { + compatible = "dp-connector"; + dp-pwr-supply = <®_dp_3p3v>; + type = "full-size"; + + port { + dp_1_connector_in: endpoint { + remote-endpoint = <&dsi2dp_out>; + }; + }; + }; + + reg_carrier_1p8v: regulator-carrier-1p8v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "On-carrier 1V8"; + }; + + reg_dp_3p3v: regulator-dp-3p3v { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_21_dp>; + /* Aquila GPIO_21_DP */ + gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "DP_3V3"; + startup-delay-us = <10000>; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,bitclock-master = <&codec_dai>; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&codec_dai>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "aquila-wm8904"; + simple-audio-card,routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN2L", "Line In Jack", + "IN2R", "Line In Jack", + "Microphone Jack", "MICBIAS", + "IN1L", "Microphone Jack", + "IN1R", "Digital Mic"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Microphone", "Digital Mic", + "Headphone", "Headphone Jack", + "Line", "Line In Jack"; + + codec_dai: simple-audio-card,codec { + sound-dai = <&wm8904_1a>; + }; + + simple-audio-card,cpu { + sound-dai = <&sai2>; + }; + }; +}; + +/* Aquila ADC_[1-4] */ +&adc1 { + status = "okay"; +}; + +/* Aquila CTRL_WAKE1_MICO# */ +&aquila_key_wake { + status = "okay"; +}; + +&dsi2dp_out { + remote-endpoint = <&dp_1_connector_in>; +}; + +/* Aquila ETH_1 */ +&enetc_port0 { + status = "okay"; +}; + +/* Aquila CAN_1 */ +&flexcan1 { + status = "okay"; +}; + +/* Aquila CAN_2 */ +&flexcan2 { + status = "okay"; +}; + +/* Aquila CAN_3 */ +&flexcan3 { + status = "okay"; +}; + +/* Aquila CAN_4 */ +&flexcan4 { + status = "okay"; +}; + +/* Aquila QSPI_1 */ +&flexspi1 { + pinctrl-0 = <&pinctrl_flexspi1_4bit>, + <&pinctrl_qspi_cs1>; + + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-max-frequency = <66000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + }; +}; + +&gpio1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_8>; +}; + +&gpio4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_1>, + <&pinctrl_gpio_2>, + <&pinctrl_gpio_3>, + <&pinctrl_gpio_4>, + <&pinctrl_gpio_5>, + <&pinctrl_gpio_6>, + <&pinctrl_gpio_7>; +}; + +/* Aquila I2C_1 */ +&lpi2c2 { + status = "okay"; + + fan_controller: fan@18 { + compatible = "ti,amc6821"; + reg = <0x18>; + #pwm-cells = <2>; + + fan { + cooling-levels = <255>; + pwms = <&fan_controller 40000 PWM_POLARITY_INVERTED>; + }; + }; + + wm8904_1a: audio-codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai2_mclk>; + clocks = <&scmi_clk IMX95_CLK_SAI2>; + clock-names = "mclk"; + #sound-dai-cells = <0>; + AVDD-supply = <®_carrier_1p8v>; + CPVDD-supply = <®_carrier_1p8v>; + DBVDD-supply = <®_carrier_1p8v>; + DCVDD-supply = <®_carrier_1p8v>; + MICVDD-supply = <®_carrier_1p8v>; + wlf,drc-cfg-names = "default", "peaklimiter"; + /* + * Config registers per name, respectively: + * KNEE_IP = 0, KNEE_OP = 0, HI_COMP = 1, LO_COMP = 1 + * KNEE_IP = -24, KNEE_OP = -6, HI_COMP = 1/4, LO_COMP = 1 + */ + wlf,drc-cfg-regs = /bits/ 16 <0x01af 0x3248 0x0000 0x0000>, + /bits/ 16 <0x04af 0x324b 0x0010 0x0408>; + /* GPIO1 = DMIC_CLK, don't touch others */ + wlf,gpio-cfg = <0x0018>, <0xffff>, <0xffff>, <0xffff>; + wlf,in1r-as-dmicdat2; + }; + + /* Current measurement into module VCC */ + hwmon@41 { + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <5000>; + }; + + temperature-sensor@4f { + compatible = "ti,tmp1075"; + reg = <0x4f>; + }; + + /* USB-C OTG (TCPC USB PD PHY) */ + tcpc@52 { + compatible = "nxp,ptn5110", "tcpci"; + reg = <0x52>; + interrupt-parent = <&som_gpio_expander_1>; + interrupts = <5 IRQ_TYPE_EDGE_FALLING>; + + connector { + compatible = "usb-c-connector"; + data-role = "dual"; + op-sink-microwatt = <0>; + power-role = "dual"; + self-powered; + sink-pdos = ; + source-pdos = ; + try-power-role = "sink"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + typec_con_hs: endpoint { + remote-endpoint = <&usb1_con_hs>; + }; + }; + + port@1 { + reg = <1>; + + typec_con_ss: endpoint { + remote-endpoint = <&usb1_con_ss>; + }; + }; + }; + }; + }; + + carrier_eeprom: eeprom@57 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x57>; + pagesize = <16>; + }; +}; + +/* Aquila I2C_2 */ +&i3c2 { + status = "okay"; +}; + +/* Aquila I2C_4_CSI1 */ +&lpi2c4 { + status = "okay"; +}; + +/* Aquila I2C_6 */ +&lpi2c5 { + status = "okay"; +}; + +/* Aquila I2C_3_DSI1/I2C_5_CSI2 */ +&lpi2c8 { + status = "okay"; + + i2c-mux@70 { + compatible = "nxp,pca9543"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + /* I2C on DSI Connector Pin #4 and #6 */ + i2c_dsi_0: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* I2C on DSI Connector Pin #52 and #54 */ + i2c_dsi_1: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; + +/* Aquila SPI_1 */ +&lpspi6 { + status = "okay"; +}; + +/* Aquila UART_3, used as the Linux Console */ +&lpuart1 { + status = "okay"; +}; + +/* Aquila UART_4 */ +&lpuart2 { + status = "okay"; +}; + +/* Aquila UART_1 */ +&lpuart3 { + status = "okay"; +}; + +/* Aquila UART_2 as RS485 */ +&lpuart7 { + linux,rs485-enabled-at-boot-time; + rs485-rts-active-low; + rs485-rx-during-tx; + + status = "okay"; +}; + +/* Aquila PCIE_1 */ +&pcie0 { + status = "okay"; +}; + +/* Aquila I2S_1 */ +&sai2 { + status = "okay"; +}; + +/* Aquila PWM_1 */ +&tpm3 { + status = "okay"; +}; + +/* Aquila PWM_2 */ +&tpm6 { + status = "okay"; +}; + +/* Aquila PWM_3_DSI and PWM_4_DP */ +&tpm5 { + status = "okay"; +}; + +/* Aquila USB_2, optional Bluetooth USB */ +&usb2 { + status = "okay"; +}; + +/* Aquila USB_1 */ +&usb3 { + status = "okay"; +}; + +&usb3_dwc3 { + status = "okay"; + + port { + usb1_con_hs: endpoint { + remote-endpoint = <&typec_con_hs>; + }; + }; +}; + +&usb3_phy { + orientation-switch; + + status = "okay"; + + port { + usb1_con_ss: endpoint { + remote-endpoint = <&typec_con_ss>; + }; + }; +}; + +/* Aquila SD_1 */ +&usdhc2 { + status = "okay"; +}; diff --git a/arch/arm/dts/imx95-aquila.dtsi b/arch/arm/dts/imx95-aquila.dtsi new file mode 100644 index 00000000000..69dc962a24a --- /dev/null +++ b/arch/arm/dts/imx95-aquila.dtsi @@ -0,0 +1,1160 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (c) Toradex + * + * https://www.toradex.com/computer-on-modules/aquila-arm-family/nxp-imx95 + */ + +#include +#include "imx95.dtsi" + +/ { + aliases { + can0 = &flexcan1; + can1 = &flexcan2; + can2 = &flexcan3; + can3 = &flexcan4; + eeprom0 = &som_eeprom; + ethernet0 = &enetc_port0; + i2c0 = &lpi2c3; + i2c1 = &lpi2c2; + i2c2 = &i3c2; + i2c3 = &lpi2c8; + i2c4 = &lpi2c4; + i2c6 = &lpi2c5; + mmc0 = &usdhc1; + mmc1 = &usdhc2; + rtc0 = &rtc_i2c; + rtc1 = &scmi_bbm; + serial0 = &lpuart3; + serial1 = &lpuart7; + serial2 = &lpuart1; + serial3 = &lpuart2; + usb0 = &usb3; + usb1 = &usb2; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + aquila_key_wake: gpio-key-wakeup { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ctrl_wake1_mico>; + + status = "disabled"; + + key-wakeup { + /* Aquila CTRL_WAKE1_MICO# */ + gpios = <&gpio5 11 GPIO_ACTIVE_LOW>; + label = "Wake Up"; + wakeup-source; + linux,code = ; + }; + }; + + clk_dsi2dp_refclk: clock-dsi2dp-refclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + + clk_dsi2dp_refclk_en: clock-dsi2dp-refclk-en { + compatible = "gpio-gate-clock"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ctrl_dp_clk_en>; + clocks = <&clk_dsi2dp_refclk>; + #clock-cells = <0>; + /* CTRL_DP_CLK_EN */ + enable-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; + }; + + clk_serdes_eth_ref: clock-serdes-eth-ref { + compatible = "gpio-gate-clock"; + #clock-cells = <0>; + /* CTRL_ETH_REF_CLK_STBY */ + enable-gpios = <&som_gpio_expander_0 6 GPIO_ACTIVE_LOW>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "On-module +V1.8"; + }; + + reg_dp_1p2v: regulator-dp-1p2v { + compatible = "regulator-fixed"; + /* CTRL_DP_BRIDGE_EN */ + gpios = <&som_gpio_expander_0 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + regulator-max-microvolt = <1200000>; + regulator-min-microvolt = <1200000>; + regulator-name = "On-module +V1.2_DP"; + vin-supply = <®_1p8v>; + }; + + reg_usb1_vbus: regulator-usb1-vbus { + compatible = "regulator-fixed"; + /* Aquila USB_1_EN */ + gpios = <&som_gpio_expander_0 2 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-name = "USB_1_EN"; + }; + + reg_usb2_vbus: regulator-usb2-vbus { + compatible = "regulator-fixed"; + /* Aquila USB_2_EN */ + gpios = <&som_gpio_expander_0 3 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-name = "USB_2_H_EN"; + }; + + reg_usdhc2_vmmc: regulator-usdhc2-vmmc { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sd1_pwr_en>; + /* Aquila SD_1_PWR_EN */ + gpios = <&gpio3 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + off-on-delay-us = <100000>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "SD_1_PWR_EN"; + startup-delay-us = <20000>; + }; + + reg_usdhc2_vqmmc: regulator-usdhc2-vqmmc { + compatible = "regulator-gpio"; + /* PMIC_SD_1_VSEL */ + gpios = <&som_gpio_expander_1 9 GPIO_ACTIVE_HIGH>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-name = "PMIC_SD_1_VSEL"; + states = <1800000 0x1>, + <3300000 0x0>; + }; + + remoteproc-cm7 { + compatible = "fsl,imx95-cm7"; + mboxes = <&mu7 0 1 &mu7 1 1 &mu7 3 1>; + mbox-names = "tx", "rx", "rxdb"; + memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, + <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>, <&m7_reserved>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + linux_cma: linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0 0x3c000000>; + alloc-ranges = <0 0x80000000 0 0x7f000000>; + linux,cma-default; + }; + + m7_reserved: memory@80000000 { + reg = <0 0x80000000 0 0x1000000>; + no-map; + }; + + rsc_table: rsc-table@88220000 { + reg = <0 0x88220000 0 0x1000>; + no-map; + }; + + vdev0vring0: vdev0vring0@88000000 { + reg = <0 0x88000000 0 0x8000>; + no-map; + }; + + vdev0vring1: vdev0vring1@88008000 { + reg = <0 0x88008000 0 0x8000>; + no-map; + }; + + vdev1vring0: vdev1vring0@88010000 { + reg = <0 0x88010000 0 0x8000>; + no-map; + }; + + vdev1vring1: vdev1vring1@88018000 { + reg = <0 0x88018000 0 0x8000>; + no-map; + }; + + vdevbuffer: vdevbuffer@88020000 { + compatible = "shared-dma-pool"; + reg = <0 0x88020000 0 0x100000>; + no-map; + }; + }; +}; + +/* Aquila ADC_[1-4] */ +&adc1 { + vref-supply = <®_1p8v>; +}; + +/* Aquila ETH_1 */ +&enetc_port0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enetc0>; + phy-handle = <ðphy1>; + phy-mode = "rgmii-id"; +}; + +/* Aquila CAN_1 */ +&flexcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; +}; + +/* Aquila CAN_2 */ +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; +}; + +/* Aquila CAN_3 */ +&flexcan3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan3>; +}; + +/* Aquila CAN_4 */ +&flexcan4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan4>; +}; + +/* Aquila QSPI_1 */ +&flexspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexspi1_8bit>, + <&pinctrl_qspi_cs1>; +}; + +&gpio1 { + gpio-line-names = "", /* 0 */ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "AQUILA_C24", /* 10 */ + "", + "AQUILA_B17", + "CTRL_GPIO_EXP_INT#", + "AQUILA_B18"; + + status = "okay"; +}; + +&gpio2 { + gpio-line-names = "", /* 0 */ + "", + "", + "", + "", + "", + "", + "AQUILA_B42", + "", + "AQUILA_B43"; +}; + +&gpio3 { + gpio-line-names = "", /* 0 */ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", /* 10 */ + "", + "", + "", + "", + "", + "", + "", + "", + "AQUILA_A11", + "", /* 20 */ + "AQUILA_B57", + "AQUILA_B19"; +}; + +&gpio4 { + gpio-line-names = "", /* 0 */ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", /* 10 */ + "", + "", + "", + "", + "", + "", + "AQUILA_C22", + "AQUILA_C21", + "AQUILA_C20", + "", /* 20 */ + "", + "", + "AQUILA_C23", + "AQUILA_D23", + "AQUILA_D24", + "", + "AQUILA_D25"; +}; + +&gpio5 { + gpio-line-names = "", /* 0 */ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", /* 10 */ + "", + "", + "AQUILA_B44", + "AQUILA_B45"; +}; + +/* Aquila I2C_2 */ +&i3c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i3c2>; + i2c-scl-hz = <100000>; +}; + +/* Aquila I2C_1 */ +&lpi2c2 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c2>; + pinctrl-1 = <&pinctrl_lpi2c2_gpio>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + scl-gpios = <&gpio1 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +}; + +/* On-module I2C - I2C_SOM */ +&lpi2c3 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c3>, <&pinctrl_ctrl_gpio_exp_int>; + pinctrl-1 = <&pinctrl_lpi2c3_gpio>, <&pinctrl_ctrl_gpio_exp_int>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + scl-gpios = <&gpio2 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + status = "okay"; + + som_gpio_expander_0: gpio@20 { + compatible = "nxp,pcal6408"; + reg = <0x20>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "AQUILA_C38", /* 0 */ + "PCIE_2_RESET#", + "AQUILA_B77", + "USB_2_H_EN", + "BT_DISABLE#", + "WIFI_DISABLE#", + "CTRL_ETH_REF_CLK_STBY", + "CTRL_DP_BRIDGE_EN"; + }; + + som_gpio_expander_1: gpio@21 { + compatible = "nxp,pcal6416"; + reg = <0x21>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio1>; + interrupts = <13 IRQ_TYPE_LEVEL_LOW>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "AQUILA_C1", /* 0 */ + "AQUILA_C2", + "AQUILA_C3", + "AQUILA_C4", + "AQUILA_C36", + "AQUILA_B74", + "AQUILA_B75", + "USB_2_H_OC#", + "AQUILA_B81", + "PMIC_SD_1_VSEL", + "ETH_1_INT#", /* 10 */ + "CTRL_TPM_INT#", + "SPI_2_CS2_TPM", + "PCIE_WAKE_WIFI#", + "WIFI_WAKE_BT", + "WIFI_WAKEUP_HOST"; + }; + + som_dsi2dp_bridge: bridge@2c { + compatible = "ti,sn65dsi86"; + reg = <0x2c>; + clocks = <&clk_dsi2dp_refclk_en>; + clock-names = "refclk"; + vcc-supply = <®_dp_1p2v>; + vcca-supply = <®_dp_1p2v>; + vccio-supply = <®_1p8v>; + vpll-supply = <®_1p8v>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dsi2dp_in: endpoint { + }; + }; + + port@1 { + reg = <1>; + + dsi2dp_out: endpoint { + data-lanes = <3 2 1 0>; + }; + }; + }; + }; + + rtc_i2c: rtc@32 { + compatible = "epson,rx8130"; + reg = <0x32>; + }; + + temperature-sensor@48 { + compatible = "ti,tmp1075"; + reg = <0x48>; + }; + + som_eeprom: eeprom@50 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +/* Aquila I2C_4_CSI1 */ +&lpi2c4 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c4>; + pinctrl-1 = <&pinctrl_lpi2c4_gpio>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + scl-gpios = <&gpio2 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +}; + +/* Aquila I2C_6 */ +&lpi2c5 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c5>; + pinctrl-1 = <&pinctrl_lpi2c5_gpio>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + scl-gpios = <&gpio2 23 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 22 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +}; + +/* Aquila I2C_3_DSI1/I2C_5_CSI2 */ +&lpi2c8 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_lpi2c8>; + pinctrl-1 = <&pinctrl_lpi2c8_gpio>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + scl-gpios = <&gpio2 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 12 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +}; + +/* Aquila SPI_2 */ +&lpspi4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpspi4>; + cs-gpios = <&gpio2 18 GPIO_ACTIVE_LOW>, + <&som_gpio_expander_1 12 GPIO_ACTIVE_LOW>; + + status = "okay"; + + som_tpm: tpm@1 { + compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; + reg = <0x1>; + interrupt-parent = <&som_gpio_expander_1>; + interrupts = <11 IRQ_TYPE_EDGE_FALLING>; + /* + * Maximum TPM-supported speed is 18.5 MHz, limited to 12 MHz + * here as lpspi4's per-clock (2x the max speed) is 24 MHz. + */ + spi-max-frequency = <12000000>; + }; +}; + +/* Aquila SPI_1 */ +&lpspi6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpspi6>; + cs-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; +}; + +/* Aquila UART_3, used as the Linux Console */ +&lpuart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; +}; + +/* Aquila UART_4 */ +&lpuart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; +}; + +/* Aquila UART_1 */ +&lpuart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + uart-has-rtscts; +}; + +/* Aquila UART_2 */ +&lpuart7 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart7>; + uart-has-rtscts; +}; + +&mu7 { + status = "okay"; +}; + +/* Aquila ETH_2_XGMII_MDIO, shared between all ethernet ports */ +&netc_emdio { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_emdio>; + + status = "okay"; + + ethphy1: ethernet-phy@1 { + reg = <1>; + interrupt-parent = <&som_gpio_expander_1>; + interrupts = <10 IRQ_TYPE_EDGE_FALLING>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + }; +}; + +&netcmix_blk_ctrl { + status = "okay"; +}; + +&netc_blk_ctrl { + status = "okay"; +}; + +&netc_timer { + status = "okay"; +}; + +/* Aquila PCIE_1 */ +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie0>; + reset-gpios = <&som_gpio_expander_0 0 GPIO_ACTIVE_LOW>; +}; + +/* On-module Wi-Fi or Aquila PCIE_2 */ +&pcie1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie1>; + reset-gpios = <&som_gpio_expander_0 1 GPIO_ACTIVE_LOW>; + + status = "okay"; +}; + +/* Aquila I2S_1 */ +&sai2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai2>; + assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>, + <&scmi_clk IMX95_CLK_AUDIOPLL2>, + <&scmi_clk IMX95_CLK_SAI2>; + assigned-clock-parents = <0>, <0>, <0>, <0>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>; + assigned-clock-rates = <3932160000>, + <3612672000>, <393216000>, + <361267200>, <12288000>; + #sound-dai-cells = <0>; + fsl,sai-mclk-direction-output; +}; + +&scmi_bbm { + linux,code = ; +}; + +&thermal_zones { + /* PF09 Main PMIC */ + pf09-thermal { + polling-delay = <2000>; + polling-delay-passive = <250>; + thermal-sensors = <&scmi_sensor 2>; + + trips { + trip0 { + hysteresis = <2000>; + temperature = <155000>; + type = "critical"; + }; + }; + }; + + /* PF53 VDD_ARM PMIC */ + pf53-arm-thermal { + polling-delay = <2000>; + polling-delay-passive = <250>; + thermal-sensors = <&scmi_sensor 4>; + + trips { + trip0 { + hysteresis = <2000>; + temperature = <155000>; + type = "critical"; + }; + }; + }; + + /* PF53 VDD_SOC PMIC */ + pf53-soc-thermal { + polling-delay = <2000>; + polling-delay-passive = <250>; + thermal-sensors = <&scmi_sensor 3>; + + trips { + trip0 { + hysteresis = <2000>; + temperature = <155000>; + type = "critical"; + }; + }; + }; +}; + +/* Aquila PWM_1 */ +&tpm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm1>; +}; + +/* Aquila PWM_2 */ +&tpm6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; +}; + +/* Aquila PWM_3_DSI and PWM_4_DP */ +&tpm5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm3_dsi>, <&pinctrl_pwm4_dp>; +}; + +/* Aquila USB_2, optional Bluetooth USB */ +&usb2 { + dr_mode = "host"; + vbus-supply = <®_usb2_vbus>; +}; + +/* Aquila USB_1 */ +&usb3 { + fsl,disable-port-power-control; +}; + +&usb3_dwc3 { + dr_mode = "otg"; + adp-disable; + hnp-disable; + srp-disable; + usb-role-switch; +}; + +&usb3_phy { + vbus-supply = <®_usb1_vbus>; +}; + +/* On-module eMMC */ +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + bus-width = <8>; + non-removable; + no-sdio; + no-sd; + + status = "okay"; +}; + +/* Aquila SD_1 */ +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_sd1_cd_gpio>; + pinctrl-1 = <&pinctrl_usdhc2>, <&pinctrl_sd1_cd_gpio>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>,<&pinctrl_sd1_cd_gpio>; + pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_sd1_cd_gpio>; + cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + vmmc-supply = <®_usdhc2_vmmc>; + vqmmc-supply = <®_usdhc2_vqmmc>; +}; + +&wdog3 { + fsl,ext-reset-output; + + status = "okay"; +}; + +&scmi_iomuxc { + /* Aquila CTRL_WAKE1_MICO# */ + pinctrl_ctrl_wake1_mico: ctrlwake1micogrp { + fsl,pins = ; /* Aquila D6 */ + }; + + pinctrl_ctrl_dp_clk_en: dpclkengrp { + fsl,pins = ; /* CTRL_DP_CLK_EN */ + }; + + /* Aquila ETH_2_XGMII_MDIO */ + pinctrl_emdio: emdiogrp { + fsl,pins = , /* Aquila B90 */ + ; /* Aquila B89 */ + }; + + /* Aquila ETH_1 */ + pinctrl_enetc0: enetc0grp { + fsl,pins = , /* ENET1_TX_CTL */ + , /* ENET1_TXC */ + , /* ENET1_TDO */ + , /* ENET1_TD1 */ + , /* ENET1_TD2 */ + , /* ENET1_TD3 */ + , /* ENET1_RX_CTL */ + , /* ENET1_RXC */ + , /* ENET1_RD0 */ + , /* ENET1_RD1 */ + , /* ENET1_RD2 */ + ; /* ENET1_RD3 */ + }; + + /* Aquila CAN_1 */ + pinctrl_flexcan1: flexcan1grp { + fsl,pins = , /* Aquila B48 */ + ; /* Aquila B49 */ + }; + + /* Aquila CAN_2 */ + pinctrl_flexcan2: flexcan2grp { + fsl,pins = , /* Aquila B50 */ + ; /* Aquila B51 */ + }; + + /* Aquila CAN_3 */ + pinctrl_flexcan3: flexcan3grp { + fsl,pins = , /* Aquila B53 */ + ; /* Aquila B54 */ + }; + + /* Aquila CAN_4 */ + pinctrl_flexcan4: flexcan4grp { + fsl,pins = , /* Aquila B55 */ + ; /* Aquila B56 */ + }; + + /* Aquila QSPI_1 (4 bit) */ + pinctrl_flexspi1_4bit: flexspi14bitgrp { + fsl,pins = , /* Aquila B65 */ + , /* Aquila B68 */ + , /* Aquila B67 */ + , /* Aquila B61 */ + , /* Aquila B60 */ + ; /* Aquila B63 */ + }; + + /* Aquila QSPI_1 (8 bit) */ + pinctrl_flexspi1_8bit: flexspi18bitgrp { + fsl,pins = , /* Aquila B65 */ + , /* Aquila B68 */ + , /* Aquila B67 */ + , /* Aquila B61 */ + , /* Aquila B60 */ + , /* Aquila B70 */ + , /* Aquila B71 */ + , /* Aquila B72 */ + , /* Aquila B73 */ + ; /* Aquila B63 */ + }; + + /* Aquila GPIO_01 */ + pinctrl_gpio_1: gpio1grp { + fsl,pins = ; /* Aquila D23 */ + }; + + /* Aquila GPIO_02 */ + pinctrl_gpio_2: gpio2grp { + fsl,pins = ; /* Aquila D24 */ + }; + + /* Aquila GPIO_03 */ + pinctrl_gpio_3: gpio3grp { + fsl,pins = ; /* Aquila D25 */ + }; + + /* Aquila GPIO_04 */ + pinctrl_gpio_4: gpio4grp { + fsl,pins = ; /* Aquila C20 */ + }; + + /* Aquila GPIO_05 */ + pinctrl_gpio_5: gpio5grp { + fsl,pins = ; /* Aquila C21 */ + }; + + /* Aquila GPIO_06 */ + pinctrl_gpio_6: gpio6grp { + fsl,pins = ; /* Aquila C22 */ + }; + + /* Aquila GPIO_07 */ + pinctrl_gpio_7: gpio7grp { + fsl,pins = ; /* Aquila C23 */ + }; + + /* Aquila GPIO_08 */ + pinctrl_gpio_8: gpio8grp { + fsl,pins = ; /* Aquila C24 */ + }; + + /* Aquila GPIO_09_CSI_1 */ + pinctrl_gpio_9_csi_1: gpio9csi1grp { + fsl,pins = ; /* Aquila B17 */ + }; + + /* Aquila GPIO_10_CSI_1 */ + pinctrl_gpio_10_csi_1: gpio10csi1grp { + fsl,pins = ; /* Aquila B18 */ + }; + + /* Aquila GPIO_11_CSI_1 */ + pinctrl_gpio_11_csi_1: gpio11csi1grp { + fsl,pins = ; /* Aquila A11*/ + }; + + /* Aquila GPIO_12_CSI_1 */ + pinctrl_gpio_12_csi_1: gpio12csi1grp { + fsl,pins = ; /* Aquila B19 */ + }; + + /* Aquila GPIO_17_DSI_1 */ + pinctrl_gpio_17_dsi_1: gpio17dsi1grp { + fsl,pins = ; /* Aquila B42 */ + }; + + /* Aquila GPIO_18_DSI_1 */ + pinctrl_gpio_18_dsi_1: gpio18dsi1grp { + fsl,pins = ; /* Aquila B43 */ + }; + + /* Aquila GPIO_19_DSI_1 */ + pinctrl_gpio_19_dsi_1: gpio19dsi1grp { + fsl,pins = ; /* Aquila B44 */ + }; + + /* Aquila GPIO_20_DSI_1 */ + pinctrl_gpio_20_dsi_1: gpio20dsi1grp { + fsl,pins = ; /* Aquila B45 */ + }; + + /* Aquila GPIO_21_DP */ + pinctrl_gpio_21_dp: gpio21dpgrp { + fsl,pins = ; /* Aquila B57 */ + }; + + pinctrl_ctrl_gpio_exp_int: gpioexpintgrp { + fsl,pins = ; /* CTRL_GPIO_EXP_INT# */ + }; + + /* Aquila I2C_2 */ + pinctrl_i3c2: i3c2cgrp { + fsl,pins = , /* Aquila C17 */ + ; /* Aquila C16 */ + }; + + /* Aquila I2C_1 as GPIOs */ + pinctrl_lpi2c2_gpio: lpi2c2gpiogrp { + fsl,pins = , /* Aquila D8 */ + ; /* Aquila D7 */ + }; + + /* Aquila I2C_1 */ + pinctrl_lpi2c2: lpi2c2grp { + fsl,pins = , /* Aquila D8 */ + ; /* Aquila D7 */ + }; + + /* On-module I2C as GPIOs */ + pinctrl_lpi2c3_gpio: lpi2c3gpiogrp { + fsl,pins = , /* I2C_SOM_SDA */ + ; /* I2C_SOM_SCL */ + }; + + /* On-module I2C */ + pinctrl_lpi2c3: lpi2c3grp { + fsl,pins = , /* I2C_SOM_SDA */ + ; /* I2C_SOM_SCL */ + }; + + /* Aquila I2C_4_CSI1 as GPIO */ + pinctrl_lpi2c4_gpio: lpi2c4gpiogrp { + fsl,pins = , /* Aquila A12 */ + ; /* Aquila A13 */ + }; + + /* Aquila I2C_4_CSI1 */ + pinctrl_lpi2c4: lpi2c4grp { + fsl,pins = , /* Aquila A12 */ + ; /* Aquila A13 */ + }; + + /* Aquila I2C_6 as GPIO */ + pinctrl_lpi2c5_gpio: lpi2c5gpiogrp { + fsl,pins = , /* Aquila C18 */ + ; /* Aquila C19 */ + }; + + /* Aquila I2C_6 */ + pinctrl_lpi2c5: lpi2c5grp { + fsl,pins = , /* Aquila C18 */ + ; /* Aquila C19 */ + }; + + /* Aquila I2C_3_DSI1/I2C_5_CSI2 as GPIO */ + pinctrl_lpi2c8_gpio: lpi2c8gpiogrp { + fsl,pins = , /* Aquila C5/B40 */ + ; /* Aquila C6/B41 */ + }; + + /* Aquila I2C_3_DSI1/I2C_5_CSI2 */ + pinctrl_lpi2c8: lpi2c8grp { + fsl,pins = , /* Aquila C5/B40 */ + ; /* Aquila C6/B41 */ + }; + + /* Aquila SPI_2 */ + pinctrl_lpspi4: lpspi4grp { + fsl,pins = , /* Aquila D16 */ + , /* Aquila D15 */ + , /* Aquila D17 */ + ; /* Aquila D14 */ + }; + + /* Aquila SPI_1 */ + pinctrl_lpspi6: lpspi6grp { + fsl,pins = , /* Aquila D9 */ + , /* Aquila D10 */ + , /* Aquila D11 */ + ; /* Aquila D12 */ + }; + + /* Aquila PCIE_1 */ + pinctrl_pcie0: pcie0grp { + fsl,pins = ; /* Aquila C37 */ + }; + + /* Aquila PCIE_2 */ + pinctrl_pcie1: pcie1grp { + fsl,pins = ; /* Aquila C34 */ + }; + + /* Aquila QSPI_1_CS1# */ + pinctrl_qspi_cs1: qspics1grp { + fsl,pins = ; /* Aquila B66 */ + }; + + /* Aquila QSPI_1_CS2# as GPIO */ + pinctrl_qspi_cs2_gpio: qspics2gpiogrp { + fsl,pins = ; /* Aquila B62 */ + }; + + /* Aquila I2S_1 */ + pinctrl_sai2: sai2grp { + fsl,pins = , /* Aquila B21 */ + , /* Aquila B20 */ + , /* Aquila B23 */ + ; /* Aquila B22 */ + }; + + pinctrl_sai2_mclk: sai2mclkgrp { + fsl,pins = ; /* Aquila B24 */ + }; + + /* Aquila SD_1_CD# as GPIO */ + pinctrl_sd1_cd_gpio: sd1cdgpiogrp { + fsl,pins = ; /* Aquila A1 */ + }; + + /* Aquila SD_1_PWR_EN */ + pinctrl_sd1_pwr_en: sd1pwrengpiogrp { + fsl,pins = ; /* Aquila A6 */ + }; + + /* Aquila PWM_1 */ + pinctrl_pwm1: tpm3ch3grp { + fsl,pins = ; /* Aquila C25 */ + }; + + /* Aquila PWM_3_DSI as GPIO */ + pinctrl_pwm3_dsi_gpio: tpm5ch0gpiogrp { + fsl,pins = ; /* Aquila B46 */ + }; + + /* Aquila PWM_3_DSI */ + pinctrl_pwm3_dsi: tpm5ch0grp { + fsl,pins = ; /* Aquila B46 */ + }; + + /* Aquila PWM_4_DP */ + pinctrl_pwm4_dp: tpm5ch3grp { + fsl,pins = ; /* Aquila B58 */ + }; + + /* Aquila PWM_2 */ + pinctrl_pwm2: tpm6ch0grp { + fsl,pins = ; /* Aquila C26 */ + }; + + /* Aquila UART_3 */ + pinctrl_uart1: uart1grp { + fsl,pins = , /* Aquila D20 */ + ; /* Aquila D19 */ + }; + + /* Aquila UART_4 */ + pinctrl_uart2: uart2grp { + fsl,pins = , /* Aquila D22 */ + ; /* Aquila D21 */ + }; + + /* Aquila UART_1 */ + pinctrl_uart3: uart3grp { + fsl,pins = , /* Aquila B37 */ + , /* Aquila B35 */ + , /* Aquila B36 */ + ; /* Aquila B38 */ + }; + + /* Aquila UART_2 */ + pinctrl_uart7: uart7grp { + fsl,pins = , /* Aquila B33 */ + , /* Aquila B31 */ + , /* Aquila B32 */ + ; /* Aquila B34 */ + }; + + /* On-module eMMC */ + pinctrl_usdhc1: usdhc1grp { + fsl,pins = , /* eMMC_CLK */ + , /* eMMC_CMD */ + , /* eMMC_DATA0 */ + , /* eMMC_DATA1 */ + , /* eMMC_DATA2 */ + , /* eMMC_DATA3 */ + , /* eMMC_DATA4 */ + , /* eMMC_DATA5 */ + , /* eMMC_DATA6 */ + , /* eMMC_DATA7 */ + ; /* eMMC_STROBE */ + }; + + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { + fsl,pins = , /* eMMC_CLK */ + , /* eMMC_CMD */ + , /* eMMC_DATA0 */ + , /* eMMC_DATA1 */ + , /* eMMC_DATA2 */ + , /* eMMC_DATA3 */ + , /* eMMC_DATA4 */ + , /* eMMC_DATA5 */ + , /* eMMC_DATA6 */ + , /* eMMC_DATA7 */ + ; /* eMMC_STROBE */ + }; + + /* Aquila SD_1 */ + pinctrl_usdhc2: usdhc2grp { + fsl,pins = , /* Aquila A5 */ + , /* Aquila A7 */ + , /* Aquila A3 */ + , /* Aquila A2 */ + , /* Aquila A10 */ + ; /* Aquila A8 */ + }; + + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = , /* Aquila A5 */ + , /* Aquila A7 */ + , /* Aquila A3 */ + , /* Aquila A2 */ + , /* Aquila A10 */ + ; /* Aquila A8 */ + }; + + pinctrl_usdhc2_sleep: usdhc2-sleepgrp { + fsl,pins = , /* Aquila A5 */ + , /* Aquila A7 */ + , /* Aquila A3 */ + , /* Aquila A2 */ + , /* Aquila A10 */ + ; /* Aquila A8 */ + }; +}; diff --git a/arch/arm/mach-imx/imx9/Kconfig b/arch/arm/mach-imx/imx9/Kconfig index ee22e411cd6..cbd0078ba2a 100644 --- a/arch/arm/mach-imx/imx9/Kconfig +++ b/arch/arm/mach-imx/imx9/Kconfig @@ -173,6 +173,10 @@ config TARGET_IMX943_EVK imply BOOTSTD_FULL imply OF_UPSTREAM +config TARGET_AQUILA_IMX95 + bool "Support Toradex Aquila iMX95" + select IMX95 + config TARGET_TORADEX_SMARC_IMX95 bool "Support Toradex SMARC iMX95" select IMX95 @@ -206,6 +210,7 @@ source "board/phytec/phycore_imx91_93/Kconfig" source "board/variscite/imx93_var_som/Kconfig" source "board/nxp/imx94_evk/Kconfig" source "board/nxp/imx95_evk/Kconfig" +source "board/toradex/aquila-imx95/Kconfig" source "board/toradex/smarc-imx95/Kconfig" source "board/toradex/verdin-imx95/Kconfig" source "board/nxp/imx952_evk/Kconfig" diff --git a/board/toradex/aquila-imx95/Kconfig b/board/toradex/aquila-imx95/Kconfig new file mode 100644 index 00000000000..5936946e1af --- /dev/null +++ b/board/toradex/aquila-imx95/Kconfig @@ -0,0 +1,36 @@ +if TARGET_AQUILA_IMX95 + +config SYS_BOARD + default "aquila-imx95" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "aquila-imx95" + +config TDX_CFG_BLOCK + default y + +config TDX_CFG_BLOCK_2ND_ETHADDR + default y + +config TDX_CFG_BLOCK_DEV + default "0" + +# Toradex config block in eMMC, at the end of 1st "boot sector" +config TDX_CFG_BLOCK_OFFSET + default "-512" + +config TDX_CFG_BLOCK_PART + default "1" + +config TDX_HAVE_EEPROM_EXTRA + default y + +config TDX_HAVE_MMC + default y + +source "board/toradex/common/Kconfig" + +endif diff --git a/board/toradex/aquila-imx95/MAINTAINERS b/board/toradex/aquila-imx95/MAINTAINERS new file mode 100644 index 00000000000..d2a74a53f5e --- /dev/null +++ b/board/toradex/aquila-imx95/MAINTAINERS @@ -0,0 +1,11 @@ +Aquila iMX95 +F: arch/arm/dts/imx95-aquila.dtsi +F: arch/arm/dts/imx95-aquila-dev.dts +F: arch/arm/dts/imx95-aquila-dev-u-boot.dtsi +F: board/toradex/aquila-imx95/ +F: configs/aquila-imx95_defconfig +F: doc/board/toradex/aquila-imx95.rst +F: include/configs/aquila-imx95.h +M: Francesco Dolcini +S: Maintained +W: https://www.toradex.com/computer-on-modules/aquila-arm-family/nxp-imx95 diff --git a/board/toradex/aquila-imx95/Makefile b/board/toradex/aquila-imx95/Makefile new file mode 100644 index 00000000000..caaf09465c8 --- /dev/null +++ b/board/toradex/aquila-imx95/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) Toradex + +obj-y += aquila-imx95.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +endif diff --git a/board/toradex/aquila-imx95/aquila-imx95.c b/board/toradex/aquila-imx95/aquila-imx95.c new file mode 100644 index 00000000000..0c6473e4b3a --- /dev/null +++ b/board/toradex/aquila-imx95/aquila-imx95.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Copyright (c) Toradex */ + +#include +#include +#include +#include + +#include "../common/tdx-cfg-block.h" + +int board_phys_sdram_size(phys_size_t *size) +{ + *size = PHYS_SDRAM_SIZE + PHYS_SDRAM_2_SIZE; + + return 0; +} + +#if IS_ENABLED(CONFIG_OF_LIBFDT) && IS_ENABLED(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return ft_common_board_setup(blob, bd); +} +#endif diff --git a/board/toradex/aquila-imx95/aquila-imx95.env b/board/toradex/aquila-imx95/aquila-imx95.env new file mode 100644 index 00000000000..5ca6cb18aaa --- /dev/null +++ b/board/toradex/aquila-imx95/aquila-imx95.env @@ -0,0 +1,20 @@ +boot_scripts=boot.scr +boot_script_dhcp=boot.scr +boot_targets=mmc1 mmc0 dhcp +console=ttyLP2 +fdt_board=dev +fdt_addr=0x9c400000 +fdt_addr_r=0x9c400000 +kernel_addr_r=CONFIG_SYS_LOAD_ADDR +kernel_comp_addr_r=0x94400000 +kernel_comp_size=0x8000000 +ramdisk_addr_r=0x9c800000 +scriptaddr=0x9c600000 + +update_uboot= + askenv confirm Did you load flash.bin (y/N)?; + if test "$confirm" = y; then + setexpr blkcnt ${filesize} + 0x1ff && setexpr blkcnt + ${blkcnt} / 0x200; mmc dev 0 1; mmc write ${loadaddr} 0x0 + ${blkcnt}; + fi diff --git a/board/toradex/aquila-imx95/spl.c b/board/toradex/aquila-imx95/spl.c new file mode 100644 index 00000000000..9f501c11c1d --- /dev/null +++ b/board/toradex/aquila-imx95/spl.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Copyright (c) Toradex */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int spl_board_boot_device(enum boot_device boot_dev_spl) +{ + switch (boot_dev_spl) { + case SD1_BOOT: + case MMC1_BOOT: + return BOOT_DEVICE_MMC1; + case SD2_BOOT: + case MMC2_BOOT: + return BOOT_DEVICE_MMC2; + case USB_BOOT: + return BOOT_DEVICE_BOARD; + default: + return BOOT_DEVICE_NONE; + } +} + +void spl_board_init(void) +{ + int ret; + + ret = ele_start_rng(); + if (ret) + printf("Fail to start RNG: %d\n", ret); +} + +void board_init_f(ulong dummy) +{ + int ret; + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + if (IS_ENABLED(CONFIG_SPL_RECOVER_DATA_SECTION)) + spl_save_restore_data(); + + timer_init(); + + /* Need dm_init() to run before any SCMI calls */ + spl_early_init(); + + /* Need to enable SCMI drivers and ELE driver before console */ + ret = imx9_probe_mu(); + if (ret) + hang(); /* MU not probed, nothing can be outputed, hang */ + + arch_cpu_init(); + + preloader_console_init(); + + debug("SOC: 0x%x\n", gd->arch.soc_rev); + debug("LC: 0x%x\n", gd->arch.lifecycle); + + get_reset_reason(true, false); + + board_init_r(NULL, 0); +} diff --git a/configs/aquila-imx95_defconfig b/configs/aquila-imx95_defconfig new file mode 100644 index 00000000000..bb3d475ef4d --- /dev/null +++ b/configs/aquila-imx95_defconfig @@ -0,0 +1,186 @@ +CONFIG_ARM=y +CONFIG_ARCH_IMX9=y +CONFIG_TEXT_BASE=0x90200000 +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SYS_MALLOC_F_LEN=0x10000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=3 +CONFIG_ENV_SIZE=0x2000 +CONFIG_ENV_OFFSET=0xFFFFDE00 +CONFIG_DM_GPIO=y +CONFIG_DEFAULT_DEVICE_TREE="imx95-aquila-dev" +CONFIG_TARGET_AQUILA_IMX95=y +CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_SYS_MONITOR_LEN=524288 +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_STACK=0x204d6000 +CONFIG_SPL_TEXT_BASE=0x20480000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x204d6000 +CONFIG_SPL_BSS_MAX_SIZE=0x2000 +CONFIG_SYS_LOAD_ADDR=0x90400000 +CONFIG_WATCHDOG_TIMEOUT_MSECS=30000 +CONFIG_SPL=y +CONFIG_SPL_RECOVER_DATA_SECTION=y +CONFIG_PCI=y +CONFIG_SYS_MEMTEST_START=0x90000000 +CONFIG_SYS_MEMTEST_END=0xA0000000 +CONFIG_REMAKE_ELF=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_BOOTSTD_FULL=y +CONFIG_BOOTDELAY=1 +CONFIG_OF_SYSTEM_SETUP=y +CONFIG_BOOTCOMMAND="bootflow scan -b" +CONFIG_USE_PREBOOT=y +CONFIG_PREBOOT="test -n \"${fdtfile}\" || setenv fdtfile imx95-aquila-${fdt_board}.dtb" +CONFIG_SYS_CBSIZE=2048 +CONFIG_SYS_PBSIZE=2074 +CONFIG_LOG=y +# CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +# CONFIG_BOARD_INIT is not set +CONFIG_PCI_INIT_R=y +CONFIG_SPL_MAX_SIZE=0x30000 +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_LOAD_IMX_CONTAINER=y +CONFIG_IMX_CONTAINER_CFG="arch/arm/mach-imx/imx9/scmi/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=0x93200000 +CONFIG_SPL_SYS_MALLOC_SIZE=0x80000 +CONFIG_SPL_SYS_MMCSD_RAW_MODE=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1040 +CONFIG_SPL_I2C=y +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_THERMAL=y +CONFIG_SPL_WATCHDOG=y +CONFIG_SYS_PROMPT="Aquila iMX95 # " +CONFIG_CMD_ASKENV=y +CONFIG_CMD_NVEDIT_EFI=y +CONFIG_CRC32_VERIFY=y +CONFIG_CMD_MD5SUM=y +CONFIG_MD5SUM_VERIFY=y +CONFIG_CMD_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_PCI=y +CONFIG_CMD_READ=y +CONFIG_CMD_REMOTEPROC=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_SDP=y +CONFIG_CMD_USB_MASS_STORAGE=y +CONFIG_CMD_BOOTCOUNT=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_SYSBOOT=y +CONFIG_CMD_UUID=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_HASH=y +CONFIG_CMD_SCMI=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_RELOC_GD_ENV_ADDR=y +CONFIG_ENV_MMC_EMMC_HW_PARTITION=1 +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_USE_ETHPRIME=y +CONFIG_ETHPRIME="eth0" +CONFIG_VERSION_VARIABLE=y +CONFIG_PROT_UDP=y +CONFIG_IP_DEFRAG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_TFTP_BLOCKSIZE=4096 +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_SYSCON=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_BOOTCOUNT_LIMIT=y +CONFIG_BOOTCOUNT_ENV=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_SPL_CLK_CCF=y +CONFIG_CLK_CCF=y +CONFIG_CLK_SCMI=y +CONFIG_SPL_CLK_SCMI=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x90400000 +CONFIG_FASTBOOT_BUF_SIZE=0x20000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_UUU_SUPPORT=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_SPL_FIRMWARE=y +# CONFIG_SCMI_AGENT_SMCCC is not set +CONFIG_IMX_SM_CPU=y +CONFIG_IMX_SM_LMM=y +CONFIG_IMX_RGPIO2P=y +CONFIG_DM_PCA953X=y +CONFIG_SPL_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_IMX_LPI2C=y +CONFIG_IMX_MU_MBOX=y +CONFIG_I2C_EEPROM=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_DM_MDIO=y +CONFIG_MII=y +CONFIG_FSL_ENETC=y +CONFIG_PHYLIB=y +CONFIG_PHY_TI_DP83867=y +CONFIG_PCIE_ECAM_GENERIC=y +CONFIG_PHY_IMX8MQ_USB=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_PINCTRL_IMX_SCMI=y +CONFIG_POWER_DOMAIN=y +CONFIG_SCMI_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_SPL_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_REMOTEPROC_IMX=y +CONFIG_DM_RNG=y +CONFIG_DM_SERIAL=y +CONFIG_FSL_LPUART=y +CONFIG_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_EHCI_HCD=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_SPL_USB_DWC3_GENERIC=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_GADGET=y +CONFIG_SPL_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Toradex" +CONFIG_USB_GADGET_VENDOR_NUM=0x1b67 +CONFIG_USB_GADGET_PRODUCT_NUM=0x4000 +CONFIG_USB_GADGET_OS_DESCRIPTORS=y +CONFIG_SDP_LOADADDR=0x90400000 +CONFIG_SPL_USB_SDP_SUPPORT=y +CONFIG_ULP_WATCHDOG=y +CONFIG_WDT=y +# CONFIG_SPL_SHA1 is not set +CONFIG_LZO=y diff --git a/doc/board/toradex/aquila-imx95.rst b/doc/board/toradex/aquila-imx95.rst new file mode 100644 index 00000000000..edd40252657 --- /dev/null +++ b/doc/board/toradex/aquila-imx95.rst @@ -0,0 +1,175 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later + +Toradex Aquila iMX95 Module +=========================== + +- SoM: https://www.toradex.com/computer-on-modules/aquila-arm-family/nxp-imx95 +- Carrier board: https://www.toradex.com/products/carrier-board/aquila-development-board-kit + +Quick Start +----------- + +- Setup environment +- Get ahab-container.img +- Get DDR PHY Firmware Images +- Get and Build OEI Images +- Get and Build System Manager Image +- Get and Build the ARM Trusted Firmware +- Build the Bootloader Image +- Boot + +Setup environment +----------------- + +Suggested current toolchains are ARM 14.3 (https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads): + +- https://developer.arm.com/-/media/Files/downloads/gnu/14.3.rel1/binrel/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz +- https://developer.arm.com/-/media/Files/downloads/gnu/14.3.rel1/binrel/arm-gnu-toolchain-14.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz + +.. code-block:: console + + $ export TOOLS= + $ export CROSS_COMPILE_32=arm-none-linux-gnueabihf- + $ export CROSS_COMPILE_64=aarch64-none-linux-gnu- + +Get ahab-container.img +---------------------- + +Note: `$srctree` is the U-Boot source directory + +.. code-block:: console + + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-ele-imx-2.0.2-89161a8.bin + $ sh firmware-ele-imx-2.0.2-89161a8.bin --auto-accept + $ cp firmware-ele-imx-2.0.2-89161a8/mx95b0-ahab-container.img $(srctree) + +Get DDR PHY Firmware Images +--------------------------- + +Note: `$srctree` is the U-Boot source directory + +.. code-block:: console + + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.28-994fa14.bin + $ sh firmware-imx-8.28-994fa14.bin --auto-accept + $ cp firmware-imx-8.28-994fa14/firmware/ddr/synopsys/lpddr5*v202409.bin $(srctree) + +Get and Build OEI Images +------------------------ + +Note: `$srctree` is the U-Boot source directory +Get OEI from: https://git.toradex.com/cgit/imx-oei-toradex.git/ +branch: main + +.. code-block:: console + + $ git clone -b main https://git.toradex.com/cgit/imx-oei-toradex.git/ + $ cd imx-oei-toradex + + $ make board=toradex-aquila-imx95 oei=ddr DEBUG=1 r=B0 all + $ cp build/toradex-aquila-imx95/ddr/oei-m33-ddr.bin $(srctree) + + $ make board=toradex-aquila-imx95 oei=tcm DEBUG=1 r=B0 all + $ cp build/toradex-aquila-imx95/tcm/oei-m33-tcm.bin $(srctree) + +The Makefile will set `DDR_CONFIG` automatically based on the selected silicon +revision. + +Get and Build the System Manager Image +-------------------------------------- + +Note: `$srctree` is the U-Boot source directory +Get System Manager from: https://git.toradex.com/cgit/imx-sm-toradex.git/ +branch: main + +.. code-block:: console + + $ git clone -b main https://git.toradex.com/cgit/imx-sm-toradex.git/ + $ cd imx-sm-toradex + $ make config=aquila-imx95 all + $ cp build/aquila-imx95/m33_image.bin $(srctree) + +Get and Build the ARM Trusted Firmware +-------------------------------------- + +Note: `$srctree` is the U-Boot source directory +Get ATF from: https://github.com/nxp-imx/imx-atf/ +branch: lf_v2.12 + +.. code-block:: console + + $ export CROSS_COMPILE=$CROSS_COMPILE_64 + $ unset LDFLAGS + $ unset AS + $ git clone -b lf_v2.12 https://github.com/nxp-imx/imx-atf.git + $ cd imx-atf + $ make PLAT=imx95 bl31 + $ cp build/imx95/release/bl31.bin $(srctree) + +Build the Bootloader Image +-------------------------- + +.. code-block:: console + + $ export CROSS_COMPILE=$CROSS_COMPILE_64 + $ make aquila-imx95_defconfig + $ make + +Flash to eMMC +------------- + +.. code-block:: console + + > tftpboot ${loadaddr} flash.bin + > setexpr blkcnt ${filesize} + 0x1ff && setexpr blkcnt ${blkcnt} / 0x200 + > mmc dev 0 1 && mmc write ${loadaddr} 0x0 ${blkcnt} + +As a convenience, instead of the last two commands, one may also use the update +U-Boot wrapper: + +.. code-block:: console + + > run update_uboot + +Boot +---- + +Boot sequence is: + +* SPL ---> ATF (TF-A) ---> U-Boot proper + +Output: + +.. code-block:: console + + U-Boot SPL 2026.07-rc3-00300-ge16706b72e14 (Jun 11 2026 - 13:07:49 +0200) + SYS Boot reason: por, origin: -1, errid: -1 + WDT: Started watchdog@42490000 with servicing every 1000ms (40s timeout) + Trying to boot from MMC1 + Load image from MMC/SD 0xd2800 + NOTICE: BL31: v2.10.0 (release):lf-6.6.52-2.2.1-dirty + NOTICE: BL31: Built : 06:40:36, Jul 7 2025 + + + U-Boot 2026.07-rc3-00300-ge16706b72e14 (Jun 11 2026 - 13:07:49 +0200) + + CPU: NXP i.MX95 Rev2.0 A55 at 1800 MHz - invalid sensor data + DRAM: 7.8 GiB + Core: 321 devices, 30 uclasses, devicetree: separate + WDT: Started watchdog@42490000 with servicing every 1000ms (40s timeout) + MMC: FSL_SDHC: 0, FSL_SDHC: 1 + Loading Environment from MMC... Reading from MMC(0)... OK + In: serial@44380000 + Out: serial@44380000 + Err: serial@44380000 + Model: Toradex 0098 Aquila iMX95 Hexa 8GB WB IT V1.0A + Serial#: 12594391 + + BuildInfo: + - ELE firmware version 2.0.2-c110ba4b + + Net: WARNING: no MAC address assigned for MAC0 + imx_get_mac_from_fuse: fuse read err: 0 + eth0: enetc-0 [PRIME] + Hit any key to stop autoboot: 0 + Aquila iMX95 # diff --git a/doc/board/toradex/index.rst b/doc/board/toradex/index.rst index 2a45bde6991..c5955ea1ad8 100644 --- a/doc/board/toradex/index.rst +++ b/doc/board/toradex/index.rst @@ -8,6 +8,7 @@ Toradex apalis-imx8 aquila-am69 + aquila-imx95 colibri_imx7 colibri-imx8x smarc-imx8mp diff --git a/include/configs/aquila-imx95.h b/include/configs/aquila-imx95.h new file mode 100644 index 00000000000..07d09d138cb --- /dev/null +++ b/include/configs/aquila-imx95.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (c) Toradex */ + +#ifndef __AQUILA_IMX95_H +#define __AQUILA_IMX95_H + +#include +#include + +#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 */ +#define SZ_6G _AC(0x180000000, ULL) + +/* first 256MB reserved for firmware */ +#define CFG_SYS_INIT_RAM_ADDR 0x90000000 +#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 PHYS_SDRAM_2_SIZE SZ_6G + +#define CFG_SYS_SECURE_SDRAM_BASE 0x8A000000 /* Secure DDR region for A55, SPL could use first 2MB */ +#define CFG_SYS_SECURE_SDRAM_SIZE 0x06000000 + +#endif -- cgit v1.3.1