diff mbox series

[v8,2/5] board: siemens: Add support for SIMATIC IOT2050 devices

Message ID 5aba498fcba978adefde9e973d01d07710e28a8e.1631945876.git.jan.kiszka@siemens.com
State Accepted
Commit a2db09e26993298c5469072660e9352feded824f
Delegated to: Tom Rini
Headers show
Series Add SIMATIC IOT2050 board support | expand

Commit Message

Jan Kiszka Sept. 18, 2021, 6:17 a.m. UTC
From: Jan Kiszka <jan.kiszka@siemens.com>

This adds support for the IOT2050 Basic and Advanced devices. The Basic
used the dual-core AM6528 GP processor, the Advanced one the AM6548 HS
quad-core version.

Both variants are booted via a Siemens-provided FSBL that runs on the R5
cores. Consequently, U-Boot support is targeting the A53 cores. U-Boot
SPL, ATF and TEE have to reside in SPI flash.

Full integration into a bootable image can be found on
https://github.com/siemens/meta-iot2050

Based on original board support by Le Jin, Gao Nian and Chao Zeng.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 arch/arm/mach-k3/Kconfig          |   1 +
 board/siemens/iot2050/Kconfig     |  32 ++++
 board/siemens/iot2050/MAINTAINERS |   9 +
 board/siemens/iot2050/Makefile    |  10 ++
 board/siemens/iot2050/board.c     | 272 ++++++++++++++++++++++++++++++
 board/siemens/iot2050/config.mk   |   8 +
 configs/iot2050_defconfig         | 130 ++++++++++++++
 doc/board/index.rst               |   1 +
 doc/board/siemens/index.rst       |   9 +
 doc/board/siemens/iot2050.rst     |  78 +++++++++
 include/configs/iot2050.h         |  62 +++++++
 11 files changed, 612 insertions(+)
 create mode 100644 board/siemens/iot2050/Kconfig
 create mode 100644 board/siemens/iot2050/MAINTAINERS
 create mode 100644 board/siemens/iot2050/Makefile
 create mode 100644 board/siemens/iot2050/board.c
 create mode 100644 board/siemens/iot2050/config.mk
 create mode 100644 configs/iot2050_defconfig
 create mode 100644 doc/board/siemens/index.rst
 create mode 100644 doc/board/siemens/iot2050.rst
 create mode 100644 include/configs/iot2050.h

Comments

Tom Rini Oct. 3, 2021, 11:34 p.m. UTC | #1
On Sat, Sep 18, 2021 at 08:17:53AM +0200, Jan Kiszka wrote:

> From: Jan Kiszka <jan.kiszka@siemens.com>
> 
> This adds support for the IOT2050 Basic and Advanced devices. The Basic
> used the dual-core AM6528 GP processor, the Advanced one the AM6548 HS
> quad-core version.
> 
> Both variants are booted via a Siemens-provided FSBL that runs on the R5
> cores. Consequently, U-Boot support is targeting the A53 cores. U-Boot
> SPL, ATF and TEE have to reside in SPI flash.
> 
> Full integration into a bootable image can be found on
> https://github.com/siemens/meta-iot2050
> 
> Based on original board support by Le Jin, Gao Nian and Chao Zeng.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>

Applied to u-boot/next, thanks!
Jan Kiszka Oct. 4, 2021, 3:54 p.m. UTC | #2
On 04.10.21 01:34, Tom Rini wrote:
> On Sat, Sep 18, 2021 at 08:17:53AM +0200, Jan Kiszka wrote:
> 
>> From: Jan Kiszka <jan.kiszka@siemens.com>
>>
>> This adds support for the IOT2050 Basic and Advanced devices. The Basic
>> used the dual-core AM6528 GP processor, the Advanced one the AM6548 HS
>> quad-core version.
>>
>> Both variants are booted via a Siemens-provided FSBL that runs on the R5
>> cores. Consequently, U-Boot support is targeting the A53 cores. U-Boot
>> SPL, ATF and TEE have to reside in SPI flash.
>>
>> Full integration into a bootable image can be found on
>> https://github.com/siemens/meta-iot2050
>>
>> Based on original board support by Le Jin, Gao Nian and Chao Zeng.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> 
> Applied to u-boot/next, thanks!
> 

