summaryrefslogtreecommitdiff
path: root/arch/arm/mach-stm32mp
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-stm32mp')
-rw-r--r--arch/arm/mach-stm32mp/Kconfig29
-rw-r--r--arch/arm/mach-stm32mp/Makefile3
-rw-r--r--arch/arm/mach-stm32mp/bsec.c60
-rw-r--r--arch/arm/mach-stm32mp/cmd_poweroff.c24
-rw-r--r--arch/arm/mach-stm32mp/config.mk15
-rw-r--r--arch/arm/mach-stm32mp/cpu.c214
-rw-r--r--arch/arm/mach-stm32mp/include/mach/stm32.h23
-rw-r--r--arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h64
-rw-r--r--arch/arm/mach-stm32mp/include/mach/sys_proto.h12
-rw-r--r--arch/arm/mach-stm32mp/psci.c8
-rw-r--r--arch/arm/mach-stm32mp/spl.c39
-rw-r--r--arch/arm/mach-stm32mp/syscon.c9
12 files changed, 441 insertions, 59 deletions
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index 8a929fa913..73aa382712 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -17,7 +17,7 @@ config SPL
select SPL_DM_RESET
select SPL_SERIAL_SUPPORT
select SPL_SYSCON
- select SPL_DRIVERS_MISC_SUPPORT
+ imply SPL_DISPLAY_PRINT
imply SPL_LIBDISK_SUPPORT
config SYS_SOC
@@ -25,18 +25,31 @@ config SYS_SOC
config TARGET_STM32MP1
bool "Support stm32mp1xx"
- select ARCH_SUPPORT_PSCI
+ select ARCH_SUPPORT_PSCI if !STM32MP1_TRUSTED
select CPU_V7A
- select CPU_V7_HAS_NONSEC
+ select CPU_V7_HAS_NONSEC if !STM32MP1_TRUSTED
select CPU_V7_HAS_VIRT
select PINCTRL_STM32
select STM32_RCC
select STM32_RESET
select SYS_ARCH_TIMER
- select SYSRESET_SYSCON
+ imply SYSRESET_PSCI if STM32MP1_TRUSTED
+ imply SYSRESET_SYSCON if !STM32MP1_TRUSTED
help
target STMicroelectronics SOC STM32MP1 family
+ STM32MP157, STM32MP153 or STM32MP151
STMicroelectronics MPU with core ARMv7
+ dual core A7 for STM32MP157/3, monocore for STM32MP151
+
+config STM32MP1_TRUSTED
+ bool "Support trusted boot with TF-A"
+ default y if !SPL
+ select ARM_SMCCC
+ help
+ 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 provides proprietary smc to manage secure devices
config SYS_TEXT_BASE
prompt "U-Boot base address"
@@ -46,6 +59,9 @@ config SYS_TEXT_BASE
when DDR driver is used:
DDR + 1MB (0xC0100000)
+config NR_DRAM_BANKS
+ default 1
+
config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2
hex "Partition on MMC2 to use to load U-Boot from"
depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
@@ -54,9 +70,6 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2
Partition on the second MMC to load U-Boot from when the MMC is being
used in raw mode
-source "board/st/stm32mp1/Kconfig"
-
-# currently activated for debug / should be deactivated for real product
if DEBUG_UART
config DEBUG_UART_BOARD_INIT
@@ -71,4 +84,6 @@ config DEBUG_UART_CLOCK
default 64000000
endif
+source "board/st/stm32mp1/Kconfig"
+
endif
diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile
index f59ced5ee1..1493914a11 100644
--- a/arch/arm/mach-stm32mp/Makefile
+++ b/arch/arm/mach-stm32mp/Makefile
@@ -11,6 +11,9 @@ ifdef CONFIG_SPL_BUILD
obj-y += spl.o
else
obj-y += bsec.o
+ifndef CONFIG_STM32MP1_TRUSTED
+obj-$(CONFIG_SYSRESET) += cmd_poweroff.o
+endif
endif
obj-$(CONFIG_ARMV7_PSCI) += psci.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR) += pwr_regulator.o
diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
index d087a31389..9ed8d8c56c 100644
--- a/arch/arm/mach-stm32mp/bsec.c
+++ b/arch/arm/mach-stm32mp/bsec.c
@@ -8,9 +8,12 @@
#include <misc.h>
#include <asm/io.h>
#include <linux/iopoll.h>
+#include <asm/arch/stm32mp1_smc.h>
+#include <linux/arm-smccc.h>
#define BSEC_OTP_MAX_VALUE 95
+#ifndef CONFIG_STM32MP1_TRUSTED
#define BSEC_TIMEOUT_US 10000
/* BSEC REGISTER OFFSET (base relative) */
@@ -168,7 +171,7 @@ static int bsec_shadow_register(u32 base, u32 otp)
ret = bsec_power_safmem(base, true);
if (ret)
return ret;
- power_up = 1;
+ power_up = true;
}
/* set BSEC_OTP_CTRL_OFF with the otp value*/
writel(otp | BSEC_READ, base + BSEC_OTP_CTRL_OFF);
@@ -270,6 +273,7 @@ static int bsec_program_otp(long base, u32 val, u32 otp)
return ret;
}
+#endif /* CONFIG_STM32MP1_TRUSTED */
/* BSEC MISC driver *******************************************************/
struct stm32mp_bsec_platdata {
@@ -278,6 +282,11 @@ struct stm32mp_bsec_platdata {
static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp)
{
+#ifdef CONFIG_STM32MP1_TRUSTED
+ return stm32_smc(STM32_SMC_BSEC,
+ STM32_SMC_READ_OTP,
+ otp, 0, val);
+#else
struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
u32 tmp_data = 0;
int ret;
@@ -299,27 +308,46 @@ static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp)
/* restore shadow value */
ret = bsec_write_shadow(plat->base, tmp_data, otp);
return ret;
+#endif
}
static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
{
+#ifdef CONFIG_STM32MP1_TRUSTED
+ return stm32_smc(STM32_SMC_BSEC,
+ STM32_SMC_READ_SHADOW,
+ otp, 0, val);
+#else
struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
return bsec_read_shadow(plat->base, val, otp);
+#endif
}
static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp)
{
+#ifdef CONFIG_STM32MP1_TRUSTED
+ return stm32_smc_exec(STM32_SMC_BSEC,
+ STM32_SMC_PROG_OTP,
+ otp, val);
+#else
struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
return bsec_program_otp(plat->base, val, otp);
+#endif
}
static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
{
+#ifdef CONFIG_STM32MP1_TRUSTED
+ return stm32_smc_exec(STM32_SMC_BSEC,
+ STM32_SMC_WRITE_SHADOW,
+ otp, val);
+#else
struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
return bsec_write_shadow(plat->base, val, otp);
+#endif
}
static int stm32mp_bsec_read(struct udevice *dev, int offset,
@@ -405,8 +433,23 @@ static int stm32mp_bsec_ofdata_to_platdata(struct udevice *dev)
return 0;
}
+#ifndef CONFIG_STM32MP1_TRUSTED
+static int stm32mp_bsec_probe(struct udevice *dev)
+{
+ int otp;
+ struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+
+ /* update unlocked shadow for OTP cleared by the rom code */
+ for (otp = 57; otp <= BSEC_OTP_MAX_VALUE; otp++)
+ if (!bsec_read_SR_lock(plat->base, otp))
+ bsec_shadow_register(plat->base, otp);
+
+ return 0;
+}
+#endif
+
static const struct udevice_id stm32mp_bsec_ids[] = {
- { .compatible = "st,stm32mp-bsec" },
+ { .compatible = "st,stm32mp15-bsec" },
{}
};
@@ -417,14 +460,7 @@ U_BOOT_DRIVER(stm32mp_bsec) = {
.ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata),
.ops = &stm32mp_bsec_ops,
-};
-
-/* bsec IP is not present in device tee, manage IP address by platdata */
-static struct stm32mp_bsec_platdata stm32_bsec_platdata = {
- .base = STM32_BSEC_BASE,
-};
-
-U_BOOT_DEVICE(stm32mp_bsec) = {
- .name = "stm32mp_bsec",
- .platdata = &stm32_bsec_platdata,
+#ifndef CONFIG_STM32MP1_TRUSTED
+ .probe = stm32mp_bsec_probe,
+#endif
};
diff --git a/arch/arm/mach-stm32mp/cmd_poweroff.c b/arch/arm/mach-stm32mp/cmd_poweroff.c
new file mode 100644
index 0000000000..f54dd1daf2
--- /dev/null
+++ b/arch/arm/mach-stm32mp/cmd_poweroff.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <command.h>
+#include <sysreset.h>
+
+int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int ret;
+
+ puts("poweroff ...\n");
+ mdelay(100);
+
+ ret = sysreset_walk(SYSRESET_POWER);
+
+ if (ret == -EINPROGRESS)
+ mdelay(1000);
+
+ /*NOTREACHED when power off*/
+ return CMD_RET_FAILURE;
+}
diff --git a/arch/arm/mach-stm32mp/config.mk b/arch/arm/mach-stm32mp/config.mk
index f371aac75b..403af2a225 100644
--- a/arch/arm/mach-stm32mp/config.mk
+++ b/arch/arm/mach-stm32mp/config.mk
@@ -3,7 +3,20 @@
# Copyright (C) 2018, STMicroelectronics - All Rights Reserved
#
-ALL-$(CONFIG_SPL_BUILD) += u-boot-spl.stm32
+ifndef CONFIG_SPL
+ALL-y += u-boot.stm32
+else
+ifdef CONFIG_SPL_BUILD
+ALL-y += u-boot-spl.stm32
+endif
+endif
+
+MKIMAGEFLAGS_u-boot.stm32 = -T stm32image -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE)
+
+u-boot.stm32: MKIMAGEOUTPUT = u-boot.stm32.log
+
+u-boot.stm32: u-boot.bin FORCE
+ $(call if_changed,mkimage)
MKIMAGEFLAGS_u-boot-spl.stm32 = -T stm32image -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE)
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index b8933587ad..7b4431c9c7 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -18,6 +18,7 @@
#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)
#define RCC_DBGCFGR_DBGCKEN BIT(8)
@@ -44,6 +45,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
@@ -55,10 +59,32 @@
#define BOOTROM_INSTANCE_SHIFT 16
/* BSEC OTP index */
+#define BSEC_OTP_RPN 1
#define BSEC_OTP_SERIAL 13
+#define BSEC_OTP_PKG 16
#define BSEC_OTP_MAC 57
+/* Device Part Number (RPN) = OTP_DATA1 lower 8 bits */
+#define RPN_SHIFT 0
+#define RPN_MASK GENMASK(7, 0)
+
+/* Package = bit 27:29 of OTP16
+ * - 100: LBGA448 (FFI) => AA = LFBGA 18x18mm 448 balls p. 0.8mm
+ * - 011: LBGA354 (LCI) => AB = LFBGA 16x16mm 359 balls p. 0.8mm
+ * - 010: TFBGA361 (FFC) => AC = TFBGA 12x12mm 361 balls p. 0.5mm
+ * - 001: TFBGA257 (LCC) => AD = TFBGA 10x10mm 257 balls p. 0.5mm
+ * - others: Reserved
+ */
+#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
+
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+#ifndef CONFIG_STM32MP1_TRUSTED
static void security_init(void)
{
/* Disable the backup domain write protection */
@@ -113,7 +139,12 @@ 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 */
/*
* Debug init
@@ -127,13 +158,19 @@ static void dbgmcu_init(void)
}
#endif /* !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) */
-static u32 get_bootmode(void)
+#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;
-#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
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;
bootrom_instance =
@@ -147,12 +184,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;
}
/*
@@ -167,16 +206,18 @@ int arch_cpu_init(void)
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
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) && \
+ !defined(CONFIG_STM32MP1_TRUSTED) && \
(!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
else
debug_uart_init();
@@ -203,25 +244,94 @@ u32 get_cpu_rev(void)
return (read_idc() & DBGMCU_IDC_REV_ID_MASK) >> DBGMCU_IDC_REV_ID_SHIFT;
}
+static u32 get_otp(int index, int shift, int mask)
+{
+ int ret;
+ struct udevice *dev;
+ u32 otp = 0;
+
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(stm32mp_bsec),
+ &dev);
+
+ if (!ret)
+ ret = misc_read(dev, STM32_BSEC_SHADOW(index),
+ &otp, sizeof(otp));
+
+ return (otp >> shift) & mask;
+}
+
+/* Get Device Part Number (RPN) from OTP */
+static u32 get_cpu_rpn(void)
+{
+ return get_otp(BSEC_OTP_RPN, RPN_SHIFT, RPN_MASK);
+}
+
u32 get_cpu_type(void)
{
- return (read_idc() & DBGMCU_IDC_DEV_ID_MASK) >> DBGMCU_IDC_DEV_ID_SHIFT;
+ u32 id;
+
+ id = (read_idc() & DBGMCU_IDC_DEV_ID_MASK) >> DBGMCU_IDC_DEV_ID_SHIFT;
+
+ return (id << 16) | get_cpu_rpn();
+}
+
+/* Get Package options from OTP */
+static u32 get_cpu_package(void)
+{
+ return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK);
}
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
- char *cpu_s, *cpu_r;
+ char *cpu_s, *cpu_r, *pkg;
+ /* MPUs Part Numbers */
switch (get_cpu_type()) {
- case CPU_STMP32MP15x:
- cpu_s = "15x";
+ case CPU_STM32MP157Cxx:
+ cpu_s = "157C";
+ break;
+ case CPU_STM32MP157Axx:
+ cpu_s = "157A";
+ break;
+ case CPU_STM32MP153Cxx:
+ cpu_s = "153C";
+ break;
+ case CPU_STM32MP153Axx:
+ cpu_s = "153A";
+ break;
+ case CPU_STM32MP151Cxx:
+ cpu_s = "151C";
+ break;
+ case CPU_STM32MP151Axx:
+ cpu_s = "151A";
+ break;
+ default:
+ cpu_s = "????";
+ break;
+ }
+
+ /* Package */
+ switch (get_cpu_package()) {
+ case PKG_AA_LBGA448:
+ pkg = "AA";
+ break;
+ case PKG_AB_LBGA354:
+ pkg = "AB";
+ break;
+ case PKG_AC_TFBGA361:
+ pkg = "AC";
+ break;
+ case PKG_AD_TFBGA257:
+ pkg = "AD";
break;
default:
- cpu_s = "?";
+ pkg = "??";
break;
}
+ /* REVISION */
switch (get_cpu_rev()) {
case CPU_REVA:
cpu_r = "A";
@@ -234,7 +344,7 @@ int print_cpuinfo(void)
break;
}
- printf("CPU: STM32MP%s.%s\n", cpu_s, cpu_r);
+ printf("CPU: STM32MP%s%s Rev.%s\n", cpu_s, pkg, cpu_r);
return 0;
}
@@ -242,20 +352,48 @@ int print_cpuinfo(void)
static void setup_boot_mode(void)
{
+ const u32 serial_addr[] = {
+ STM32_USART1_BASE,
+ STM32_USART2_BASE,
+ STM32_USART3_BASE,
+ STM32_UART4_BASE,
+ STM32_UART5_BASE,
+ STM32_USART6_BASE,
+ STM32_UART7_BASE,
+ STM32_UART8_BASE
+ };
char cmd[60];
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;
+ u32 forced_mode = (boot_ctx & TAMP_BOOT_FORCED_MASK);
+ struct udevice *dev;
+ int alias;
- pr_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d\n",
- __func__, boot_ctx, boot_mode, instance);
-
+ pr_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d forced=%x\n",
+ __func__, boot_ctx, boot_mode, instance, forced_mode);
switch (boot_mode & TAMP_BOOT_DEVICE_MASK) {
case BOOT_SERIAL_UART:
- sprintf(cmd, "%d", instance);
- env_set("boot_device", "uart");
+ if (instance > ARRAY_SIZE(serial_addr))
+ break;
+ /* serial : search associated alias in devicetree */
+ sprintf(cmd, "serial@%x", serial_addr[instance]);
+ if (uclass_get_device_by_name(UCLASS_SERIAL, cmd, &dev))
+ break;
+ if (fdtdec_get_alias_seq(gd->fdt_blob, "serial",
+ dev_of_offset(dev), &alias))
+ break;
+ sprintf(cmd, "%d", alias);
+ env_set("boot_device", "serial");
env_set("boot_instance", cmd);
+
+ /* restore console on uart when not used */
+ if (gd->cur_serial_dev != dev) {
+ gd->flags &= ~(GD_FLG_SILENT |
+ GD_FLG_DISABLE_CONSOLE);
+ printf("serial boot with console enabled!\n");
+ }
break;
case BOOT_SERIAL_USB:
env_set("boot_device", "usb");
@@ -279,6 +417,36 @@ static void setup_boot_mode(void)
pr_debug("unexpected boot mode = %x\n", boot_mode);
break;
}
+
+ switch (forced_mode) {
+ case BOOT_FASTBOOT:
+ printf("Enter fastboot!\n");
+ env_set("preboot", "env set preboot; fastboot 0");
+ break;
+ case BOOT_STM32PROG:
+ env_set("boot_device", "usb");
+ env_set("boot_instance", "0");
+ break;
+ case BOOT_UMS_MMC0:
+ case BOOT_UMS_MMC1:
+ case BOOT_UMS_MMC2:
+ printf("Enter UMS!\n");
+ instance = forced_mode - BOOT_UMS_MMC0;
+ sprintf(cmd, "env set preboot; ums 0 mmc %d", instance);
+ env_set("preboot", cmd);
+ break;
+ case BOOT_RECOVERY:
+ env_set("preboot", "env set preboot; run altbootcmd");
+ break;
+ case BOOT_NORMAL:
+ break;
+ default:
+ pr_debug("unexpected forced boot mode = %x\n", forced_mode);
+ break;
+ }
+
+ /* clear TAMP for next reboot */
+ clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_FORCED_MASK, BOOT_NORMAL);
}
/*
@@ -304,7 +472,7 @@ static int setup_mac_address(void)
if (ret)
return ret;
- ret = misc_read(dev, BSEC_OTP_MAC * 4 + STM32_BSEC_OTP_OFFSET,
+ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_MAC),
otp, sizeof(otp));
if (ret < 0)
return ret;
@@ -342,12 +510,12 @@ static int setup_serial_number(void)
if (ret)
return ret;
- ret = misc_read(dev, BSEC_OTP_SERIAL * 4 + STM32_BSEC_OTP_OFFSET,
+ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_SERIAL),
otp, sizeof(otp));
if (ret < 0)
return ret;
- sprintf(serial_string, "%08x%08x%08x", otp[0], otp[1], otp[2]);
+ sprintf(serial_string, "%08X%08X%08X", otp[0], otp[1], otp[2]);
env_set("serial#", serial_string);
return 0;
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h
index 5d0bdca178..c526c88e3e 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -13,13 +13,10 @@
#define STM32_RCC_BASE 0x50000000
#define STM32_PWR_BASE 0x50001000
#define STM32_DBGMCU_BASE 0x50081000
-#define STM32_BSEC_BASE 0x5C005000
#define STM32_TZC_BASE 0x5C006000
#define STM32_ETZPC_BASE 0x5C007000
#define STM32_TAMP_BASE 0x5C00A000
-#ifdef CONFIG_DEBUG_UART_BASE
-/* hardcoded value can be only used for DEBUG UART */
#define STM32_USART1_BASE 0x5C000000
#define STM32_USART2_BASE 0x4000E000
#define STM32_USART3_BASE 0x4000F000
@@ -28,7 +25,6 @@
#define STM32_USART6_BASE 0x44003000
#define STM32_UART7_BASE 0x40018000
#define STM32_UART8_BASE 0x40019000
-#endif
#define STM32_SYSRAM_BASE 0x2FFC0000
#define STM32_SYSRAM_SIZE SZ_256K
@@ -40,8 +36,10 @@
/* enumerated used to identify the SYSCON driver instance */
enum {
STM32MP_SYSCON_UNKNOWN,
- STM32MP_SYSCON_STGEN,
+ STM32MP_SYSCON_ETZPC,
STM32MP_SYSCON_PWR,
+ STM32MP_SYSCON_STGEN,
+ STM32MP_SYSCON_SYSCFG,
};
/*
@@ -95,10 +93,25 @@ enum boot_device {
#define TAMP_BOOT_MODE_SHIFT 8
#define TAMP_BOOT_DEVICE_MASK GENMASK(7, 4)
#define TAMP_BOOT_INSTANCE_MASK GENMASK(3, 0)
+#define TAMP_BOOT_FORCED_MASK GENMASK(7, 0)
+
+enum forced_boot_mode {
+ BOOT_NORMAL = 0x00,
+ BOOT_FASTBOOT = 0x01,
+ BOOT_RECOVERY = 0x02,
+ BOOT_STM32PROG = 0x03,
+ BOOT_UMS_MMC0 = 0x10,
+ BOOT_UMS_MMC1 = 0x11,
+ BOOT_UMS_MMC2 = 0x12,
+};
/* offset used for BSEC driver: misc_read and misc_write */
#define STM32_BSEC_SHADOW_OFFSET 0x0
+#define STM32_BSEC_SHADOW(id) (STM32_BSEC_SHADOW_OFFSET + (id) * 4)
#define STM32_BSEC_OTP_OFFSET 0x80000000
+#define STM32_BSEC_OTP(id) (STM32_BSEC_OTP_OFFSET + (id) * 4)
+
+#define BSEC_OTP_BOARD 59
#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
new file mode 100644
index 0000000000..8130546b27
--- /dev/null
+++ b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef __STM32MP1_SMC_H__
+#define __STM32MP1_SMC_H__
+
+#include <linux/arm-smccc.h>
+
+/*
+ * SMC function IDs for STM32 Service queries
+ * STM32 SMC services use the space between 0x82000000 and 0x8200FFFF
+ * like this is defined in SMC calling Convention by ARM
+ * for SiP (silicon Partner)
+ * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+ */
+#define STM32_SMC_VERSION 0x82000000
+
+/* Secure Service access from Non-secure */
+#define STM32_SMC_BSEC 0x82001003
+
+/* Service for BSEC */
+#define STM32_SMC_READ_SHADOW 0x01
+#define STM32_SMC_PROG_OTP 0x02
+#define STM32_SMC_WRITE_SHADOW 0x03
+#define STM32_SMC_READ_OTP 0x04
+#define STM32_SMC_READ_ALL 0x05
+#define STM32_SMC_WRITE_ALL 0x06
+
+/* SMC error codes */
+#define STM32_SMC_OK 0x0
+#define STM32_SMC_NOT_SUPPORTED -1
+#define STM32_SMC_FAILED -2
+#define STM32_SMC_INVALID_PARAMS -3
+
+#define stm32_smc_exec(svc, op, data1, data2) \
+ stm32_smc(svc, op, data1, data2, NULL)
+
+#ifdef CONFIG_ARM_SMCCC
+static inline u32 stm32_smc(u32 svc, u8 op, u32 data1, u32 data2, u32 *result)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(svc, op, data1, data2, 0, 0, 0, 0, &res);
+
+ if (res.a0) {
+ pr_err("%s: Failed to exec in secure mode (err = %ld)\n",
+ __func__, res.a0);
+ return -EINVAL;
+ }
+ if (result)
+ *result = (u32)res.a1;
+
+ return 0;
+}
+#else
+static inline u32 stm32_smc(u32 svc, u8 op, u32 data1, u32 data2, u32 *result)
+{
+ return 0;
+}
+#endif
+
+#endif /* __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 41d4b40bcb..71a3ba794d 100644
--- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h
+++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
@@ -3,9 +3,15 @@
* Copyright (C) 2015-2017, STMicroelectronics - All Rights Reserved
*/
-#define CPU_STMP32MP15x 0x500
+/* ID = Device Version (bit31:16) + Device Part Number (RPN) (bit15:0)*/
+#define CPU_STM32MP157Cxx 0x05000000
+#define CPU_STM32MP157Axx 0x05000001
+#define CPU_STM32MP153Cxx 0x05000024
+#define CPU_STM32MP153Axx 0x05000025
+#define CPU_STM32MP151Cxx 0x0500002E
+#define CPU_STM32MP151Axx 0x0500002F
-/* return CPU_STMP32MPxx constants */
+/* return CPU_STMP32MP...Xxx constants */
u32 get_cpu_type(void);
#define CPU_REVA 0x1000
@@ -13,3 +19,5 @@ u32 get_cpu_type(void);
/* return CPU_REV constants */
u32 get_cpu_rev(void);
+/* return boot mode */
+u32 get_bootmode(void);
diff --git a/arch/arm/mach-stm32mp/psci.c b/arch/arm/mach-stm32mp/psci.c
index 6ed2482080..c2dff38c36 100644
--- a/arch/arm/mach-stm32mp/psci.c
+++ b/arch/arm/mach-stm32mp/psci.c
@@ -103,7 +103,13 @@ int __secure psci_affinity_info(u32 function_id, u32 target_affinity,
int __secure psci_migrate_info_type(u32 function_id)
{
- /* Trusted OS is either not present or does not require migration */
+ /*
+ * in Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+ * return 2 = Trusted OS is either not present or does not require
+ * migration, system of this type does not require the caller
+ * to use the MIGRATE function.
+ * MIGRATE function calls return NOT_SUPPORTED.
+ */
return 2;
}
diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c
index 790973e8b6..a3b0d6f382 100644
--- a/arch/arm/mach-stm32mp/spl.c
+++ b/arch/arm/mach-stm32mp/spl.c
@@ -7,13 +7,14 @@
#include <dm.h>
#include <spl.h>
#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <linux/libfdt.h>
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:
@@ -22,6 +23,21 @@ u32 spl_boot_device(void)
case BOOT_FLASH_SD_2:
case BOOT_FLASH_EMMC_2:
return BOOT_DEVICE_MMC2;
+ case BOOT_SERIAL_UART_1:
+ case BOOT_SERIAL_UART_2:
+ case BOOT_SERIAL_UART_3:
+ case BOOT_SERIAL_UART_4:
+ case BOOT_SERIAL_UART_5:
+ case BOOT_SERIAL_UART_6:
+ case BOOT_SERIAL_UART_7:
+ case BOOT_SERIAL_UART_8:
+ return BOOT_DEVICE_UART;
+ case BOOT_SERIAL_USB_OTG:
+ return BOOT_DEVICE_USB;
+ case BOOT_FLASH_NAND_FMC:
+ return BOOT_DEVICE_NAND;
+ case BOOT_FLASH_NOR_QSPI:
+ return BOOT_DEVICE_SPI;
}
return BOOT_DEVICE_MMC1;
@@ -44,6 +60,21 @@ int spl_boot_partition(const u32 boot_device)
}
}
+#ifdef CONFIG_SPL_DISPLAY_PRINT
+void spl_display_print(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ const char *model;
+
+ /* same code than show_board_info() but not compiled for SPL
+ * see CONFIG_DISPLAY_BOARDINFO & common/board_info.c
+ */
+ model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
+ if (model)
+ printf("Model: %s\n", model);
+}
+#endif
+
void board_init_f(ulong dummy)
{
struct udevice *dev;
@@ -80,7 +111,7 @@ void board_init_f(ulong dummy)
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret) {
- debug("DRAM init failed: %d\n", ret);
- return;
+ printf("DRAM init failed: %d\n", ret);
+ hang();
}
}
diff --git a/arch/arm/mach-stm32mp/syscon.c b/arch/arm/mach-stm32mp/syscon.c
index eb7f435f10..242f8340ab 100644
--- a/arch/arm/mach-stm32mp/syscon.c
+++ b/arch/arm/mach-stm32mp/syscon.c
@@ -9,10 +9,11 @@
#include <asm/arch/stm32.h>
static const struct udevice_id stm32mp_syscon_ids[] = {
- { .compatible = "st,stm32-stgen",
- .data = STM32MP_SYSCON_STGEN },
- { .compatible = "st,stm32mp1-pwr",
- .data = STM32MP_SYSCON_PWR },
+ { .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",
+ .data = STM32MP_SYSCON_SYSCFG },
{ }
};