From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001
From: Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com>
Date: Tue, 10 Oct 2023 14:33:42 +0000
Subject: Add submodule dependency files

Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
---
 roms/u-boot/board/st/stm32mp1/Kconfig              |  13 +
 roms/u-boot/board/st/stm32mp1/MAINTAINERS          |  10 +
 roms/u-boot/board/st/stm32mp1/Makefile             |  10 +
 roms/u-boot/board/st/stm32mp1/README               |   1 +
 roms/u-boot/board/st/stm32mp1/extlinux.conf        |  20 +
 .../board/st/stm32mp1/fit_copro_kernel_dtb.its     | 117 +++
 roms/u-boot/board/st/stm32mp1/fit_kernel_dtb.its   |  82 ++
 roms/u-boot/board/st/stm32mp1/spl.c                |  55 ++
 roms/u-boot/board/st/stm32mp1/stm32mp1.c           | 916 +++++++++++++++++++++
 9 files changed, 1224 insertions(+)
 create mode 100644 roms/u-boot/board/st/stm32mp1/Kconfig
 create mode 100644 roms/u-boot/board/st/stm32mp1/MAINTAINERS
 create mode 100644 roms/u-boot/board/st/stm32mp1/Makefile
 create mode 100644 roms/u-boot/board/st/stm32mp1/README
 create mode 100644 roms/u-boot/board/st/stm32mp1/extlinux.conf
 create mode 100644 roms/u-boot/board/st/stm32mp1/fit_copro_kernel_dtb.its
 create mode 100644 roms/u-boot/board/st/stm32mp1/fit_kernel_dtb.its
 create mode 100644 roms/u-boot/board/st/stm32mp1/spl.c
 create mode 100644 roms/u-boot/board/st/stm32mp1/stm32mp1.c

(limited to 'roms/u-boot/board/st/stm32mp1')

