diff options
author | 2023-10-10 14:33:42 +0000 | |
---|---|---|
committer | 2023-10-10 14:33:42 +0000 | |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/u-boot/board/st/common | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/u-boot/board/st/common')
-rw-r--r-- | roms/u-boot/board/st/common/Kconfig | 78 | ||||
-rw-r--r-- | roms/u-boot/board/st/common/MAINTAINERS | 6 | ||||
-rw-r--r-- | roms/u-boot/board/st/common/Makefile | 14 | ||||
-rw-r--r-- | roms/u-boot/board/st/common/cmd_stboard.c | 206 | ||||
-rw-r--r-- | roms/u-boot/board/st/common/stm32mp_dfu.c | 250 | ||||
-rw-r--r-- | roms/u-boot/board/st/common/stm32mp_mtdparts.c | 163 | ||||
-rw-r--r-- | roms/u-boot/board/st/common/stpmic1.c | 219 | ||||
-rw-r--r-- | roms/u-boot/board/st/common/stpmic1.h | 6 | ||||
-rw-r--r-- | roms/u-boot/board/st/common/stusb160x.c | 48 | ||||
-rw-r--r-- | roms/u-boot/board/st/common/stusb160x.h | 10 |
10 files changed, 1000 insertions, 0 deletions
diff --git a/roms/u-boot/board/st/common/Kconfig b/roms/u-boot/board/st/common/Kconfig new file mode 100644 index 000000000..ddcf33a12 --- /dev/null +++ b/roms/u-boot/board/st/common/Kconfig @@ -0,0 +1,78 @@ +config CMD_STBOARD + bool "stboard - command for OTP board information" + depends on ARCH_STM32MP + default y if TARGET_ST_STM32MP15x + help + This compile the stboard command to + read and write the board in the OTP. + +config MTDPARTS_NAND0_BOOT + string "mtd boot partitions for nand0" + default "2m(fsbl),2m(ssbl1),2m(ssbl2)" + depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP + help + This define the partitions of nand0 used to build mtparts dynamically + for boot from nand0. + Each partition need to be aligned with the device erase block size, + 512KB is the max size for the NAND supported by stm32mp1 platform. + +config MTDPARTS_NAND0_TEE + string "mtd tee partitions for nand0" + default "512k(teeh),512k(teed),512k(teex)" + depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP + help + This define the tee partitions added in mtparts dynamically + when tee is supported with boot from nand0. + Each partition need to be aligned with the device erase block size, + 512KB is the max size for the NAND supported by stm32mp1 platform. + +config MTDPARTS_NOR0_BOOT + string "mtd boot partitions for nor0" + default "256k(fsbl1),256k(fsbl2),2m(ssbl),512k(u-boot-env)" + depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP + help + This define the partitions of nand0 used to build mtparts dynamically + for boot from nor0. + Each partition need to be aligned with the device erase block size, + with 256KB we support all the NOR. + U-Boot env partition (512kB) use 2 erase block for redundancy. + +config MTDPARTS_NOR0_TEE + string "mtd tee partitions for nor0" + default "256k(teeh),512k(teed),256k(teex)" + depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP + help + This define the tee partitions added in mtparts dynamically + when tee is supported with boot from nor0. + +config MTDPARTS_SPINAND0_BOOT + string "mtd boot partitions for spi-nand0" + default "2m(fsbl),2m(ssbl1),2m(ssbl2)" + depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP + help + This define the partitions of nand0 used to build mtparts dynamically + for boot from spi-nand0, + 512KB is the max size for the NAND supported by stm32mp1 platform. + +config MTDPARTS_SPINAND0_TEE + string "mtd tee partitions for spi-nand0" + default "512k(teeh),512k(teed),512k(teex)" + depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP + help + This define the tee partitions added in mtparts dynamically + when tee is supported with boot from spi-nand0, + 512KB is the max size for the NAND supported by stm32mp1 platform. + +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/roms/u-boot/board/st/common/MAINTAINERS b/roms/u-boot/board/st/common/MAINTAINERS new file mode 100644 index 000000000..0c6db5477 --- /dev/null +++ b/roms/u-boot/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/roms/u-boot/board/st/common/Makefile b/roms/u-boot/board/st/common/Makefile new file mode 100644 index 000000000..65bbebd6a --- /dev/null +++ b/roms/u-boot/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_SYS_MTDPARTS_RUNTIME) += stm32mp_mtdparts.o +obj-$(CONFIG_SET_DFU_ALT_INFO) += stm32mp_dfu.o +endif + +obj-$(CONFIG_TYPEC_STUSB160X) += stusb160x.o diff --git a/roms/u-boot/board/st/common/cmd_stboard.c b/roms/u-boot/board/st/common/cmd_stboard.c new file mode 100644 index 000000000..2fba38316 --- /dev/null +++ b/roms/u-boot/board/st/common/cmd_stboard.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2019, STMicroelectronics - All Rights Reserved + * + * the st command stboard supports the STMicroelectronics board identification + * saved in OTP 59. + * + * 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 OTP59, 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 <common.h> +#include <command.h> +#include <console.h> +#include <misc.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, + }; + + 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 < 0) { + puts("OTP read error"); + return CMD_RET_FAILURE; + } + + ret = misc_read(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD), + &lock, sizeof(lock)); + if (ret < 0) { + puts("LOCK read error"); + 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 == 1 ? "" : "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 < 0) { + puts("BOARD programming error\n"); + return CMD_RET_FAILURE; + } + + /* write persistent lock */ + otp = 1; + ret = misc_write(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD), + &otp, sizeof(otp)); + if (ret < 0) { + 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/roms/u-boot/board/st/common/stm32mp_dfu.c b/roms/u-boot/board/st/common/stm32mp_dfu.c new file mode 100644 index 000000000..00d1fb8f5 --- /dev/null +++ b/roms/u-boot/board/st/common/stm32mp_dfu.c @@ -0,0 +1,250 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +#include <common.h> +#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> + +#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_if_type_name(desc->if_type); + 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; + bool first = true; + 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++; + if (!first) + len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ";"); + first = false; + + 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 (CONFIG_IS_ENABLED(MTD)) { + /* probe all MTD devices */ + mtd_probe_devices(); + + /* probe SPI flash device on a bus */ + if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) { + mtd = get_mtd_device_nm("nor0"); + if (!IS_ERR_OR_NULL(mtd)) + board_get_alt_info_mtd(mtd, buf); + } + + mtd = get_mtd_device_nm("nand0"); + if (!IS_ERR_OR_NULL(mtd)) + board_get_alt_info_mtd(mtd, buf); + + mtd = get_mtd_device_nm("spi-nand0"); + if (!IS_ERR_OR_NULL(mtd)) + board_get_alt_info_mtd(mtd, buf); + } + + if (IS_ENABLED(CONFIG_DFU_VIRT) && + IS_ENABLED(CMD_STM32PROG_USB)) { + strncat(buf, "&virt 0=OTP", DFU_ALT_BUF_LEN); + + if (IS_ENABLED(CONFIG_PMIC_STPMIC1)) + strncat(buf, "&virt 1=PMIC", DFU_ALT_BUF_LEN); + } + + env_set("dfu_alt_info", buf); + puts("DFU alt info setting: done\n"); +} + +#if CONFIG_IS_ENABLED(DFU_VIRT) +#include <dfu.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; +#ifdef CONFIG_PMIC_STPMIC1 + struct udevice *dev; + + 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; + } +#else + log_err("PMIC update not supported"); + ret = -EOPNOTSUPP; +#endif + + 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 __weak 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; +} + +#endif diff --git a/roms/u-boot/board/st/common/stm32mp_mtdparts.c b/roms/u-boot/board/st/common/stm32mp_mtdparts.c new file mode 100644 index 000000000..f074fc189 --- /dev/null +++ b/roms/u-boot/board/st/common/stm32mp_mtdparts.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +#include <common.h> +#include <dfu.h> +#include <dm.h> +#include <env.h> +#include <env_internal.h> +#include <log.h> +#include <mtd.h> +#include <mtd_node.h> +#include <tee.h> +#include <asm/arch/stm32prog.h> +#include <asm/arch/sys_proto.h> +#include <asm/global_data.h> + +#define MTDPARTS_LEN 256 +#define MTDIDS_LEN 128 + +/* + * Get a global data pointer + */ +DECLARE_GLOBAL_DATA_PTR; + +/** + * update the variables "mtdids" and "mtdparts" with boot, tee and user strings + */ +static void board_set_mtdparts(const char *dev, + char *mtdids, + char *mtdparts, + const char *boot, + const char *tee, + const char *user) +{ + /* mtdids: "<dev>=<dev>, ...." */ + if (mtdids[0] != '\0') + strcat(mtdids, ","); + strcat(mtdids, dev); + strcat(mtdids, "="); + strcat(mtdids, dev); + + /* mtdparts: "mtdparts=<dev>:<mtdparts_<dev>>;..." */ + if (mtdparts[0] != '\0') + strncat(mtdparts, ";", MTDPARTS_LEN); + else + strcat(mtdparts, "mtdparts="); + + strncat(mtdparts, dev, MTDPARTS_LEN); + strncat(mtdparts, ":", MTDPARTS_LEN); + + if (boot) { + strncat(mtdparts, boot, MTDPARTS_LEN); + strncat(mtdparts, ",", MTDPARTS_LEN); + } + + if (tee) { + strncat(mtdparts, tee, MTDPARTS_LEN); + strncat(mtdparts, ",", MTDPARTS_LEN); + } + + strncat(mtdparts, user, MTDPARTS_LEN); +} + +void board_mtdparts_default(const char **mtdids, const char **mtdparts) +{ + struct mtd_info *mtd; + struct udevice *dev; + static char parts[3 * MTDPARTS_LEN + 1]; + static char ids[MTDIDS_LEN + 1]; + static bool mtd_initialized; + bool tee, nor, nand, spinand, serial; + + if (mtd_initialized) { + *mtdids = ids; + *mtdparts = parts; + return; + } + + tee = false; + nor = false; + nand = false; + spinand = false; + serial = false; + + switch (get_bootmode() & TAMP_BOOT_DEVICE_MASK) { + case BOOT_SERIAL_UART: + case BOOT_SERIAL_USB: + serial = true; + if (CONFIG_IS_ENABLED(CMD_STM32PROG)) { + tee = stm32prog_get_tee_partitions(); + nor = stm32prog_get_fsbl_nor(); + } + nand = true; + spinand = true; + break; + case BOOT_FLASH_NAND: + nand = true; + break; + case BOOT_FLASH_SPINAND: + spinand = true; + break; + case BOOT_FLASH_NOR: + nor = true; + break; + default: + break; + } + + if (!serial && CONFIG_IS_ENABLED(OPTEE) && + tee_find_device(NULL, NULL, NULL, NULL)) + tee = true; + + memset(parts, 0, sizeof(parts)); + memset(ids, 0, sizeof(ids)); + + /* probe all MTD devices */ + for (uclass_first_device(UCLASS_MTD, &dev); + dev; + uclass_next_device(&dev)) { + log_debug("mtd device = %s\n", dev->name); + } + + if (nand) { + mtd = get_mtd_device_nm("nand0"); + if (!IS_ERR_OR_NULL(mtd)) { + const char *mtd_tee = CONFIG_MTDPARTS_NAND0_TEE; + board_set_mtdparts("nand0", ids, parts, + CONFIG_MTDPARTS_NAND0_BOOT, + !nor && tee ? mtd_tee : NULL, + "-(UBI)"); + put_mtd_device(mtd); + } + } + + if (spinand) { + mtd = get_mtd_device_nm("spi-nand0"); + if (!IS_ERR_OR_NULL(mtd)) { + const char *mtd_tee = CONFIG_MTDPARTS_SPINAND0_TEE; + board_set_mtdparts("spi-nand0", ids, parts, + CONFIG_MTDPARTS_SPINAND0_BOOT, + !nor && tee ? mtd_tee : NULL, + "-(UBI)"); + put_mtd_device(mtd); + } + } + + if (nor) { + if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) { + const char *mtd_tee = CONFIG_MTDPARTS_NOR0_TEE; + board_set_mtdparts("nor0", ids, parts, + CONFIG_MTDPARTS_NOR0_BOOT, + tee ? mtd_tee : NULL, + "-(nor_user)"); + } + } + + mtd_initialized = true; + *mtdids = ids; + *mtdparts = parts; + log_debug("mtdids=%s & mtdparts=%s\n", ids, parts); +} diff --git a/roms/u-boot/board/st/common/stpmic1.c b/roms/u-boot/board/st/common/stpmic1.c new file mode 100644 index 000000000..5fb1be2fd --- /dev/null +++ b/roms/u-boot/board/st/common/stpmic1.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +#define LOG_CATEGORY LOGC_BOARD + +#include <common.h> +#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 */ +void stpmic1_init(u32 voltage_mv) +{ + struct udevice *dev; + + if (uclass_get_device_by_driver(UCLASS_PMIC, + DM_DRIVER_GET(pmic_stpmic1), &dev)) + return; + + /* update VDDCORE = BUCK1 */ + if (voltage_mv) + stmpic_buck1_set(dev, 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)); + + /* Check if debug is enabled to program PMIC according to the bit */ + if (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_DEBUG_ON) { + log_info("Keep debug unit ON\n"); + + pmic_clrsetbits(dev, STPMIC1_BUCKS_MRST_CR, + STPMIC1_MRST_BUCK_DEBUG, + STPMIC1_MRST_BUCK_DEBUG); + + if (STPMIC1_MRST_LDO_DEBUG) + pmic_clrsetbits(dev, STPMIC1_LDOS_MRST_CR, + STPMIC1_MRST_LDO_DEBUG, + STPMIC1_MRST_LDO_DEBUG); + } +} diff --git a/roms/u-boot/board/st/common/stpmic1.h b/roms/u-boot/board/st/common/stpmic1.h new file mode 100644 index 000000000..b17d6f163 --- /dev/null +++ b/roms/u-boot/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 + */ + +void stpmic1_init(u32 voltage_mv); diff --git a/roms/u-boot/board/st/common/stusb160x.c b/roms/u-boot/board/st/common/stusb160x.c new file mode 100644 index 000000000..f0385e5e3 --- /dev/null +++ b/roms/u-boot/board/st/common/stusb160x.c @@ -0,0 +1,48 @@ +// 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 <common.h> +#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/roms/u-boot/board/st/common/stusb160x.h b/roms/u-boot/board/st/common/stusb160x.h new file mode 100644 index 000000000..fe39840b4 --- /dev/null +++ b/roms/u-boot/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 |