Thanks for merging - it just does not boot anymore, no output after
TF-A. Trying to understand the differences now, already ruled out
arch/arm/dts/k3-am65* as source.

Jan
Tom Rini Oct. 4, 2021, 4:02 p.m. UTC | #3
On Mon, Oct 04, 2021 at 05:54:46PM +0200, Jan Kiszka wrote:
> On 04.10.21 01:34, Tom Rini wrote:
> > On Sat, Sep 18, 2021 at 08:17:53AM +0200, Jan Kiszka wrote:
> > 
> >> From: Jan Kiszka <jan.kiszka@siemens.com>
> >>
> >> This adds support for the IOT2050 Basic and Advanced devices. The Basic
> >> used the dual-core AM6528 GP processor, the Advanced one the AM6548 HS
> >> quad-core version.
> >>
> >> Both variants are booted via a Siemens-provided FSBL that runs on the R5
> >> cores. Consequently, U-Boot support is targeting the A53 cores. U-Boot
> >> SPL, ATF and TEE have to reside in SPI flash.
> >>
> >> Full integration into a bootable image can be found on
> >> https://github.com/siemens/meta-iot2050
> >>
> >> Based on original board support by Le Jin, Gao Nian and Chao Zeng.
> >>
> >> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> > 
> > Applied to u-boot/next, thanks!
> > 
> 
> Thanks for merging - it just does not boot anymore, no output after
> TF-A. Trying to understand the differences now, already ruled out
> arch/arm/dts/k3-am65* as source.

Have you enabled debug uart?  I found that quite helpful figuring out
what was wrong when updating the dts files, and the correct values for
that are in the dts files too.
Jan Kiszka Oct. 4, 2021, 4:35 p.m. UTC | #4
On 04.10.21 18:02, Tom Rini wrote:
> On Mon, Oct 04, 2021 at 05:54:46PM +0200, Jan Kiszka wrote:
>> On 04.10.21 01:34, Tom Rini wrote:
>>> On Sat, Sep 18, 2021 at 08:17:53AM +0200, Jan Kiszka wrote:
>>>
>>>> From: Jan Kiszka <jan.kiszka@siemens.com>
>>>>
>>>> This adds support for the IOT2050 Basic and Advanced devices. The Basic
>>>> used the dual-core AM6528 GP processor, the Advanced one the AM6548 HS
>>>> quad-core version.
>>>>
>>>> Both variants are booted via a Siemens-provided FSBL that runs on the R5
>>>> cores. Consequently, U-Boot support is targeting the A53 cores. U-Boot
>>>> SPL, ATF and TEE have to reside in SPI flash.
>>>>
>>>> Full integration into a bootable image can be found on
>>>> https://github.com/siemens/meta-iot2050
>>>>
>>>> Based on original board support by Le Jin, Gao Nian and Chao Zeng.
>>>>
>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>
>>> Applied to u-boot/next, thanks!
>>>
>>
>> Thanks for merging - it just does not boot anymore, no output after
>> TF-A. Trying to understand the differences now, already ruled out
>> arch/arm/dts/k3-am65* as source.
> 
> Have you enabled debug uart?  I found that quite helpful figuring out
> what was wrong when updating the dts files, and the correct values for
> that are in the dts files too.
> 

We do, and it stays silent so far.

Meanwhile I already updated the defconfig, in line with the changes to
the similar am65x_evm* (CONFIG_SPL_SERIAL[_SUPPORT]...), but no
break-through yet.

Jan
diff mbox series

Patch

diff --git a/arch/arm/mach-k3/Kconfig b/arch/arm/mach-k3/Kconfig
index fa8d134b42..526f5f8b76 100644
--- a/arch/arm/mach-k3/Kconfig
+++ b/arch/arm/mach-k3/Kconfig
@@ -168,4 +168,5 @@  config K3_DM_FW
 source "board/ti/am65x/Kconfig"
 source "board/ti/am64x/Kconfig"
 source "board/ti/j721e/Kconfig"
