From 3aac802adabb5ef4d55d2bfda97d264725aa25ad Mon Sep 17 00:00:00 2001 From: Romuald JEANNE Date: Tue, 17 Sep 2019 13:54:46 +0200 Subject: [PATCH 09/13] ARM v2018.11 stm32mp r3 MACHINE --- arch/arm/mach-stm32mp/Kconfig | 30 +-- arch/arm/mach-stm32mp/Makefile | 8 +- arch/arm/mach-stm32mp/bsec.c | 16 +- arch/arm/mach-stm32mp/cmd_poweroff.c | 2 +- arch/arm/mach-stm32mp/cmd_stm32key.c | 3 +- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 25 ++- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h | 2 +- .../mach-stm32mp/cmd_stm32prog/stm32prog_serial.c | 44 ++-- .../arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c | 11 +- arch/arm/mach-stm32mp/config.mk | 5 +- arch/arm/mach-stm32mp/cpu.c | 165 ++++++++------- arch/arm/mach-stm32mp/fdt.c | 224 +++++++++++++++++++++ arch/arm/mach-stm32mp/include/mach/stm32.h | 6 - arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h | 2 +- arch/arm/mach-stm32mp/include/mach/sys_proto.h | 13 ++ arch/arm/mach-stm32mp/psci.c | 23 ++- arch/arm/mach-stm32mp/spl.c | 6 +- arch/arm/mach-stm32mp/stm32-etzpc.c | 199 ------------------ arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S | 136 +++++++++++++ arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S | 124 ------------ arch/arm/mach-stm32mp/syscon.c | 1 - 21 files changed, 581 insertions(+), 464 deletions(-) create mode 100644 arch/arm/mach-stm32mp/fdt.c delete mode 100644 arch/arm/mach-stm32mp/stm32-etzpc.c create mode 100644 arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S delete mode 100644 arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig index fbc8195..470b51f 100644 --- a/arch/arm/mach-stm32mp/Kconfig +++ b/arch/arm/mach-stm32mp/Kconfig @@ -39,16 +39,18 @@ config TARGET_STM32MP1 select STM32_RESET select STM32_SERIAL imply BOOTCOUNT_LIMIT + imply PRE_CONSOLE_BUFFER + imply SILENT_CONSOLE imply SYSRESET_PSCI if STM32MP1_TRUSTED imply SYSRESET_SYSCON if !STM32MP1_TRUSTED help target STMicroelectronics SOC STM32MP1 family - STM32MP153 or STM32MP151 + STM32MP157, STM32MP153 or STM32MP151 STMicroelectronics MPU with core ARMv7 - dual core A7 for STM32MP153, monocore for STM32MP151 + dual core A7 for STM32MP157/3, monocore for STM32MP151 config STM32MP1_RESET_HALT_WORKAROUND - bool "workaround for reset halt deubg on stm32mp15x" + bool "workaround for reset halt debug on stm32mp15x" depends on TARGET_STM32MP1 default y help @@ -59,7 +61,6 @@ config STM32MP1_RESET_HALT_WORKAROUND it can be removed when using the Soc revision that fixes the limitation. - config STM32MP1_TRUSTED bool "Support trusted boot with TF-A" default y if !SPL @@ -68,7 +69,7 @@ config STM32MP1_TRUSTED Say Y here to enable boot with TF-A Trusted boot chain is : BootRom => TF-A.stm32 (clock & DDR) => U-Boot.stm32 - TF-A monitor provide ST smc to manage secure devices + TF-A monitor provides proprietary smc to manage secure devices config STM32MP1_OPTEE bool "Support trusted boot with TF-A and OPTEE" @@ -96,8 +97,6 @@ config STM32_ETZPC Say y to enable STM32 Extended TrustZone Protection Controller (ETZPC) -source "board/st/stm32mp1/Kconfig" - config CMD_STM32PROG bool "command stm32prog for STM32CudeProgrammer" default y @@ -132,13 +131,18 @@ config SYS_TEXT_BASE when DDR driver is used: DDR + 1MB (0xC0100000) +config PRE_CON_BUF_ADDR + default 0xC02FF000 + +config PRE_CON_BUF_SZ + default 4096 + config NR_DRAM_BANKS default 1 config BOOTSTAGE_STASH_ADDR default 0xC3000000 - if BOOTCOUNT_LIMIT config SYS_BOOTCOUNT_SINGLEWORD default y @@ -149,6 +153,10 @@ config SYS_BOOTCOUNT_ADDR endif if DEBUG_UART + +config DEBUG_UART_BOARD_INIT + default y + # debug on UART4 by default config DEBUG_UART_BASE default 0x40010000 @@ -156,10 +164,8 @@ config DEBUG_UART_BASE # clock source is HSI on reset config DEBUG_UART_CLOCK default 64000000 - -# currently activated for debug / should be deactivated for real product -config DEBUG_UART_BOARD_INIT - default y endif +source "board/st/stm32mp1/Kconfig" + endif diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile index c67bcce..9158a20 100644 --- a/arch/arm/mach-stm32mp/Makefile +++ b/arch/arm/mach-stm32mp/Makefile @@ -9,15 +9,15 @@ obj-y += syscon.o ifdef CONFIG_SPL_BUILD obj-y += spl.o -obj-$(CONFIG_STM32MP1_RESET_HALT_WORKAROUND) += stm32mp1_helper_dgb.o +obj-$(CONFIG_STM32MP1_RESET_HALT_WORKAROUND) += stm32mp1_helper_dbg.o else obj-$(CONFIG_CMD_STM32PROG) += cmd_stm32prog/ obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o -obj-$(CONFIG_ARMV7_PSCI) += psci.o obj-y += bsec.o -obj-y += cmd_poweroff.o +obj-$(CONFIG_SYSRESET) += cmd_poweroff.o +obj-$(CONFIG_ARMV7_PSCI) += psci.o endif obj-$(CONFIG_$(SPL_)DM_REGULATOR) += pwr_regulator.o -obj-$(CONFIG_STM32_ETZPC) += stm32-etzpc.o +obj-$(CONFIG_OF_SYSTEM_SETUP) += fdt.o diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c index 913dbef..5256378 100644 --- a/arch/arm/mach-stm32mp/bsec.c +++ b/arch/arm/mach-stm32mp/bsec.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ @@ -359,12 +359,13 @@ static int stm32mp_bsec_read(struct udevice *dev, int offset, bool shadow = true; int nb_otp = size / sizeof(u32); int otp; + unsigned int offs = offset; - if (offset >= STM32_BSEC_OTP_OFFSET) { - offset -= STM32_BSEC_OTP_OFFSET; + if (offs >= STM32_BSEC_OTP_OFFSET) { + offs -= STM32_BSEC_OTP_OFFSET; shadow = false; } - otp = offset / sizeof(u32); + otp = offs / sizeof(u32); if (otp < 0 || (otp + nb_otp - 1) > BSEC_OTP_MAX_VALUE) { dev_err(dev, "wrong value for otp, max value : %i\n", @@ -394,12 +395,13 @@ static int stm32mp_bsec_write(struct udevice *dev, int offset, bool shadow = true; int nb_otp = size / sizeof(u32); int otp; + unsigned int offs = offset; - if (offset >= STM32_BSEC_OTP_OFFSET) { - offset -= STM32_BSEC_OTP_OFFSET; + if (offs >= STM32_BSEC_OTP_OFFSET) { + offs -= STM32_BSEC_OTP_OFFSET; shadow = false; } - otp = offset / sizeof(u32); + otp = offs / sizeof(u32); if (otp < 0 || (otp + nb_otp - 1) > BSEC_OTP_MAX_VALUE) { dev_err(dev, "wrong value for otp, max value : %d\n", diff --git a/arch/arm/mach-stm32mp/cmd_poweroff.c b/arch/arm/mach-stm32mp/cmd_poweroff.c index a6fdc79..f54dd1d 100644 --- a/arch/arm/mach-stm32mp/cmd_poweroff.c +++ b/arch/arm/mach-stm32mp/cmd_poweroff.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * Copyright (C) 2019, STMicroelectronics - All Rights Reserved */ #include diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index 4245e6f..6b1e4db 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -66,7 +66,8 @@ static int confirm_prog(void) return 0; } -int do_stm32key(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_stm32key(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) { u32 addr; const char *op = argc >= 2 ? argv[1] : NULL; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index d263b38..8325b56 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -46,12 +46,17 @@ EFI_GUID(0xFD58F1C7, 0xBE0D, 0x4338, \ 0x88, 0xE9, 0xAD, 0x8F, 0x05, 0x0A, 0xEB, 0x18) +/* RAW parttion (binary / bootloader) used Linux - reserved UUID */ +#define LINUX_RESERVED_UUID "8DA63339-0007-60C0-C436-083AC8230908" + +#define DFU_DEV_UNDEFINED 0xFFFF + /* * unique partition guid (uuid) for partition named "rootfs" * on each MMC instance = SD Card or eMMC * allow fixed kernel bootcmd: "rootf=PARTUID=e91c4e10-..." */ -const static efi_guid_t uuid_mmc[3] = { +static const efi_guid_t uuid_mmc[3] = { ROOTFS_MMC0_UUID, ROOTFS_MMC1_UUID, ROOTFS_MMC2_UUID @@ -89,7 +94,7 @@ char *stm32prog_get_error(struct stm32prog_data *data) u8 stm32prog_header_check(struct raw_header_s *raw_header, struct image_header_s *header) { - int i; + unsigned int i; header->present = 0; header->image_checksum = 0x0; @@ -261,7 +266,7 @@ static int parse_ip(struct stm32prog_data *data, char *p, struct stm32prog_part_t *part) { int result = 0; - int len = 0; + unsigned int len = 0; part->dev_id = 0; if (!strcmp(p, "none")) { @@ -431,7 +436,7 @@ static int parse_flash_layout(struct stm32prog_data *data, eof = true; continue; } - /* no break */ + /* fall through */ /* by default continue with the next character */ default: p++; @@ -769,7 +774,7 @@ static int treat_partition_list(struct stm32prog_data *data) struct stm32prog_part_t *part; for (j = 0; j < STM32PROG_MAX_DEV; j++) { - data->dev[j].dev_type = -1; + data->dev[j].dev_type = DFU_DEV_UNDEFINED; INIT_LIST_HEAD(&data->dev[j].part_list); } @@ -812,7 +817,7 @@ static int treat_partition_list(struct stm32prog_data *data) } } for (j = 0; j < STM32PROG_MAX_DEV; j++) { - if (data->dev[j].dev_type == -1) { + if (data->dev[j].dev_type == DFU_DEV_UNDEFINED) { /* new device found */ data->dev[j].dev_type = part->dev_type; data->dev[j].dev_id = part->dev_id; @@ -841,7 +846,8 @@ static int create_partitions(struct stm32prog_data *data) char buf[ENV_BUF_LEN]; char uuid[UUID_STR_LEN + 1]; unsigned char *uuid_bin; - int i, mmc_id; + unsigned int mmc_id; + int i; bool rootfs_found; struct stm32prog_part_t *part; @@ -874,7 +880,8 @@ static int create_partitions(struct stm32prog_data *data) if (part->part_type == PART_BINARY) offset += snprintf(buf + offset, ENV_BUF_LEN - offset, - ",type=data"); + ",type=" + LINUX_RESERVED_UUID); else offset += snprintf(buf + offset, ENV_BUF_LEN - offset, @@ -1517,7 +1524,7 @@ static int part_delete(struct stm32prog_data *data, return ret; } -void stm32prog_devices_init(struct stm32prog_data *data) +static void stm32prog_devices_init(struct stm32prog_data *data) { int i; int ret; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 51541bc..08d6e5e 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -139,7 +139,7 @@ struct stm32prog_data { int full_update; /* command internal information */ - int phase; + unsigned int phase; u32 offset; char error[255]; struct stm32prog_part_t *cur_part; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c index 36f9393..f9dee73 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c @@ -29,7 +29,7 @@ const u8 cmd_id[] = { #define NB_CMD sizeof(cmd_id) /* DFU support for serial *********************************************/ -struct dfu_entity *stm32prog_get_entity(struct stm32prog_data *data) +static struct dfu_entity *stm32prog_get_entity(struct stm32prog_data *data) { int alt_id; @@ -76,6 +76,7 @@ static int stm32prog_read(struct stm32prog_data *data, u8 phase, u32 offset, u8 *buffer, u32 buffer_size) { struct dfu_entity *dfu_entity; + u32 size; int ret; /* pr_debug("%s entry\n", __func__); */ @@ -128,12 +129,15 @@ static int stm32prog_read(struct stm32prog_data *data, u8 phase, u32 offset, ret, phase, offset); return ret; } - if (ret < buffer_size) { + + size = ret; + + if (size < buffer_size) { data->offset = 0; data->read_phase = PHASE_END; - memset(buffer + ret, 0, buffer_size - ret); + memset(buffer + size, 0, buffer_size - size); } else { - data->offset += ret; + data->offset += size; } /*pr_debug("%s exit ret=%d\n", __func__, ret);*/ return ret; @@ -215,8 +219,10 @@ static int stm32prog_serial_getc_err(void) do { err = ops->getc(down_serial_dev); - if (err == -EAGAIN) + if (err == -EAGAIN) { ctrlc(); + WATCHDOG_RESET(); + } } while ((err == -EAGAIN) && (!had_ctrlc())); return err; @@ -243,6 +249,7 @@ static bool stm32prog_serial_get_buffer(u8 *buffer, u32 *count) *count -= 1; } else if (err == -EAGAIN) { ctrlc(); + WATCHDOG_RESET(); } else { break; } @@ -626,7 +633,7 @@ static void download_command(struct stm32prog_data *data) u32 packet_number; u32 result = ACK_BYTE; u8 ret; - int i; + unsigned int i; bool error; int rcv; @@ -729,6 +736,10 @@ static void download_command(struct stm32prog_data *data) if (rcv_xor != my_xor) { printf("checksum error on packet %d\n", packet_number); + /* wait to be sure that all data are received + * in the FIFO before flush + */ + mdelay(30); data->packet_number--; result = NACK_BYTE; goto end; @@ -785,7 +796,7 @@ static void download_command(struct stm32prog_data *data) if (data->cursor <= BL_HEADER_SIZE) goto end; /* compute checksum on payload */ - for (i = size; i < codesize; i++) + for (i = (unsigned long)size; i < codesize; i++) data->checksum += data->buffer[i]; if (data->cursor > @@ -822,10 +833,10 @@ end: */ static void read_partition_command(struct stm32prog_data *data) { - u32 part_id, codesize, offset = 0, rcv_data; + u32 i, part_id, codesize, offset = 0, rcv_data; long size; u8 tmp_xor; - int i, res; + int res; u8 buffer[256]; part_id = stm32prog_serial_getc(); @@ -854,28 +865,29 @@ static void read_partition_command(struct stm32prog_data *data) } pr_debug("%s : %x\n", __func__, part_id); + rcv_data = 0; switch (part_id) { case PHASE_OTP: - res = 0; size = codesize; if (!stm32prog_otp_read(data, offset, buffer, &size)) - res = size; + rcv_data = size; break; case PHASE_PMIC: - res = 0; size = codesize; if (!stm32prog_pmic_read(data, offset, buffer, &size)) - res = size; + rcv_data = size; break; default: res = stm32prog_read(data, part_id, offset, buffer, codesize); + if (res > 0) + rcv_data = res; break; } - if (res > 0) { + if (rcv_data > 0) { stm32prog_serial_putc(ACK_BYTE); /*----------- Send data to the host -----------*/ - for (i = 0; i < res; i++) + for (i = 0; i < rcv_data; i++) stm32prog_serial_putc(buffer[i]); /*----------- Send filler to the host -----------*/ for (; i < codesize; i++) @@ -951,7 +963,7 @@ bool stm32prog_serial_loop(struct stm32prog_data *data) /* wait to be sure that all data are received * in the FIFO before flush (CMD and XOR) */ - mdelay(2); + mdelay(3); stm32prog_serial_result(NACK_BYTE); } else { /*pr_debug("+ cmd %x\n", counter);*/ diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c index c7dd678..f795a9c 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c @@ -254,6 +254,7 @@ static const char product[] = bool stm32prog_usb_loop(struct stm32prog_data *data, int dev) { int ret; + bool result; stm32prog_data = data; g_dnl_set_product(product); @@ -267,8 +268,14 @@ bool stm32prog_usb_loop(struct stm32prog_data *data, int dev) /* found next selected partition */ stm32prog_next_phase(data); } - return (run_usb_dnl_gadget(dev, "usb_dnl_dfu") || - (stm32prog_data->phase == PHASE_DO_RESET)); + + ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu") ; + + result = !!(ret) || (stm32prog_data->phase == PHASE_DO_RESET); + + stm32prog_data = NULL; + + return result; } int g_dnl_get_board_bcd_device_number(int gcnum) diff --git a/arch/arm/mach-stm32mp/config.mk b/arch/arm/mach-stm32mp/config.mk index bd8944a..d9d39fd 100644 --- a/arch/arm/mach-stm32mp/config.mk +++ b/arch/arm/mach-stm32mp/config.mk @@ -7,7 +7,7 @@ ifndef CONFIG_SPL ALL-y += u-boot.stm32 else ifdef CONFIG_SPL_BUILD -ALL-y += spl/u-boot-spl.stm32 +ALL-y += u-boot-spl.stm32 endif endif @@ -25,3 +25,6 @@ spl/u-boot-spl.stm32: MKIMAGEOUTPUT = spl/u-boot-spl.stm32.log spl/u-boot-spl.stm32: spl/u-boot-spl.bin FORCE $(call if_changed,mkimage) + +u-boot-spl.stm32 : spl/u-boot-spl.stm32 + $(call if_changed,copy) diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c index 5d5ce4a..efe8b79 100644 --- a/arch/arm/mach-stm32mp/cpu.c +++ b/arch/arm/mach-stm32mp/cpu.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -15,13 +16,13 @@ #include #include #include -#include /* RCC register */ #define RCC_TZCR (STM32_RCC_BASE + 0x00) #define RCC_DBGCFGR (STM32_RCC_BASE + 0x080C) #define RCC_BDCR (STM32_RCC_BASE + 0x0140) #define RCC_MP_APB5ENSETR (STM32_RCC_BASE + 0x0208) +#define RCC_MP_AHB5ENSETR (STM32_RCC_BASE + 0x0210) #define RCC_BDCR_VSWRST BIT(31) #define RCC_BDCR_RTCSRC GENMASK(17, 16) @@ -49,6 +50,9 @@ #define DBGMCU_IDC_REV_ID_MASK GENMASK(31, 16) #define DBGMCU_IDC_REV_ID_SHIFT 16 +/* GPIOZ registers */ +#define GPIOZ_SECCFGR 0x54004030 + /* boot interface from Bootrom * - boot instance = bit 31:16 * - boot device = bit 15:0 @@ -79,11 +83,6 @@ #define PKG_SHIFT 27 #define PKG_MASK GENMASK(2, 0) -#define PKG_AA_LBGA448 4 -#define PKG_AB_LBGA354 3 -#define PKG_AC_TFBGA361 2 -#define PKG_AD_TFBGA257 1 - DECLARE_GLOBAL_DATA_PTR; #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) @@ -142,6 +141,10 @@ static void security_init(void) * Bit 16 ITAMP1E: RTC power domain supply monitoring */ writel(0x0, TAMP_CR1); + + /* GPIOZ: deactivate the security */ + writel(BIT(0), RCC_MP_AHB5ENSETR); + writel(0x0, GPIOZ_SECCFGR); } #endif /* CONFIG_STM32MP1_TRUSTED */ @@ -157,14 +160,18 @@ static void dbgmcu_init(void) } #endif /* !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) */ -static u32 get_bootmode(void) -{ - u32 boot_mode; #if !defined(CONFIG_STM32MP1_TRUSTED) && \ (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) +/* get bootmode from ROM code boot context: saved in TAMP register */ +static void update_bootmode(void) +{ + u32 boot_mode; u32 bootrom_itf = readl(BOOTROM_PARAM_ADDR); u32 bootrom_device, bootrom_instance; + /* enable TAMP clock = RTCAPBEN */ + writel(BIT(8), RCC_MP_APB5ENSETR); + /* read bootrom context */ bootrom_device = (bootrom_itf & BOOTROM_MODE_MASK) >> BOOTROM_MODE_SHIFT; @@ -179,12 +186,14 @@ static u32 get_bootmode(void) clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_MODE_MASK, boot_mode << TAMP_BOOT_MODE_SHIFT); -#else - /* read TAMP backup register */ - boot_mode = (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >> - TAMP_BOOT_MODE_SHIFT; +} #endif - return boot_mode; + +u32 get_bootmode(void) +{ + /* read bootmode from TAMP backup register */ + return (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >> + TAMP_BOOT_MODE_SHIFT; } /* @@ -201,15 +210,15 @@ int arch_cpu_init(void) dbgmcu_init(); #ifndef CONFIG_STM32MP1_TRUSTED security_init(); + update_bootmode(); #endif #endif - /* get bootmode from BootRom context: saved in TAMP register */ boot_mode = get_bootmode(); if ((boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART) gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; -#if defined(CONFIG_DEBUG_UART) &&\ +#if defined(CONFIG_DEBUG_UART) && \ !defined(CONFIG_STM32MP1_TRUSTED) && \ (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) else @@ -270,7 +279,7 @@ u32 get_cpu_type(void) } /* Get Package options from OTP */ -static u32 get_cpu_package(void) +u32 get_cpu_package(void) { return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK); } @@ -359,7 +368,7 @@ static void setup_boot_mode(void) u32 boot_ctx = readl(TAMP_BOOT_CONTEXT); u32 boot_mode = (boot_ctx & TAMP_BOOT_MODE_MASK) >> TAMP_BOOT_MODE_SHIFT; - int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1; + unsigned int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1; u32 forced_mode = (boot_ctx & TAMP_BOOT_FORCED_MASK); struct udevice *dev; int alias; @@ -399,14 +408,16 @@ static void setup_boot_mode(void) env_set("boot_instance", cmd); break; case BOOT_FLASH_NAND: - sprintf(cmd, "%d", instance); env_set("boot_device", "nand"); - env_set("boot_instance", cmd); + env_set("boot_instance", "0"); break; case BOOT_FLASH_NOR: env_set("boot_device", "nor"); env_set("boot_instance", "0"); break; + default: + pr_debug("unexpected boot mode = %x\n", boot_mode); + break; } switch (forced_mode) { @@ -415,8 +426,8 @@ static void setup_boot_mode(void) env_set("preboot", "env set preboot; fastboot 0"); break; case BOOT_STM32PROG: - printf("Enter STM32CubeProgrammer mode!\n"); - env_set("preboot", "env set preboot; stm32prog usb 0"); + env_set("boot_device", "usb"); + env_set("boot_instance", "0"); break; case BOOT_UMS_MMC0: case BOOT_UMS_MMC1: @@ -430,8 +441,9 @@ static void setup_boot_mode(void) env_set("preboot", "env set preboot; run altbootcmd"); break; case BOOT_NORMAL: + break; default: - pr_debug("unexpected boot mode = %x\n", boot_mode); + pr_debug("unexpected forced boot mode = %x\n", forced_mode); break; } @@ -450,12 +462,9 @@ static int setup_mac_address(void) int i; u32 otp[2]; uchar enetaddr[6]; + char buf[ARP_HLEN_ASCII + 1]; struct udevice *dev; - /* MAC already in environment */ - if (eth_env_get_enetaddr("ethaddr", enetaddr)) - return 0; - ret = uclass_get_device_by_driver(UCLASS_MISC, DM_GET_DRIVER(stm32mp_bsec), &dev); @@ -474,9 +483,11 @@ static int setup_mac_address(void) pr_err("invalid MAC address in OTP %pM", enetaddr); return -EINVAL; } + pr_debug("OTP MAC address = %pM\n", enetaddr); - ret = !eth_env_set_enetaddr("ethaddr", enetaddr); - if (!ret) + sprintf(buf, "%pM", enetaddr); + ret = env_set("ethaddr", buf); + if (ret) pr_err("Failed to set mac address %pM from OTP: %d\n", enetaddr, ret); #endif @@ -491,9 +502,6 @@ static int setup_serial_number(void) struct udevice *dev; int ret; - if (env_get("serial#")) - return 0; - ret = uclass_get_device_by_driver(UCLASS_MISC, DM_GET_DRIVER(stm32mp_bsec), &dev); @@ -511,53 +519,64 @@ static int setup_serial_number(void) return 0; } -int arch_misc_init(void) -{ - setup_boot_mode(); - setup_mac_address(); - setup_serial_number(); - return 0; +#if defined(CONFIG_WDT) && \ +(defined(CONFIG_SPL_WATCHDOG_SUPPORT) || !defined(CONFIG_SPL_BUILD)) +/* Called by macro WATCHDOG_RESET */ +void watchdog_reset(void) +{ + static ulong next_reset; + struct udevice *watchdog_dev; + ulong now; + + now = timer_get_us(); + + /* Do not reset the watchdog too often, only every 1 sec */ + if (now > next_reset) { + /* + * Watchdog has been enabled at SPL stage, to avoid + * watchdog_dev bad reference after relocation, we don't save + * it in a static variable, we retrieve it each time using + * uclass_get_device() call. + */ + if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) + return; + + wdt_reset(watchdog_dev); + next_reset = now + 1000000; + } } -/* - * This function is called right before the kernel is booted. "blob" is the - * device tree that will be passed to the kernel. - */ -int ft_system_setup(void *blob, bd_t *bd) +int watchdog_start(void) { - int ret = 0; - u32 pkg; + struct udevice *watchdog_dev; -#if CONFIG_STM32_ETZPC - ret = stm32_fdt_fixup_etzpc(blob); - if (ret) - return ret; + if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { + debug("Watchdog: Not found by seq!\n"); + if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { + puts("Watchdog: Not found!\n"); + return 0; + } + } + + wdt_start(watchdog_dev, 0, 0); + printf("Watchdog: Started\n"); + + return 0; +} +#else +int watchdog_start(void) +{ + return 0; +} #endif - switch (get_cpu_package()) { - case PKG_AA_LBGA448: - pkg = STM32MP157CAA; - break; - case PKG_AB_LBGA354: - pkg = STM32MP157CAB; - break; - case PKG_AC_TFBGA361: - pkg = STM32MP157CAC; - break; - case PKG_AD_TFBGA257: - pkg = STM32MP157CAD; - break; - default: - pkg = 0; - break; - } - if (pkg) { - do_fixup_by_compat_u32(blob, "st,stm32mp157-pinctrl", - "st,package", pkg, false); - do_fixup_by_compat_u32(blob, "st,stm32mp157-z-pinctrl", - "st,package", pkg, false); - } +int arch_misc_init(void) +{ + watchdog_start(); + setup_boot_mode(); + setup_mac_address(); + setup_serial_number(); - return ret; + return 0; } diff --git a/arch/arm/mach-stm32mp/fdt.c b/arch/arm/mach-stm32mp/fdt.c new file mode 100644 index 0000000..259b99a --- /dev/null +++ b/arch/arm/mach-stm32mp/fdt.c @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2019, STMicroelectronics - All Rights Reserved + */ + +#include +#include +#include +#include +#include +#include + +#define ETZPC_DECPROT(n) (STM32_ETZPC_BASE + 0x10 + 4 * (n)) +#define ETZPC_DECPROT_NB 6 + +#define DECPROT_MASK 0x03 +#define NB_PROT_PER_REG 0x10 +#define DECPROT_NB_BITS 2 + +#define DECPROT_SECURED 0x00 +#define DECPROT_WRITE_SECURE 0x01 +#define DECPROT_MCU_ISOLATION 0x02 +#define DECPROT_NON_SECURED 0x03 + +#define ETZPC_RESERVED 0xffffffff + +static const u32 stm32mp1_ip_addr[] = { + 0x5c008000, /* 00 stgenc */ + 0x54000000, /* 01 bkpsram */ + 0x5c003000, /* 02 iwdg1 */ + 0x5c000000, /* 03 usart1 */ + 0x5c001000, /* 04 spi6 */ + 0x5c002000, /* 05 i2c4 */ + ETZPC_RESERVED, /* 06 reserved */ + 0x54003000, /* 07 rng1 */ + 0x54002000, /* 08 hash1 */ + 0x54001000, /* 09 cryp1 */ + 0x5a003000, /* 0A ddrctrl */ + 0x5a004000, /* 0B ddrphyc */ + 0x5c009000, /* 0C i2c6 */ + ETZPC_RESERVED, /* 0D reserved */ + ETZPC_RESERVED, /* 0E reserved */ + ETZPC_RESERVED, /* 0F reserved */ + 0x40000000, /* 10 tim2 */ + 0x40001000, /* 11 tim3 */ + 0x40002000, /* 12 tim4 */ + 0x40003000, /* 13 tim5 */ + 0x40004000, /* 14 tim6 */ + 0x40005000, /* 15 tim7 */ + 0x40006000, /* 16 tim12 */ + 0x40007000, /* 17 tim13 */ + 0x40008000, /* 18 tim14 */ + 0x40009000, /* 19 lptim1 */ + 0x4000a000, /* 1A wwdg1 */ + 0x4000b000, /* 1B spi2 */ + 0x4000c000, /* 1C spi3 */ + 0x4000d000, /* 1D spdifrx */ + 0x4000e000, /* 1E usart2 */ + 0x4000f000, /* 1F usart3 */ + 0x40010000, /* 20 uart4 */ + 0x40011000, /* 21 uart5 */ + 0x40012000, /* 22 i2c1 */ + 0x40013000, /* 23 i2c2 */ + 0x40014000, /* 24 i2c3 */ + 0x40015000, /* 25 i2c5 */ + 0x40016000, /* 26 cec */ + 0x40017000, /* 27 dac */ + 0x40018000, /* 28 uart7 */ + 0x40019000, /* 29 uart8 */ + ETZPC_RESERVED, /* 2A reserved */ + ETZPC_RESERVED, /* 2B reserved */ + 0x4001c000, /* 2C mdios */ + ETZPC_RESERVED, /* 2D reserved */ + ETZPC_RESERVED, /* 2E reserved */ + ETZPC_RESERVED, /* 2F reserved */ + 0x44000000, /* 30 tim1 */ + 0x44001000, /* 31 tim8 */ + ETZPC_RESERVED, /* 32 reserved */ + 0x44003000, /* 33 usart6 */ + 0x44004000, /* 34 spi1 */ + 0x44005000, /* 35 spi4 */ + 0x44006000, /* 36 tim15 */ + 0x44007000, /* 37 tim16 */ + 0x44008000, /* 38 tim17 */ + 0x44009000, /* 39 spi5 */ + 0x4400a000, /* 3A sai1 */ + 0x4400b000, /* 3B sai2 */ + 0x4400c000, /* 3C sai3 */ + 0x4400d000, /* 3D dfsdm */ + 0x4400e000, /* 3E tt_fdcan */ + ETZPC_RESERVED, /* 3F reserved */ + 0x50021000, /* 40 lptim2 */ + 0x50022000, /* 41 lptim3 */ + 0x50023000, /* 42 lptim4 */ + 0x50024000, /* 43 lptim5 */ + 0x50027000, /* 44 sai4 */ + 0x50025000, /* 45 vrefbuf */ + 0x4c006000, /* 46 dcmi */ + 0x4c004000, /* 47 crc2 */ + 0x48003000, /* 48 adc */ + 0x4c002000, /* 49 hash2 */ + 0x4c003000, /* 4A rng2 */ + 0x4c005000, /* 4B cryp2 */ + ETZPC_RESERVED, /* 4C reserved */ + ETZPC_RESERVED, /* 4D reserved */ + ETZPC_RESERVED, /* 4E reserved */ + ETZPC_RESERVED, /* 4F reserved */ + ETZPC_RESERVED, /* 50 sram1 */ + ETZPC_RESERVED, /* 51 sram2 */ + ETZPC_RESERVED, /* 52 sram3 */ + ETZPC_RESERVED, /* 53 sram4 */ + ETZPC_RESERVED, /* 54 retram */ + 0x49000000, /* 55 otg */ + 0x48004000, /* 56 sdmmc3 */ + 0x48005000, /* 57 dlybsd3 */ + 0x48000000, /* 58 dma1 */ + 0x48001000, /* 59 dma2 */ + 0x48002000, /* 5A dmamux */ + 0x58002000, /* 5B fmc */ + 0x58003000, /* 5C qspi */ + 0x58004000, /* 5D dlybq */ + 0x5800a000, /* 5E eth */ + ETZPC_RESERVED, /* 5F reserved */ +}; + +/* fdt helper */ +static bool fdt_disable_subnode_by_address(void *fdt, int offset, u32 addr) +{ + int node; + + for (node = fdt_first_subnode(fdt, offset); + node >= 0; + node = fdt_next_subnode(fdt, node)) { + if (addr == (u32)fdt_getprop(fdt, node, "reg", 0)) { + if (fdtdec_get_is_enabled(fdt, node)) { + fdt_status_disabled(fdt, node); + + return true; + } + return false; + } + } + + return false; +} + +static int stm32_fdt_fixup_etzpc(void *fdt) +{ + const u32 *array; + int array_size, i; + int soc_node, offset, shift; + u32 addr, status, decprot[ETZPC_DECPROT_NB]; + + array = stm32mp1_ip_addr; + array_size = ARRAY_SIZE(stm32mp1_ip_addr); + + for (i = 0; i < ETZPC_DECPROT_NB; i++) + decprot[i] = readl(ETZPC_DECPROT(i)); + + soc_node = fdt_path_offset(fdt, "/soc"); + if (soc_node < 0) + return soc_node; + + for (i = 0; i < array_size; i++) { + offset = i / NB_PROT_PER_REG; + shift = (i % NB_PROT_PER_REG) * DECPROT_NB_BITS; + status = (decprot[offset] >> shift) & DECPROT_MASK; + addr = array[i]; + + debug("ETZPC: 0x%08x decprot %d=%d\n", addr, i, status); + + if (addr == ETZPC_RESERVED || + status == DECPROT_NON_SECURED) + continue; + + if (fdt_disable_subnode_by_address(fdt, soc_node, addr)) + printf("ETZPC: 0x%08x node disabled, decprot %d=%d\n", + addr, i, status); + } + + return 0; +} + +/* + * This function is called right before the kernel is booted. "blob" is the + * device tree that will be passed to the kernel. + */ +int ft_system_setup(void *blob, bd_t *bd) +{ + int ret = 0; + u32 pkg; + + if (CONFIG_IS_ENABLED(STM32_ETZPC)) { + ret = stm32_fdt_fixup_etzpc(blob); + if (ret) + return ret; + } + + switch (get_cpu_package()) { + case PKG_AA_LBGA448: + pkg = STM32MP157CAA; + break; + case PKG_AB_LBGA354: + pkg = STM32MP157CAB; + break; + case PKG_AC_TFBGA361: + pkg = STM32MP157CAC; + break; + case PKG_AD_TFBGA257: + pkg = STM32MP157CAD; + break; + default: + pkg = 0; + break; + } + if (pkg) { + do_fixup_by_compat_u32(blob, "st,stm32mp157-pinctrl", + "st,package", pkg, false); + do_fixup_by_compat_u32(blob, "st,stm32mp157-z-pinctrl", + "st,package", pkg, false); + } + + return ret; +} diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h index 36b885b..5283e90 100644 --- a/arch/arm/mach-stm32mp/include/mach/stm32.h +++ b/arch/arm/mach-stm32mp/include/mach/stm32.h @@ -44,8 +44,6 @@ /* enumerated used to identify the SYSCON driver instance */ enum { STM32MP_SYSCON_UNKNOWN, - STM32MP_SYSCON_ETZPC, - STM32MP_SYSCON_IWDG, STM32MP_SYSCON_PWR, STM32MP_SYSCON_STGEN, STM32MP_SYSCON_SYSCFG, @@ -126,9 +124,5 @@ enum forced_boot_mode { #define BSEC_OTP_BOARD 59 -#if CONFIG_STM32_ETZPC -int stm32_fdt_fixup_etzpc(void *fdt); -#endif - #endif /* __ASSEMBLY__*/ #endif /* _MACH_STM32_H_ */ diff --git a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h index 538958f..9ee7fb7 100644 --- a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h +++ b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * Copyright (C) 2019, STMicroelectronics - All Rights Reserved */ #ifndef __STM32MP1_SMC_H__ diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h index c565748..871324b 100644 --- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h +++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h @@ -19,3 +19,16 @@ u32 get_cpu_type(void); /* return CPU_REV constants */ u32 get_cpu_rev(void); + +/* Get Package options from OTP */ +u32 get_cpu_package(void); + +#define PKG_AA_LBGA448 4 +#define PKG_AB_LBGA354 3 +#define PKG_AC_TFBGA361 2 +#define PKG_AD_TFBGA257 1 + +/* return boot mode */ +u32 get_bootmode(void); +/* start IWDG watchdog */ +int watchdog_start(void); diff --git a/arch/arm/mach-stm32mp/psci.c b/arch/arm/mach-stm32mp/psci.c index c2dff38..708a699 100644 --- a/arch/arm/mach-stm32mp/psci.c +++ b/arch/arm/mach-stm32mp/psci.c @@ -47,14 +47,14 @@ static u32 __secure stm32mp_get_gicd_base_address(void) return (periphbase & CBAR_MASK) + GIC_DIST_OFFSET; } -static void __secure stm32mp_smp_kick_all_cpus(void) +static void __secure stm32mp_raise_sgi0(int cpu) { u32 gic_dist_addr; gic_dist_addr = stm32mp_get_gicd_base_address(); - /* kick all CPUs (except this one) by writing to GICD_SGIR */ - writel(1U << 24, gic_dist_addr + GICD_SGIR); + /* ask cpu with SGI0 */ + writel((BIT(cpu) << 16), gic_dist_addr + GICD_SGIR); } void __secure psci_arch_cpu_entry(void) @@ -62,6 +62,9 @@ void __secure psci_arch_cpu_entry(void) u32 cpu = psci_get_cpu_id(); psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON); + + /* reset magic in TAMP register */ + writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER); } int __secure psci_features(u32 function_id, u32 psci_fid) @@ -127,6 +130,17 @@ int __secure psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc, if (psci_state[cpu] == PSCI_AFFINITY_LEVEL_ON) return ARM_PSCI_RET_ALREADY_ON; + /* reset magic in TAMP register */ + if (readl(TAMP_BACKUP_MAGIC_NUMBER)) + writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER); + + /* + * ROM code need a first SGI0 after core reset + * core is ready when magic is set to 0 in ROM code + */ + while (readl(TAMP_BACKUP_MAGIC_NUMBER)) + stm32mp_raise_sgi0(cpu); + /* store target PC and context id*/ psci_save(cpu, pc, context_id); @@ -142,7 +156,8 @@ int __secure psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc, writel(BOOT_API_A7_CORE0_MAGIC_NUMBER, TAMP_BACKUP_MAGIC_NUMBER); - stm32mp_smp_kick_all_cpus(); + /* Generate an IT to start the core */ + stm32mp_raise_sgi0(cpu); return ARM_PSCI_RET_SUCCESS; } diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c index fa393cc..6c8744f 100644 --- a/arch/arm/mach-stm32mp/spl.c +++ b/arch/arm/mach-stm32mp/spl.c @@ -24,8 +24,7 @@ u32 spl_boot_device(void) { u32 boot_mode; - boot_mode = (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >> - TAMP_BOOT_MODE_SHIFT; + boot_mode = get_bootmode(); switch (boot_mode) { case BOOT_FLASH_SD_1: @@ -50,6 +49,7 @@ u32 spl_boot_device(void) case BOOT_FLASH_NOR_QSPI: return BOOT_DEVICE_SPI; } + return BOOT_DEVICE_MMC1; } @@ -119,6 +119,8 @@ void board_init_f(ulong dummy) /* enable console uart printing */ preloader_console_init(); + watchdog_start(); + ret = uclass_get_device(UCLASS_RAM, 0, &dev); if (ret) { printf("DRAM init failed: %d\n", ret); diff --git a/arch/arm/mach-stm32mp/stm32-etzpc.c b/arch/arm/mach-stm32mp/stm32-etzpc.c deleted file mode 100644 index ea6dcca..0000000 --- a/arch/arm/mach-stm32mp/stm32-etzpc.c +++ /dev/null @@ -1,199 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -/* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved - */ - -#include -#include -#include -#include -#include - -#define ETZPC_DECPROT(n) (0x10 + 4 * (n)) -#define ETZPC_DECPROT_NB 6 - -#define ETZPC_IP_VER 0x3F4 - -#define IP_VER_STM32MP1 0x00000020 - -#define DECPROT_MASK 0x03 -#define NB_PROT_PER_REG 0x10 -#define DECPROT_NB_BITS 2 - -#define DECPROT_SECURED 0x00 -#define DECPROT_WRITE_SECURE 0x01 -#define DECPROT_MCU_ISOLATION 0x02 -#define DECPROT_NON_SECURED 0x03 - -#define ETZPC_RESERVED 0xffffffff - -static const u32 stm32mp1_ip_addr[] = { - 0x5c008000, /* 00 stgenc */ - 0x54000000, /* 01 bkpsram */ - 0x5c003000, /* 02 iwdg1 */ - 0x5c000000, /* 03 usart1 */ - 0x5c001000, /* 04 spi6 */ - 0x5c002000, /* 05 i2c4 */ - ETZPC_RESERVED, /* 06 reserved */ - 0x54003000, /* 07 rng1 */ - 0x54002000, /* 08 hash1 */ - 0x54001000, /* 09 cryp1 */ - 0x5a003000, /* 0A ddrctrl */ - 0x5a004000, /* 0B ddrphyc */ - 0x5c009000, /* 0C i2c6 */ - ETZPC_RESERVED, /* 0D reserved */ - ETZPC_RESERVED, /* 0E reserved */ - ETZPC_RESERVED, /* 0F reserved */ - 0x40000000, /* 10 tim2 */ - 0x40001000, /* 11 tim3 */ - 0x40002000, /* 12 tim4 */ - 0x40003000, /* 13 tim5 */ - 0x40004000, /* 14 tim6 */ - 0x40005000, /* 15 tim7 */ - 0x40006000, /* 16 tim12 */ - 0x40007000, /* 17 tim13 */ - 0x40008000, /* 18 tim14 */ - 0x40009000, /* 19 lptim1 */ - 0x4000a000, /* 1A wwdg1 */ - 0x4000b000, /* 1B spi2 */ - 0x4000c000, /* 1C spi3 */ - 0x4000d000, /* 1D spdifrx */ - 0x4000e000, /* 1E usart2 */ - 0x4000f000, /* 1F usart3 */ - 0x40010000, /* 20 uart4 */ - 0x40011000, /* 21 uart5 */ - 0x40012000, /* 22 i2c1 */ - 0x40013000, /* 23 i2c2 */ - 0x40014000, /* 24 i2c3 */ - 0x40015000, /* 25 i2c5 */ - 0x40016000, /* 26 cec */ - 0x40017000, /* 27 dac */ - 0x40018000, /* 28 uart7 */ - 0x40019000, /* 29 uart8 */ - ETZPC_RESERVED, /* 2A reserved */ - ETZPC_RESERVED, /* 2B reserved */ - 0x4001c000, /* 2C mdios */ - ETZPC_RESERVED, /* 2D reserved */ - ETZPC_RESERVED, /* 2E reserved */ - ETZPC_RESERVED, /* 2F reserved */ - 0x44000000, /* 30 tim1 */ - 0x44001000, /* 31 tim8 */ - ETZPC_RESERVED, /* 32 reserved */ - 0x44003000, /* 33 usart6 */ - 0x44004000, /* 34 spi1 */ - 0x44005000, /* 35 spi4 */ - 0x44006000, /* 36 tim15 */ - 0x44007000, /* 37 tim16 */ - 0x44008000, /* 38 tim17 */ - 0x44009000, /* 39 spi5 */ - 0x4400a000, /* 3A sai1 */ - 0x4400b000, /* 3B sai2 */ - 0x4400c000, /* 3C sai3 */ - 0x4400d000, /* 3D dfsdm */ - 0x4400e000, /* 3E tt_fdcan */ - ETZPC_RESERVED, /* 3F reserved */ - 0x50021000, /* 40 lptim2 */ - 0x50022000, /* 41 lptim3 */ - 0x50023000, /* 42 lptim4 */ - 0x50024000, /* 43 lptim5 */ - 0x50027000, /* 44 sai4 */ - 0x50025000, /* 45 vrefbuf */ - 0x4c006000, /* 46 dcmi */ - 0x4c004000, /* 47 crc2 */ - 0x48003000, /* 48 adc */ - 0x4c002000, /* 49 hash2 */ - 0x4c003000, /* 4A rng2 */ - 0x4c005000, /* 4B cryp2 */ - ETZPC_RESERVED, /* 4C reserved */ - ETZPC_RESERVED, /* 4D reserved */ - ETZPC_RESERVED, /* 4E reserved */ - ETZPC_RESERVED, /* 4F reserved */ - ETZPC_RESERVED, /* 50 sram1 */ - ETZPC_RESERVED, /* 51 sram2 */ - ETZPC_RESERVED, /* 52 sram3 */ - ETZPC_RESERVED, /* 53 sram4 */ - ETZPC_RESERVED, /* 54 retram */ - 0x49000000, /* 55 otg */ - 0x48004000, /* 56 sdmmc3 */ - 0x48005000, /* 57 dlybsd3 */ - 0x48000000, /* 58 dma1 */ - 0x48001000, /* 59 dma2 */ - 0x48002000, /* 5A dmamux */ - 0x58002000, /* 5B fmc */ - 0x58003000, /* 5C qspi */ - 0x58004000, /* 5D dlybq */ - 0x5800a000, /* 5E eth */ - ETZPC_RESERVED, /* 5F reserved */ -}; - -/* fdt helper */ -static bool fdt_disable_subnode_by_address(void *fdt, int offset, u32 addr) -{ - int node; - - for (node = fdt_first_subnode(fdt, offset); - node >= 0; - node = fdt_next_subnode(fdt, node)) { - if (addr == (u32)fdt_getprop(fdt, node, "reg", 0)) { - if (fdtdec_get_is_enabled(fdt, node)) { - fdt_status_disabled(fdt, node); - - return true; - } - return false; - } - } - - return false; -} - -int stm32_fdt_fixup_etzpc(void *fdt) -{ - void *base; - u32 version; - const u32 *array; - int array_size, i; - int soc_node, offset, shift; - u32 addr, status, decprot[ETZPC_DECPROT_NB]; - - base = syscon_get_first_range(STM32MP_SYSCON_ETZPC); - if (IS_ERR(base)) - return PTR_ERR(base); - - version = readl(base + ETZPC_IP_VER); - - switch (version) { - case IP_VER_STM32MP1: - array = stm32mp1_ip_addr; - array_size = ARRAY_SIZE(stm32mp1_ip_addr); - break; - default: - return 0; - } - - for (i = 0; i < ETZPC_DECPROT_NB; i++) - decprot[i] = readl(base + ETZPC_DECPROT(i)); - - soc_node = fdt_path_offset(fdt, "/soc"); - if (soc_node < 0) - return soc_node; - - for (i = 0; i < array_size; i++) { - offset = i / NB_PROT_PER_REG; - shift = (i % NB_PROT_PER_REG) * DECPROT_NB_BITS; - status = (decprot[offset] >> shift) & DECPROT_MASK; - addr = array[i]; - - debug("ETZPC: 0x%08x decprot %d=%d\n", addr, i, status); - - if (addr == ETZPC_RESERVED || - status == DECPROT_NON_SECURED) - continue; - - if (fdt_disable_subnode_by_address(fdt, soc_node, addr)) - printf("ETZPC: 0x%08x node disabled, decprot %d=%d\n", - addr, i, status); - } - - return 0; -} diff --git a/arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S b/arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S new file mode 100644 index 0000000..37a1b06 --- /dev/null +++ b/arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * + */ + +/***************************************************************************** + * This file is only needed for current Soc revision which has a limitation on + * debug reset halt. This can be removed when using the Soc revision that + * fixes the limitation. Anyway, this source code identifies the Soc revision + * and is only executed if it corresponds, so it can be kept on other + * revisions without any consequence. + ****************************************************************************/ + +#include +#include + +#define BIT(nr) (1 << (nr)) + +#define BSEC_OTP_DATA0_ADDR 0x5C005200 +#define BSEC_OTP_DATA0_CLOSED BIT(6) + +#define DBG_DSCR_ADDR 0x500D0088 +#define DBG_DSCR_HDBGEN BIT(14) + +#define RCC_DBGCFGR_ADDR 0x5000080C +#define RCC_DBGCFGR_DBGCKEN BIT(8) + +#define PWR_CR1_ADDR 0x50001000 +#define PWR_CR1_DBP BIT(8) + +#define DBGMCU_IDC_ADDR 0x50081000 +#define DBGMCU_IDC_MASK 0xFFFF0FFF +#define DBGMCU_IDC_VALUE 0x20000500 + +#define TAMP_BKP_REGISTER_20 (0x5C00A100 + (20 << 2)) + + + .globl save_boot_params + +ENTRY(save_boot_params) + /* + * This function is the first call after reset. + * Boot rom parameters are stored in r0..r3, so we mustn't use them + * here. And because they are saved in r9..r12 just after the + * execution of this function, we should firstly use these registers. + * And then, if more registers needed, we have to start by using + * r8, and then r7 and so on. By this way, debug will be done in + * conditions closed to the initial context. + */ + + /* + * Check Sec Close bit in OTP (word 0 bit 6). If enabled, do not allow + * debug session and exit function. + */ + ldr r12, =BSEC_OTP_DATA0_ADDR + ldr r12, [r12] + ands r11, r12, #BSEC_OTP_DATA0_CLOSED + bne func_exit + + /* Check Soc revision */ + ldr r12, =RCC_DBGCFGR_ADDR + ldr r11, [r12] /* read RCC_DBGCFGR (r11) */ + orr r10, r11, #RCC_DBGCFGR_DBGCKEN + str r10, [r12] /* update RCC_DBGCFGR */ + ldr r10, =DBGMCU_IDC_ADDR + ldr r10, [r10] /* read DBGMCU_IDC (r10) */ + str r11, [r12] /* restore RCC_DBGCFGR (r11) */ + ldr r12, =DBGMCU_IDC_MASK + and r10, r12 /* mask reserved bits */ + ldr r11, =DBGMCU_IDC_VALUE + teq r10, r11 /* test DBGMCU_IDC */ + bne func_exit + + /* Disable the backup domain write protection */ + ldr r12, =PWR_CR1_ADDR + ldr r11, [r12] + orr r11, r11, #PWR_CR1_DBP + str r11, [r12] +poll_dbp: + ldr r11, [r12] + tst r11, #PWR_CR1_DBP + beq poll_dbp + + /* Clear tamper 20 bit 16 if set */ + ldr r12, =TAMP_BKP_REGISTER_20 + ldr r11, [r12] + tst r11, #(BIT(16)) + beq func_exit + bic r11, #(BIT(16)) + str r11, [r12] + + /* Re-enable the backup domain write protection */ + ldr r12, =PWR_CR1_ADDR + ldr r11, [r12] + bic r11, #PWR_CR1_DBP + str r11, [r12] +poll_dbp_2: + ldr r11, [r12] + tst r11, #PWR_CR1_DBP + bne poll_dbp_2 + + /* Get current time + 1 second */ + /* CNTFRQ */ + mrc p15, 0, r12, c14, c0, 0 + /* CNTPCT_64 */ + mrrc p15, 0, r11, r10, c14 + add r12, r12, r11 + +loop: + /* Check A7 DBG_DSCR HDBGEN bit value */ + ldr r10, =DBG_DSCR_ADDR + ldr r10, [r10] + tst r10, #DBG_DSCR_HDBGEN + beq loop_continue + /* Sw break */ + bkpt 5 + /* Jump entrypoint */ + b reset +loop_continue: + /* Check 1 second expiration */ + mrrc p15, 0, r10, r9, c14 + /* Check if MSB 64-bit increment needed */ + cmp r12, r11 + bmi msb_incr + cmp r12, r10 + bmi func_exit + b loop +msb_incr: + cmp r12, r10 + bpl loop + cmp r11, r10 + bmi loop +func_exit: + b save_boot_params_ret +ENDPROC(save_boot_params) diff --git a/arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S b/arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S deleted file mode 100644 index 29f8e1f..0000000 --- a/arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S +++ /dev/null @@ -1,124 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ -/* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved - * - */ - -/***************************************************************************** - * This file is only needed for current Soc revision which has a limitation on - * debug reset halt. This can be removed when using the Soc revision that - * fixes the limitation. Anyway, this source code identifies the Soc revision - * and is only executed if it corresponds, so it can be kept on other - * revisions without any consequence. - ****************************************************************************/ - -#include -#include - -#define BIT(nr) (1 << (nr)) - -#define DBG_DSCR_ADDR 0x500D0088 -#define DBG_DSCR_HDBGEN BIT(14) - -#define RCC_DBGCFGR_ADDR 0x5000080C -#define RCC_DBGCFGR_DBGCKEN BIT(8) - -#define PWR_CR1_ADDR 0x50001000 -#define PWR_CR1_DBP BIT(8) - -#define DBGMCU_IDC_ADDR 0x50081000 -#define DBGMCU_IDC_MASK 0xFFFF0FFF -#define DBGMCU_IDC_VALUE 0x20000500 - -#define TAMP_BKP_REGISTER_20 (0x5C00A100 + (20 << 2)) - - - .globl save_boot_params - -ENTRY(save_boot_params) - /* - * This function is the first call after reset. - * Boot rom parameters are stored in r0..r3, so we mustn't use them - * here. And because they are saved in r9..r12 just after the - * execution of this function, we should firstly use these registers. - * And then, if more registers needed, we have to start by using - * r8, and then r7 and so on. By this way, debug will be done in - * conditions closed to the initial context. - */ - - /* Check Soc revision */ - ldr r12, =RCC_DBGCFGR_ADDR - ldr r11, [r12] /* read RCC_DBGCFGR (r11) */ - orr r10, r11, #RCC_DBGCFGR_DBGCKEN - str r10, [r12] /* update RCC_DBGCFGR */ - ldr r10, =DBGMCU_IDC_ADDR - ldr r10, [r10] /* read DBGMCU_IDC (r10) */ - str r11, [r12] /* restore RCC_DBGCFGR (r11) */ - ldr r12, =DBGMCU_IDC_MASK - and r10, r12 /* mask reserved bits */ - ldr r11, =DBGMCU_IDC_VALUE - teq r10, r11 /* test DBGMCU_IDC */ - bne func_exit - - /* Disable the backup domain write protection */ - ldr r12, =PWR_CR1_ADDR - ldr r11, [r12] - orr r11, r11, #PWR_CR1_DBP - str r11, [r12] -poll_dbp: - ldr r11, [r12] - tst r11, #PWR_CR1_DBP - beq poll_dbp - - /* Clear tamper 20 bit 16 if set */ - ldr r12, =TAMP_BKP_REGISTER_20 - ldr r11, [r12] - tst r11, #(BIT(16)) - beq func_exit - bic r11, #(BIT(16)) - str r11, [r12] - - /* Re-enable the backup domain write protection */ - ldr r12, =PWR_CR1_ADDR - ldr r11, [r12] - bic r11, #PWR_CR1_DBP - str r11, [r12] -poll_dbp_2: - ldr r11, [r12] - tst r11, #PWR_CR1_DBP - bne poll_dbp_2 - - /* Get current time + 1 second */ - /* CNTFRQ */ - mrc p15, 0, r12, c14, c0, 0 - /* CNTPCT_64 */ - mrrc p15, 0, r11, r10, c14 - add r12, r12, r11 - -loop: - /* Check A7 DBG_DSCR HDBGEN bit value */ - ldr r10, =DBG_DSCR_ADDR - ldr r10, [r10] - tst r10, #DBG_DSCR_HDBGEN - beq loop_continue - /* Sw break */ - bkpt 5 - /* Jump entrypoint */ - b reset -loop_continue: - /* Check 1 second expiration */ - mrrc p15, 0, r10, r9, c14 - /* Check if MSB 64-bit increment needed */ - cmp r12, r11 - bmi msb_incr - cmp r12, r10 - bmi func_exit - b loop -msb_incr: - cmp r12, r10 - bpl loop - cmp r11, r10 - bmi loop -func_exit: - b save_boot_params_ret -ENDPROC(save_boot_params) diff --git a/arch/arm/mach-stm32mp/syscon.c b/arch/arm/mach-stm32mp/syscon.c index 242f834..e10c42e 100644 --- a/arch/arm/mach-stm32mp/syscon.c +++ b/arch/arm/mach-stm32mp/syscon.c @@ -9,7 +9,6 @@ #include static const struct udevice_id stm32mp_syscon_ids[] = { - { .compatible = "st,stm32mp1-etzpc", .data = STM32MP_SYSCON_ETZPC }, { .compatible = "st,stm32mp1-pwr", .data = STM32MP_SYSCON_PWR }, { .compatible = "st,stm32-stgen", .data = STM32MP_SYSCON_STGEN }, { .compatible = "st,stm32mp157-syscfg", -- 2.7.4