diff options
Diffstat (limited to 'board/st')
57 files changed, 2944 insertions, 0 deletions
diff --git a/board/st/common/Kconfig b/board/st/common/Kconfig new file mode 100644 index 00000000000..5efac658cf4 --- /dev/null +++ b/board/st/common/Kconfig @@ -0,0 +1,21 @@ +config CMD_STBOARD + bool "stboard - command for OTP board information" + depends on ARCH_STM32MP + default y if TARGET_ST_STM32MP25X || TARGET_ST_STM32MP15X || TARGET_ST_STM32MP13X + help + This compile the stboard command to + read and write the board in the OTP. + +config DFU_ALT_RAM0 + string "dfu for ram0" + default "uImage ram 0xc2000000 0x2000000;devicetree.dtb ram 0xc4000000 0x100000;uramdisk.image.gz ram 0xc4400000 0x10000000" + depends on ARCH_STM32MP && SET_DFU_ALT_INFO + help + This defines the partitions of ram used to build dfu dynamically. + +config TYPEC_STUSB160X + tristate "STMicroelectronics STUSB160X Type-C controller driver" + depends on DM_I2C + help + Say Y if your system has STMicroelectronics STUSB160X Type-C port + controller. diff --git a/board/st/common/MAINTAINERS b/board/st/common/MAINTAINERS new file mode 100644 index 00000000000..0c6db547725 --- /dev/null +++ b/board/st/common/MAINTAINERS @@ -0,0 +1,6 @@ +ST BOARDS +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: board/st/common/ diff --git a/board/st/common/Makefile b/board/st/common/Makefile new file mode 100644 index 00000000000..b01245e4b48 --- /dev/null +++ b/board/st/common/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +# +# Copyright (C) 2020, STMicroelectronics - All Rights Reserved +# + +obj-$(CONFIG_CMD_STBOARD) += cmd_stboard.o +obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o + +ifeq ($(CONFIG_ARCH_STM32MP),y) +obj-$(CONFIG_SET_DFU_ALT_INFO) += stm32mp_dfu.o +obj-$(CONFIG_$(SPL_)DFU_VIRT) += stm32mp_dfu_virt.o +endif + +obj-$(CONFIG_TYPEC_STUSB160X) += stusb160x.o diff --git a/board/st/common/cmd_stboard.c b/board/st/common/cmd_stboard.c new file mode 100644 index 00000000000..50da063051b --- /dev/null +++ b/board/st/common/cmd_stboard.c @@ -0,0 +1,209 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2019, STMicroelectronics - All Rights Reserved + * + * the command stboard supports the STMicroelectronics board identification + * saved in OTP_BOARD. + * + * The ST product codification have several element + * - "Commercial Product Name" (CPN): type of product board (DKX, EVX) + * associated to the board ID "MBxxxx" + * - "Finished Good" or "Finish Good" (FG): + * effective content of the product without chip STM32MP1xx (LCD, Wifi,...) + * - BOM: cost variant for same FG (for example, several provider of the same + * component) + * + * For example + * - commercial product = STM32MP157C-EV1 for board MB1263 + * - Finished Good = EVA32MP157A1$AU1 + * + * Both information are written on board and these information are also saved + * in OTP_BOARD (59 for STM32MP15x or 60 for STM32MP13x), with: + * bit [31:16] (hex) => Board id, MBxxxx + * bit [15:12] (dec) => Variant CPN (1....15) + * bit [11:8] (dec) => Revision board (index with A = 1, Z = 26) + * bit [7:4] (dec) => Variant FG : finished good index + * bit [3:0] (dec) => BOM (01, .... 255) + * + * and displayed with the format: + * Board: MB<Board> Var<VarCPN>.<VarFG> Rev.<Revision>-<BOM> + */ + +#ifndef CONFIG_SPL_BUILD +#include <command.h> +#include <console.h> +#include <misc.h> +#include <asm/arch/bsec.h> +#include <dm/device.h> +#include <dm/uclass.h> + +static bool check_stboard(u16 board) +{ + unsigned int i; + /* list of supported ST boards */ + const u16 st_board_id[] = { + 0x1272, + 0x1263, + 0x1264, + 0x1298, + 0x1341, + 0x1497, + 0x1605, /* stm32mp25xx-dk */ + 0x1635, + 0x1936, /* stm32mp25xx-ev1 */ + }; + + for (i = 0; i < ARRAY_SIZE(st_board_id); i++) + if (board == st_board_id[i]) + return true; + + return false; +} + +static void display_stboard(u32 otp) +{ + /* display board indentification with OPT coding */ + printf("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); +} + +static int do_stboard(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + u32 otp, lock; + u8 revision; + unsigned long board, var_cpn, var_fg, bom; + struct udevice *dev; + int confirmed = argc == 7 && !strcmp(argv[1], "-y"); + + argc -= 1 + confirmed; + argv += 1 + confirmed; + + if (argc != 0 && argc != 5) + return CMD_RET_USAGE; + + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_DRIVER_GET(stm32mp_bsec), + &dev); + + ret = misc_read(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD), + &otp, sizeof(otp)); + + if (ret != sizeof(otp)) { + puts("OTP read error\n"); + return CMD_RET_FAILURE; + } + + ret = misc_read(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD), + &lock, sizeof(lock)); + if (ret != sizeof(lock)) { + puts("LOCK read error\n"); + return CMD_RET_FAILURE; + } + + if (argc == 0) { + if (!otp) + puts("Board : OTP board FREE\n"); + else + display_stboard(otp); + printf(" OTP %d %s locked !\n", BSEC_OTP_BOARD, + lock & BSEC_LOCK_PERM ? "" : "NOT"); + return CMD_RET_SUCCESS; + } + + if (otp) { + display_stboard(otp); + printf("ERROR: OTP board not FREE\n"); + return CMD_RET_FAILURE; + } + + if (strict_strtoul(argv[0], 16, &board) < 0 || + board == 0 || board > 0xFFFF) { + printf("argument %d invalid: %s\n", 1, argv[0]); + return CMD_RET_USAGE; + } + + if (strict_strtoul(argv[1], 10, &var_cpn) < 0 || + var_cpn == 0 || var_cpn > 15) { + printf("argument %d invalid: %s\n", 2, argv[1]); + return CMD_RET_USAGE; + } + + revision = argv[2][0] - 'A' + 1; + if (strlen(argv[2]) > 1 || revision == 0 || revision > 15) { + printf("argument %d invalid: %s\n", 3, argv[2]); + return CMD_RET_USAGE; + } + + if (strict_strtoul(argv[3], 10, &var_fg) < 0 || + var_fg > 15) { + printf("argument %d invalid: %s\n", 4, argv[3]); + return CMD_RET_USAGE; + } + + if (strict_strtoul(argv[4], 10, &bom) < 0 || + bom == 0 || bom > 15) { + printf("argument %d invalid: %s\n", 4, argv[3]); + return CMD_RET_USAGE; + } + + /* st board indentification value */ + otp = (board << 16) | (var_cpn << 12) | (revision << 8) | + (var_fg << 4) | bom; + display_stboard(otp); + printf("=> OTP[%d] = %08X\n", BSEC_OTP_BOARD, otp); + + if (!check_stboard((u16)board)) { + printf("Unknown board MB%04x\n", (u16)board); + return CMD_RET_FAILURE; + } + if (!confirmed) { + printf("Warning: Programming BOARD in OTP is irreversible!\n"); + printf("Really perform this OTP programming? <y/N>\n"); + + if (!confirm_yesno()) { + puts("BOARD programming aborted\n"); + return CMD_RET_FAILURE; + } + } + + ret = misc_write(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD), + &otp, sizeof(otp)); + + if (ret != sizeof(otp)) { + puts("BOARD programming error\n"); + return CMD_RET_FAILURE; + } + + /* write persistent lock */ + otp = BSEC_LOCK_PERM; + ret = misc_write(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD), + &otp, sizeof(otp)); + if (ret != sizeof(otp)) { + puts("BOARD lock error\n"); + return CMD_RET_FAILURE; + } + + puts("BOARD programming done\n"); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(stboard, 7, 0, do_stboard, + "read/write board reference in OTP", + "\n" + " Print current board information\n" + "stboard [-y] <Board> <VarCPN> <Revision> <VarFG> <BOM>\n" + " Write board information\n" + " - Board: xxxx, example 1264 for MB1264\n" + " - VarCPN: 1...15\n" + " - Revision: A...O\n" + " - VarFG: 0...15\n" + " - BOM: 1...15\n"); + +#endif diff --git a/board/st/common/stm32mp_dfu.c b/board/st/common/stm32mp_dfu.c new file mode 100644 index 00000000000..1db8e45480e --- /dev/null +++ b/board/st/common/stm32mp_dfu.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +#include <blk.h> +#include <dm.h> +#include <dfu.h> +#include <env.h> +#include <log.h> +#include <memalign.h> +#include <misc.h> +#include <mtd.h> +#include <mtd_node.h> +#include <asm/arch/stm32prog.h> +#include <linux/printk.h> + +#define DFU_ALT_BUF_LEN SZ_1K + +static void board_get_alt_info_mmc(struct udevice *dev, char *buf) +{ + struct disk_partition info; + int p, len, devnum; + bool first = true; + const char *name; + struct mmc *mmc; + struct blk_desc *desc; + + mmc = mmc_get_mmc_dev(dev); + if (!mmc) + return; + + if (mmc_init(mmc)) + return; + + desc = mmc_get_blk_desc(mmc); + if (!desc) + return; + + name = blk_get_uclass_name(desc->uclass_id); + devnum = desc->devnum; + len = strlen(buf); + + if (buf[0] != '\0') + len += snprintf(buf + len, + DFU_ALT_BUF_LEN - len, "&"); + len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, + "%s %d=", name, devnum); + + if (IS_MMC(mmc) && mmc->capacity_boot) { + len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, + "%s%d_boot1 raw 0x0 0x%llx mmcpart 1;", + name, devnum, mmc->capacity_boot); + len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, + "%s%d_boot2 raw 0x0 0x%llx mmcpart 2", + name, devnum, mmc->capacity_boot); + first = false; + } + + for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { + if (part_get_info(desc, p, &info)) + continue; + if (!first) + len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ";"); + first = false; + len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, + "%s%d_%s part %d %d", + name, devnum, info.name, devnum, p); + } +} + +static void board_get_alt_info_mtd(struct mtd_info *mtd, char *buf) +{ + struct mtd_info *part; + const char *name; + int len, partnum = 0; + + name = mtd->name; + len = strlen(buf); + + if (buf[0] != '\0') + len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "&"); + len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, + "mtd %s=", name); + + len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, + "%s raw 0x0 0x%llx", + name, mtd->size); + + list_for_each_entry(part, &mtd->partitions, node) { + partnum++; + len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, + ";%s_%s part %d", + name, part->name, partnum); + } +} + +void set_dfu_alt_info(char *interface, char *devstr) +{ + struct udevice *dev; + struct mtd_info *mtd; + + ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); + + if (env_get("dfu_alt_info")) + return; + + memset(buf, 0, sizeof(buf)); + + snprintf(buf, DFU_ALT_BUF_LEN, + "ram 0=%s", CONFIG_DFU_ALT_RAM0); + + if (CONFIG_IS_ENABLED(MMC)) { + if (!uclass_get_device(UCLASS_MMC, 0, &dev)) + board_get_alt_info_mmc(dev, buf); + + if (!uclass_get_device(UCLASS_MMC, 1, &dev)) + board_get_alt_info_mmc(dev, buf); + } + + if (IS_ENABLED(CONFIG_MTD)) { + /* probe all MTD devices */ + mtd_probe_devices(); + + mtd_for_each_device(mtd) + if (!mtd_is_partition(mtd)) + board_get_alt_info_mtd(mtd, buf); + } + + if (IS_ENABLED(CONFIG_DFU_VIRT)) { + /* virtual device id 0 is aligned with stm32mp_dfu_virt.c */ + strlcat(buf, "&virt 0=OTP", DFU_ALT_BUF_LEN); + + if (IS_ENABLED(CONFIG_PMIC_STPMIC1)) + strlcat(buf, "&virt 1=PMIC", DFU_ALT_BUF_LEN); + } + + env_set("dfu_alt_info", buf); + puts("DFU alt info setting: done\n"); +} diff --git a/board/st/common/stm32mp_dfu_virt.c b/board/st/common/stm32mp_dfu_virt.c new file mode 100644 index 00000000000..4049d72bf9d --- /dev/null +++ b/board/st/common/stm32mp_dfu_virt.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (C) 2023, STMicroelectronics - All Rights Reserved + */ + +#include <dfu.h> +#include <dm.h> +#include <misc.h> +#include <asm/arch/stm32prog.h> +#include <power/stpmic1.h> + +static int dfu_otp_read(u64 offset, u8 *buffer, long *size) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_DRIVER_GET(stm32mp_bsec), + &dev); + if (ret) + return ret; + + ret = misc_read(dev, offset + STM32_BSEC_OTP_OFFSET, buffer, *size); + if (ret >= 0) { + *size = ret; + ret = 0; + } + + return 0; +} + +static int dfu_pmic_read(u64 offset, u8 *buffer, long *size) +{ + int ret; + struct udevice *dev; + + if (!IS_ENABLED(CONFIG_PMIC_STPMIC1)) { + log_err("PMIC update not supported"); + return -EOPNOTSUPP; + } + + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_DRIVER_GET(stpmic1_nvm), + &dev); + if (ret) + return ret; + + ret = misc_read(dev, 0xF8 + offset, buffer, *size); + if (ret >= 0) { + *size = ret; + ret = 0; + } + if (ret == -EACCES) { + *size = 0; + ret = 0; + } + + return ret; +} + +int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset, + void *buf, long *len) +{ + switch (dfu->data.virt.dev_num) { + case 0x0: + return dfu_otp_read(offset, buf, len); + case 0x1: + return dfu_pmic_read(offset, buf, len); + } + + if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) && + dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM) + return stm32prog_read_medium_virt(dfu, offset, buf, len); + + *len = 0; + return 0; +} + +int dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset, + void *buf, long *len) +{ + if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) && + dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM) + return stm32prog_write_medium_virt(dfu, offset, buf, len); + + return -EOPNOTSUPP; +} + +int dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) +{ + if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) && + dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM) + return stm32prog_get_medium_size_virt(dfu, size); + + *size = SZ_1K; + + return 0; +} diff --git a/board/st/common/stpmic1.c b/board/st/common/stpmic1.c new file mode 100644 index 00000000000..45c2bb5bcea --- /dev/null +++ b/board/st/common/stpmic1.c @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +#define LOG_CATEGORY LOGC_BOARD + +#include <dm.h> +#include <log.h> +#include <asm/io.h> +#include <asm/arch/ddr.h> +#include <linux/bitops.h> +#include <linux/delay.h> +#include <power/pmic.h> +#include <power/stpmic1.h> + +int board_ddr_power_init(enum ddr_type ddr_type) +{ + struct udevice *dev; + bool buck3_at_1800000v = false; + int ret; + u32 buck2; + + ret = uclass_get_device_by_driver(UCLASS_PMIC, + DM_DRIVER_GET(pmic_stpmic1), &dev); + if (ret) + /* No PMIC on board */ + return 0; + + switch (ddr_type) { + case STM32MP_DDR3: + /* VTT = Set LDO3 to sync mode */ + ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3)); + if (ret < 0) + return ret; + + ret &= ~STPMIC1_LDO3_MODE; + ret &= ~STPMIC1_LDO12356_VOUT_MASK; + ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL); + + ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), + ret); + if (ret < 0) + return ret; + + /* VDD_DDR = Set BUCK2 to 1.35V */ + ret = pmic_clrsetbits(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), + STPMIC1_BUCK_VOUT_MASK, + STPMIC1_BUCK2_1350000V); + if (ret < 0) + return ret; + + /* Enable VDD_DDR = BUCK2 */ + ret = pmic_clrsetbits(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), + STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA); + if (ret < 0) + return ret; + + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); + + /* Enable VREF */ + ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR, + STPMIC1_VREF_ENA, STPMIC1_VREF_ENA); + if (ret < 0) + return ret; + + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); + + /* Enable VTT = LDO3 */ + ret = pmic_clrsetbits(dev, + STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), + STPMIC1_LDO_ENA, STPMIC1_LDO_ENA); + if (ret < 0) + return ret; + + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); + + break; + + case STM32MP_LPDDR2_16: + case STM32MP_LPDDR2_32: + case STM32MP_LPDDR3_16: + case STM32MP_LPDDR3_32: + /* + * configure VDD_DDR1 = LDO3 + * Set LDO3 to 1.8V + * + bypass mode if BUCK3 = 1.8V + * + normal mode if BUCK3 != 1.8V + */ + ret = pmic_reg_read(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK3)); + if (ret < 0) + return ret; + + if ((ret & STPMIC1_BUCK3_1800000V) == STPMIC1_BUCK3_1800000V) + buck3_at_1800000v = true; + + ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3)); + if (ret < 0) + return ret; + + ret &= ~STPMIC1_LDO3_MODE; + ret &= ~STPMIC1_LDO12356_VOUT_MASK; + ret |= STPMIC1_LDO3_1800000; + if (buck3_at_1800000v) + ret |= STPMIC1_LDO3_MODE; + + ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), + ret); + if (ret < 0) + return ret; + + /* VDD_DDR2 : Set BUCK2 to 1.2V (16bits) or 1.25V (32 bits)*/ + switch (ddr_type) { + case STM32MP_LPDDR2_32: + case STM32MP_LPDDR3_32: + buck2 = STPMIC1_BUCK2_1250000V; + break; + default: + case STM32MP_LPDDR2_16: + case STM32MP_LPDDR3_16: + buck2 = STPMIC1_BUCK2_1200000V; + break; + } + + ret = pmic_clrsetbits(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), + STPMIC1_BUCK_VOUT_MASK, + buck2); + if (ret < 0) + return ret; + + /* Enable VDD_DDR1 = LDO3 */ + ret = pmic_clrsetbits(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), + STPMIC1_LDO_ENA, STPMIC1_LDO_ENA); + if (ret < 0) + return ret; + + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); + + /* Enable VDD_DDR2 =BUCK2 */ + ret = pmic_clrsetbits(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), + STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA); + if (ret < 0) + return ret; + + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); + + /* Enable VREF */ + ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR, + STPMIC1_VREF_ENA, STPMIC1_VREF_ENA); + if (ret < 0) + return ret; + + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); + + break; + + default: + break; + }; + + return 0; +} + +static int stmpic_buck1_set(struct udevice *dev, u32 voltage_mv) +{ + u32 value; + + /* VDDCORE= STMPCI1 BUCK1 ramp=+25mV, 5 => 725mV, 36 => 1500mV */ + value = ((voltage_mv - 725) / 25) + 5; + if (value < 5) + value = 5; + if (value > 36) + value = 36; + + return pmic_clrsetbits(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK1), + STPMIC1_BUCK_VOUT_MASK, + STPMIC1_BUCK_VOUT(value)); +} + +/* early init of PMIC */ +struct udevice *stpmic1_init(u32 voltage_mv) +{ + struct udevice *dev; + + if (uclass_get_device_by_driver(UCLASS_PMIC, + DM_DRIVER_GET(pmic_stpmic1), &dev)) + return NULL; + + /* update VDDCORE = BUCK1 */ + if (voltage_mv) + stmpic_buck1_set(dev, voltage_mv); + + return dev; +} diff --git a/board/st/common/stpmic1.h b/board/st/common/stpmic1.h new file mode 100644 index 00000000000..7a7169d7cea --- /dev/null +++ b/board/st/common/stpmic1.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +struct udevice *stpmic1_init(u32 voltage_mv); diff --git a/board/st/common/stusb160x.c b/board/st/common/stusb160x.c new file mode 100644 index 00000000000..e1ad8b00717 --- /dev/null +++ b/board/st/common/stusb160x.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * STMicroelectronics STUSB Type-C controller driver + * based on Linux drivers/usb/typec/stusb160x.c + * + * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +#define LOG_CATEGORY UCLASS_I2C_GENERIC + +#include <dm.h> +#include <i2c.h> + +/* REGISTER */ +#define STUSB160X_CC_CONNECTION_STATUS 0x0E + +/* STUSB160X_CC_CONNECTION_STATUS bitfields */ +#define STUSB160X_CC_ATTACH BIT(0) + +int stusb160x_cable_connected(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_I2C_GENERIC, + DM_DRIVER_GET(stusb160x), + &dev); + if (ret < 0) + return ret; + + ret = dm_i2c_reg_read(dev, STUSB160X_CC_CONNECTION_STATUS); + if (ret < 0) + return 0; + + return ret & STUSB160X_CC_ATTACH; +} + +static const struct udevice_id stusb160x_ids[] = { + { .compatible = "st,stusb1600" }, + {} +}; + +U_BOOT_DRIVER(stusb160x) = { + .name = "stusb160x", + .id = UCLASS_I2C_GENERIC, + .of_match = stusb160x_ids, +}; diff --git a/board/st/common/stusb160x.h b/board/st/common/stusb160x.h new file mode 100644 index 00000000000..fe39840b41d --- /dev/null +++ b/board/st/common/stusb160x.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020, STMicroelectronics + */ + +#ifdef CONFIG_TYPEC_STUSB160X +int stusb160x_cable_connected(void); +#else +int stusb160x_cable_connected(void) { return -ENODEV; } +#endif diff --git a/board/st/stih410-b2260/Kconfig b/board/st/stih410-b2260/Kconfig new file mode 100644 index 00000000000..441a83cbaea --- /dev/null +++ b/board/st/stih410-b2260/Kconfig @@ -0,0 +1,18 @@ +if TARGET_STIH410_B2260 + +config SYS_BOARD + string + default "stih410-b2260" + +config SYS_VENDOR + string + default "st" + +config SYS_SOC + string + default "stih410" + +config SYS_CONFIG_NAME + default "stih410-b2260" + +endif diff --git a/board/st/stih410-b2260/MAINTAINERS b/board/st/stih410-b2260/MAINTAINERS new file mode 100644 index 00000000000..6fa625507b7 --- /dev/null +++ b/board/st/stih410-b2260/MAINTAINERS @@ -0,0 +1,7 @@ +STIH410-B2260 BOARD +M: Patrice Chotard <patrice.chotard@foss.st.com> +S: Maintained +F: board/st/stih410-b2260/ +F: include/configs/stih410-b2260.h +F: configs/stih410-b2260_defconfig +F: arch/arm/dts/stih* diff --git a/board/st/stih410-b2260/Makefile b/board/st/stih410-b2260/Makefile new file mode 100644 index 00000000000..ea573ca1455 --- /dev/null +++ b/board/st/stih410-b2260/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2017, STMicroelectronics - All Rights Reserved +# Author(s): Patrice CHOTARD, <patrice.chotard@foss.st.com> for STMicroelectronics. + +obj-y = board.o diff --git a/board/st/stih410-b2260/board.c b/board/st/stih410-b2260/board.c new file mode 100644 index 00000000000..a912712c9dd --- /dev/null +++ b/board/st/stih410-b2260/board.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved + * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. + */ + +#include <cpu_func.h> +#include <init.h> +#include <asm/cache.h> +#include <asm/global_data.h> +#include <linux/usb/otg.h> +#include <dwc3-sti-glue.h> +#include <dwc3-uboot.h> +#include <usb.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + gd->ram_size = PHYS_SDRAM_1_SIZE; + return 0; +} + +int dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + + return 0; +} + +#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} +#endif + +int board_init(void) +{ + return 0; +} + +#ifdef CONFIG_USB_DWC3 +static struct dwc3_device dwc3_device_data = { + .maximum_speed = USB_SPEED_HIGH, + .dr_mode = USB_DR_MODE_PERIPHERAL, + .index = 0, +}; + +int board_usb_init(int index, enum usb_init_type init) +{ + int node; + const void *blob = gd->fdt_blob; + + /* find the snps,dwc3 node */ + node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc3"); + + dwc3_device_data.base = fdtdec_get_addr(blob, node, "reg"); + + return dwc3_uboot_init(&dwc3_device_data); +} + +int board_usb_cleanup(int index, enum usb_init_type init) +{ + dwc3_uboot_exit(index); + return 0; +} + +int g_dnl_board_usb_cable_connected(void) +{ + return 1; +} +#endif diff --git a/board/st/stm32f429-discovery/Kconfig b/board/st/stm32f429-discovery/Kconfig new file mode 100644 index 00000000000..3c93df20afa --- /dev/null +++ b/board/st/stm32f429-discovery/Kconfig @@ -0,0 +1,18 @@ +if TARGET_STM32F429_DISCOVERY + +config SYS_BOARD + string + default "stm32f429-discovery" + +config SYS_VENDOR + string + default "st" + +config SYS_SOC + string + default "stm32f4" + +config SYS_CONFIG_NAME + default "stm32f429-discovery" + +endif diff --git a/board/st/stm32f429-discovery/MAINTAINERS b/board/st/stm32f429-discovery/MAINTAINERS new file mode 100644 index 00000000000..7661a15fdde --- /dev/null +++ b/board/st/stm32f429-discovery/MAINTAINERS @@ -0,0 +1,7 @@ +STM32F429-DISCOVERY BOARD +M: Kamil Lulko <kamil.lulko@gmail.com> +S: Maintained +F: doc/board/st/ +F: board/st/stm32f429-discovery/ +F: include/configs/stm32f429-discovery.h +F: configs/stm32f429-discovery_defconfig diff --git a/board/st/stm32f429-discovery/Makefile b/board/st/stm32f429-discovery/Makefile new file mode 100644 index 00000000000..6b02c0fddec --- /dev/null +++ b/board/st/stm32f429-discovery/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2000-2004 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2015 +# Kamil Lulko, <kamil.lulko@gmail.com> + +obj-y := stm32f429-discovery.o +obj-y += led.o diff --git a/board/st/stm32f429-discovery/led.c b/board/st/stm32f429-discovery/led.c new file mode 100644 index 00000000000..4b8038341b9 --- /dev/null +++ b/board/st/stm32f429-discovery/led.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2015 + * Kamil Lulko, <kamil.lulko@gmail.com> + */ + +#include <status_led.h> +#include <asm-generic/gpio.h> + +#define RED_LED 110 +#define GREEN_LED 109 + +void coloured_LED_init(void) +{ + gpio_request(RED_LED, "red led"); + gpio_direction_output(RED_LED, 0); + gpio_request(GREEN_LED, "green led"); + gpio_direction_output(GREEN_LED, 0); +} + +void red_led_off(void) +{ + gpio_set_value(RED_LED, 0); +} + +void green_led_off(void) +{ + gpio_set_value(GREEN_LED, 0); +} + +void red_led_on(void) +{ + gpio_set_value(RED_LED, 1); +} + +void green_led_on(void) +{ + gpio_set_value(GREEN_LED, 1); +} diff --git a/board/st/stm32f429-discovery/stm32f429-discovery.c b/board/st/stm32f429-discovery/stm32f429-discovery.c new file mode 100644 index 00000000000..22d751b44d3 --- /dev/null +++ b/board/st/stm32f429-discovery/stm32f429-discovery.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2011, 2012, 2013 + * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com + * Alexander Potashev, Emcraft Systems, aspotashev@emcraft.com + * Vladimir Khusainov, Emcraft Systems, vlad@emcraft.com + * Pavel Boldin, Emcraft Systems, paboldin@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, <kamil.lulko@gmail.com> + */ + +#include <dm.h> +#include <env.h> +#include <init.h> +#include <log.h> +#include <asm/global_data.h> + +#include <asm/io.h> +#include <asm/arch/stm32.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + int rv; + struct udevice *dev; + + rv = uclass_get_device(UCLASS_RAM, 0, &dev); + if (rv) { + debug("DRAM init failed: %d\n", rv); + return rv; + } + + if (fdtdec_setup_mem_size_base() != 0) + rv = -EINVAL; + + return rv; +} + +int dram_init_banksize(void) +{ + fdtdec_setup_memory_banksize(); + + return 0; +} + +int board_init(void) +{ + return 0; +} + +#ifdef CONFIG_MISC_INIT_R +int misc_init_r(void) +{ + char serialno[25]; + uint32_t u_id_low, u_id_mid, u_id_high; + + if (!env_get("serial#")) { + u_id_low = readl(&STM32_U_ID->u_id_low); + u_id_mid = readl(&STM32_U_ID->u_id_mid); + u_id_high = readl(&STM32_U_ID->u_id_high); + sprintf(serialno, "%08x%08x%08x", + u_id_high, u_id_mid, u_id_low); + env_set("serial#", serialno); + } + + return 0; +} +#endif diff --git a/board/st/stm32f429-evaluation/Kconfig b/board/st/stm32f429-evaluation/Kconfig new file mode 100644 index 00000000000..eaa40db8a74 --- /dev/null +++ b/board/st/stm32f429-evaluation/Kconfig @@ -0,0 +1,18 @@ +if TARGET_STM32F429_EVALUATION + +config SYS_BOARD + string + default "stm32f429-evaluation" + +config SYS_VENDOR + string + default "st" + +config SYS_SOC + string + default "stm32f4" + +config SYS_CONFIG_NAME + default "stm32f429-evaluation" + +endif diff --git a/board/st/stm32f429-evaluation/MAINTAINERS b/board/st/stm32f429-evaluation/MAINTAINERS new file mode 100644 index 00000000000..b272893ef7b --- /dev/null +++ b/board/st/stm32f429-evaluation/MAINTAINERS @@ -0,0 +1,7 @@ +STM32F429-EVALUATION BOARD +M: Patrice Chotard <patrice.chotard@foss.st.com> +S: Maintained +F: doc/board/st/ +F: board/st/stm32f429-evaluation/ +F: include/configs/stm32f429-evaluation.h +F: configs/stm32f429-evaluation_defconfig diff --git a/board/st/stm32f429-evaluation/Makefile b/board/st/stm32f429-evaluation/Makefile new file mode 100644 index 00000000000..109fba876b3 --- /dev/null +++ b/board/st/stm32f429-evaluation/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2018, STMicroelectronics - All Rights Reserved +# Author(s): Patrice CHOTARD, <patrice.chotard@foss.st.com> for STMicroelectronics. + +obj-y := stm32f429-evaluation.o diff --git a/board/st/stm32f429-evaluation/stm32f429-evaluation.c b/board/st/stm32f429-evaluation/stm32f429-evaluation.c new file mode 100644 index 00000000000..db59ebb838e --- /dev/null +++ b/board/st/stm32f429-evaluation/stm32f429-evaluation.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. + */ + +#include <dm.h> +#include <env.h> +#include <init.h> +#include <log.h> +#include <asm/global_data.h> + +#include <asm/io.h> +#include <asm/arch/stm32.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + int rv; + struct udevice *dev; + + rv = uclass_get_device(UCLASS_RAM, 0, &dev); + if (rv) { + debug("DRAM init failed: %d\n", rv); + return rv; + } + + if (fdtdec_setup_mem_size_base() != 0) + rv = -EINVAL; + + return rv; +} + +int dram_init_banksize(void) +{ + fdtdec_setup_memory_banksize(); + + return 0; +} + +int board_init(void) +{ + return 0; +} + +#ifdef CONFIG_MISC_INIT_R +int misc_init_r(void) +{ + char serialno[25]; + u32 u_id_low, u_id_mid, u_id_high; + + if (!env_get("serial#")) { + u_id_low = readl(&STM32_U_ID->u_id_low); + u_id_mid = readl(&STM32_U_ID->u_id_mid); + u_id_high = readl(&STM32_U_ID->u_id_high); + sprintf(serialno, "%08x%08x%08x", + u_id_high, u_id_mid, u_id_low); + env_set("serial#", serialno); + } + + return 0; +} +#endif diff --git a/board/st/stm32f469-discovery/Kconfig b/board/st/stm32f469-discovery/Kconfig new file mode 100644 index 00000000000..622a8d82d81 --- /dev/null +++ b/board/st/stm32f469-discovery/Kconfig @@ -0,0 +1,18 @@ +if TARGET_STM32F469_DISCOVERY + +config SYS_BOARD + string + default "stm32f469-discovery" + +config SYS_VENDOR + string + default "st" + +config SYS_SOC + string + default "stm32f4" + +config SYS_CONFIG_NAME + default "stm32f469-discovery" + +endif diff --git a/board/st/stm32f469-discovery/MAINTAINERS b/board/st/stm32f469-discovery/MAINTAINERS new file mode 100644 index 00000000000..a95f93f6f6c --- /dev/null +++ b/board/st/stm32f469-discovery/MAINTAINERS @@ -0,0 +1,7 @@ +STM32F469-DISCOVERY BOARD +M: Patrice Chotard <patrice.chotard@foss.st.com> +S: Maintained +F: doc/board/st/ +F: board/st/stm32f469-discovery/ +F: include/configs/stm32f469-discovery.h +F: configs/stm32f469-discovery_defconfig diff --git a/board/st/stm32f469-discovery/Makefile b/board/st/stm32f469-discovery/Makefile new file mode 100644 index 00000000000..45480b72c5f --- /dev/null +++ b/board/st/stm32f469-discovery/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) STMicroelectronics SA 2017 +# Author(s): Patrice CHOTARD, <patrice.chotard@foss.st.com> for STMicroelectronics. + +obj-y := stm32f469-discovery.o diff --git a/board/st/stm32f469-discovery/stm32f469-discovery.c b/board/st/stm32f469-discovery/stm32f469-discovery.c new file mode 100644 index 00000000000..134d207d95d --- /dev/null +++ b/board/st/stm32f469-discovery/stm32f469-discovery.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) STMicroelectronics SA 2017 + * Author(s): Patrice CHOTARD, <patrice.chotard@foss.st.com> for STMicroelectronics. + */ + +#include <dm.h> +#include <env.h> +#include <init.h> +#include <log.h> +#include <asm/global_data.h> + +#include <asm/io.h> +#include <asm/arch/stm32.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + int rv; + struct udevice *dev; + + rv = uclass_get_device(UCLASS_RAM, 0, &dev); + if (rv) { + debug("DRAM init failed: %d\n", rv); + return rv; + } + + if (fdtdec_setup_mem_size_base() != 0) + rv = -EINVAL; + + return rv; +} + +int dram_init_banksize(void) +{ + fdtdec_setup_memory_banksize(); + + return 0; +} + +int board_init(void) +{ + return 0; +} + +#ifdef CONFIG_MISC_INIT_R +int misc_init_r(void) +{ + char serialno[25]; + u32 u_id_low, u_id_mid, u_id_high; + + if (!env_get("serial#")) { + u_id_low = readl(&STM32_U_ID->u_id_low); + u_id_mid = readl(&STM32_U_ID->u_id_mid); + u_id_high = readl(&STM32_U_ID->u_id_high); + sprintf(serialno, "%08x%08x%08x", + u_id_high, u_id_mid, u_id_low); + env_set("serial#", serialno); + } + + return 0; +} +#endif diff --git a/board/st/stm32f746-disco/Kconfig b/board/st/stm32f746-disco/Kconfig new file mode 100644 index 00000000000..86ace17377c --- /dev/null +++ b/board/st/stm32f746-disco/Kconfig @@ -0,0 +1,18 @@ +if TARGET_STM32F746_DISCO + +config SYS_BOARD + string + default "stm32f746-disco" + +config SYS_VENDOR + string + default "st" + +config SYS_SOC + string + default "stm32f7" + +config SYS_CONFIG_NAME + default "stm32f746-disco" + +endif diff --git a/board/st/stm32f746-disco/MAINTAINERS b/board/st/stm32f746-disco/MAINTAINERS new file mode 100644 index 00000000000..18e4c99c4fb --- /dev/null +++ b/board/st/stm32f746-disco/MAINTAINERS @@ -0,0 +1,12 @@ +STM32F746 DISCOVERY BOARD +M: Vikas Manocha <vikas.manocha@st.com> +S: Maintained +F: doc/board/st/ +F: board/st/stm32f746-disco +F: include/configs/stm32f746-disco.h +F: configs/stm32f746-disco_defconfig +F: configs/stm32f746-disco_spl_defconfig +F: configs/stm32746g-eval_defconfig +F: configs/stm32746g-eval_spl_defconfig +F: configs/stm32f769-disco_defconfig +F: configs/stm32f769-disco_spl_defconfig diff --git a/board/st/stm32f746-disco/Makefile b/board/st/stm32f746-disco/Makefile new file mode 100644 index 00000000000..369f17a2db0 --- /dev/null +++ b/board/st/stm32f746-disco/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2016, STMicroelectronics - All Rights Reserved +# Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics. + +obj-y := stm32f746-disco.o diff --git a/board/st/stm32f746-disco/stm32f746-disco.c b/board/st/stm32f746-disco/stm32f746-disco.c new file mode 100644 index 00000000000..6d86e4fe7aa --- /dev/null +++ b/board/st/stm32f746-disco/stm32f746-disco.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016, STMicroelectronics - All Rights Reserved + * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics. + */ + +#include <config.h> +#include <dm.h> +#include <init.h> +#include <log.h> +#include <miiphy.h> +#include <phy_interface.h> +#include <ram.h> +#include <serial.h> +#include <spl.h> +#include <splash.h> +#include <video.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/armv7m.h> +#include <asm/arch/stm32.h> +#include <asm/arch/syscfg.h> +#include <asm/gpio.h> +#include <linux/delay.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ +#ifndef CONFIG_SPL_BUILD + int rv; + struct udevice *dev; + rv = uclass_get_device(UCLASS_RAM, 0, &dev); + if (rv) { + debug("DRAM init failed: %d\n", rv); + return rv; + } + +#endif + return fdtdec_setup_mem_size_base(); +} + +int dram_init_banksize(void) +{ + return fdtdec_setup_memory_banksize(); +} + +#ifdef CONFIG_SPL_BUILD +#ifdef CONFIG_SPL_OS_BOOT +int spl_start_uboot(void) +{ + debug("SPL: booting kernel\n"); + /* break into full u-boot on 'c' */ + return serial_tstc() && serial_getc() == 'c'; +} +#endif + +int spl_dram_init(void) +{ + struct udevice *dev; + int rv; + rv = uclass_get_device(UCLASS_RAM, 0, &dev); + if (rv) + debug("DRAM init failed: %d\n", rv); + return rv; +} +void spl_board_init(void) +{ + preloader_console_init(); + spl_dram_init(); + arch_cpu_init(); /* to configure mpu for sdram rw permissions */ +} +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_XIP; +} +#endif + +int board_late_init(void) +{ + struct gpio_desc gpio = {}; + int node; + + node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "st,led1"); + if (node < 0) + return -1; + + gpio_request_by_name_nodev(offset_to_ofnode(node), "led-gpio", 0, &gpio, + GPIOD_IS_OUT); + + if (dm_gpio_is_valid(&gpio)) { + dm_gpio_set_value(&gpio, 0); + mdelay(10); + dm_gpio_set_value(&gpio, 1); + } + + /* read button 1*/ + node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "st,button1"); + if (node < 0) + return -1; + + gpio_request_by_name_nodev(offset_to_ofnode(node), "button-gpio", 0, + &gpio, GPIOD_IS_IN); + + if (dm_gpio_is_valid(&gpio)) { + if (dm_gpio_get_value(&gpio)) + puts("usr button is at HIGH LEVEL\n"); + else + puts("usr button is at LOW LEVEL\n"); + } + + return 0; +} + +int board_init(void) +{ +#ifdef CONFIG_ETH_DESIGNWARE + ofnode node; + + node = ofnode_by_compatible(ofnode_null(), "st,stm32-dwmac"); + if (!ofnode_valid(node)) + return -1; + + switch (ofnode_read_phy_mode(node)) { + case PHY_INTERFACE_MODE_RMII: + STM32_SYSCFG->pmc |= SYSCFG_PMC_MII_RMII_SEL; + break; + case PHY_INTERFACE_MODE_MII: + STM32_SYSCFG->pmc &= ~SYSCFG_PMC_MII_RMII_SEL; + break; + default: + printf("Unsupported PHY interface!\n"); + } +#endif + + return 0; +} diff --git a/board/st/stm32h743-disco/Kconfig b/board/st/stm32h743-disco/Kconfig new file mode 100644 index 00000000000..bc116bcf32f --- /dev/null +++ b/board/st/stm32h743-disco/Kconfig @@ -0,0 +1,18 @@ +if TARGET_STM32H743_DISCO + +config SYS_BOARD + string + default "stm32h743-disco" + +config SYS_VENDOR + string + default "st" + +config SYS_SOC + string + default "stm32h7" + +config SYS_CONFIG_NAME + default "stm32h743-disco" + +endif diff --git a/board/st/stm32h743-disco/MAINTAINERS b/board/st/stm32h743-disco/MAINTAINERS new file mode 100644 index 00000000000..f4ecef3aa50 --- /dev/null +++ b/board/st/stm32h743-disco/MAINTAINERS @@ -0,0 +1,8 @@ +STM32H743 DISCOVERY BOARD +M: Patrice Chotard <patrice.chotard@foss.st.com> +S: Maintained +F: doc/board/st/ +F: board/st/stm32h743-disco +F: include/configs/stm32h743-disco.h +F: configs/stm32h743-disco_defconfig +F: arch/arm/dts/stm32h7* diff --git a/board/st/stm32h743-disco/Makefile b/board/st/stm32h743-disco/Makefile new file mode 100644 index 00000000000..b6c22be1ea1 --- /dev/null +++ b/board/st/stm32h743-disco/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2017, STMicroelectronics - All Rights Reserved +# Author(s): Patrice CHOTARD, <patrice.chotard@foss.st.com> for STMicroelectronics. + +obj-y := stm32h743-disco.o diff --git a/board/st/stm32h743-disco/stm32h743-disco.c b/board/st/stm32h743-disco/stm32h743-disco.c new file mode 100644 index 00000000000..35ef9ff9e28 --- /dev/null +++ b/board/st/stm32h743-disco/stm32h743-disco.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved + * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. + */ + +#include <dm.h> +#include <init.h> +#include <log.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) { + debug("DRAM init failed: %d\n", ret); + return ret; + } + + if (fdtdec_setup_mem_size_base() != 0) + ret = -EINVAL; + + return ret; +} + +int dram_init_banksize(void) +{ + fdtdec_setup_memory_banksize(); + + return 0; +} + +int board_init(void) +{ + return 0; +} diff --git a/board/st/stm32h743-eval/Kconfig b/board/st/stm32h743-eval/Kconfig new file mode 100644 index 00000000000..ff86de25f7d --- /dev/null +++ b/board/st/stm32h743-eval/Kconfig @@ -0,0 +1,18 @@ +if TARGET_STM32H743_EVAL + +config SYS_BOARD + string + default "stm32h743-eval" + +config SYS_VENDOR + string + default "st" + +config SYS_SOC + string + default "stm32h7" + +config SYS_CONFIG_NAME + default "stm32h743-eval" + +endif diff --git a/board/st/stm32h743-eval/MAINTAINERS b/board/st/stm32h743-eval/MAINTAINERS new file mode 100644 index 00000000000..b69e0d4abbb --- /dev/null +++ b/board/st/stm32h743-eval/MAINTAINERS @@ -0,0 +1,7 @@ +STM32H743 EVALUATION BOARD +M: Patrice Chotard <patrice.chotard@foss.st.com> +S: Maintained +F: doc/board/st/ +F: board/st/stm32h743-eval +F: include/configs/stm32h743-eval.h +F: configs/stm32h743-eval_defconfig diff --git a/board/st/stm32h743-eval/Makefile b/board/st/stm32h743-eval/Makefile new file mode 100644 index 00000000000..86ef19fc36c --- /dev/null +++ b/board/st/stm32h743-eval/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2017, STMicroelectronics - All Rights Reserved +# Author(s): Patrice CHOTARD, <patrice.chotard@foss.st.com> for STMicroelectronics. + +obj-y := stm32h743-eval.o diff --git a/board/st/stm32h743-eval/stm32h743-eval.c b/board/st/stm32h743-eval/stm32h743-eval.c new file mode 100644 index 00000000000..35ef9ff9e28 --- /dev/null +++ b/board/st/stm32h743-eval/stm32h743-eval.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved + * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. + */ + +#include <dm.h> +#include <init.h> +#include <log.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) { + debug("DRAM init failed: %d\n", ret); + return ret; + } + + if (fdtdec_setup_mem_size_base() != 0) + ret = -EINVAL; + + return ret; +} + +int dram_init_banksize(void) +{ + fdtdec_setup_memory_banksize(); + + return 0; +} + +int board_init(void) +{ + return 0; +} diff --git a/board/st/stm32h750-art-pi/Kconfig b/board/st/stm32h750-art-pi/Kconfig new file mode 100644 index 00000000000..ab2d0f227d7 --- /dev/null +++ b/board/st/stm32h750-art-pi/Kconfig @@ -0,0 +1,18 @@ +if TARGET_STM32H750_ART_PI + +config SYS_BOARD + string + default "stm32h750-art-pi" + +config SYS_VENDOR + string + default "st" + +config SYS_SOC + string + default "stm32h7" + +config SYS_CONFIG_NAME + default "stm32h750-art-pi" + +endif diff --git a/board/st/stm32h750-art-pi/MAINTAINERS b/board/st/stm32h750-art-pi/MAINTAINERS new file mode 100644 index 00000000000..2fd69e6d1ca --- /dev/null +++ b/board/st/stm32h750-art-pi/MAINTAINERS @@ -0,0 +1,8 @@ +STM32H750 ART PI BOARD +M: Dillon Min <dillon.minfei@gmail.com> +S: Maintained +F: doc/board/st/ +F: board/st/stm32h750-art-pi +F: include/configs/stm32h750-art-pi.h +F: configs/stm32h750-art-pi_defconfig +F: arch/arm/dts/stm32h7* diff --git a/board/st/stm32h750-art-pi/Makefile b/board/st/stm32h750-art-pi/Makefile new file mode 100644 index 00000000000..a06de87526b --- /dev/null +++ b/board/st/stm32h750-art-pi/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2021, RT-Thread - All Rights Reserved +# Author(s): Dillon Min, <dillon.minfei@gmail.com> for RT-Thread. + +obj-y := stm32h750-art-pi.o diff --git a/board/st/stm32h750-art-pi/stm32h750-art-pi.c b/board/st/stm32h750-art-pi/stm32h750-art-pi.c new file mode 100644 index 00000000000..75aa4d139fb --- /dev/null +++ b/board/st/stm32h750-art-pi/stm32h750-art-pi.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021, STMicroelectronics - All Rights Reserved + * Author(s): Dillon Min <dillon.minfei@gmail.com> + */ + +#include <dm.h> +#include <init.h> +#include <log.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) { + debug("DRAM init failed: %d\n", ret); + return ret; + } + + if (fdtdec_setup_mem_size_base() != 0) + ret = -EINVAL; + + return ret; +} + +int dram_init_banksize(void) +{ + fdtdec_setup_memory_banksize(); + + return 0; +} + +int board_early_init_f(void) +{ + return 0; +} + +int board_late_init(void) +{ + return 0; +} + +int board_init(void) +{ + return 0; +} diff --git a/board/st/stm32mp1/Kconfig b/board/st/stm32mp1/Kconfig new file mode 100644 index 00000000000..96de41546f1 --- /dev/null +++ b/board/st/stm32mp1/Kconfig @@ -0,0 +1,28 @@ +if TARGET_ST_STM32MP15X + +config SYS_BOARD + default "stm32mp1" + +config SYS_VENDOR + default "st" + +config SYS_CONFIG_NAME + default "stm32mp15_st_common" + +source "board/st/common/Kconfig" +endif + +if TARGET_ST_STM32MP13X + +config SYS_BOARD + default "stm32mp1" + +config SYS_VENDOR + default "st" + +config SYS_CONFIG_NAME + default "stm32mp13_st_common" + +source "board/st/common/Kconfig" + +endif diff --git a/board/st/stm32mp1/MAINTAINERS b/board/st/stm32mp1/MAINTAINERS new file mode 100644 index 00000000000..d5a09cdc39f --- /dev/null +++ b/board/st/stm32mp1/MAINTAINERS @@ -0,0 +1,16 @@ +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/stm32mp13* +F: arch/arm/dts/stm32mp15* +F: board/st/stm32mp1/ +F: configs/stm32mp13_defconfig +F: configs/stm32mp15_defconfig +F: configs/stm32mp15_basic_defconfig +F: configs/stm32mp15_trusted_defconfig +F: include/configs/stm32mp13_common.h +F: include/configs/stm32mp13_st_common.h +F: include/configs/stm32mp15_common.h +F: include/configs/stm32mp15_st_common.h diff --git a/board/st/stm32mp1/Makefile b/board/st/stm32mp1/Makefile new file mode 100644 index 00000000000..f2d720b67b3 --- /dev/null +++ b/board/st/stm32mp1/Makefile @@ -0,0 +1,12 @@ +# 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 + +obj-$(CONFIG_DEBUG_UART_BOARD_INIT) += debug_uart.o diff --git a/board/st/stm32mp1/README b/board/st/stm32mp1/README new file mode 100644 index 00000000000..8172d26a66c --- /dev/null +++ b/board/st/stm32mp1/README @@ -0,0 +1 @@ +see doc/board/st/stm32mp1.rst diff --git a/board/st/stm32mp1/debug_uart.c b/board/st/stm32mp1/debug_uart.c new file mode 100644 index 00000000000..24e3f9f2201 --- /dev/null +++ b/board/st/stm32mp1/debug_uart.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved + */ + +#include <config.h> +#include <debug_uart.h> +#include <asm/io.h> +#include <asm/arch/stm32.h> +#include <linux/bitops.h> + +#define RCC_MP_APB1ENSETR (STM32_RCC_BASE + 0x0A00) +#define RCC_MP_AHB4ENSETR (STM32_RCC_BASE + 0x0A28) + +#define GPIOG_BASE 0x50008000 + +void board_debug_uart_init(void) +{ + if (CONFIG_DEBUG_UART_BASE == STM32_UART4_BASE) { + /* UART4 clock enable */ + setbits_le32(RCC_MP_APB1ENSETR, BIT(16)); + + /* 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); + } +} diff --git a/board/st/stm32mp1/extlinux.conf b/board/st/stm32mp1/extlinux.conf new file mode 100644 index 00000000000..2b4632804df --- /dev/null +++ b/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/board/st/stm32mp1/fit_copro_kernel_dtb.its b/board/st/stm32mp1/fit_copro_kernel_dtb.its new file mode 100644 index 00000000000..dc43639af4b --- /dev/null +++ b/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/board/st/stm32mp1/fit_kernel_dtb.its b/board/st/stm32mp1/fit_kernel_dtb.its new file mode 100644 index 00000000000..8456a3c460f --- /dev/null +++ b/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/board/st/stm32mp1/spl.c b/board/st/stm32mp1/spl.c new file mode 100644 index 00000000000..d63dffd97e8 --- /dev/null +++ b/board/st/stm32mp1/spl.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + */ + +#include <config.h> +#include <power/pmic.h> +#include <power/stpmic1.h> +#include <asm/arch/sys_proto.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)) + opp_voltage_mv = voltage_mv; +} + +int board_early_init_f(void) +{ + if (IS_ENABLED(CONFIG_PMIC_STPMIC1) && CONFIG_IS_ENABLED(POWER)) { + struct udevice *dev = stpmic1_init(opp_voltage_mv); + + /* Keep vdd on during the reset cycle */ + pmic_clrsetbits(dev, + STPMIC1_BUCKS_MRST_CR, + STPMIC1_MRST_BUCK(STPMIC1_BUCK3), + STPMIC1_MRST_BUCK(STPMIC1_BUCK3)); + } + + return 0; +} + diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c new file mode 100644 index 00000000000..97532a8156f --- /dev/null +++ b/board/st/stm32mp1/stm32mp1.c @@ -0,0 +1,896 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + */ + +#define LOG_CATEGORY LOGC_BOARD + +#include <adc.h> +#include <bootm.h> +#include <button.h> +#include <clk.h> +#include <config.h> +#include <dm.h> +#include <efi_loader.h> +#include <env.h> +#include <env_internal.h> +#include <fdt_simplefb.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 <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 <dm/device-internal.h> +#include <dm/ofnode.h> +#include <jffs2/load_kernel.h> +#include <linux/bitops.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/iopoll.h> +#include <linux/printk.h> +#include <power/regulator.h> +#include <usb/dwc2_udc.h> + +#include "../../st/common/stusb160x.h" + +/* SYSCFG registers */ +#define SYSCFG_BOOTR 0x00 +#define SYSCFG_IOCTRLSETR 0x18 +#define SYSCFG_ICNR 0x1C +#define SYSCFG_CMPCR 0x20 +#define SYSCFG_CMPENSETR 0x24 + +#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 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 + +#if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_image fw_images[1]; + +struct efi_capsule_update_info update_info = { + .num_images = ARRAY_SIZE(fw_images), + .images = fw_images, +}; + +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + +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)) { + if (IS_ENABLED(CONFIG_STM32MP15X_STM32IMAGE)) + mode = "trusted - stm32image"; + else + mode = "trusted"; + } else { + mode = "basic"; + } + + fdt_compat = ofnode_get_property(ofnode_root(), "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 (IS_ENABLED(CONFIG_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) +{ + struct udevice *button1 = NULL, *button2 = NULL; + enum forced_boot_mode boot_mode = BOOT_NORMAL; + int ret; + + if (!IS_ENABLED(CONFIG_BUTTON)) + return; + + if (!IS_ENABLED(CONFIG_FASTBOOT) && !IS_ENABLED(CONFIG_CMD_STM32PROG)) + return; + + if (IS_ENABLED(CONFIG_CMD_STM32PROG)) + button_get_by_label("User-1", &button1); + + if (IS_ENABLED(CONFIG_FASTBOOT)) + button_get_by_label("User-2", &button2); + + if (!button1 && !button2) + return; + + if (button2) { + if (button_get_state(button2) == BUTTON_ON) { + log_notice("Fastboot key pressed, "); + boot_mode = BOOT_FASTBOOT; + } + /* + * On some boards, same gpio is shared betwwen gpio-keys and + * leds, remove the button device to free the gpio for led + * usage + */ + ret = device_remove(button2, DM_REMOVE_NORMAL); + if (ret) + log_err("Can't remove button2 (%d)\n", ret); + } + + if (button1) { + if (button_get_state(button1) == BUTTON_ON) { + log_notice("STM32Programmer key pressed, "); + boot_mode = BOOT_STM32PROG; + } + /* + * On some boards, same gpio is shared betwwen gpio-keys and + * leds, remove the button device to free the gpio for led + * usage + */ + ret = device_remove(button1, DM_REMOVE_NORMAL); + if (ret) + log_err("Can't remove button1 (%d)\n", ret); + } + + 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; + + /* + * In case of USB boot device is detected, consider USB cable is + * connected + */ + if ((get_bootmode() & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_USB) + return true; + + /* 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) +{ + const char *led_name; + int ret; + + led_name = ofnode_conf_read_str(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); + schedule(); + } + 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) { + 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); +} + +static int board_stm32mp15x_dk2_init(void) +{ + ofnode node; + struct gpio_desc hdmi, audio; + int ret = 0; + + /* Fix to make I2C1 usable on DK2 for touchscreen usage in kernel */ + 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_stm32mp15x_dk2(void) +{ + if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15X) && + of_machine_is_compatible("st,stm32mp157c-dk2")) + return true; + + return false; +} + +static bool board_is_stm32mp15x_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_stm32mp15x_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) +{ + board_key_check(); + + if (board_is_stm32mp15x_ev1()) + board_stm32mp15x_ev1_init(); + + if (board_is_stm32mp15x_dk2()) + board_stm32mp15x_dk2_init(); + + regulators_enable_boot_on(_DEBUG); + + /* + * sysconf initialisation done only when U-Boot is running in secure + * done in TF-A for TFABOOT. + */ + if (IS_ENABLED(CONFIG_ARMV7_NONSEC)) + sysconf_init(); + + setup_led(LEDST_ON); + +#if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) + efi_guid_t image_type_guid = STM32MP_FIP_IMAGE_GUID; + + guidcpy(&fw_images[0].image_type_id, &image_type_guid); + fw_images[0].fw_name = u"STM32MP-FIP"; + fw_images[0].image_index = 1; +#endif + 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 = ofnode_get_property(ofnode_root(), "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); +} + +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 (IS_ENABLED(CONFIG_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 ""; + } +} + +int mmc_get_boot(void) +{ + struct udevice *dev; + u32 boot_mode = get_bootmode(); + unsigned int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1; + char cmd[20]; + const u32 sdmmc_addr[] = { + STM32_SDMMC1_BASE, + STM32_SDMMC2_BASE, + STM32_SDMMC3_BASE + }; + + if (instance >= ARRAY_SIZE(sdmmc_addr)) + return 0; + + /* search associated sdmmc node in devicetree */ + snprintf(cmd, sizeof(cmd), "mmc@%x", sdmmc_addr[instance]); + if (uclass_get_device_by_name(UCLASS_MMC, cmd, &dev)) { + log_err("mmc%d = %s not found in device tree!\n", instance, cmd); + return 0; + } + + return dev_seq(dev); +}; + +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; + + return dev_part[mmc_get_boot()]; +} + +int mmc_get_env_dev(void) +{ + const int mmc_env_dev = CONFIG_IS_ENABLED(ENV_IS_IN_MMC, (CONFIG_SYS_MMC_ENV_DEV), (-1)); + + if (mmc_env_dev >= 0) + return mmc_env_dev; + + /* use boot instance to select the correct mmc device identifier */ + return mmc_get_boot(); +} + +#if defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + fdt_copy_fixed_partitions(blob); + + if (IS_ENABLED(CONFIG_FDT_SIMPLEFB)) + fdt_simplefb_enable_and_mem_rsv(blob); + + 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); + +#if defined(CONFIG_FWU_MULTI_BANK_UPDATE) + +#include <fwu.h> + +/** + * fwu_plat_get_bootidx() - Get the value of the boot index + * @boot_idx: Boot index value + * + * Get the value of the bank(partition) from which the platform + * has booted. This value is passed to U-Boot from the earlier + * stage bootloader which loads and boots all the relevant + * firmware images + * + */ +void fwu_plat_get_bootidx(uint *boot_idx) +{ + *boot_idx = (readl(TAMP_FWU_BOOT_INFO_REG) >> + TAMP_FWU_BOOT_IDX_OFFSET) & TAMP_FWU_BOOT_IDX_MASK; +} +#endif /* CONFIG_FWU_MULTI_BANK_UPDATE */ diff --git a/board/st/stm32mp2/Kconfig b/board/st/stm32mp2/Kconfig new file mode 100644 index 00000000000..89039f068a2 --- /dev/null +++ b/board/st/stm32mp2/Kconfig @@ -0,0 +1,13 @@ +if TARGET_ST_STM32MP25X + +config SYS_BOARD + default "stm32mp2" + +config SYS_VENDOR + default "st" + +config SYS_CONFIG_NAME + default "stm32mp25_common" + +source "board/st/common/Kconfig" +endif diff --git a/board/st/stm32mp2/MAINTAINERS b/board/st/stm32mp2/MAINTAINERS new file mode 100644 index 00000000000..e6bea910f92 --- /dev/null +++ b/board/st/stm32mp2/MAINTAINERS @@ -0,0 +1,9 @@ +STM32MP2 BOARD +M: Patrice Chotard <patrice.chotard@st.com> +M: Patrick Delaunay <patrick.delaunay@st.com> +L: uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers) +S: Maintained +F: arch/arm/dts/stm32mp25* +F: board/st/stm32mp2/ +F: configs/stm32mp25_defconfig +F: include/configs/stm32mp25_common.h diff --git a/board/st/stm32mp2/Makefile b/board/st/stm32mp2/Makefile new file mode 100644 index 00000000000..50352fb71b4 --- /dev/null +++ b/board/st/stm32mp2/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +# +# Copyright (C) 2023, STMicroelectronics - All Rights Reserved +# + +obj-y += stm32mp2.o diff --git a/board/st/stm32mp2/stm32mp2.c b/board/st/stm32mp2/stm32mp2.c new file mode 100644 index 00000000000..aa7dd31996e --- /dev/null +++ b/board/st/stm32mp2/stm32mp2.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (C) 2023, STMicroelectronics - All Rights Reserved + */ + +#define LOG_CATEGORY LOGC_BOARD + +#include <config.h> +#include <env.h> +#include <fdt_support.h> +#include <log.h> +#include <misc.h> +#include <asm/global_data.h> +#include <asm/arch/sys_proto.h> +#include <dm/device.h> +#include <dm/ofnode.h> +#include <dm/uclass.h> + +/* + * Get a global data pointer + */ +DECLARE_GLOBAL_DATA_PTR; + +int checkboard(void) +{ + int ret; + u32 otp; + struct udevice *dev; + const char *fdt_compat; + int fdt_compat_len; + + fdt_compat = ofnode_get_property(ofnode_root(), "compatible", &fdt_compat_len); + + log_info("Board: stm32mp2 (%s)\n", 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; +} + +/* board dependent setup after realloc */ +int board_init(void) +{ + return 0; +} + +int board_late_init(void) +{ + const void *fdt_compat; + int fdt_compat_len; + 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); + strlcpy(dtb_name, fdt_compat + 3, buf_len); + buf_len -= strlen(fdt_compat + 3); + strlcat(dtb_name, ".dtb", buf_len); + env_set("fdtfile", dtb_name); + } + } + } + + return 0; +} |