+source "board/siemens/iot2050/Kconfig"
 endif
diff --git a/board/siemens/iot2050/Kconfig b/board/siemens/iot2050/Kconfig
new file mode 100644
index 0000000000..8f634c172c
--- /dev/null
+++ b/board/siemens/iot2050/Kconfig
@@ -0,0 +1,32 @@ 
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) Siemens AG, 2018-2021
+#
+# Authors:
+#   Le Jin <le.jin@siemens.com>
+#   Jan Kiszka <jan.kiszka@siemens.com>
+
+config TARGET_IOT2050_A53
+	bool "IOT2050 running on A53"
+	select ARM64
+	select SOC_K3_AM6
+	select BOARD_LATE_INIT
+	select SYS_DISABLE_DCACHE_OPS
+	select BINMAN
+
+if TARGET_IOT2050_A53
+
+config SYS_BOARD
+	default "iot2050"
+
+config SYS_VENDOR
+	default "siemens"
+
+config SYS_CONFIG_NAME
+	default "iot2050"
+
+config IOT2050_BOOT_SWITCH
+	bool "Disable eMMC boot via USER button (Advanced version only)"
+	default y
+
+endif
diff --git a/board/siemens/iot2050/MAINTAINERS b/board/siemens/iot2050/MAINTAINERS
new file mode 100644
index 0000000000..1b525356c2
--- /dev/null
+++ b/board/siemens/iot2050/MAINTAINERS
@@ -0,0 +1,9 @@ 
+IOT2050 BOARD
+M:	Le Jin <le.jin@siemens.com>
+M:	Jan Kiszka <jan.kiszka@siemens.com>
+S:	Maintained
+F:	board/siemens/iot2050/
+F:	include/configs/iot2050.h
+F:	configs/iot2050_defconfig
+F:	arch/arm/dts/iot2050-*
+F:	doc/board/siemens/iot2050.rst
diff --git a/board/siemens/iot2050/Makefile b/board/siemens/iot2050/Makefile
new file mode 100644
index 0000000000..619594ab8e
--- /dev/null
+++ b/board/siemens/iot2050/Makefile
@@ -0,0 +1,10 @@ 
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Makefile for Siemens IOT2050 board
+# Copyright (c) Siemens AG, 2018-2021
+#
+# Authors:
+#   Le Jin <le.jin@siemens.com>
+#
+
+obj-y += board.o
diff --git a/board/siemens/iot2050/board.c b/board/siemens/iot2050/board.c
new file mode 100644
index 0000000000..b2110978ae
--- /dev/null
+++ b/board/siemens/iot2050/board.c
@@ -0,0 +1,272 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Board specific initialization for IOT2050
+ * Copyright (c) Siemens AG, 2018-2021
+ *
+ * Authors:
+ *   Le Jin <le.jin@siemens.com>
+ *   Jan Kiszka <jan.kiszka@siemens.com>
+ */
+
+#include <common.h>
+#include <bootstage.h>
+#include <dm.h>
+#include <i2c.h>
+#include <led.h>
+#include <malloc.h>
+#include <net.h>
+#include <phy.h>
+#include <spl.h>
+#include <version.h>
+#include <linux/delay.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+
+#define IOT2050_INFO_MAGIC		0x20502050
+
+struct iot2050_info {
+	u32 magic;
+	u16 size;
+	char name[20 + 1];
+	char serial[16 + 1];
+	char mlfb[18 + 1];
+	char uuid[32 + 1];
+	char a5e[18 + 1];
+	u8 mac_addr_cnt;
+	u8 mac_addr[8][ARP_HLEN];
+	char seboot_version[40 + 1];
+} __packed;
+
+/*
+ * Scratch SRAM (available before DDR RAM) contains extracted EEPROM data.
+ */
+#define IOT2050_INFO_DATA ((struct iot2050_info *) \
+			     TI_SRAM_SCRATCH_BOARD_EEPROM_START)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static bool board_is_advanced(void)
+{
+	struct iot2050_info *info = IOT2050_INFO_DATA;
+
+	return info->magic == IOT2050_INFO_MAGIC &&
+		strstr((char *)info->name, "IOT2050-ADVANCED") != NULL;
+}
+
+static bool board_is_sr1(void)
+{
+	struct iot2050_info *info = IOT2050_INFO_DATA;
+
+	return info->magic == IOT2050_INFO_MAGIC &&
+		!strstr((char *)info->name, "-PG2");
+}
+
+static void remove_mmc1_target(void)
+{
+	char *boot_targets = strdup(env_get("boot_targets"));
+	char *mmc1 = strstr(boot_targets, "mmc1");
+
+	if (mmc1) {
+		memmove(mmc1, mmc1 + 4, strlen(mmc1 + 4) + 1);
+		env_set("boot_targets", boot_targets);
+	}
+
+	free(boot_targets);
+}
+
+void set_board_info_env(void)
+{
+	struct iot2050_info *info = IOT2050_INFO_DATA;
+	u8 __maybe_unused mac_cnt;
+	const char *fdtfile;
+
+	if (info->magic != IOT2050_INFO_MAGIC) {
+		pr_err("IOT2050: Board info parsing error!\n");
+		return;
+	}
+
+	if (env_get("board_uuid"))
+		return;
+
+	env_set("board_name", info->name);
+	env_set("board_serial", info->serial);
+	env_set("mlfb", info->mlfb);
+	env_set("board_uuid", info->uuid);
+	env_set("board_a5e", info->a5e);
+	env_set("fw_version", PLAIN_VERSION);
+	env_set("seboot_version", info->seboot_version);
+
+	if (IS_ENABLED(CONFIG_NET)) {
+		/* set MAC addresses to ensure forwarding to the OS */
+		for (mac_cnt = 0; mac_cnt < info->mac_addr_cnt; mac_cnt++) {
+			if (is_valid_ethaddr(info->mac_addr[mac_cnt]))
+				eth_env_set_enetaddr_by_index("eth",
+							      mac_cnt + 1,
+							      info->mac_addr[mac_cnt]);
+		}
+	}
+
+	if (board_is_advanced()) {
+		if (board_is_sr1())
+			fdtfile = "ti/k3-am6548-iot2050-advanced.dtb";
+		else
+			fdtfile = "ti/k3-am6548-iot2050-advanced-pg2.dtb";
+	} else {
+		if (board_is_sr1())
+			fdtfile = "ti/k3-am6528-iot2050-basic.dtb";
+		else
+			fdtfile = "ti/k3-am6528-iot2050-basic-pg2.dtb";
+		/* remove the unavailable eMMC (mmc1) from the list */
+		remove_mmc1_target();
+	}
+	env_set("fdtfile", fdtfile);
+
+	env_save();
+}
+
+int board_init(void)
+{
+	return 0;
+}
+
+int dram_init(void)
+{
+	if (board_is_advanced())
+		gd->ram_size = SZ_2G;
+	else
+		gd->ram_size = SZ_1G;
+
+	return 0;
+}
+
+int dram_init_banksize(void)
+{
+	dram_init();
+
+	/* Bank 0 declares the memory available in the DDR low region */
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+	gd->bd->bi_dram[0].size = gd->ram_size;
+
+	/* Bank 1 declares the memory available in the DDR high region */
+	gd->bd->bi_dram[1].start = 0;
+	gd->bd->bi_dram[1].size = 0;
+
+	return 0;
+}
+
+#ifdef CONFIG_SPL_LOAD_FIT
+int board_fit_config_name_match(const char *name)
+{
+	struct iot2050_info *info = IOT2050_INFO_DATA;
+	char upper_name[32];
+
+	if (info->magic != IOT2050_INFO_MAGIC ||
+	    strlen(name) >= sizeof(upper_name))
+		return -1;
+
+	str_to_upper(name, upper_name, sizeof(upper_name));
+	if (!strcmp(upper_name, (char *)info->name))
+		return 0;
+
+	return -1;
+}
+#endif
+
+int do_board_detect(void)
+{
+	return 0;
+}
+
+#ifdef CONFIG_IOT2050_BOOT_SWITCH
+static bool user_button_pressed(void)
+{
+	struct udevice *red_led = NULL;
+	unsigned long count = 0;
+	struct gpio_desc gpio;
+
+	memset(&gpio, 0, sizeof(gpio));
+
+	if (dm_gpio_lookup_name("25", &gpio) < 0 ||
+	    dm_gpio_request(&gpio, "USER button") < 0 ||
+	    dm_gpio_set_dir_flags(&gpio, GPIOD_IS_IN) < 0)
+		return false;
+
+	if (dm_gpio_get_value(&gpio) == 1)
+		return false;
+
+	printf("USER button pressed - booting from external media only\n");
+
+	led_get_by_label("status-led-red", &red_led);
+
+	if (red_led)
+		led_set_state(red_led, LEDST_ON);
+
+	while (dm_gpio_get_value(&gpio) == 0 && count++ < 10000)
+		mdelay(1);
+
+	if (red_led)
+		led_set_state(red_led, LEDST_OFF);
+
+	return true;
+}
+#endif
+
+#define SERDES0_LANE_SELECT	0x00104080
+
+int board_late_init(void)
+{
+	/* change CTRL_MMR register to let serdes0 not output USB3.0 signals. */
+	writel(0x3, SERDES0_LANE_SELECT);
+
+	set_board_info_env();
+
+	/* remove the eMMC if requested via button */
+	if (IS_ENABLED(CONFIG_IOT2050_BOOT_SWITCH) && board_is_advanced() &&
+	    user_button_pressed())
+		remove_mmc1_target();
+
+	return 0;
+}
+
+#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+	int ret;
+
+	ret = fdt_fixup_msmc_ram(blob, "/bus@100000", "sram@70000000");
+	if (ret < 0)
+		ret = fdt_fixup_msmc_ram(blob, "/interconnect@100000",
+					 "sram@70000000");
+	if (ret)
+		pr_err("%s: fixing up msmc ram failed %d\n", __func__, ret);
+
+	return ret;
+}
+#endif
+
+void spl_board_init(void)
+{
+}
+
+#if CONFIG_IS_ENABLED(LED) && CONFIG_IS_ENABLED(BOOTSTAGE)
+/*
+ * Indicate any error or (accidental?) entering of CLI via the red status LED.
+ */
+void show_boot_progress(int progress)
+{
+	struct udevice *dev;
+	int ret;
+
+	if (progress < 0 || progress == BOOTSTAGE_ID_ENTER_CLI_LOOP) {
+		ret = led_get_by_label("status-led-green", &dev);
+		if (ret == 0)
+			led_set_state(dev, LEDST_OFF);
+
+		ret = led_get_by_label("status-led-red", &dev);
+		if (ret == 0)
+			led_set_state(dev, LEDST_ON);
+	}
+}
+#endif
diff --git a/board/siemens/iot2050/config.mk b/board/siemens/iot2050/config.mk
new file mode 100644
index 0000000000..267ec76c4e
--- /dev/null
+++ b/board/siemens/iot2050/config.mk
@@ -0,0 +1,8 @@ 
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) Siemens AG, 2020-2021
+#
+# Authors:
+#   Jan Kiszka <jan.kiszka@siemens.com>
+
+flash.bin: all
diff --git a/configs/iot2050_defconfig b/configs/iot2050_defconfig
new file mode 100644
index 0000000000..b5c5fd7ac1
--- /dev/null
+++ b/configs/iot2050_defconfig
@@ -0,0 +1,130 @@ 
+CONFIG_ARM=y
+CONFIG_ARCH_K3=y
+CONFIG_SPL_GPIO=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_SOC_K3_AM6=y
+CONFIG_TARGET_IOT2050_A53=y
+CONFIG_ENV_SIZE=0x20000
+CONFIG_ENV_OFFSET=0x680000
+CONFIG_ENV_SECT_SIZE=0x20000
+CONFIG_DM_GPIO=y
+CONFIG_SPL_DM_SPI=y
+CONFIG_DEFAULT_DEVICE_TREE="k3-am6528-iot2050-basic"
+CONFIG_SPL_TEXT_BASE=0x80080000
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_STACK_R_ADDR=0x82000000
+CONFIG_ENV_OFFSET_REDUND=0x6a0000
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_DISTRO_DEFAULTS=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_LOAD_FIT=y
+# CONFIG_USE_SPL_FIT_GENERATOR is not set
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_BOOTSTAGE=y
+CONFIG_CONSOLE_MUX=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
+CONFIG_SPL_DM_MAILBOX=y
+CONFIG_SPL_DM_SPI_FLASH=y
+CONFIG_SPL_DM_RESET=y
+CONFIG_SPL_POWER_DOMAIN=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000
+CONFIG_SYS_PROMPT="IOT2050> "
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_DFU=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=y
+# CONFIG_ISO_PARTITION is not set
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIST="k3-am6528-iot2050-basic k3-am6548-iot2050-advanced"
+CONFIG_SPL_MULTI_DTB_FIT=y
+CONFIG_SPL_OF_LIST="k3-am65-iot2050-spl"
+CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
+CONFIG_DM=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_CLK_TI_SCI=y
+CONFIG_DFU_MMC=y
+CONFIG_DFU_RAM=y
+CONFIG_DFU_SF=y
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
+CONFIG_TI_SCI_PROTOCOL=y
+CONFIG_DA8XX_GPIO=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_I2C=y
+CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
+CONFIG_SYS_I2C_OMAP24XX=y
+CONFIG_LED=y
+CONFIG_SPL_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_SPL_LED_GPIO=y
+CONFIG_DM_MAILBOX=y
+CONFIG_K3_SEC_PROXY=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_AM654=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_DM_ETH=y
+CONFIG_PCI=y
+CONFIG_PCI_KEYSTONE=y
+CONFIG_PHY=y
+CONFIG_AM654_PHY=y
+CONFIG_OMAP_USB2_PHY=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_GENERIC is not set
+CONFIG_SPL_PINCTRL=y
+# CONFIG_SPL_PINCTRL_GENERIC is not set
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_TI_SCI_POWER_DOMAIN=y
+CONFIG_REMOTEPROC_TI_K3_R5F=y
+CONFIG_DM_RESET=y
+CONFIG_RESET_TI_SCI=y
+CONFIG_DM_SERIAL=y
+CONFIG_SOC_DEVICE=y
+CONFIG_SOC_DEVICE_TI_K3=y
+CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
+CONFIG_SYSRESET=y
+CONFIG_SPL_SYSRESET=y
+CONFIG_SYSRESET_TI_SCI=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/doc/board/index.rst b/doc/board/index.rst
index 33087074fa..df4bc671c5 100644
--- a/doc/board/index.rst
+++ b/doc/board/index.rst
@@ -22,6 +22,7 @@  Board-specific doc
    openpiton/index
    qualcomm/index
    rockchip/index
