1c9d75b3cSYann Gautier /* 2db3e0eceSYann Gautier * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. 3c9d75b3cSYann Gautier * 4c9d75b3cSYann Gautier * SPDX-License-Identifier: BSD-3-Clause 5c9d75b3cSYann Gautier */ 6c9d75b3cSYann Gautier 78f282daeSYann Gautier #include <assert.h> 88f282daeSYann Gautier 933667d29SYann Gautier #include <drivers/clk.h> 10d7176f03SYann Gautier #include <drivers/st/stm32_gpio.h> 11d7176f03SYann Gautier #include <drivers/st/stm32_iwdg.h> 124dc77a35SYann Gautier #include <lib/mmio.h> 13d7176f03SYann Gautier #include <lib/xlat_tables/xlat_tables_v2.h> 14ff7675ebSYann Gautier #include <libfdt.h> 1510e7a9e9SYann Gautier 16ba02add9SSughosh Ganu #include <plat/common/platform.h> 17c9d75b3cSYann Gautier #include <platform_def.h> 18c9d75b3cSYann Gautier 1910e7a9e9SYann Gautier /* Internal layout of the 32bit OTP word board_id */ 2010e7a9e9SYann Gautier #define BOARD_ID_BOARD_NB_MASK GENMASK(31, 16) 2110e7a9e9SYann Gautier #define BOARD_ID_BOARD_NB_SHIFT 16 22f964f5c3SPatrick Delaunay #define BOARD_ID_VARCPN_MASK GENMASK(15, 12) 23f964f5c3SPatrick Delaunay #define BOARD_ID_VARCPN_SHIFT 12 2410e7a9e9SYann Gautier #define BOARD_ID_REVISION_MASK GENMASK(11, 8) 2510e7a9e9SYann Gautier #define BOARD_ID_REVISION_SHIFT 8 26f964f5c3SPatrick Delaunay #define BOARD_ID_VARFG_MASK GENMASK(7, 4) 27f964f5c3SPatrick Delaunay #define BOARD_ID_VARFG_SHIFT 4 2810e7a9e9SYann Gautier #define BOARD_ID_BOM_MASK GENMASK(3, 0) 2910e7a9e9SYann Gautier 3010e7a9e9SYann Gautier #define BOARD_ID2NB(_id) (((_id) & BOARD_ID_BOARD_NB_MASK) >> \ 3110e7a9e9SYann Gautier BOARD_ID_BOARD_NB_SHIFT) 32f964f5c3SPatrick Delaunay #define BOARD_ID2VARCPN(_id) (((_id) & BOARD_ID_VARCPN_MASK) >> \ 33f964f5c3SPatrick Delaunay BOARD_ID_VARCPN_SHIFT) 3410e7a9e9SYann Gautier #define BOARD_ID2REV(_id) (((_id) & BOARD_ID_REVISION_MASK) >> \ 3510e7a9e9SYann Gautier BOARD_ID_REVISION_SHIFT) 36f964f5c3SPatrick Delaunay #define BOARD_ID2VARFG(_id) (((_id) & BOARD_ID_VARFG_MASK) >> \ 37f964f5c3SPatrick Delaunay BOARD_ID_VARFG_SHIFT) 3810e7a9e9SYann Gautier #define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK) 3910e7a9e9SYann Gautier 404dc77a35SYann Gautier #define TAMP_BOOT_MODE_BACKUP_REG_ID U(20) 414dc77a35SYann Gautier #define TAMP_BOOT_MODE_ITF_MASK U(0x0000FF00) 424dc77a35SYann Gautier #define TAMP_BOOT_MODE_ITF_SHIFT 8 434dc77a35SYann Gautier 44ba02add9SSughosh Ganu #define TAMP_BOOT_COUNTER_REG_ID U(21) 45ba02add9SSughosh Ganu 460754143aSEtienne Carriere #if defined(IMAGE_BL2) 470754143aSEtienne Carriere #define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ 483f9c9784SYann Gautier STM32MP_SYSRAM_SIZE, \ 49c9d75b3cSYann Gautier MT_MEMORY | \ 50c9d75b3cSYann Gautier MT_RW | \ 51c9d75b3cSYann Gautier MT_SECURE | \ 52c9d75b3cSYann Gautier MT_EXECUTE_NEVER) 530754143aSEtienne Carriere #elif defined(IMAGE_BL32) 540754143aSEtienne Carriere #define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \ 550754143aSEtienne Carriere STM32MP_SEC_SYSRAM_SIZE, \ 560754143aSEtienne Carriere MT_MEMORY | \ 570754143aSEtienne Carriere MT_RW | \ 580754143aSEtienne Carriere MT_SECURE | \ 590754143aSEtienne Carriere MT_EXECUTE_NEVER) 600754143aSEtienne Carriere 610754143aSEtienne Carriere /* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */ 620754143aSEtienne Carriere #define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \ 630754143aSEtienne Carriere STM32MP_NS_SYSRAM_SIZE, \ 640754143aSEtienne Carriere MT_DEVICE | \ 650754143aSEtienne Carriere MT_RW | \ 660754143aSEtienne Carriere MT_NS | \ 670754143aSEtienne Carriere MT_EXECUTE_NEVER) 680754143aSEtienne Carriere #endif 69c9d75b3cSYann Gautier 70c9d75b3cSYann Gautier #define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \ 71c9d75b3cSYann Gautier STM32MP1_DEVICE1_SIZE, \ 72c9d75b3cSYann Gautier MT_DEVICE | \ 73c9d75b3cSYann Gautier MT_RW | \ 74c9d75b3cSYann Gautier MT_SECURE | \ 75c9d75b3cSYann Gautier MT_EXECUTE_NEVER) 76c9d75b3cSYann Gautier 77c9d75b3cSYann Gautier #define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \ 78c9d75b3cSYann Gautier STM32MP1_DEVICE2_SIZE, \ 79c9d75b3cSYann Gautier MT_DEVICE | \ 80c9d75b3cSYann Gautier MT_RW | \ 81c9d75b3cSYann Gautier MT_SECURE | \ 82c9d75b3cSYann Gautier MT_EXECUTE_NEVER) 83c9d75b3cSYann Gautier 84c9d75b3cSYann Gautier #if defined(IMAGE_BL2) 85c9d75b3cSYann Gautier static const mmap_region_t stm32mp1_mmap[] = { 860754143aSEtienne Carriere MAP_SEC_SYSRAM, 87c9d75b3cSYann Gautier MAP_DEVICE1, 88db3e0eceSYann Gautier #if STM32MP_RAW_NAND 89c9d75b3cSYann Gautier MAP_DEVICE2, 90db3e0eceSYann Gautier #endif 91c9d75b3cSYann Gautier {0} 92c9d75b3cSYann Gautier }; 93c9d75b3cSYann Gautier #endif 94c9d75b3cSYann Gautier #if defined(IMAGE_BL32) 95c9d75b3cSYann Gautier static const mmap_region_t stm32mp1_mmap[] = { 960754143aSEtienne Carriere MAP_SEC_SYSRAM, 970754143aSEtienne Carriere MAP_NS_SYSRAM, 98c9d75b3cSYann Gautier MAP_DEVICE1, 99c9d75b3cSYann Gautier MAP_DEVICE2, 100c9d75b3cSYann Gautier {0} 101c9d75b3cSYann Gautier }; 102c9d75b3cSYann Gautier #endif 103c9d75b3cSYann Gautier 104c9d75b3cSYann Gautier void configure_mmu(void) 105c9d75b3cSYann Gautier { 106c9d75b3cSYann Gautier mmap_add(stm32mp1_mmap); 107c9d75b3cSYann Gautier init_xlat_tables(); 108c9d75b3cSYann Gautier 109c9d75b3cSYann Gautier enable_mmu_svc_mon(0); 110c9d75b3cSYann Gautier } 1118f282daeSYann Gautier 112c0ea3b1bSEtienne Carriere uintptr_t stm32_get_gpio_bank_base(unsigned int bank) 113c0ea3b1bSEtienne Carriere { 114*111a384cSYann Gautier #if STM32MP13 115*111a384cSYann Gautier assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I); 116*111a384cSYann Gautier #endif 117*111a384cSYann Gautier #if STM32MP15 118c0ea3b1bSEtienne Carriere if (bank == GPIO_BANK_Z) { 119c0ea3b1bSEtienne Carriere return GPIOZ_BASE; 120c0ea3b1bSEtienne Carriere } 121c0ea3b1bSEtienne Carriere 122c0ea3b1bSEtienne Carriere assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K); 123*111a384cSYann Gautier #endif 124c0ea3b1bSEtienne Carriere 125c0ea3b1bSEtienne Carriere return GPIOA_BASE + (bank * GPIO_BANK_OFFSET); 126c0ea3b1bSEtienne Carriere } 127c0ea3b1bSEtienne Carriere 128c0ea3b1bSEtienne Carriere uint32_t stm32_get_gpio_bank_offset(unsigned int bank) 129c0ea3b1bSEtienne Carriere { 130*111a384cSYann Gautier #if STM32MP13 131*111a384cSYann Gautier assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I); 132*111a384cSYann Gautier #endif 133*111a384cSYann Gautier #if STM32MP15 134c0ea3b1bSEtienne Carriere if (bank == GPIO_BANK_Z) { 135c0ea3b1bSEtienne Carriere return 0; 136c0ea3b1bSEtienne Carriere } 137c0ea3b1bSEtienne Carriere 138c0ea3b1bSEtienne Carriere assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K); 139*111a384cSYann Gautier #endif 140c0ea3b1bSEtienne Carriere 141c0ea3b1bSEtienne Carriere return bank * GPIO_BANK_OFFSET; 142c0ea3b1bSEtienne Carriere } 143c0ea3b1bSEtienne Carriere 144737ad29bSYann Gautier bool stm32_gpio_is_secure_at_reset(unsigned int bank) 145737ad29bSYann Gautier { 146*111a384cSYann Gautier #if STM32MP13 147*111a384cSYann Gautier return true; 148*111a384cSYann Gautier #endif 149*111a384cSYann Gautier #if STM32MP15 150737ad29bSYann Gautier if (bank == GPIO_BANK_Z) { 151737ad29bSYann Gautier return true; 152737ad29bSYann Gautier } 153737ad29bSYann Gautier 154737ad29bSYann Gautier return false; 155*111a384cSYann Gautier #endif 156737ad29bSYann Gautier } 157737ad29bSYann Gautier 1588f282daeSYann Gautier unsigned long stm32_get_gpio_bank_clock(unsigned int bank) 1598f282daeSYann Gautier { 160*111a384cSYann Gautier #if STM32MP13 161*111a384cSYann Gautier assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I); 162*111a384cSYann Gautier #endif 163*111a384cSYann Gautier #if STM32MP15 1648f282daeSYann Gautier if (bank == GPIO_BANK_Z) { 1658f282daeSYann Gautier return GPIOZ; 1668f282daeSYann Gautier } 1678f282daeSYann Gautier 1688f282daeSYann Gautier assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K); 169*111a384cSYann Gautier #endif 1708f282daeSYann Gautier 1718f282daeSYann Gautier return GPIOA + (bank - GPIO_BANK_A); 1728f282daeSYann Gautier } 17373680c23SYann Gautier 174ccc199edSEtienne Carriere int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank) 175ccc199edSEtienne Carriere { 176ccc199edSEtienne Carriere switch (bank) { 177ccc199edSEtienne Carriere case GPIO_BANK_A: 178ccc199edSEtienne Carriere case GPIO_BANK_B: 179ccc199edSEtienne Carriere case GPIO_BANK_C: 180ccc199edSEtienne Carriere case GPIO_BANK_D: 181ccc199edSEtienne Carriere case GPIO_BANK_E: 182ccc199edSEtienne Carriere case GPIO_BANK_F: 183ccc199edSEtienne Carriere case GPIO_BANK_G: 184ccc199edSEtienne Carriere case GPIO_BANK_H: 185ccc199edSEtienne Carriere case GPIO_BANK_I: 186*111a384cSYann Gautier #if STM32MP15 187ccc199edSEtienne Carriere case GPIO_BANK_J: 188ccc199edSEtienne Carriere case GPIO_BANK_K: 189*111a384cSYann Gautier #endif 190ccc199edSEtienne Carriere return fdt_path_offset(fdt, "/soc/pin-controller"); 191*111a384cSYann Gautier #if STM32MP15 192ccc199edSEtienne Carriere case GPIO_BANK_Z: 193ccc199edSEtienne Carriere return fdt_path_offset(fdt, "/soc/pin-controller-z"); 194*111a384cSYann Gautier #endif 195ccc199edSEtienne Carriere default: 196ccc199edSEtienne Carriere panic(); 197ccc199edSEtienne Carriere } 198ccc199edSEtienne Carriere } 199ccc199edSEtienne Carriere 200acf28c26SYann Gautier #if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2) 2019083fa11SPatrick Delaunay /* 2029083fa11SPatrick Delaunay * UART Management 2039083fa11SPatrick Delaunay */ 2049083fa11SPatrick Delaunay static const uintptr_t stm32mp1_uart_addresses[8] = { 2059083fa11SPatrick Delaunay USART1_BASE, 2069083fa11SPatrick Delaunay USART2_BASE, 2079083fa11SPatrick Delaunay USART3_BASE, 2089083fa11SPatrick Delaunay UART4_BASE, 2099083fa11SPatrick Delaunay UART5_BASE, 2109083fa11SPatrick Delaunay USART6_BASE, 2119083fa11SPatrick Delaunay UART7_BASE, 2129083fa11SPatrick Delaunay UART8_BASE, 2139083fa11SPatrick Delaunay }; 2149083fa11SPatrick Delaunay 2159083fa11SPatrick Delaunay uintptr_t get_uart_address(uint32_t instance_nb) 2169083fa11SPatrick Delaunay { 2179083fa11SPatrick Delaunay if ((instance_nb == 0U) || 2189083fa11SPatrick Delaunay (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) { 2199083fa11SPatrick Delaunay return 0U; 2209083fa11SPatrick Delaunay } 2219083fa11SPatrick Delaunay 2229083fa11SPatrick Delaunay return stm32mp1_uart_addresses[instance_nb - 1U]; 2239083fa11SPatrick Delaunay } 2249083fa11SPatrick Delaunay #endif 2259083fa11SPatrick Delaunay 226d7176f03SYann Gautier #if STM32MP_USB_PROGRAMMER 227d7176f03SYann Gautier struct gpio_bank_pin_list { 228d7176f03SYann Gautier uint32_t bank; 229d7176f03SYann Gautier uint32_t pin; 230d7176f03SYann Gautier }; 231d7176f03SYann Gautier 232d7176f03SYann Gautier static const struct gpio_bank_pin_list gpio_list[] = { 233d7176f03SYann Gautier { /* USART2_RX: GPIOA3 */ 234d7176f03SYann Gautier .bank = 0U, 235d7176f03SYann Gautier .pin = 3U, 236d7176f03SYann Gautier }, 237d7176f03SYann Gautier { /* USART3_RX: GPIOB12 */ 238d7176f03SYann Gautier .bank = 1U, 239d7176f03SYann Gautier .pin = 12U, 240d7176f03SYann Gautier }, 241d7176f03SYann Gautier { /* UART4_RX: GPIOB2 */ 242d7176f03SYann Gautier .bank = 1U, 243d7176f03SYann Gautier .pin = 2U, 244d7176f03SYann Gautier }, 245d7176f03SYann Gautier { /* UART5_RX: GPIOB4 */ 246d7176f03SYann Gautier .bank = 1U, 247d7176f03SYann Gautier .pin = 5U, 248d7176f03SYann Gautier }, 249d7176f03SYann Gautier { /* USART6_RX: GPIOC7 */ 250d7176f03SYann Gautier .bank = 2U, 251d7176f03SYann Gautier .pin = 7U, 252d7176f03SYann Gautier }, 253d7176f03SYann Gautier { /* UART7_RX: GPIOF6 */ 254d7176f03SYann Gautier .bank = 5U, 255d7176f03SYann Gautier .pin = 6U, 256d7176f03SYann Gautier }, 257d7176f03SYann Gautier { /* UART8_RX: GPIOE0 */ 258d7176f03SYann Gautier .bank = 4U, 259d7176f03SYann Gautier .pin = 0U, 260d7176f03SYann Gautier }, 261d7176f03SYann Gautier }; 262d7176f03SYann Gautier 263d7176f03SYann Gautier void stm32mp1_deconfigure_uart_pins(void) 264d7176f03SYann Gautier { 265d7176f03SYann Gautier size_t i; 266d7176f03SYann Gautier 267d7176f03SYann Gautier for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) { 268d7176f03SYann Gautier set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin); 269d7176f03SYann Gautier } 270d7176f03SYann Gautier } 271d7176f03SYann Gautier #endif 272d7176f03SYann Gautier 27392661e01SYann Gautier uint32_t stm32mp_get_chip_version(void) 274dec286ddSYann Gautier { 27592661e01SYann Gautier uint32_t version = 0U; 27692661e01SYann Gautier 27792661e01SYann Gautier if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) { 27892661e01SYann Gautier INFO("Cannot get CPU version, debug disabled\n"); 27992661e01SYann Gautier return 0U; 28092661e01SYann Gautier } 28192661e01SYann Gautier 28292661e01SYann Gautier return version; 28392661e01SYann Gautier } 28492661e01SYann Gautier 28592661e01SYann Gautier uint32_t stm32mp_get_chip_dev_id(void) 28692661e01SYann Gautier { 287dec286ddSYann Gautier uint32_t dev_id; 288dec286ddSYann Gautier 289dec286ddSYann Gautier if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) { 29092661e01SYann Gautier INFO("Use default chip ID, debug disabled\n"); 29192661e01SYann Gautier dev_id = STM32MP1_CHIP_ID; 29292661e01SYann Gautier } 29392661e01SYann Gautier 29492661e01SYann Gautier return dev_id; 29592661e01SYann Gautier } 29692661e01SYann Gautier 29792661e01SYann Gautier static uint32_t get_part_number(void) 29892661e01SYann Gautier { 29992661e01SYann Gautier static uint32_t part_number; 30092661e01SYann Gautier 30192661e01SYann Gautier if (part_number != 0U) { 30292661e01SYann Gautier return part_number; 303dec286ddSYann Gautier } 304dec286ddSYann Gautier 305ae3ce8b2SLionel Debieve if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) { 30692661e01SYann Gautier panic(); 307dec286ddSYann Gautier } 308dec286ddSYann Gautier 309dec286ddSYann Gautier part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >> 310dec286ddSYann Gautier PART_NUMBER_OTP_PART_SHIFT; 311dec286ddSYann Gautier 31292661e01SYann Gautier part_number |= stm32mp_get_chip_dev_id() << 16; 313dec286ddSYann Gautier 31492661e01SYann Gautier return part_number; 315dec286ddSYann Gautier } 316dec286ddSYann Gautier 31792661e01SYann Gautier static uint32_t get_cpu_package(void) 318dec286ddSYann Gautier { 319dec286ddSYann Gautier uint32_t package; 320dec286ddSYann Gautier 321ae3ce8b2SLionel Debieve if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) { 32292661e01SYann Gautier panic(); 323dec286ddSYann Gautier } 324dec286ddSYann Gautier 32592661e01SYann Gautier package = (package & PACKAGE_OTP_PKG_MASK) >> 326dec286ddSYann Gautier PACKAGE_OTP_PKG_SHIFT; 327dec286ddSYann Gautier 32892661e01SYann Gautier return package; 329dec286ddSYann Gautier } 330dec286ddSYann Gautier 33192661e01SYann Gautier void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE]) 332dec286ddSYann Gautier { 33392661e01SYann Gautier char *cpu_s, *cpu_r, *pkg; 334dec286ddSYann Gautier 335dec286ddSYann Gautier /* MPUs Part Numbers */ 33692661e01SYann Gautier switch (get_part_number()) { 337dec286ddSYann Gautier case STM32MP157C_PART_NB: 338dec286ddSYann Gautier cpu_s = "157C"; 339dec286ddSYann Gautier break; 340dec286ddSYann Gautier case STM32MP157A_PART_NB: 341dec286ddSYann Gautier cpu_s = "157A"; 342dec286ddSYann Gautier break; 343dec286ddSYann Gautier case STM32MP153C_PART_NB: 344dec286ddSYann Gautier cpu_s = "153C"; 345dec286ddSYann Gautier break; 346dec286ddSYann Gautier case STM32MP153A_PART_NB: 347dec286ddSYann Gautier cpu_s = "153A"; 348dec286ddSYann Gautier break; 349dec286ddSYann Gautier case STM32MP151C_PART_NB: 350dec286ddSYann Gautier cpu_s = "151C"; 351dec286ddSYann Gautier break; 352dec286ddSYann Gautier case STM32MP151A_PART_NB: 353dec286ddSYann Gautier cpu_s = "151A"; 354dec286ddSYann Gautier break; 3558ccf4954SLionel Debieve case STM32MP157F_PART_NB: 3568ccf4954SLionel Debieve cpu_s = "157F"; 3578ccf4954SLionel Debieve break; 3588ccf4954SLionel Debieve case STM32MP157D_PART_NB: 3598ccf4954SLionel Debieve cpu_s = "157D"; 3608ccf4954SLionel Debieve break; 3618ccf4954SLionel Debieve case STM32MP153F_PART_NB: 3628ccf4954SLionel Debieve cpu_s = "153F"; 3638ccf4954SLionel Debieve break; 3648ccf4954SLionel Debieve case STM32MP153D_PART_NB: 3658ccf4954SLionel Debieve cpu_s = "153D"; 3668ccf4954SLionel Debieve break; 3678ccf4954SLionel Debieve case STM32MP151F_PART_NB: 3688ccf4954SLionel Debieve cpu_s = "151F"; 3698ccf4954SLionel Debieve break; 3708ccf4954SLionel Debieve case STM32MP151D_PART_NB: 3718ccf4954SLionel Debieve cpu_s = "151D"; 3728ccf4954SLionel Debieve break; 373dec286ddSYann Gautier default: 374dec286ddSYann Gautier cpu_s = "????"; 375dec286ddSYann Gautier break; 376dec286ddSYann Gautier } 377dec286ddSYann Gautier 378dec286ddSYann Gautier /* Package */ 37992661e01SYann Gautier switch (get_cpu_package()) { 380dec286ddSYann Gautier case PKG_AA_LFBGA448: 381dec286ddSYann Gautier pkg = "AA"; 382dec286ddSYann Gautier break; 383dec286ddSYann Gautier case PKG_AB_LFBGA354: 384dec286ddSYann Gautier pkg = "AB"; 385dec286ddSYann Gautier break; 386dec286ddSYann Gautier case PKG_AC_TFBGA361: 387dec286ddSYann Gautier pkg = "AC"; 388dec286ddSYann Gautier break; 389dec286ddSYann Gautier case PKG_AD_TFBGA257: 390dec286ddSYann Gautier pkg = "AD"; 391dec286ddSYann Gautier break; 392dec286ddSYann Gautier default: 393dec286ddSYann Gautier pkg = "??"; 394dec286ddSYann Gautier break; 395dec286ddSYann Gautier } 396dec286ddSYann Gautier 397dec286ddSYann Gautier /* REVISION */ 39892661e01SYann Gautier switch (stm32mp_get_chip_version()) { 399dec286ddSYann Gautier case STM32MP1_REV_B: 400dec286ddSYann Gautier cpu_r = "B"; 401dec286ddSYann Gautier break; 402ffb3f277SLionel Debieve case STM32MP1_REV_Z: 403ffb3f277SLionel Debieve cpu_r = "Z"; 404ffb3f277SLionel Debieve break; 405dec286ddSYann Gautier default: 406dec286ddSYann Gautier cpu_r = "?"; 407dec286ddSYann Gautier break; 408dec286ddSYann Gautier } 409dec286ddSYann Gautier 41092661e01SYann Gautier snprintf(name, STM32_SOC_NAME_SIZE, 41192661e01SYann Gautier "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r); 41292661e01SYann Gautier } 41392661e01SYann Gautier 41492661e01SYann Gautier void stm32mp_print_cpuinfo(void) 41592661e01SYann Gautier { 41692661e01SYann Gautier char name[STM32_SOC_NAME_SIZE]; 41792661e01SYann Gautier 41892661e01SYann Gautier stm32mp_get_soc_name(name); 41992661e01SYann Gautier NOTICE("CPU: %s\n", name); 420dec286ddSYann Gautier } 421dec286ddSYann Gautier 42210e7a9e9SYann Gautier void stm32mp_print_boardinfo(void) 42310e7a9e9SYann Gautier { 424ae3ce8b2SLionel Debieve uint32_t board_id = 0; 42510e7a9e9SYann Gautier 426ae3ce8b2SLionel Debieve if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) { 42710e7a9e9SYann Gautier return; 42810e7a9e9SYann Gautier } 42910e7a9e9SYann Gautier 43010e7a9e9SYann Gautier if (board_id != 0U) { 43110e7a9e9SYann Gautier char rev[2]; 43210e7a9e9SYann Gautier 43310e7a9e9SYann Gautier rev[0] = BOARD_ID2REV(board_id) - 1 + 'A'; 43410e7a9e9SYann Gautier rev[1] = '\0'; 435ab049ec0SYann Gautier NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n", 43610e7a9e9SYann Gautier BOARD_ID2NB(board_id), 437f964f5c3SPatrick Delaunay BOARD_ID2VARCPN(board_id), 438f964f5c3SPatrick Delaunay BOARD_ID2VARFG(board_id), 43910e7a9e9SYann Gautier rev, 44010e7a9e9SYann Gautier BOARD_ID2BOM(board_id)); 44110e7a9e9SYann Gautier } 44210e7a9e9SYann Gautier } 44310e7a9e9SYann Gautier 444b2182cdeSYann Gautier /* Return true when SoC provides a single Cortex-A7 core, and false otherwise */ 445b2182cdeSYann Gautier bool stm32mp_is_single_core(void) 446b2182cdeSYann Gautier { 447f7130e81SYann Gautier bool single_core = false; 448f7130e81SYann Gautier 44992661e01SYann Gautier switch (get_part_number()) { 450b2182cdeSYann Gautier case STM32MP151A_PART_NB: 451b2182cdeSYann Gautier case STM32MP151C_PART_NB: 4528ccf4954SLionel Debieve case STM32MP151D_PART_NB: 4538ccf4954SLionel Debieve case STM32MP151F_PART_NB: 454f7130e81SYann Gautier single_core = true; 455f7130e81SYann Gautier break; 456b2182cdeSYann Gautier default: 457f7130e81SYann Gautier break; 458b2182cdeSYann Gautier } 459f7130e81SYann Gautier 460f7130e81SYann Gautier return single_core; 461b2182cdeSYann Gautier } 462b2182cdeSYann Gautier 463f700423cSLionel Debieve /* Return true when device is in closed state */ 464f700423cSLionel Debieve bool stm32mp_is_closed_device(void) 465f700423cSLionel Debieve { 466f700423cSLionel Debieve uint32_t value; 467f700423cSLionel Debieve 468ae3ce8b2SLionel Debieve if (stm32_get_otp_value(CFG0_OTP, &value) != 0) { 469f700423cSLionel Debieve return true; 470f700423cSLionel Debieve } 471f700423cSLionel Debieve 472ae3ce8b2SLionel Debieve return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE; 473f700423cSLionel Debieve } 474f700423cSLionel Debieve 47549abdfd8SLionel Debieve /* Return true when device supports secure boot */ 47649abdfd8SLionel Debieve bool stm32mp_is_auth_supported(void) 47749abdfd8SLionel Debieve { 47849abdfd8SLionel Debieve bool supported = false; 47949abdfd8SLionel Debieve 48049abdfd8SLionel Debieve switch (get_part_number()) { 48149abdfd8SLionel Debieve case STM32MP151C_PART_NB: 48249abdfd8SLionel Debieve case STM32MP151F_PART_NB: 48349abdfd8SLionel Debieve case STM32MP153C_PART_NB: 48449abdfd8SLionel Debieve case STM32MP153F_PART_NB: 48549abdfd8SLionel Debieve case STM32MP157C_PART_NB: 48649abdfd8SLionel Debieve case STM32MP157F_PART_NB: 48749abdfd8SLionel Debieve supported = true; 48849abdfd8SLionel Debieve break; 48949abdfd8SLionel Debieve default: 49049abdfd8SLionel Debieve break; 49149abdfd8SLionel Debieve } 49249abdfd8SLionel Debieve 49349abdfd8SLionel Debieve return supported; 49449abdfd8SLionel Debieve } 49549abdfd8SLionel Debieve 49673680c23SYann Gautier uint32_t stm32_iwdg_get_instance(uintptr_t base) 49773680c23SYann Gautier { 49873680c23SYann Gautier switch (base) { 49973680c23SYann Gautier case IWDG1_BASE: 50073680c23SYann Gautier return IWDG1_INST; 50173680c23SYann Gautier case IWDG2_BASE: 50273680c23SYann Gautier return IWDG2_INST; 50373680c23SYann Gautier default: 50473680c23SYann Gautier panic(); 50573680c23SYann Gautier } 50673680c23SYann Gautier } 50773680c23SYann Gautier 50873680c23SYann Gautier uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst) 50973680c23SYann Gautier { 51073680c23SYann Gautier uint32_t iwdg_cfg = 0U; 51173680c23SYann Gautier uint32_t otp_value; 51273680c23SYann Gautier 513ae3ce8b2SLionel Debieve if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) { 51473680c23SYann Gautier panic(); 51573680c23SYann Gautier } 51673680c23SYann Gautier 51773680c23SYann Gautier if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) { 51873680c23SYann Gautier iwdg_cfg |= IWDG_HW_ENABLED; 51973680c23SYann Gautier } 52073680c23SYann Gautier 52173680c23SYann Gautier if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) { 52273680c23SYann Gautier iwdg_cfg |= IWDG_DISABLE_ON_STOP; 52373680c23SYann Gautier } 52473680c23SYann Gautier 52573680c23SYann Gautier if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) { 52673680c23SYann Gautier iwdg_cfg |= IWDG_DISABLE_ON_STANDBY; 52773680c23SYann Gautier } 52873680c23SYann Gautier 52973680c23SYann Gautier return iwdg_cfg; 53073680c23SYann Gautier } 53173680c23SYann Gautier 53273680c23SYann Gautier #if defined(IMAGE_BL2) 53373680c23SYann Gautier uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags) 53473680c23SYann Gautier { 535ae3ce8b2SLionel Debieve uint32_t otp_value; 53673680c23SYann Gautier uint32_t otp; 53773680c23SYann Gautier uint32_t result; 53873680c23SYann Gautier 539ae3ce8b2SLionel Debieve if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) { 54073680c23SYann Gautier panic(); 54173680c23SYann Gautier } 54273680c23SYann Gautier 543ae3ce8b2SLionel Debieve if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) { 544ae3ce8b2SLionel Debieve panic(); 54573680c23SYann Gautier } 54673680c23SYann Gautier 547ae3ce8b2SLionel Debieve if ((flags & IWDG_DISABLE_ON_STOP) != 0) { 548ae3ce8b2SLionel Debieve otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS); 54973680c23SYann Gautier } 55073680c23SYann Gautier 551ae3ce8b2SLionel Debieve if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) { 552ae3ce8b2SLionel Debieve otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS); 553ae3ce8b2SLionel Debieve } 554ae3ce8b2SLionel Debieve 555ae3ce8b2SLionel Debieve result = bsec_write_otp(otp_value, otp); 55673680c23SYann Gautier if (result != BSEC_OK) { 55773680c23SYann Gautier return result; 55873680c23SYann Gautier } 55973680c23SYann Gautier 56073680c23SYann Gautier /* Sticky lock OTP_IWDG (read and write) */ 561ae3ce8b2SLionel Debieve if ((bsec_set_sr_lock(otp) != BSEC_OK) || 562ae3ce8b2SLionel Debieve (bsec_set_sw_lock(otp) != BSEC_OK)) { 56373680c23SYann Gautier return BSEC_LOCK_FAIL; 56473680c23SYann Gautier } 56573680c23SYann Gautier 56673680c23SYann Gautier return BSEC_OK; 56773680c23SYann Gautier } 56873680c23SYann Gautier #endif 569e6cc3ccfSYann Gautier 5704584e01dSLionel Debieve #if STM32MP_USE_STM32IMAGE 571e6cc3ccfSYann Gautier /* Get the non-secure DDR size */ 572e6cc3ccfSYann Gautier uint32_t stm32mp_get_ddr_ns_size(void) 573e6cc3ccfSYann Gautier { 574e6cc3ccfSYann Gautier static uint32_t ddr_ns_size; 575e6cc3ccfSYann Gautier uint32_t ddr_size; 576e6cc3ccfSYann Gautier 577e6cc3ccfSYann Gautier if (ddr_ns_size != 0U) { 578e6cc3ccfSYann Gautier return ddr_ns_size; 579e6cc3ccfSYann Gautier } 580e6cc3ccfSYann Gautier 581e6cc3ccfSYann Gautier ddr_size = dt_get_ddr_size(); 582e6cc3ccfSYann Gautier if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) || 583e6cc3ccfSYann Gautier (ddr_size > STM32MP_DDR_MAX_SIZE)) { 584e6cc3ccfSYann Gautier panic(); 585e6cc3ccfSYann Gautier } 586e6cc3ccfSYann Gautier 587e6cc3ccfSYann Gautier ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE); 588e6cc3ccfSYann Gautier 589e6cc3ccfSYann Gautier return ddr_ns_size; 590e6cc3ccfSYann Gautier } 5914584e01dSLionel Debieve #endif /* STM32MP_USE_STM32IMAGE */ 5924dc77a35SYann Gautier 5934dc77a35SYann Gautier void stm32_save_boot_interface(uint32_t interface, uint32_t instance) 5944dc77a35SYann Gautier { 595c870188dSNicolas Toromanoff uintptr_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID); 5964dc77a35SYann Gautier 59733667d29SYann Gautier clk_enable(RTCAPB); 5984dc77a35SYann Gautier 5994dc77a35SYann Gautier mmio_clrsetbits_32(bkpr_itf_idx, 6004dc77a35SYann Gautier TAMP_BOOT_MODE_ITF_MASK, 6014dc77a35SYann Gautier ((interface << 4) | (instance & 0xFU)) << 6024dc77a35SYann Gautier TAMP_BOOT_MODE_ITF_SHIFT); 6034dc77a35SYann Gautier 60433667d29SYann Gautier clk_disable(RTCAPB); 6054dc77a35SYann Gautier } 606a6bfa75cSYann Gautier 607a6bfa75cSYann Gautier void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance) 608a6bfa75cSYann Gautier { 609a6bfa75cSYann Gautier static uint32_t itf; 610a6bfa75cSYann Gautier 611a6bfa75cSYann Gautier if (itf == 0U) { 612c870188dSNicolas Toromanoff uintptr_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID); 613a6bfa75cSYann Gautier 61433667d29SYann Gautier clk_enable(RTCAPB); 615a6bfa75cSYann Gautier 616a6bfa75cSYann Gautier itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >> 617a6bfa75cSYann Gautier TAMP_BOOT_MODE_ITF_SHIFT; 618a6bfa75cSYann Gautier 61933667d29SYann Gautier clk_disable(RTCAPB); 620a6bfa75cSYann Gautier } 621a6bfa75cSYann Gautier 622a6bfa75cSYann Gautier *interface = itf >> 4; 623a6bfa75cSYann Gautier *instance = itf & 0xFU; 624a6bfa75cSYann Gautier } 625ba02add9SSughosh Ganu 626ba02add9SSughosh Ganu #if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT 627ba02add9SSughosh Ganu void stm32mp1_fwu_set_boot_idx(void) 628ba02add9SSughosh Ganu { 629ba02add9SSughosh Ganu clk_enable(RTCAPB); 630ba02add9SSughosh Ganu mmio_write_32(tamp_bkpr(TAMP_BOOT_COUNTER_REG_ID), 631ba02add9SSughosh Ganu plat_fwu_get_boot_idx()); 632ba02add9SSughosh Ganu clk_disable(RTCAPB); 633ba02add9SSughosh Ganu } 634ba02add9SSughosh Ganu #endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */ 635