diff --git a/roms/u-boot/board/st/stm32mp1/Kconfig b/roms/u-boot/board/st/stm32mp1/Kconfig
new file mode 100644
index 000000000..c5ab7553d
--- /dev/null
+++ b/roms/u-boot/board/st/stm32mp1/Kconfig
@@ -0,0 +1,13 @@
+if TARGET_ST_STM32MP15x
+
+config SYS_BOARD
+	default "stm32mp1"
+
+config SYS_VENDOR
+	default "st"
+
+config SYS_CONFIG_NAME
+	default "stm32mp1"
+
+source "board/st/common/Kconfig"
+endif
diff --git a/roms/u-boot/board/st/stm32mp1/MAINTAINERS b/roms/u-boot/board/st/stm32mp1/MAINTAINERS
new file mode 100644
index 000000000..fe8fc6f48
--- /dev/null
+++ b/roms/u-boot/board/st/stm32mp1/MAINTAINERS
@@ -0,0 +1,10 @@
+STM32MP1 BOARD
+M:	Patrick Delaunay <patrick.delaunay@foss.st.com>
+L:	uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers)
+T:	git https://source.denx.de/u-boot/custodians/u-boot-stm.git
+S:	Maintained
+F:	arch/arm/dts/stm32mp15*
+F:	board/st/stm32mp1/
+F:	configs/stm32mp15_basic_defconfig
+F:	configs/stm32mp15_trusted_defconfig
+F:	include/configs/stm32mp1.h
diff --git a/roms/u-boot/board/st/stm32mp1/Makefile b/roms/u-boot/board/st/stm32mp1/Makefile
new file mode 100644
index 000000000..65560df29
--- /dev/null
+++ b/roms/u-boot/board/st/stm32mp1/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+#
+# Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+#
+
+ifdef CONFIG_SPL_BUILD
+obj-y += spl.o
+else
+obj-y += stm32mp1.o
+endif
diff --git a/roms/u-boot/board/st/stm32mp1/README b/roms/u-boot/board/st/stm32mp1/README
new file mode 100644
index 000000000..8172d26a6
--- /dev/null
+++ b/roms/u-boot/board/st/stm32mp1/README
@@ -0,0 +1 @@
+see doc/board/st/stm32mp1.rst
diff --git a/roms/u-boot/board/st/stm32mp1/extlinux.conf b/roms/u-boot/board/st/stm32mp1/extlinux.conf
new file mode 100644
index 000000000..2b4632804
--- /dev/null
+++ b/roms/u-boot/board/st/stm32mp1/extlinux.conf
@@ -0,0 +1,20 @@
+# Generic Distro Configuration for STM32MP157
+menu title Select the boot mode
+TIMEOUT 20
+DEFAULT stm32mp157c-ev1
+
+LABEL stm32mp157c-ev1
+	KERNEL /fit_kernel_dtb.itb#ev1
+	APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttyS3,115200
+
+LABEL stm32mp157c-ev1-m4
+	KERNEL /fit_copro_kernel_dtb.itb#ev1-m4
+	APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttyS3,115200
+
+LABEL stm32mp157c-dk2
+	KERNEL /fit_kernel_dtb.itb#dk2
+	APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttyS3,115200
+
+LABEL stm32mp157c-dk2-m4
+	KERNEL /fit_copro_kernel_dtb.itb#dk2-m4
+	APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttyS3,115200
diff --git a/roms/u-boot/board/st/stm32mp1/fit_copro_kernel_dtb.its b/roms/u-boot/board/st/stm32mp1/fit_copro_kernel_dtb.its
new file mode 100644
index 000000000..dc43639af
--- /dev/null
+++ b/roms/u-boot/board/st/stm32mp1/fit_copro_kernel_dtb.its
@@ -0,0 +1,117 @@
+/*
+ * Compilation:
+ * mkimage -f fit_copro_kernel_dtb.its fit_copro_kernel_dtb.itb
+ *
+ * M4 firmware to load with remoteproc: rproc-m4-fw.elf
+ *
+ * Files in linux build dir:
+ * - arch/arm/boot/zImage
+ * - arch/arm/boot/dts/stm32mp157c-dk2.dtb
+ * - arch/arm/boot/dts/stm32mp157c-ev1.dtb
+ *
+ * load mmc 0:4 $kernel_addr_r fit_copro_kernel_dtb.itb
+ * bootm $kernel_addr_r
+ * bootm $kernel_addr_r#dk2
+ * bootm $kernel_addr_r#ev1
+ * bootm $kernel_addr_r#dk2-m4
+ * bootm $kernel_addr_r#ev1-m4
+ */
+
+/dts-v1/;
+/ {
+	description = "U-Boot fitImage for stm32mp157";
+	#address-cells = <1>;
+
+	images {
+
+		copro {
+			description = "M4 copro";
+			data = /incbin/("rproc-m4-fw.elf");
+			type = "copro";
+			arch = "arm";
+			compression = "none";
+			load = <0xC0800000>;
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+
+		kernel {
+			description = "Linux kernel";
+			data = /incbin/("zImage");
+			type = "kernel";
+			arch = "arm";
+			os = "linux";
+			compression = "none";
+			load = <0xC4000000>;
+			entry = <0xC4000000>;
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+
+		fdt-dk2 {
+			description = "FDT dk2";
+			data = /incbin/("stm32mp157c-dk2.dtb");
+			type = "flat_dt";
+			arch = "arm";
+			compression = "none";
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+
+		fdt-ev1 {
+			description = "FDT ev1";
+			data = /incbin/("stm32mp157c-ev1.dtb");
+			type = "flat_dt";
+			arch = "arm";
+			compression = "none";
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+	};
+
+	configurations {
+		default = "dk2-m4";
+
+		dk2-m4 {
+			description = "dk2-m4";
+			loadables = "copro";
+			kernel = "kernel";
+			fdt = "fdt-dk2";
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+
+		dk2 {
+			description = "dk2";
+			kernel = "kernel";
+			fdt = "fdt-dk2";
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+
+		ev1-m4 {
+			description = "ev1-m4";
+			loadables = "copro";
+			kernel = "kernel";
+			fdt = "fdt-ev1";
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+
+		ev1 {
+			description = "ev1";
+			kernel = "kernel";
+			fdt = "fdt-ev1";
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+	};
+};
diff --git a/roms/u-boot/board/st/stm32mp1/fit_kernel_dtb.its b/roms/u-boot/board/st/stm32mp1/fit_kernel_dtb.its
new file mode 100644
index 000000000..8456a3c46
--- /dev/null
+++ b/roms/u-boot/board/st/stm32mp1/fit_kernel_dtb.its
@@ -0,0 +1,82 @@
+/*
+ * Compilation:
+ * mkimage -f fit_kernel_dtb.its fit_kernel_dtb.itb
+ *
+ * Files in linux build dir:
+ * - arch/arm/boot/Image (gzipped in Image.gz)
+ * - arch/arm/boot/dts/stm32mp157c-dk2.dtb
+ * - arch/arm/boot/dts/stm32mp157c-ev1.dtb
+ *
+ * load mmc 0:4 $kernel_addr_r fit_kernel_dtb.itb
+ * bootm $kernel_addr_r
+ * bootm $kernel_addr_r#dk2
+ * bootm $kernel_addr_r#ev1
+ *
+ * or use extlinux.conf in this directory
+ */
+
+/dts-v1/;
+/ {
+	description = "U-Boot fitImage for stm32mp157";
+	#address-cells = <1>;
+
+	images {
+		kernel {
+			description = "Linux kernel";
+			data = /incbin/("Image.gz");
+			type = "kernel";
+			arch = "arm";
+			os = "linux";
+			compression = "gzip";
+			load = <0xC0008000>;
+			entry = <0xC0008000>;
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+
+		fdt-dk2 {
+			description = "FDT dk2";
+			data = /incbin/("stm32mp157c-dk2.dtb");
+			type = "flat_dt";
+			arch = "arm";
+			compression = "none";
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+
+		fdt-ev1 {
+			description = "FDT ev1";
+			data = /incbin/("stm32mp157c-ev1.dtb");
+			type = "flat_dt";
+			arch = "arm";
+			compression = "none";
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+	};
+
+	configurations {
+		default = "dk2";
+
+		dk2 {
+			description = "dk2";
+			kernel = "kernel";
+			fdt = "fdt-dk2";
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+
+		ev1 {
+			description = "ev1";
+			kernel = "kernel";
+			fdt = "fdt-ev1";
+			hash-1 {
+				algo = "sha1";
+			};
+		};
+	};
+};
diff --git a/roms/u-boot/board/st/stm32mp1/spl.c b/roms/u-boot/board/st/stm32mp1/spl.c
new file mode 100644
index 000000000..a6a41780c
--- /dev/null
+++ b/roms/u-boot/board/st/stm32mp1/spl.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#include <config.h>
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include "../common/stpmic1.h"
+
+/* board early initialisation in board_f: need to use global variable */
+static u32 opp_voltage_mv __section(".data");
+
+void board_vddcore_init(u32 voltage_mv)
+{
+	if (IS_ENABLED(CONFIG_PMIC_STPMIC1) && CONFIG_IS_ENABLED(POWER_SUPPORT))
+		opp_voltage_mv = voltage_mv;
+}
+
+int board_early_init_f(void)
+{
+	if (IS_ENABLED(CONFIG_PMIC_STPMIC1) && CONFIG_IS_ENABLED(POWER_SUPPORT))
+		stpmic1_init(opp_voltage_mv);
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+#if (CONFIG_DEBUG_UART_BASE == STM32_UART4_BASE)
+
+#define RCC_MP_APB1ENSETR (STM32_RCC_BASE + 0x0A00)
+#define RCC_MP_AHB4ENSETR (STM32_RCC_BASE + 0x0A28)
+
+	/* UART4 clock enable */
+	setbits_le32(RCC_MP_APB1ENSETR, BIT(16));
+
+#define GPIOG_BASE 0x50008000
+	/* GPIOG clock enable */
+	writel(BIT(6), RCC_MP_AHB4ENSETR);
+	/* GPIO configuration for ST boards: Uart4 TX = G11 */
+	writel(0xffbfffff, GPIOG_BASE + 0x00);
+	writel(0x00006000, GPIOG_BASE + 0x24);
+#else
+
+#error("CONFIG_DEBUG_UART_BASE: not supported value")
+
+#endif
+}
+#endif
diff --git a/roms/u-boot/board/st/stm32mp1/stm32mp1.c b/roms/u-boot/board/st/stm32mp1/stm32mp1.c
new file mode 100644
index 000000000..261ec15e1
--- /dev/null
+++ b/roms/u-boot/board/st/stm32mp1/stm32mp1.c
@@ -0,0 +1,916 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#define LOG_CATEGORY LOGC_BOARD
+
+#include <common.h>
+#include <adc.h>
+#include <bootm.h>
+#include <clk.h>
+#include <config.h>
+#include <dm.h>
+#include <env.h>
+#include <env_internal.h>
+#include <fdt_support.h>
+#include <g_dnl.h>
+#include <generic-phy.h>
+#include <hang.h>
+#include <i2c.h>
+#include <init.h>
+#include <led.h>
+#include <log.h>
+#include <malloc.h>
+#include <misc.h>
+#include <mtd_node.h>
+#include <net.h>
+#include <netdev.h>
+#include <phy.h>
+#include <remoteproc.h>
+#include <reset.h>
+#include <syscon.h>
+#include <usb.h>
+#include <watchdog.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/stm32.h>
+#include <asm/arch/sys_proto.h>
+#include <jffs2/load_kernel.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <power/regulator.h>
+#include <usb/dwc2_udc.h>
+
+#include "../../st/common/stusb160x.h"
+
+/* SYSCFG registers */
+#define SYSCFG_BOOTR		0x00
+#define SYSCFG_PMCSETR		0x04
+#define SYSCFG_IOCTRLSETR	0x18
+#define SYSCFG_ICNR		0x1C
+#define SYSCFG_CMPCR		0x20
+#define SYSCFG_CMPENSETR	0x24
+#define SYSCFG_PMCCLRR		0x44
+
+#define SYSCFG_BOOTR_BOOT_MASK		GENMASK(2, 0)
+#define SYSCFG_BOOTR_BOOTPD_SHIFT	4
+
+#define SYSCFG_IOCTRLSETR_HSLVEN_TRACE		BIT(0)
+#define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI	BIT(1)
+#define SYSCFG_IOCTRLSETR_HSLVEN_ETH		BIT(2)
+#define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC		BIT(3)
+#define SYSCFG_IOCTRLSETR_HSLVEN_SPI		BIT(4)
+
+#define SYSCFG_CMPCR_SW_CTRL		BIT(1)
+#define SYSCFG_CMPCR_READY		BIT(8)
+
+#define SYSCFG_CMPENSETR_MPU_EN		BIT(0)
+
+#define SYSCFG_PMCSETR_ETH_CLK_SEL	BIT(16)
+#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL	BIT(17)
+
+#define SYSCFG_PMCSETR_ETH_SELMII	BIT(20)
+
+#define SYSCFG_PMCSETR_ETH_SEL_MASK	GENMASK(23, 21)
+#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII	0
+#define SYSCFG_PMCSETR_ETH_SEL_RGMII	BIT(21)
+#define SYSCFG_PMCSETR_ETH_SEL_RMII	BIT(23)
+
+/*
+ * Get a global data pointer
+ */
+DECLARE_GLOBAL_DATA_PTR;
+
+#define USB_LOW_THRESHOLD_UV		200000
+#define USB_WARNING_LOW_THRESHOLD_UV	660000
+#define USB_START_LOW_THRESHOLD_UV	1230000
+#define USB_START_HIGH_THRESHOLD_UV	2150000
+
+int board_early_init_f(void)
+{
+	/* nothing to do, only used in SPL */
+	return 0;
+}
+
+int checkboard(void)
+{
+	int ret;
+	char *mode;
+	u32 otp;
+	struct udevice *dev;
+	const char *fdt_compat;
+	int fdt_compat_len;
+
+	if (IS_ENABLED(CONFIG_TFABOOT))
+		mode = "trusted";
+	else
+		mode = "basic";
+
+	fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
+				 &fdt_compat_len);
+
+	log_info("Board: stm32mp1 in %s mode (%s)\n", mode,
+		 fdt_compat && fdt_compat_len ? fdt_compat : "");
+
+	/* display the STMicroelectronics board identification */
+	if (CONFIG_IS_ENABLED(CMD_STBOARD)) {
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_DRIVER_GET(stm32mp_bsec),
+						  &dev);
+		if (!ret)
+			ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
+					&otp, sizeof(otp));
+		if (ret > 0 && otp)
+			log_info("Board: MB%04x Var%d.%d Rev.%c-%02d\n",
+				 otp >> 16,
+				 (otp >> 12) & 0xF,
+				 (otp >> 4) & 0xF,
+				 ((otp >> 8) & 0xF) - 1 + 'A',
+				 otp & 0xF);
+	}
+
+	return 0;
+}
+
+static void board_key_check(void)
+{
+	ofnode node;
+	struct gpio_desc gpio;
+	enum forced_boot_mode boot_mode = BOOT_NORMAL;
+
+	if (!IS_ENABLED(CONFIG_FASTBOOT) && !IS_ENABLED(CONFIG_CMD_STM32PROG))
+		return;
+
+	node = ofnode_path("/config");
+	if (!ofnode_valid(node)) {
+		log_debug("no /config node?\n");
+		return;
+	}
+	if (IS_ENABLED(CONFIG_FASTBOOT)) {
+		if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0,
+					       &gpio, GPIOD_IS_IN)) {
+			log_debug("could not find a /config/st,fastboot-gpios\n");
+		} else {
+			if (dm_gpio_get_value(&gpio)) {
+				log_notice("Fastboot key pressed, ");
+				boot_mode = BOOT_FASTBOOT;
+			}
+
+			dm_gpio_free(NULL, &gpio);
+		}
+	}
+	if (IS_ENABLED(CONFIG_CMD_STM32PROG)) {
+		if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0,
+					       &gpio, GPIOD_IS_IN)) {
+			log_debug("could not find a /config/st,stm32prog-gpios\n");
+		} else {
+			if (dm_gpio_get_value(&gpio)) {
+				log_notice("STM32Programmer key pressed, ");
+				boot_mode = BOOT_STM32PROG;
+			}
+			dm_gpio_free(NULL, &gpio);
+		}
+	}
+	if (boot_mode != BOOT_NORMAL) {
+		log_notice("entering download mode...\n");
+		clrsetbits_le32(TAMP_BOOT_CONTEXT,
+				TAMP_BOOT_FORCED_MASK,
+				boot_mode);
+	}
+}
+
+int g_dnl_board_usb_cable_connected(void)
+{
+	struct udevice *dwc2_udc_otg;
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_USB_GADGET_DWC2_OTG))
+		return -ENODEV;
+
+	/* if typec stusb160x is present, means DK1 or DK2 board */
+	ret = stusb160x_cable_connected();
+	if (ret >= 0)
+		return ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_USB_GADGET_GENERIC,
+					  DM_DRIVER_GET(dwc2_udc_otg),
+					  &dwc2_udc_otg);
+	if (ret) {
+		log_debug("dwc2_udc_otg init failed\n");
+		return ret;
+	}
+
+	return dwc2_udc_B_session_valid(dwc2_udc_otg);
+}
+
+#ifdef CONFIG_USB_GADGET_DOWNLOAD
+#define STM32MP1_G_DNL_DFU_PRODUCT_NUM 0xdf11
+#define STM32MP1_G_DNL_FASTBOOT_PRODUCT_NUM 0x0afb
+
+int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
+{
+	if (IS_ENABLED(CONFIG_DFU_OVER_USB) &&
+	    !strcmp(name, "usb_dnl_dfu"))
+		put_unaligned(STM32MP1_G_DNL_DFU_PRODUCT_NUM, &dev->idProduct);
+	else if (IS_ENABLED(CONFIG_FASTBOOT) &&
+		 !strcmp(name, "usb_dnl_fastboot"))
+		put_unaligned(STM32MP1_G_DNL_FASTBOOT_PRODUCT_NUM,
+			      &dev->idProduct);
+	else
+		put_unaligned(CONFIG_USB_GADGET_PRODUCT_NUM, &dev->idProduct);
+
+	return 0;
+}
+#endif /* CONFIG_USB_GADGET_DOWNLOAD */
+
+static int get_led(struct udevice **dev, char *led_string)
+{
+	char *led_name;
+	int ret;
+
+	led_name = fdtdec_get_config_string(gd->fdt_blob, led_string);
+	if (!led_name) {
+		log_debug("could not find %s config string\n", led_string);
+		return -ENOENT;
+	}
+	ret = led_get_by_label(led_name, dev);
+	if (ret) {
+		log_debug("get=%d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int setup_led(enum led_state_t cmd)
+{
+	struct udevice *dev;
+	int ret;
+
+	if (!CONFIG_IS_ENABLED(LED))
+		return 0;
+
+	ret = get_led(&dev, "u-boot,boot-led");
+	if (ret)
+		return ret;
+
+	ret = led_set_state(dev, cmd);
+	return ret;
+}
+
+static void __maybe_unused led_error_blink(u32 nb_blink)
+{
+	int ret;
+	struct udevice *led;
+	u32 i;
+
+	if (!nb_blink)
+		return;
+
+	if (CONFIG_IS_ENABLED(LED)) {
+		ret = get_led(&led, "u-boot,error-led");
+		if (!ret) {
+			/* make u-boot,error-led blinking */
+			/* if U32_MAX and 125ms interval, for 17.02 years */
+			for (i = 0; i < 2 * nb_blink; i++) {
+				led_set_state(led, LEDST_TOGGLE);
+				mdelay(125);
+				WATCHDOG_RESET();
+			}
+			led_set_state(led, LEDST_ON);
+		}
+	}
+
+	/* infinite: the boot process must be stopped */
+	if (nb_blink == U32_MAX)
+		hang();
+}
+
+static int adc_measurement(ofnode node, int adc_count, int *min_uV, int *max_uV)
+{
+	struct ofnode_phandle_args adc_args;
+	struct udevice *adc;
+	unsigned int raw;
+	int ret, uV;
+	int i;
+
+	for (i = 0; i < adc_count; i++) {
+		if (ofnode_parse_phandle_with_args(node, "st,adc_usb_pd",
+						   "#io-channel-cells", 0, i,
+						   &adc_args)) {
+			log_debug("can't find /config/st,adc_usb_pd\n");
+			return 0;
+		}
+
+		ret = uclass_get_device_by_ofnode(UCLASS_ADC, adc_args.node,
+						  &adc);
+
+		if (ret) {
+			log_err("Can't get adc device(%d)\n", ret);
+			return ret;
+		}
+
+		ret = adc_channel_single_shot(adc->name, adc_args.args[0],
+					      &raw);
+		if (ret) {
+			log_err("single shot failed for %s[%d]!\n",
+				adc->name, adc_args.args[0]);
+			return ret;
+		}
+		/* Convert to uV */
+		if (!adc_raw_to_uV(adc, raw, &uV)) {
+			if (uV > *max_uV)
+				*max_uV = uV;
+			if (uV < *min_uV)
+				*min_uV = uV;
+			log_debug("%s[%02d] = %u, %d uV\n",
+				  adc->name, adc_args.args[0], raw, uV);
+		} else {
+			log_err("Can't get uV value for %s[%d]\n",
+				adc->name, adc_args.args[0]);
+		}
+	}
+
+	return 0;
+}
+
+static int board_check_usb_power(void)
+{
+	ofnode node;
+	int max_uV = 0;
+	int min_uV = USB_START_HIGH_THRESHOLD_UV;
+	int adc_count, ret;
+	u32 nb_blink;
+	u8 i;
+
+	if (!IS_ENABLED(CONFIG_ADC))
+		return -ENODEV;
+
+	node = ofnode_path("/config");
+	if (!ofnode_valid(node)) {
+		log_debug("no /config node?\n");
+		return -ENOENT;
+	}
+
+	/*
+	 * Retrieve the ADC channels devices and get measurement
+	 * for each of them
+	 */
+	adc_count = ofnode_count_phandle_with_args(node, "st,adc_usb_pd",
+						   "#io-channel-cells", 0);
+	if (adc_count < 0) {
+		if (adc_count == -ENOENT)
+			return 0;
+
+		log_err("Can't find adc channel (%d)\n", adc_count);
+
+		return adc_count;
+	}
+
+	/* perform maximum of 2 ADC measurements to detect power supply current */
+	for (i = 0; i < 2; i++) {
+		ret = adc_measurement(node, adc_count, &min_uV, &max_uV);
+		if (ret)
+			return ret;
+
+		/*
+		 * If highest value is inside 1.23 Volts and 2.10 Volts, that means
+		 * board is plugged on an USB-C 3A power supply and boot process can
+		 * continue.
+		 */
+		if (max_uV > USB_START_LOW_THRESHOLD_UV &&
+		    max_uV <= USB_START_HIGH_THRESHOLD_UV &&
+		    min_uV <= USB_LOW_THRESHOLD_UV)
+			return 0;
+
+		if (i == 0) {
+			log_err("Previous ADC measurements was not the one expected, retry in 20ms\n");
+			mdelay(20);  /* equal to max tPDDebounce duration (min 10ms - max 20ms) */
+		}
+	}
+
+	log_notice("****************************************************\n");
+	/*
+	 * If highest and lowest value are either both below
+	 * USB_LOW_THRESHOLD_UV or both above USB_LOW_THRESHOLD_UV, that
+	 * means USB TYPE-C is in unattached mode, this is an issue, make
+	 * u-boot,error-led blinking and stop boot process.
+	 */
+	if ((max_uV > USB_LOW_THRESHOLD_UV &&
+	     min_uV > USB_LOW_THRESHOLD_UV) ||
+	     (max_uV <= USB_LOW_THRESHOLD_UV &&
+	     min_uV <= USB_LOW_THRESHOLD_UV)) {
+		log_notice("* ERROR USB TYPE-C connection in unattached mode   *\n");
+		log_notice("* Check that USB TYPE-C cable is correctly plugged *\n");
+		/* with 125ms interval, led will blink for 17.02 years ....*/
+		nb_blink = U32_MAX;
+	}
+
+	if (max_uV > USB_LOW_THRESHOLD_UV &&
+	    max_uV <= USB_WARNING_LOW_THRESHOLD_UV &&
+	    min_uV <= USB_LOW_THRESHOLD_UV) {
+		log_notice("*        WARNING 500mA power supply detected       *\n");
+		nb_blink = 2;
+	}
+
+	if (max_uV > USB_WARNING_LOW_THRESHOLD_UV &&
+	    max_uV <= USB_START_LOW_THRESHOLD_UV &&
+	    min_uV <= USB_LOW_THRESHOLD_UV) {
+		log_notice("*       WARNING 1.5A power supply detected        *\n");
+		nb_blink = 3;
+	}
+
+	/*
+	 * If highest value is above 2.15 Volts that means that the USB TypeC
+	 * supplies more than 3 Amp, this is not compliant with TypeC specification
+	 */
+	if (max_uV > USB_START_HIGH_THRESHOLD_UV) {
+		log_notice("*      USB TYPE-C charger not compliant with       *\n");
+		log_notice("*                   specification                  *\n");
+		log_notice("****************************************************\n\n");
+		/* with 125ms interval, led will blink for 17.02 years ....*/
+		nb_blink = U32_MAX;
+	} else {
+		log_notice("*     Current too low, use a 3A power supply!      *\n");
+		log_notice("****************************************************\n\n");
+	}
+
+	led_error_blink(nb_blink);
+
+	return 0;
+}
+
+static void sysconf_init(void)
+{
+	u8 *syscfg;
+	struct udevice *pwr_dev;
+	struct udevice *pwr_reg;
+	struct udevice *dev;
+	u32 otp = 0;
+	int ret;
+	u32 bootr, val;
+
+	syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
+
+	/* interconnect update : select master using the port 1 */
+	/* LTDC = AXI_M9 */
+	/* GPU  = AXI_M8 */
+	/* today information is hardcoded in U-Boot */
+	writel(BIT(9), syscfg + SYSCFG_ICNR);
+
+	/* disable Pull-Down for boot pin connected to VDD */
+	bootr = readl(syscfg + SYSCFG_BOOTR);
+	bootr &= ~(SYSCFG_BOOTR_BOOT_MASK << SYSCFG_BOOTR_BOOTPD_SHIFT);
+	bootr |= (bootr & SYSCFG_BOOTR_BOOT_MASK) << SYSCFG_BOOTR_BOOTPD_SHIFT;
+	writel(bootr, syscfg + SYSCFG_BOOTR);
+
+	/* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
+	 * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
+	 * The customer will have to disable this for low frequencies
+	 * or if AFMUX is selected but the function not used, typically for
+	 * TRACE. Otherwise, impact on power consumption.
+	 *
+	 * WARNING:
+	 *   enabling High Speed mode while VDD>2.7V
+	 *   with the OTP product_below_2v5 (OTP 18, BIT 13)
+	 *   erroneously set to 1 can damage the IC!
+	 *   => U-Boot set the register only if VDD < 2.7V (in DT)
+	 *      but this value need to be consistent with board design
+	 */
+	ret = uclass_get_device_by_driver(UCLASS_PMIC,
+					  DM_DRIVER_GET(stm32mp_pwr_pmic),
+					  &pwr_dev);
+	if (!ret && IS_ENABLED(CONFIG_DM_REGULATOR)) {
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_DRIVER_GET(stm32mp_bsec),
+						  &dev);
+		if (ret) {
+			log_err("Can't find stm32mp_bsec driver\n");
+			return;
+		}
+
+		ret = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4);
+		if (ret > 0)
+			otp = otp & BIT(13);
+
+		/* get VDD = vdd-supply */
+		ret = device_get_supply_regulator(pwr_dev, "vdd-supply",
+						  &pwr_reg);
+
+		/* check if VDD is Low Voltage */
+		if (!ret) {
+			if (regulator_get_value(pwr_reg) < 2700000) {
+				writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
+				       SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
+				       SYSCFG_IOCTRLSETR_HSLVEN_ETH |
+				       SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
+				       SYSCFG_IOCTRLSETR_HSLVEN_SPI,
+				       syscfg + SYSCFG_IOCTRLSETR);
+
+				if (!otp)
+					log_err("product_below_2v5=0: HSLVEN protected by HW\n");
+			} else {
+				if (otp)
+					log_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n");
+			}
+		} else {
+			log_debug("VDD unknown");
+		}
+	}
+
+	/* activate automatic I/O compensation
+	 * warning: need to ensure CSI enabled and ready in clock driver
+	 */
+	writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR);
+
+	/* poll until ready (1s timeout) */
+	ret = readl_poll_timeout(syscfg + SYSCFG_CMPCR, val,
+				 val & SYSCFG_CMPCR_READY,
+				 1000000);
+	if (ret) {
+		log_err("SYSCFG: I/O compensation failed, timeout.\n");
+		led_error_blink(10);
+	}
+
+	clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
+}
+
+/* Fix to make I2C1 usable on DK2 for touchscreen usage in kernel */
+static int dk2_i2c1_fix(void)
+{
+	ofnode node;
+	struct gpio_desc hdmi, audio;
+	int ret = 0;
+
+	if (!IS_ENABLED(CONFIG_DM_REGULATOR))
+		return -ENODEV;
+
+	node = ofnode_path("/soc/i2c@40012000/hdmi-transmitter@39");
+	if (!ofnode_valid(node)) {
+		log_debug("no hdmi-transmitter@39 ?\n");
+		return -ENOENT;
+	}
+
+	if (gpio_request_by_name_nodev(node, "reset-gpios", 0,
+				       &hdmi, GPIOD_IS_OUT)) {
+		log_debug("could not find reset-gpios\n");
+		return -ENOENT;
+	}
+
+	node = ofnode_path("/soc/i2c@40012000/cs42l51@4a");
+	if (!ofnode_valid(node)) {
+		log_debug("no cs42l51@4a ?\n");
+		return -ENOENT;
+	}
+
+	if (gpio_request_by_name_nodev(node, "reset-gpios", 0,
+				       &audio, GPIOD_IS_OUT)) {
+		log_debug("could not find reset-gpios\n");
+		return -ENOENT;
+	}
+
+	/* before power up, insure that HDMI and AUDIO IC is under reset */
+	ret = dm_gpio_set_value(&hdmi, 1);
+	if (ret) {
+		log_err("can't set_value for hdmi_nrst gpio");
+		goto error;
+	}
+	ret = dm_gpio_set_value(&audio, 1);
+	if (ret) {
+		log_err("can't set_value for audio_nrst gpio");
+		goto error;
+	}
+
+	/* power-up audio IC */
+	regulator_autoset_by_name("v1v8_audio", NULL);
+
+	/* power-up HDMI IC */
+	regulator_autoset_by_name("v1v2_hdmi", NULL);
+	regulator_autoset_by_name("v3v3_hdmi", NULL);
+
+error:
+	return ret;
+}
+
+static bool board_is_dk2(void)
+{
+	if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) &&
+	    of_machine_is_compatible("st,stm32mp157c-dk2"))
+		return true;
+
+	return false;
+}
+
+static bool board_is_ev1(void)
+{
+	if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) &&
+	    (of_machine_is_compatible("st,stm32mp157a-ev1") ||
+	     of_machine_is_compatible("st,stm32mp157c-ev1") ||
+	     of_machine_is_compatible("st,stm32mp157d-ev1") ||
+	     of_machine_is_compatible("st,stm32mp157f-ev1")))
+		return true;
+
+	return false;
+}
+
+/* touchscreen driver: only used for pincontrol configuration */
+static const struct udevice_id goodix_ids[] = {
+	{ .compatible = "goodix,gt9147", },
+	{ }
+};
+
+U_BOOT_DRIVER(goodix) = {
+	.name		= "goodix",
+	.id		= UCLASS_NOP,
+	.of_match	= goodix_ids,
+};
+
+static void board_ev1_init(void)
+{
+	struct udevice *dev;
+
+	/* configure IRQ line on EV1 for touchscreen before LCD reset */
+	uclass_get_device_by_driver(UCLASS_NOP, DM_DRIVER_GET(goodix), &dev);
+}
+
+/* board dependent setup after realloc */
+int board_init(void)
+{
+	/* address of boot parameters */
+	gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
+
+	if (CONFIG_IS_ENABLED(DM_GPIO_HOG))
+		gpio_hog_probe_all();
+
+	board_key_check();
+
+	if (board_is_ev1())
+		board_ev1_init();
+
+	if (board_is_dk2())
+		dk2_i2c1_fix();
+
+	if (IS_ENABLED(CONFIG_DM_REGULATOR))
+		regulators_enable_boot_on(_DEBUG);
+
+	if (!IS_ENABLED(CONFIG_TFABOOT))
+		sysconf_init();
+
+	if (CONFIG_IS_ENABLED(LED))
+		led_default_state();
+
+	setup_led(LEDST_ON);
+
+	return 0;
+}
+
+int board_late_init(void)
+{
+	const void *fdt_compat;
+	int fdt_compat_len;
+	int ret;
+	u32 otp;
+	struct udevice *dev;
+	char buf[10];
+	char dtb_name[256];
+	int buf_len;
+
+	if (IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)) {
+		fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
+					 &fdt_compat_len);
+		if (fdt_compat && fdt_compat_len) {
+			if (strncmp(fdt_compat, "st,", 3) != 0) {
+				env_set("board_name", fdt_compat);
+			} else {
+				env_set("board_name", fdt_compat + 3);
+
+				buf_len = sizeof(dtb_name);
+				strncpy(dtb_name, fdt_compat + 3, buf_len);
+				buf_len -= strlen(fdt_compat + 3);
+				strncat(dtb_name, ".dtb", buf_len);
+				env_set("fdtfile", dtb_name);
+			}
+		}
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_DRIVER_GET(stm32mp_bsec),
+						  &dev);
+
+		if (!ret)
+			ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
+					&otp, sizeof(otp));
+		if (ret > 0 && otp) {
+			snprintf(buf, sizeof(buf), "0x%04x", otp >> 16);
+			env_set("board_id", buf);
+
+			snprintf(buf, sizeof(buf), "0x%04x",
+				 ((otp >> 8) & 0xF) - 1 + 0xA);
+			env_set("board_rev", buf);
+		}
+	}
+
+	/* for DK1/DK2 boards */
+	board_check_usb_power();
+
+	return 0;
+}
+
+void board_quiesce_devices(void)
+{
+	setup_led(LEDST_OFF);
+}
+
+/* eth init function : weak called in eqos driver */
+int board_interface_eth_init(struct udevice *dev,
+			     phy_interface_t interface_type)
+{
+	u8 *syscfg;
+	u32 value;
+	bool eth_clk_sel_reg = false;
+	bool eth_ref_clk_sel_reg = false;
+
+	/* Gigabit Ethernet 125MHz clock selection. */
+	eth_clk_sel_reg = dev_read_bool(dev, "st,eth_clk_sel");
+
+	/* Ethernet 50Mhz RMII clock selection */
+	eth_ref_clk_sel_reg =
+		dev_read_bool(dev, "st,eth_ref_clk_sel");
+
+	syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
+
+	if (!syscfg)
+		return -ENODEV;
+
+	switch (interface_type) {
+	case PHY_INTERFACE_MODE_MII:
+		value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
+			SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
+		log_debug("PHY_INTERFACE_MODE_MII\n");
+		break;
+	case PHY_INTERFACE_MODE_GMII:
+		if (eth_clk_sel_reg)
+			value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
+				SYSCFG_PMCSETR_ETH_CLK_SEL;
+		else
+			value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII;
+		log_debug("PHY_INTERFACE_MODE_GMII\n");
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		if (eth_ref_clk_sel_reg)
+			value = SYSCFG_PMCSETR_ETH_SEL_RMII |
+				SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
+		else
+			value = SYSCFG_PMCSETR_ETH_SEL_RMII;
+		log_debug("PHY_INTERFACE_MODE_RMII\n");
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		if (eth_clk_sel_reg)
+			value = SYSCFG_PMCSETR_ETH_SEL_RGMII |
+				SYSCFG_PMCSETR_ETH_CLK_SEL;
+		else
+			value = SYSCFG_PMCSETR_ETH_SEL_RGMII;
+		log_debug("PHY_INTERFACE_MODE_RGMII\n");
+		break;
+	default:
+		log_debug("Do not manage %d interface\n",
+			  interface_type);
+		/* Do not manage others interfaces */
+		return -EINVAL;
+	}
+
+	/* clear and set ETH configuration bits */
+	writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII |
+	       SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL,
+	       syscfg + SYSCFG_PMCCLRR);
+	writel(value, syscfg + SYSCFG_PMCSETR);
+
+	return 0;
+}
+
+enum env_location env_get_location(enum env_operation op, int prio)
+{
+	u32 bootmode = get_bootmode();
+
+	if (prio)
+		return ENVL_UNKNOWN;
+
+	switch (bootmode & TAMP_BOOT_DEVICE_MASK) {
+	case BOOT_FLASH_SD:
+	case BOOT_FLASH_EMMC:
+		if (CONFIG_IS_ENABLED(ENV_IS_IN_MMC))
+			return ENVL_MMC;
+		else if (CONFIG_IS_ENABLED(ENV_IS_IN_EXT4))
+			return ENVL_EXT4;
+		else
+			return ENVL_NOWHERE;
+
+	case BOOT_FLASH_NAND:
+	case BOOT_FLASH_SPINAND:
+		if (CONFIG_IS_ENABLED(ENV_IS_IN_UBI))
+			return ENVL_UBI;
+		else
+			return ENVL_NOWHERE;
+
+	case BOOT_FLASH_NOR:
+		if (CONFIG_IS_ENABLED(ENV_IS_IN_SPI_FLASH))
+			return ENVL_SPI_FLASH;
+		else
+			return ENVL_NOWHERE;
+
+	default:
+		return ENVL_NOWHERE;
+	}
+}
+
+const char *env_ext4_get_intf(void)
+{
+	u32 bootmode = get_bootmode();
+
+	switch (bootmode & TAMP_BOOT_DEVICE_MASK) {
+	case BOOT_FLASH_SD:
+	case BOOT_FLASH_EMMC:
+		return "mmc";
+	default:
+		return "";
+	}
+}
+
+const char *env_ext4_get_dev_part(void)
+{
+	static char *const env_dev_part =
+#ifdef CONFIG_ENV_EXT4_DEVICE_AND_PART
+		CONFIG_ENV_EXT4_DEVICE_AND_PART;
+#else
+		"";
+#endif
+	static char *const dev_part[] = {"0:auto", "1:auto", "2:auto"};
+
+	if (strlen(env_dev_part) > 0)
+		return env_dev_part;
+
+	u32 bootmode = get_bootmode();
+
+	return dev_part[(bootmode & TAMP_BOOT_INSTANCE_MASK) - 1];
+}
+
+int mmc_get_env_dev(void)
+{
+	u32 bootmode;
+
+	if (CONFIG_SYS_MMC_ENV_DEV >= 0)
+		return CONFIG_SYS_MMC_ENV_DEV;
+
+	bootmode = get_bootmode();
+
+	/* use boot instance to select the correct mmc device identifier */
+	return (bootmode & TAMP_BOOT_INSTANCE_MASK) - 1;
+}
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+	static const struct node_info nodes[] = {
+		{ "st,stm32f469-qspi",		MTD_DEV_TYPE_NOR,  },
+		{ "st,stm32f469-qspi",		MTD_DEV_TYPE_SPINAND},
+		{ "st,stm32mp15-fmc2",		MTD_DEV_TYPE_NAND, },
+		{ "st,stm32mp1-fmc2-nfc",	MTD_DEV_TYPE_NAND, },
+	};
+	char *boot_device;
+
+	/* Check the boot-source and don't update MTD for serial or usb boot */
+	boot_device = env_get("boot_device");
+	if (!boot_device ||
+	    (strcmp(boot_device, "serial") && strcmp(boot_device, "usb")))
+		if (IS_ENABLED(CONFIG_FDT_FIXUP_PARTITIONS))
+			fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
+
+	return 0;
+}
+#endif
+
+static void board_copro_image_process(ulong fw_image, size_t fw_size)
+{
+	int ret, id = 0; /* Copro id fixed to 0 as only one coproc on mp1 */
+
+	if (!rproc_is_initialized())
+		if (rproc_init()) {
+			log_err("Remote Processor %d initialization failed\n",
+				id);
+			return;
+		}
+
+	ret = rproc_load(id, fw_image, fw_size);
+	log_err("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n",
+		id, fw_image, fw_size, ret ? " Failed!" : " Success!");
+
+	if (!ret)
+		rproc_start(id);
+}
+
+U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process);
-- 
cgit