+   siemens/index
    sifive/index
    sipeed/index
    socionext/index
diff --git a/doc/board/siemens/index.rst b/doc/board/siemens/index.rst
new file mode 100644
index 0000000000..082936ea7e
--- /dev/null
+++ b/doc/board/siemens/index.rst
@@ -0,0 +1,9 @@ 
+.. SPDX-License-Identifier: GPL-2.0+
+
+Siemens
+=======
+
+.. toctree::
+   :maxdepth: 2
+
+   iot2050
diff --git a/doc/board/siemens/iot2050.rst b/doc/board/siemens/iot2050.rst
new file mode 100644
index 0000000000..592c59be03
--- /dev/null
+++ b/doc/board/siemens/iot2050.rst
@@ -0,0 +1,78 @@ 
+.. SPDX-License-Identifier: GPL-2.0+
+.. sectionauthor:: Jan Kiszka <jan.kiszka@siemens.com>
+
+SIMATIC IOT2050 BASIC and ADVANCED
+==================================
+
+The SIMATIC IOT2050 is an open industrial IoT gateway that is using the TI
+AM6528 GP (Basic variant) or the AM6548 HS (Advanced variant). The Advanced
+variant is prepared for secure boot.
+
+The IOT2050 starts only from OSPI. It loads a Siemens-provided bootloader
+called SE-Boot for the MCU domain (R5F cores), then hands over to ATF and
+OP-TEE, before booting U-Boot on the A53 cores. This describes how to build all
+open artifacts into a flashable image for the OSPI flash. The flash image will
+work on both variants.
+
+Dependencies
+------------
+
+ATF:    Upstream release 2.4 or newer
+OP-TEE: Upstream release 3.10.0 or newer
+
+Binary dependencies can be found in
+https://github.com/siemens/meta-iot2050/tree/master/recipes-bsp/u-boot/files/prebuild.
+The following binaries from that source need to be present in the build folder:
+
+ - tiboot3.bin
+ - sysfw.itb
+ - sysfw.itb_HS
+ - sysfw_sr2.itb
+ - sysfw_sr2.itb_HS
+
+Building
+--------
+
+Make sure that CROSS_COMPILE is set appropriately:
+
+.. code-block:: text
+
+ $ export CROSS_COMPILE=aarch64-linux-gnu-
+
+ATF:
+
+.. code-block:: text
+
+ $ make PLAT=k3 SPD=opteed K3_USART=1
+
+OP-TEE:
+
+.. code-block:: text
+
+ $ make PLATFORM=k3-am65x CFG_ARM64_core=y CFG_TEE_CORE_LOG_LEVEL=2 CFG_CONSOLE_UART=1
+
+U-Boot:
+
+.. code-block:: text
+
+ $ export ATF=/path/to/bl31.bin
+ $ export TEE=/path/to/tee-pager_v2.bin
+ $ make iot2050_defconfig
+ $ make
+
+Flashing
+--------
+
+Via U-Boot:
+
+.. code-block:: text
+
+ IOT2050> sf probe
+ IOT2050> load mmc 0:1 $loadaddr /path/to/flash.bin
+ IOT2050> sf update $loadaddr 0x0 $filesize
+
+Via external programmer Dediprog SF100 or SF600:
+
+.. code-block:: text
+
+ $ dpcmd --vcc 2 -v -u flash.bin
diff --git a/include/configs/iot2050.h b/include/configs/iot2050.h
new file mode 100644
index 0000000000..ddb4cfcc8e
--- /dev/null
+++ b/include/configs/iot2050.h
@@ -0,0 +1,62 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Configuration header file for IOT2050
+ * Copyright (c) Siemens AG, 2018-2021
+ *
+ * Authors:
+ *   Le Jin <le.jin@siemens.com>
+ *   Jan Kiszka <jan.kiszka@siemens.com>
+ */
+
+#ifndef __CONFIG_IOT2050_H
+#define __CONFIG_IOT2050_H
+
+#include <linux/sizes.h>
+
+/* SPL Loader Configuration */
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SPL_TEXT_BASE + \
+					 CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE)
+
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+#define CONFIG_SPL_MAX_SIZE		CONFIG_SYS_K3_MAX_DOWNLODABLE_IMAGE_SIZE
+
+#define CONFIG_SYS_BOOTM_LEN		SZ_64M
+
+/* U-Boot general configuration */
+#define EXTRA_ENV_IOT2050_BOARD_SETTINGS				\
+	"usb_pgood_delay=900\0"
+
+#ifndef CONFIG_SPL_BUILD
+
+#if CONFIG_IS_ENABLED(CMD_USB)
+# define BOOT_TARGET_USB(func) \
+	func(USB, usb, 0) \
+	func(USB, usb, 1) \
+	func(USB, usb, 2)
+#else
+# define BOOT_TARGET_USB(func)
+#endif
+
+/*
+ * This defines all MMC devices, even if the basic variant has no mmc1.
+ * The non-supported device will be removed from the boot targets during
+ * runtime, when that board was detected.
+ */
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 1) \
+	func(MMC, mmc, 0) \
+	BOOT_TARGET_USB(func)
+
+#include <config_distro_bootcmd.h>
+
+#endif
+
+#define CONFIG_EXTRA_ENV_SETTINGS					\
+	DEFAULT_LINUX_BOOT_ENV						\
+	BOOTENV								\
+	EXTRA_ENV_IOT2050_BOARD_SETTINGS
+
+#include <configs/ti_armv7_common.h>
+
+#endif /* __CONFIG_IOT2050_H */