From 2514c2d0e6abe98157c1de83bce5c8bb69ac3a77 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Mon, 12 Mar 2018 10:46:10 +0100 Subject: [PATCH] arm: stm32: add new architecture for STM32MP family - add new arch stm32mp for STM32 MPU/Soc based on Cortex A - support for stm32mp157 SOC - SPL is used as first boot stage loader - using driver model for all the drivers, even in SPL - all security feature are deactivated (ETZC and TZC) - reused STM32 MCU drivers when it is possible Signed-off-by: Patrick Delaunay --- MAINTAINERS | 5 + arch/arm/Kconfig | 25 +++- arch/arm/Makefile | 1 + arch/arm/mach-stm32mp/Kconfig | 41 ++++++ arch/arm/mach-stm32mp/Makefile | 10 ++ arch/arm/mach-stm32mp/config.mk | 14 +++ arch/arm/mach-stm32mp/cpu.c | 139 +++++++++++++++++++++ arch/arm/mach-stm32mp/dram_init.c | 34 +++++ arch/arm/mach-stm32mp/include/mach/gpio.h | 115 +++++++++++++++++ arch/arm/mach-stm32mp/include/mach/stm32.h | 27 ++++ arch/arm/mach-stm32mp/spl.c | 60 +++++++++ drivers/gpio/Kconfig | 2 +- drivers/i2c/Kconfig | 2 +- drivers/serial/Kconfig | 6 +- 14 files changed, 475 insertions(+), 6 deletions(-) create mode 100644 arch/arm/mach-stm32mp/Kconfig create mode 100644 arch/arm/mach-stm32mp/Makefile create mode 100644 arch/arm/mach-stm32mp/config.mk create mode 100644 arch/arm/mach-stm32mp/cpu.c create mode 100644 arch/arm/mach-stm32mp/dram_init.c create mode 100644 arch/arm/mach-stm32mp/include/mach/gpio.h create mode 100644 arch/arm/mach-stm32mp/include/mach/stm32.h create mode 100644 arch/arm/mach-stm32mp/spl.c diff --git a/MAINTAINERS b/MAINTAINERS index f251cf71e8..c4f10aa692 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -195,6 +195,11 @@ T: git git://git.denx.de/u-boot-stm.git F: arch/arm/cpu/arm926ejs/spear/ F: arch/arm/include/asm/arch-spear/ +ARM STM STM32MP +M: Patrick Delaunay +S: Maintained +F: arch/arm/mach-stm32mp + ARM STM STV0991 M: Vikas Manocha S: Maintained diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 95553bee9d..b8f7a982d9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1132,7 +1132,7 @@ config ARCH_UNIPHIER (formerly, System LSI Business Division of Panasonic Corporation) config STM32 - bool "Support STM32" + bool "Support STMicroelectronics STM32 MCU with cortex M" select CPU_V7M select DM select DM_SERIAL @@ -1150,6 +1150,27 @@ config ARCH_STI Support for STMicroelectronics STiH407/10 SoC family. This SoC is used on Linaro 96Board STiH410-B2260 +config ARCH_STM32MP + bool "Support STMicroelectronics STM32MP Socs with cortex A" + select BOARD_LATE_INIT + select CLK + select DM + select DM_GPIO + select DM_RESET + select DM_SERIAL + select OF_CONTROL + select OF_LIBFDT + select PINCTRL + select REGMAP + select SUPPORT_SPL + select SYSCON + select SYS_THUMB_BUILD + help + Support for STM32MP SoC family developed by STMicroelectronics, + MPUs based on ARM cortex A core + U-BOOT is running in DDR and SPL support is the unsecure First Stage + BootLoader (FSBL) + config ARCH_ROCKCHIP bool "Support Rockchip SoCs" select OF_CONTROL @@ -1262,6 +1283,8 @@ source "arch/arm/mach-sti/Kconfig" source "arch/arm/mach-stm32/Kconfig" +source "arch/arm/mach-stm32mp/Kconfig" + source "arch/arm/mach-sunxi/Kconfig" source "arch/arm/mach-tegra/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 5881fdc8e2..4fa8b38397 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -72,6 +72,7 @@ machine-$(CONFIG_ARCH_SOCFPGA) += socfpga machine-$(CONFIG_ARCH_RMOBILE) += rmobile machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip machine-$(CONFIG_STM32) += stm32 +machine-$(CONFIG_ARCH_STM32MP) += stm32mp machine-$(CONFIG_TEGRA) += tegra machine-$(CONFIG_ARCH_UNIPHIER) += uniphier machine-$(CONFIG_ARCH_ZYNQ) += zynq diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig new file mode 100644 index 0000000000..ab94879c42 --- /dev/null +++ b/arch/arm/mach-stm32mp/Kconfig @@ -0,0 +1,41 @@ +if ARCH_STM32MP + +config SPL + select SPL_BOARD_INIT + select SPL_CLK + select SPL_DM + select SPL_DM_SEQ_ALIAS + select SPL_FRAMEWORK + select SPL_GPIO_SUPPORT + select SPL_LIBCOMMON_SUPPORT + select SPL_LIBGENERIC_SUPPORT + select SPL_OF_CONTROL + select SPL_OF_TRANSLATE + select SPL_PINCTRL + select SPL_REGMAP + select SPL_RESET_SUPPORT + select SPL_SERIAL_SUPPORT + select SPL_SYSCON + imply SPL_LIBDISK_SUPPORT + +config SYS_SOC + default "stm32mp" + +config TARGET_STM32MP1 + bool "Support stm32mp1xx" + select CPU_V7 + select PINCTRL_STM32 + select STM32_RESET + help + target STMicroelectronics SOC STM32MP1 family + STMicroelectronics MPU with core ARMv7 + +config SYS_TEXT_BASE + prompt "U-Boot base address" + default 0xC0100000 + help + configure the U-Boot base address + when DDR driver is used: + DDR + 1MB (0xC0100000) + +endif diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile new file mode 100644 index 0000000000..4620869b36 --- /dev/null +++ b/arch/arm/mach-stm32mp/Makefile @@ -0,0 +1,10 @@ +# +# Copyright (C) 2018, STMicroelectronics - All Rights Reserved +# +# SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause +# + +obj-y += cpu.o +obj-y += dram_init.o + +obj-$(CONFIG_SPL_BUILD) += spl.o diff --git a/arch/arm/mach-stm32mp/config.mk b/arch/arm/mach-stm32mp/config.mk new file mode 100644 index 0000000000..34e59c61ac --- /dev/null +++ b/arch/arm/mach-stm32mp/config.mk @@ -0,0 +1,14 @@ +# +# Copyright (C) 2018, STMicroelectronics - All Rights Reserved +# +# SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause +# + +ALL-$(CONFIG_SPL_BUILD) += spl/u-boot-spl.stm32 + +MKIMAGEFLAGS_u-boot-spl.stm32 = -T stm32image -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) + +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) diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c new file mode 100644 index 0000000000..7c43dc1294 --- /dev/null +++ b/arch/arm/mach-stm32mp/cpu.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause + */ +#include +#include +#include +#include + +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} + +#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) +/********************************************** + * Security init + *********************************************/ +#define ETZPC_TZMA1_SIZE (STM32_ETZPC_BASE + 0x04) +#define ETZPC_DECPROT0 (STM32_ETZPC_BASE + 0x10) + +#define TZC_GATE_KEEPER (STM32_TZC_BASE + 0x008) +#define TZC_REGION_ATTRIBUTE0 (STM32_TZC_BASE + 0x110) +#define TZC_REGION_ID_ACCESS0 (STM32_TZC_BASE + 0x114) + +#define TAMP_CR1 (STM32_TAMP_BASE + 0x00) + +#define PWR_CR1 (STM32_PWR_BASE + 0x00) +#define PWR_CR1_DBP BIT(8) + +#define RCC_TZCR (STM32_RCC_BASE + 0x00) +#define RCC_BDCR (STM32_RCC_BASE + 0x0140) +#define RCC_MP_APB5ENSETR (STM32_RCC_BASE + 0x0208) + +#define RCC_BDCR_VSWRST BIT(31) +#define RCC_BDCR_RTCSRC GENMASK(17, 16) + +static void security_init(void) +{ + /* Disable the backup domain write protection */ + /* the protection is enable at each reset by hardware */ + /* And must be disable by software */ + setbits_le32(PWR_CR1, PWR_CR1_DBP); + + while (!(readl(PWR_CR1) & PWR_CR1_DBP)) + ; + + /* If RTC clock isn't enable so this is a cold boot then we need + * to reset the backup domain + */ + if (!(readl(RCC_BDCR) & RCC_BDCR_RTCSRC)) { + setbits_le32(RCC_BDCR, RCC_BDCR_VSWRST); + while (!(readl(RCC_BDCR) & RCC_BDCR_VSWRST)) + ; + clrbits_le32(RCC_BDCR, RCC_BDCR_VSWRST); + } + + /* allow non secure access in Write/Read for all peripheral */ + writel(GENMASK(25, 0), ETZPC_DECPROT0); + + /* Open SYSRAM for no secure access */ + writel(0x0, ETZPC_TZMA1_SIZE); + + /* enable TZC1 TZC2 clock */ + writel(BIT(11) | BIT(12), RCC_MP_APB5ENSETR); + + /* Region 0 set to no access by default */ + /* bit 0 / 16 => nsaid0 read/write Enable + * bit 1 / 17 => nsaid1 read/write Enable + * ... + * bit 15 / 31 => nsaid15 read/write Enable + */ + writel(0xFFFFFFFF, TZC_REGION_ID_ACCESS0); + /* bit 30 / 31 => Secure Global Enable : write/read */ + /* bit 0 / 1 => Region Enable for filter 0/1 */ + writel(BIT(0) | BIT(1) | BIT(30) | BIT(31), TZC_REGION_ATTRIBUTE0); + + /* Enable Filter 0 and 1 */ + setbits_le32(TZC_GATE_KEEPER, BIT(0) | BIT(1)); + + /* RCC trust zone deactivated */ + writel(0x0, RCC_TZCR); + + /* TAMP: deactivate the internal tamper + * Bit 23 ITAMP8E: monotonic counter overflow + * Bit 20 ITAMP5E: RTC calendar overflow + * Bit 19 ITAMP4E: HSE monitoring + * Bit 18 ITAMP3E: LSE monitoring + * Bit 16 ITAMP1E: RTC power domain supply monitoring + */ + writel(0x0, TAMP_CR1); +} + +/********************************************** + * Debug init + *********************************************/ +#define RCC_DBGCFGR (STM32_RCC_BASE + 0x080C) +#define RCC_DBGCFGR_DBGCKEN BIT(8) + +#define DBGMCU_APB4FZ1 (STM32_DBGMCU_BASE + 0x2C) +#define DBGMCU_APB4FZ1_IWDG2 BIT(2) + +static void dbgmcu_init(void) +{ + setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); + + /* Freeze IWDG2 if Cortex-A7 is in debug mode */ + setbits_le32(DBGMCU_APB4FZ1, DBGMCU_APB4FZ1_IWDG2); +} +#endif /* !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) */ + +int arch_cpu_init(void) +{ + /* early armv7 timer init: needed for polling */ + timer_init(); + +#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) + dbgmcu_init(); + + security_init(); +#endif + + return 0; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + printf("CPU: STM32MP15x\n"); + + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ + +void reset_cpu(ulong addr) +{ +} diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c new file mode 100644 index 0000000000..ecb4c988d2 --- /dev/null +++ b/arch/arm/mach-stm32mp/dram_init.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + struct ram_info ram; + struct udevice *dev; + int ret; + + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) { + debug("RAM init failed: %d\n", ret); + return ret; + } + ret = ram_get_info(dev, &ram); + if (ret) { + debug("Cannot get RAM size: %d\n", ret); + return ret; + } + debug("RAM init base=%lx, size=%x\n", ram.base, ram.size); + + gd->ram_size = ram.size; + + return 0; +} diff --git a/arch/arm/mach-stm32mp/include/mach/gpio.h b/arch/arm/mach-stm32mp/include/mach/gpio.h new file mode 100644 index 0000000000..5952557792 --- /dev/null +++ b/arch/arm/mach-stm32mp/include/mach/gpio.h @@ -0,0 +1,115 @@ +/* + * (C) Copyright 2016 + * Vikas Manocha, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _STM32_GPIO_H_ +#define _STM32_GPIO_H_ +#include + +enum stm32_gpio_port { + STM32_GPIO_PORT_A = 0, + STM32_GPIO_PORT_B, + STM32_GPIO_PORT_C, + STM32_GPIO_PORT_D, + STM32_GPIO_PORT_E, + STM32_GPIO_PORT_F, + STM32_GPIO_PORT_G, + STM32_GPIO_PORT_H, + STM32_GPIO_PORT_I +}; + +enum stm32_gpio_pin { + STM32_GPIO_PIN_0 = 0, + STM32_GPIO_PIN_1, + STM32_GPIO_PIN_2, + STM32_GPIO_PIN_3, + STM32_GPIO_PIN_4, + STM32_GPIO_PIN_5, + STM32_GPIO_PIN_6, + STM32_GPIO_PIN_7, + STM32_GPIO_PIN_8, + STM32_GPIO_PIN_9, + STM32_GPIO_PIN_10, + STM32_GPIO_PIN_11, + STM32_GPIO_PIN_12, + STM32_GPIO_PIN_13, + STM32_GPIO_PIN_14, + STM32_GPIO_PIN_15 +}; + +enum stm32_gpio_mode { + STM32_GPIO_MODE_IN = 0, + STM32_GPIO_MODE_OUT, + STM32_GPIO_MODE_AF, + STM32_GPIO_MODE_AN +}; + +enum stm32_gpio_otype { + STM32_GPIO_OTYPE_PP = 0, + STM32_GPIO_OTYPE_OD +}; + +enum stm32_gpio_speed { + STM32_GPIO_SPEED_2M = 0, + STM32_GPIO_SPEED_25M, + STM32_GPIO_SPEED_50M, + STM32_GPIO_SPEED_100M +}; + +enum stm32_gpio_pupd { + STM32_GPIO_PUPD_NO = 0, + STM32_GPIO_PUPD_UP, + STM32_GPIO_PUPD_DOWN +}; + +enum stm32_gpio_af { + STM32_GPIO_AF0 = 0, + STM32_GPIO_AF1, + STM32_GPIO_AF2, + STM32_GPIO_AF3, + STM32_GPIO_AF4, + STM32_GPIO_AF5, + STM32_GPIO_AF6, + STM32_GPIO_AF7, + STM32_GPIO_AF8, + STM32_GPIO_AF9, + STM32_GPIO_AF10, + STM32_GPIO_AF11, + STM32_GPIO_AF12, + STM32_GPIO_AF13, + STM32_GPIO_AF14, + STM32_GPIO_AF15 +}; + +struct stm32_gpio_dsc { + enum stm32_gpio_port port; + enum stm32_gpio_pin pin; +}; + +struct stm32_gpio_ctl { + enum stm32_gpio_mode mode; + enum stm32_gpio_otype otype; + enum stm32_gpio_speed speed; + enum stm32_gpio_pupd pupd; + enum stm32_gpio_af af; +}; + +struct stm32_gpio_regs { + u32 moder; /* GPIO port mode */ + u32 otyper; /* GPIO port output type */ + u32 ospeedr; /* GPIO port output speed */ + u32 pupdr; /* GPIO port pull-up/pull-down */ + u32 idr; /* GPIO port input data */ + u32 odr; /* GPIO port output data */ + u32 bsrr; /* GPIO port bit set/reset */ + u32 lckr; /* GPIO port configuration lock */ + u32 afr[2]; /* GPIO alternate function */ +}; + +struct stm32_gpio_priv { + struct stm32_gpio_regs *regs; +}; +#endif /* _STM32_GPIO_H_ */ diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h new file mode 100644 index 0000000000..ffbe0b1034 --- /dev/null +++ b/arch/arm/mach-stm32mp/include/mach/stm32.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause + */ + +#ifndef _MACH_STM32_H_ +#define _MACH_STM32_H_ + +/* + * Peripheral memory map + * only address used before device tree parsing + */ +#define STM32_RCC_BASE 0x50000000 +#define STM32_PWR_BASE 0x50001000 +#define STM32_DBGMCU_BASE 0x50081000 +#define STM32_TZC_BASE 0x5C006000 +#define STM32_ETZPC_BASE 0x5C007000 +#define STM32_TAMP_BASE 0x5C00A000 + +#define STM32_SYSRAM_BASE 0x2FFC0000 +#define STM32_SYSRAM_SIZE SZ_256K + +#define STM32_DDR_BASE 0xC0000000 +#define STM32_DDR_SIZE SZ_1G + +#endif /* _MACH_STM32_H_ */ diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c new file mode 100644 index 0000000000..8f5962a935 --- /dev/null +++ b/arch/arm/mach-stm32mp/spl.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause + */ + +#include +#include +#include + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_MMC1; +} + +u32 spl_boot_mode(const u32 boot_device) +{ + return MMCSD_MODE_RAW; +} + +void board_init_f(ulong dummy) +{ + struct udevice *dev; + int ret; + + arch_cpu_init(); + + ret = spl_early_init(); + if (ret) { + debug("spl_early_init() failed: %d\n", ret); + hang(); + } + + ret = uclass_get_device(UCLASS_CLK, 0, &dev); + if (ret) { + debug("Clock init failed: %d\n", ret); + return; + } + + ret = uclass_get_device(UCLASS_RESET, 0, &dev); + if (ret) { + debug("Reset init failed: %d\n", ret); + return; + } + + ret = uclass_get_device(UCLASS_PINCTRL, 0, &dev); + if (ret) { + debug("%s: Cannot find pinctrl device\n", __func__); + return; + } + + /* enable console uart printing */ + preloader_console_init(); + + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) { + debug("DRAM init failed: %d\n", ret); + return; + } +} diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index cc75aece6a..b7e4ffb09d 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -234,7 +234,7 @@ config PIC32_GPIO config STM32F7_GPIO bool "ST STM32 GPIO driver" - depends on DM_GPIO && STM32 + depends on DM_GPIO && (STM32 || ARCH_STM32MP) default y help Device model driver support for STM32 GPIO controller. It should be diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 932abd3059..3299ef0fea 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -207,7 +207,7 @@ config SYS_I2C_S3C24X0 config SYS_I2C_STM32F7 bool "STMicroelectronics STM32F7 I2C support" - depends on (STM32F7 || STM32H7) && DM_I2C + depends on (STM32F7 || STM32H7 || ARCH_STM32MP) && DM_I2C help Enable this option to add support for STM32 I2C controller introduced with STM32F7/H7 SoCs. This I2C controller supports : diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 76d5e99647..eb718a650f 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -609,10 +609,10 @@ config STI_ASC_SERIAL config STM32_SERIAL bool "STMicroelectronics STM32 SoCs on-chip UART" - depends on DM_SERIAL && (STM32F4 || STM32F7 || STM32H7) + depends on DM_SERIAL && (STM32F4 || STM32F7 || STM32H7 || ARCH_STM32MP) help - If you have a machine based on a STM32 F4, F7 or H7 SoC you can - enable its onboard serial ports, say Y to this option. + If you have a machine based on a STM32 F4, F7, H7 or MP1 SOC + you can enable its onboard serial ports, say Y to this option. If unsure, say N. config ZYNQ_SERIAL -- 2.25.1