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 404b031ab4SYann Gautier #if STM32MP13 414b031ab4SYann Gautier #define TAMP_BOOT_MODE_BACKUP_REG_ID U(30) 424b031ab4SYann Gautier #endif 434b031ab4SYann Gautier #if STM32MP15 444dc77a35SYann Gautier #define TAMP_BOOT_MODE_BACKUP_REG_ID U(20) 454b031ab4SYann Gautier #endif 464dc77a35SYann Gautier #define TAMP_BOOT_MODE_ITF_MASK U(0x0000FF00) 474dc77a35SYann Gautier #define TAMP_BOOT_MODE_ITF_SHIFT 8 484dc77a35SYann Gautier 49ba02add9SSughosh Ganu #define TAMP_BOOT_COUNTER_REG_ID U(21) 50ba02add9SSughosh Ganu 510754143aSEtienne Carriere #if defined(IMAGE_BL2) 520754143aSEtienne Carriere #define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ 533f9c9784SYann Gautier STM32MP_SYSRAM_SIZE, \ 54c9d75b3cSYann Gautier MT_MEMORY | \ 55c9d75b3cSYann Gautier MT_RW | \ 56c9d75b3cSYann Gautier MT_SECURE | \ 57c9d75b3cSYann Gautier MT_EXECUTE_NEVER) 580754143aSEtienne Carriere #elif defined(IMAGE_BL32) 590754143aSEtienne Carriere #define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \ 600754143aSEtienne Carriere STM32MP_SEC_SYSRAM_SIZE, \ 610754143aSEtienne Carriere MT_MEMORY | \ 620754143aSEtienne Carriere MT_RW | \ 630754143aSEtienne Carriere MT_SECURE | \ 640754143aSEtienne Carriere MT_EXECUTE_NEVER) 650754143aSEtienne Carriere 660754143aSEtienne Carriere /* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */ 670754143aSEtienne Carriere #define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \ 680754143aSEtienne Carriere STM32MP_NS_SYSRAM_SIZE, \ 690754143aSEtienne Carriere MT_DEVICE | \ 700754143aSEtienne Carriere MT_RW | \ 710754143aSEtienne Carriere MT_NS | \ 720754143aSEtienne Carriere MT_EXECUTE_NEVER) 730754143aSEtienne Carriere #endif 74c9d75b3cSYann Gautier 75c9d75b3cSYann Gautier #define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \ 76c9d75b3cSYann Gautier STM32MP1_DEVICE1_SIZE, \ 77c9d75b3cSYann Gautier MT_DEVICE | \ 78c9d75b3cSYann Gautier MT_RW | \ 79c9d75b3cSYann Gautier MT_SECURE | \ 80c9d75b3cSYann Gautier MT_EXECUTE_NEVER) 81c9d75b3cSYann Gautier 82c9d75b3cSYann Gautier #define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \ 83c9d75b3cSYann Gautier STM32MP1_DEVICE2_SIZE, \ 84c9d75b3cSYann Gautier MT_DEVICE | \ 85c9d75b3cSYann Gautier MT_RW | \ 86c9d75b3cSYann Gautier MT_SECURE | \ 87c9d75b3cSYann Gautier MT_EXECUTE_NEVER) 88c9d75b3cSYann Gautier 89c9d75b3cSYann Gautier #if defined(IMAGE_BL2) 90c9d75b3cSYann Gautier static const mmap_region_t stm32mp1_mmap[] = { 910754143aSEtienne Carriere MAP_SEC_SYSRAM, 92c9d75b3cSYann Gautier MAP_DEVICE1, 93db3e0eceSYann Gautier #if STM32MP_RAW_NAND 94c9d75b3cSYann Gautier MAP_DEVICE2, 95db3e0eceSYann Gautier #endif 96c9d75b3cSYann Gautier {0} 97c9d75b3cSYann Gautier }; 98c9d75b3cSYann Gautier #endif 99c9d75b3cSYann Gautier #if defined(IMAGE_BL32) 100c9d75b3cSYann Gautier static const mmap_region_t stm32mp1_mmap[] = { 1010754143aSEtienne Carriere MAP_SEC_SYSRAM, 1020754143aSEtienne Carriere MAP_NS_SYSRAM, 103c9d75b3cSYann Gautier MAP_DEVICE1, 104c9d75b3cSYann Gautier MAP_DEVICE2, 105c9d75b3cSYann Gautier {0} 106c9d75b3cSYann Gautier }; 107c9d75b3cSYann Gautier #endif 108c9d75b3cSYann Gautier 109c9d75b3cSYann Gautier void configure_mmu(void) 110c9d75b3cSYann Gautier { 111c9d75b3cSYann Gautier mmap_add(stm32mp1_mmap); 112c9d75b3cSYann Gautier init_xlat_tables(); 113c9d75b3cSYann Gautier 114c9d75b3cSYann Gautier enable_mmu_svc_mon(0); 115c9d75b3cSYann Gautier } 1168f282daeSYann Gautier 117c0ea3b1bSEtienne Carriere uintptr_t stm32_get_gpio_bank_base(unsigned int bank) 118c0ea3b1bSEtienne Carriere { 119111a384cSYann Gautier #if STM32MP13 120111a384cSYann Gautier assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I); 121111a384cSYann Gautier #endif 122111a384cSYann Gautier #if STM32MP15 123c0ea3b1bSEtienne Carriere if (bank == GPIO_BANK_Z) { 124c0ea3b1bSEtienne Carriere return GPIOZ_BASE; 125c0ea3b1bSEtienne Carriere } 126c0ea3b1bSEtienne Carriere 127c0ea3b1bSEtienne Carriere assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K); 128111a384cSYann Gautier #endif 129c0ea3b1bSEtienne Carriere 130c0ea3b1bSEtienne Carriere return GPIOA_BASE + (bank * GPIO_BANK_OFFSET); 131c0ea3b1bSEtienne Carriere } 132c0ea3b1bSEtienne Carriere 133c0ea3b1bSEtienne Carriere uint32_t stm32_get_gpio_bank_offset(unsigned int bank) 134c0ea3b1bSEtienne Carriere { 135111a384cSYann Gautier #if STM32MP13 136111a384cSYann Gautier assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I); 137111a384cSYann Gautier #endif 138111a384cSYann Gautier #if STM32MP15 139c0ea3b1bSEtienne Carriere if (bank == GPIO_BANK_Z) { 140c0ea3b1bSEtienne Carriere return 0; 141c0ea3b1bSEtienne Carriere } 142c0ea3b1bSEtienne Carriere 143c0ea3b1bSEtienne Carriere assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K); 144111a384cSYann Gautier #endif 145c0ea3b1bSEtienne Carriere 146c0ea3b1bSEtienne Carriere return bank * GPIO_BANK_OFFSET; 147c0ea3b1bSEtienne Carriere } 148c0ea3b1bSEtienne Carriere 149737ad29bSYann Gautier bool stm32_gpio_is_secure_at_reset(unsigned int bank) 150737ad29bSYann Gautier { 151111a384cSYann Gautier #if STM32MP13 152111a384cSYann Gautier return true; 153111a384cSYann Gautier #endif 154111a384cSYann Gautier #if STM32MP15 155737ad29bSYann Gautier if (bank == GPIO_BANK_Z) { 156737ad29bSYann Gautier return true; 157737ad29bSYann Gautier } 158737ad29bSYann Gautier 159737ad29bSYann Gautier return false; 160111a384cSYann Gautier #endif 161737ad29bSYann Gautier } 162737ad29bSYann Gautier 1638f282daeSYann Gautier unsigned long stm32_get_gpio_bank_clock(unsigned int bank) 1648f282daeSYann Gautier { 165111a384cSYann Gautier #if STM32MP13 166111a384cSYann Gautier assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I); 167111a384cSYann Gautier #endif 168111a384cSYann Gautier #if STM32MP15 1698f282daeSYann Gautier if (bank == GPIO_BANK_Z) { 1708f282daeSYann Gautier return GPIOZ; 1718f282daeSYann Gautier } 1728f282daeSYann Gautier 1738f282daeSYann Gautier assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K); 174111a384cSYann Gautier #endif 1758f282daeSYann Gautier 1768f282daeSYann Gautier return GPIOA + (bank - GPIO_BANK_A); 1778f282daeSYann Gautier } 17873680c23SYann Gautier 179ccc199edSEtienne Carriere int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank) 180ccc199edSEtienne Carriere { 181ccc199edSEtienne Carriere switch (bank) { 182ccc199edSEtienne Carriere case GPIO_BANK_A: 183ccc199edSEtienne Carriere case GPIO_BANK_B: 184ccc199edSEtienne Carriere case GPIO_BANK_C: 185ccc199edSEtienne Carriere case GPIO_BANK_D: 186ccc199edSEtienne Carriere case GPIO_BANK_E: 187ccc199edSEtienne Carriere case GPIO_BANK_F: 188ccc199edSEtienne Carriere case GPIO_BANK_G: 189ccc199edSEtienne Carriere case GPIO_BANK_H: 190ccc199edSEtienne Carriere case GPIO_BANK_I: 191111a384cSYann Gautier #if STM32MP15 192ccc199edSEtienne Carriere case GPIO_BANK_J: 193ccc199edSEtienne Carriere case GPIO_BANK_K: 194111a384cSYann Gautier #endif 195ccc199edSEtienne Carriere return fdt_path_offset(fdt, "/soc/pin-controller"); 196111a384cSYann Gautier #if STM32MP15 197ccc199edSEtienne Carriere case GPIO_BANK_Z: 198ccc199edSEtienne Carriere return fdt_path_offset(fdt, "/soc/pin-controller-z"); 199111a384cSYann Gautier #endif 200ccc199edSEtienne Carriere default: 201ccc199edSEtienne Carriere panic(); 202ccc199edSEtienne Carriere } 203ccc199edSEtienne Carriere } 204ccc199edSEtienne Carriere 205acf28c26SYann Gautier #if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2) 2069083fa11SPatrick Delaunay /* 2079083fa11SPatrick Delaunay * UART Management 2089083fa11SPatrick Delaunay */ 2099083fa11SPatrick Delaunay static const uintptr_t stm32mp1_uart_addresses[8] = { 2109083fa11SPatrick Delaunay USART1_BASE, 2119083fa11SPatrick Delaunay USART2_BASE, 2129083fa11SPatrick Delaunay USART3_BASE, 2139083fa11SPatrick Delaunay UART4_BASE, 2149083fa11SPatrick Delaunay UART5_BASE, 2159083fa11SPatrick Delaunay USART6_BASE, 2169083fa11SPatrick Delaunay UART7_BASE, 2179083fa11SPatrick Delaunay UART8_BASE, 2189083fa11SPatrick Delaunay }; 2199083fa11SPatrick Delaunay 2209083fa11SPatrick Delaunay uintptr_t get_uart_address(uint32_t instance_nb) 2219083fa11SPatrick Delaunay { 2229083fa11SPatrick Delaunay if ((instance_nb == 0U) || 2239083fa11SPatrick Delaunay (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) { 2249083fa11SPatrick Delaunay return 0U; 2259083fa11SPatrick Delaunay } 2269083fa11SPatrick Delaunay 2279083fa11SPatrick Delaunay return stm32mp1_uart_addresses[instance_nb - 1U]; 2289083fa11SPatrick Delaunay } 2299083fa11SPatrick Delaunay #endif 2309083fa11SPatrick Delaunay 231d7176f03SYann Gautier #if STM32MP_USB_PROGRAMMER 232d7176f03SYann Gautier struct gpio_bank_pin_list { 233d7176f03SYann Gautier uint32_t bank; 234d7176f03SYann Gautier uint32_t pin; 235d7176f03SYann Gautier }; 236d7176f03SYann Gautier 237d7176f03SYann Gautier static const struct gpio_bank_pin_list gpio_list[] = { 238d7176f03SYann Gautier { /* USART2_RX: GPIOA3 */ 239d7176f03SYann Gautier .bank = 0U, 240d7176f03SYann Gautier .pin = 3U, 241d7176f03SYann Gautier }, 242d7176f03SYann Gautier { /* USART3_RX: GPIOB12 */ 243d7176f03SYann Gautier .bank = 1U, 244d7176f03SYann Gautier .pin = 12U, 245d7176f03SYann Gautier }, 246d7176f03SYann Gautier { /* UART4_RX: GPIOB2 */ 247d7176f03SYann Gautier .bank = 1U, 248d7176f03SYann Gautier .pin = 2U, 249d7176f03SYann Gautier }, 250d7176f03SYann Gautier { /* UART5_RX: GPIOB4 */ 251d7176f03SYann Gautier .bank = 1U, 252d7176f03SYann Gautier .pin = 5U, 253d7176f03SYann Gautier }, 254d7176f03SYann Gautier { /* USART6_RX: GPIOC7 */ 255d7176f03SYann Gautier .bank = 2U, 256d7176f03SYann Gautier .pin = 7U, 257d7176f03SYann Gautier }, 258d7176f03SYann Gautier { /* UART7_RX: GPIOF6 */ 259d7176f03SYann Gautier .bank = 5U, 260d7176f03SYann Gautier .pin = 6U, 261d7176f03SYann Gautier }, 262d7176f03SYann Gautier { /* UART8_RX: GPIOE0 */ 263d7176f03SYann Gautier .bank = 4U, 264d7176f03SYann Gautier .pin = 0U, 265d7176f03SYann Gautier }, 266d7176f03SYann Gautier }; 267d7176f03SYann Gautier 268d7176f03SYann Gautier void stm32mp1_deconfigure_uart_pins(void) 269d7176f03SYann Gautier { 270d7176f03SYann Gautier size_t i; 271d7176f03SYann Gautier 272d7176f03SYann Gautier for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) { 273d7176f03SYann Gautier set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin); 274d7176f03SYann Gautier } 275d7176f03SYann Gautier } 276d7176f03SYann Gautier #endif 277d7176f03SYann Gautier 27892661e01SYann Gautier uint32_t stm32mp_get_chip_version(void) 279dec286ddSYann Gautier { 28092661e01SYann Gautier uint32_t version = 0U; 28192661e01SYann Gautier 28292661e01SYann Gautier if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) { 28392661e01SYann Gautier INFO("Cannot get CPU version, debug disabled\n"); 28492661e01SYann Gautier return 0U; 28592661e01SYann Gautier } 28692661e01SYann Gautier 28792661e01SYann Gautier return version; 28892661e01SYann Gautier } 28992661e01SYann Gautier 29092661e01SYann Gautier uint32_t stm32mp_get_chip_dev_id(void) 29192661e01SYann Gautier { 292dec286ddSYann Gautier uint32_t dev_id; 293dec286ddSYann Gautier 294dec286ddSYann Gautier if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) { 29592661e01SYann Gautier INFO("Use default chip ID, debug disabled\n"); 29692661e01SYann Gautier dev_id = STM32MP1_CHIP_ID; 29792661e01SYann Gautier } 29892661e01SYann Gautier 29992661e01SYann Gautier return dev_id; 30092661e01SYann Gautier } 30192661e01SYann Gautier 30292661e01SYann Gautier static uint32_t get_part_number(void) 30392661e01SYann Gautier { 30492661e01SYann Gautier static uint32_t part_number; 30592661e01SYann Gautier 30692661e01SYann Gautier if (part_number != 0U) { 30792661e01SYann Gautier return part_number; 308dec286ddSYann Gautier } 309dec286ddSYann Gautier 310ae3ce8b2SLionel Debieve if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) { 31192661e01SYann Gautier panic(); 312dec286ddSYann Gautier } 313dec286ddSYann Gautier 314dec286ddSYann Gautier part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >> 315dec286ddSYann Gautier PART_NUMBER_OTP_PART_SHIFT; 316dec286ddSYann Gautier 31792661e01SYann Gautier part_number |= stm32mp_get_chip_dev_id() << 16; 318dec286ddSYann Gautier 31992661e01SYann Gautier return part_number; 320dec286ddSYann Gautier } 321dec286ddSYann Gautier 322*30eea116SYann Gautier #if STM32MP15 32392661e01SYann Gautier static uint32_t get_cpu_package(void) 324dec286ddSYann Gautier { 325dec286ddSYann Gautier uint32_t package; 326dec286ddSYann Gautier 327ae3ce8b2SLionel Debieve if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) { 32892661e01SYann Gautier panic(); 329dec286ddSYann Gautier } 330dec286ddSYann Gautier 33192661e01SYann Gautier package = (package & PACKAGE_OTP_PKG_MASK) >> 332dec286ddSYann Gautier PACKAGE_OTP_PKG_SHIFT; 333dec286ddSYann Gautier 33492661e01SYann Gautier return package; 335dec286ddSYann Gautier } 336*30eea116SYann Gautier #endif 337dec286ddSYann Gautier 33892661e01SYann Gautier void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE]) 339dec286ddSYann Gautier { 34092661e01SYann Gautier char *cpu_s, *cpu_r, *pkg; 341dec286ddSYann Gautier 342dec286ddSYann Gautier /* MPUs Part Numbers */ 34392661e01SYann Gautier switch (get_part_number()) { 344*30eea116SYann Gautier #if STM32MP13 345*30eea116SYann Gautier case STM32MP135F_PART_NB: 346*30eea116SYann Gautier cpu_s = "135F"; 347*30eea116SYann Gautier break; 348*30eea116SYann Gautier case STM32MP135D_PART_NB: 349*30eea116SYann Gautier cpu_s = "135D"; 350*30eea116SYann Gautier break; 351*30eea116SYann Gautier case STM32MP135C_PART_NB: 352*30eea116SYann Gautier cpu_s = "135C"; 353*30eea116SYann Gautier break; 354*30eea116SYann Gautier case STM32MP135A_PART_NB: 355*30eea116SYann Gautier cpu_s = "135A"; 356*30eea116SYann Gautier break; 357*30eea116SYann Gautier case STM32MP133F_PART_NB: 358*30eea116SYann Gautier cpu_s = "133F"; 359*30eea116SYann Gautier break; 360*30eea116SYann Gautier case STM32MP133D_PART_NB: 361*30eea116SYann Gautier cpu_s = "133D"; 362*30eea116SYann Gautier break; 363*30eea116SYann Gautier case STM32MP133C_PART_NB: 364*30eea116SYann Gautier cpu_s = "133C"; 365*30eea116SYann Gautier break; 366*30eea116SYann Gautier case STM32MP133A_PART_NB: 367*30eea116SYann Gautier cpu_s = "133A"; 368*30eea116SYann Gautier break; 369*30eea116SYann Gautier case STM32MP131F_PART_NB: 370*30eea116SYann Gautier cpu_s = "131F"; 371*30eea116SYann Gautier break; 372*30eea116SYann Gautier case STM32MP131D_PART_NB: 373*30eea116SYann Gautier cpu_s = "131D"; 374*30eea116SYann Gautier break; 375*30eea116SYann Gautier case STM32MP131C_PART_NB: 376*30eea116SYann Gautier cpu_s = "131C"; 377*30eea116SYann Gautier break; 378*30eea116SYann Gautier case STM32MP131A_PART_NB: 379*30eea116SYann Gautier cpu_s = "131A"; 380*30eea116SYann Gautier break; 381*30eea116SYann Gautier #endif 382*30eea116SYann Gautier #if STM32MP15 383dec286ddSYann Gautier case STM32MP157C_PART_NB: 384dec286ddSYann Gautier cpu_s = "157C"; 385dec286ddSYann Gautier break; 386dec286ddSYann Gautier case STM32MP157A_PART_NB: 387dec286ddSYann Gautier cpu_s = "157A"; 388dec286ddSYann Gautier break; 389dec286ddSYann Gautier case STM32MP153C_PART_NB: 390dec286ddSYann Gautier cpu_s = "153C"; 391dec286ddSYann Gautier break; 392dec286ddSYann Gautier case STM32MP153A_PART_NB: 393dec286ddSYann Gautier cpu_s = "153A"; 394dec286ddSYann Gautier break; 395dec286ddSYann Gautier case STM32MP151C_PART_NB: 396dec286ddSYann Gautier cpu_s = "151C"; 397dec286ddSYann Gautier break; 398dec286ddSYann Gautier case STM32MP151A_PART_NB: 399dec286ddSYann Gautier cpu_s = "151A"; 400dec286ddSYann Gautier break; 4018ccf4954SLionel Debieve case STM32MP157F_PART_NB: 4028ccf4954SLionel Debieve cpu_s = "157F"; 4038ccf4954SLionel Debieve break; 4048ccf4954SLionel Debieve case STM32MP157D_PART_NB: 4058ccf4954SLionel Debieve cpu_s = "157D"; 4068ccf4954SLionel Debieve break; 4078ccf4954SLionel Debieve case STM32MP153F_PART_NB: 4088ccf4954SLionel Debieve cpu_s = "153F"; 4098ccf4954SLionel Debieve break; 4108ccf4954SLionel Debieve case STM32MP153D_PART_NB: 4118ccf4954SLionel Debieve cpu_s = "153D"; 4128ccf4954SLionel Debieve break; 4138ccf4954SLionel Debieve case STM32MP151F_PART_NB: 4148ccf4954SLionel Debieve cpu_s = "151F"; 4158ccf4954SLionel Debieve break; 4168ccf4954SLionel Debieve case STM32MP151D_PART_NB: 4178ccf4954SLionel Debieve cpu_s = "151D"; 4188ccf4954SLionel Debieve break; 419*30eea116SYann Gautier #endif 420dec286ddSYann Gautier default: 421dec286ddSYann Gautier cpu_s = "????"; 422dec286ddSYann Gautier break; 423dec286ddSYann Gautier } 424dec286ddSYann Gautier 425dec286ddSYann Gautier /* Package */ 426*30eea116SYann Gautier #if STM32MP13 427*30eea116SYann Gautier /* On STM32MP13, package is not present in OTP */ 428*30eea116SYann Gautier pkg = ""; 429*30eea116SYann Gautier #endif 430*30eea116SYann Gautier #if STM32MP15 43192661e01SYann Gautier switch (get_cpu_package()) { 432dec286ddSYann Gautier case PKG_AA_LFBGA448: 433dec286ddSYann Gautier pkg = "AA"; 434dec286ddSYann Gautier break; 435dec286ddSYann Gautier case PKG_AB_LFBGA354: 436dec286ddSYann Gautier pkg = "AB"; 437dec286ddSYann Gautier break; 438dec286ddSYann Gautier case PKG_AC_TFBGA361: 439dec286ddSYann Gautier pkg = "AC"; 440dec286ddSYann Gautier break; 441dec286ddSYann Gautier case PKG_AD_TFBGA257: 442dec286ddSYann Gautier pkg = "AD"; 443dec286ddSYann Gautier break; 444dec286ddSYann Gautier default: 445dec286ddSYann Gautier pkg = "??"; 446dec286ddSYann Gautier break; 447dec286ddSYann Gautier } 448*30eea116SYann Gautier #endif 449dec286ddSYann Gautier 450dec286ddSYann Gautier /* REVISION */ 45192661e01SYann Gautier switch (stm32mp_get_chip_version()) { 452dec286ddSYann Gautier case STM32MP1_REV_B: 453dec286ddSYann Gautier cpu_r = "B"; 454dec286ddSYann Gautier break; 455ffb3f277SLionel Debieve case STM32MP1_REV_Z: 456ffb3f277SLionel Debieve cpu_r = "Z"; 457ffb3f277SLionel Debieve break; 458dec286ddSYann Gautier default: 459dec286ddSYann Gautier cpu_r = "?"; 460dec286ddSYann Gautier break; 461dec286ddSYann Gautier } 462dec286ddSYann Gautier 46392661e01SYann Gautier snprintf(name, STM32_SOC_NAME_SIZE, 46492661e01SYann Gautier "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r); 46592661e01SYann Gautier } 46692661e01SYann Gautier 46792661e01SYann Gautier void stm32mp_print_cpuinfo(void) 46892661e01SYann Gautier { 46992661e01SYann Gautier char name[STM32_SOC_NAME_SIZE]; 47092661e01SYann Gautier 47192661e01SYann Gautier stm32mp_get_soc_name(name); 47292661e01SYann Gautier NOTICE("CPU: %s\n", name); 473dec286ddSYann Gautier } 474dec286ddSYann Gautier 47510e7a9e9SYann Gautier void stm32mp_print_boardinfo(void) 47610e7a9e9SYann Gautier { 477ae3ce8b2SLionel Debieve uint32_t board_id = 0; 47810e7a9e9SYann Gautier 479ae3ce8b2SLionel Debieve if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) { 48010e7a9e9SYann Gautier return; 48110e7a9e9SYann Gautier } 48210e7a9e9SYann Gautier 48310e7a9e9SYann Gautier if (board_id != 0U) { 48410e7a9e9SYann Gautier char rev[2]; 48510e7a9e9SYann Gautier 48610e7a9e9SYann Gautier rev[0] = BOARD_ID2REV(board_id) - 1 + 'A'; 48710e7a9e9SYann Gautier rev[1] = '\0'; 488ab049ec0SYann Gautier NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n", 48910e7a9e9SYann Gautier BOARD_ID2NB(board_id), 490f964f5c3SPatrick Delaunay BOARD_ID2VARCPN(board_id), 491f964f5c3SPatrick Delaunay BOARD_ID2VARFG(board_id), 49210e7a9e9SYann Gautier rev, 49310e7a9e9SYann Gautier BOARD_ID2BOM(board_id)); 49410e7a9e9SYann Gautier } 49510e7a9e9SYann Gautier } 49610e7a9e9SYann Gautier 497b2182cdeSYann Gautier /* Return true when SoC provides a single Cortex-A7 core, and false otherwise */ 498b2182cdeSYann Gautier bool stm32mp_is_single_core(void) 499b2182cdeSYann Gautier { 5007b48a9f3SYann Gautier #if STM32MP13 5017b48a9f3SYann Gautier return true; 5027b48a9f3SYann Gautier #endif 5037b48a9f3SYann Gautier #if STM32MP15 504f7130e81SYann Gautier bool single_core = false; 505f7130e81SYann Gautier 50692661e01SYann Gautier switch (get_part_number()) { 507b2182cdeSYann Gautier case STM32MP151A_PART_NB: 508b2182cdeSYann Gautier case STM32MP151C_PART_NB: 5098ccf4954SLionel Debieve case STM32MP151D_PART_NB: 5108ccf4954SLionel Debieve case STM32MP151F_PART_NB: 511f7130e81SYann Gautier single_core = true; 512f7130e81SYann Gautier break; 513b2182cdeSYann Gautier default: 514f7130e81SYann Gautier break; 515b2182cdeSYann Gautier } 516f7130e81SYann Gautier 517f7130e81SYann Gautier return single_core; 5187b48a9f3SYann Gautier #endif 519b2182cdeSYann Gautier } 520b2182cdeSYann Gautier 521f700423cSLionel Debieve /* Return true when device is in closed state */ 522f700423cSLionel Debieve bool stm32mp_is_closed_device(void) 523f700423cSLionel Debieve { 524f700423cSLionel Debieve uint32_t value; 525f700423cSLionel Debieve 526ae3ce8b2SLionel Debieve if (stm32_get_otp_value(CFG0_OTP, &value) != 0) { 527f700423cSLionel Debieve return true; 528f700423cSLionel Debieve } 529f700423cSLionel Debieve 530ae3ce8b2SLionel Debieve return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE; 531f700423cSLionel Debieve } 532f700423cSLionel Debieve 53349abdfd8SLionel Debieve /* Return true when device supports secure boot */ 53449abdfd8SLionel Debieve bool stm32mp_is_auth_supported(void) 53549abdfd8SLionel Debieve { 53649abdfd8SLionel Debieve bool supported = false; 53749abdfd8SLionel Debieve 53849abdfd8SLionel Debieve switch (get_part_number()) { 539*30eea116SYann Gautier #if STM32MP13 540*30eea116SYann Gautier case STM32MP131C_PART_NB: 541*30eea116SYann Gautier case STM32MP131F_PART_NB: 542*30eea116SYann Gautier case STM32MP133C_PART_NB: 543*30eea116SYann Gautier case STM32MP133F_PART_NB: 544*30eea116SYann Gautier case STM32MP135C_PART_NB: 545*30eea116SYann Gautier case STM32MP135F_PART_NB: 546*30eea116SYann Gautier #endif 547*30eea116SYann Gautier #if STM32MP15 54849abdfd8SLionel Debieve case STM32MP151C_PART_NB: 54949abdfd8SLionel Debieve case STM32MP151F_PART_NB: 55049abdfd8SLionel Debieve case STM32MP153C_PART_NB: 55149abdfd8SLionel Debieve case STM32MP153F_PART_NB: 55249abdfd8SLionel Debieve case STM32MP157C_PART_NB: 55349abdfd8SLionel Debieve case STM32MP157F_PART_NB: 554*30eea116SYann Gautier #endif 55549abdfd8SLionel Debieve supported = true; 55649abdfd8SLionel Debieve break; 55749abdfd8SLionel Debieve default: 55849abdfd8SLionel Debieve break; 55949abdfd8SLionel Debieve } 56049abdfd8SLionel Debieve 56149abdfd8SLionel Debieve return supported; 56249abdfd8SLionel Debieve } 56349abdfd8SLionel Debieve 56473680c23SYann Gautier uint32_t stm32_iwdg_get_instance(uintptr_t base) 56573680c23SYann Gautier { 56673680c23SYann Gautier switch (base) { 56773680c23SYann Gautier case IWDG1_BASE: 56873680c23SYann Gautier return IWDG1_INST; 56973680c23SYann Gautier case IWDG2_BASE: 57073680c23SYann Gautier return IWDG2_INST; 57173680c23SYann Gautier default: 57273680c23SYann Gautier panic(); 57373680c23SYann Gautier } 57473680c23SYann Gautier } 57573680c23SYann Gautier 57673680c23SYann Gautier uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst) 57773680c23SYann Gautier { 57873680c23SYann Gautier uint32_t iwdg_cfg = 0U; 57973680c23SYann Gautier uint32_t otp_value; 58073680c23SYann Gautier 581ae3ce8b2SLionel Debieve if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) { 58273680c23SYann Gautier panic(); 58373680c23SYann Gautier } 58473680c23SYann Gautier 58573680c23SYann Gautier if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) { 58673680c23SYann Gautier iwdg_cfg |= IWDG_HW_ENABLED; 58773680c23SYann Gautier } 58873680c23SYann Gautier 58973680c23SYann Gautier if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) { 59073680c23SYann Gautier iwdg_cfg |= IWDG_DISABLE_ON_STOP; 59173680c23SYann Gautier } 59273680c23SYann Gautier 59373680c23SYann Gautier if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) { 59473680c23SYann Gautier iwdg_cfg |= IWDG_DISABLE_ON_STANDBY; 59573680c23SYann Gautier } 59673680c23SYann Gautier 59773680c23SYann Gautier return iwdg_cfg; 59873680c23SYann Gautier } 59973680c23SYann Gautier 60073680c23SYann Gautier #if defined(IMAGE_BL2) 60173680c23SYann Gautier uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags) 60273680c23SYann Gautier { 603ae3ce8b2SLionel Debieve uint32_t otp_value; 60473680c23SYann Gautier uint32_t otp; 60573680c23SYann Gautier uint32_t result; 60673680c23SYann Gautier 607ae3ce8b2SLionel Debieve if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) { 60873680c23SYann Gautier panic(); 60973680c23SYann Gautier } 61073680c23SYann Gautier 611ae3ce8b2SLionel Debieve if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) { 612ae3ce8b2SLionel Debieve panic(); 61373680c23SYann Gautier } 61473680c23SYann Gautier 615ae3ce8b2SLionel Debieve if ((flags & IWDG_DISABLE_ON_STOP) != 0) { 616ae3ce8b2SLionel Debieve otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS); 61773680c23SYann Gautier } 61873680c23SYann Gautier 619ae3ce8b2SLionel Debieve if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) { 620ae3ce8b2SLionel Debieve otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS); 621ae3ce8b2SLionel Debieve } 622ae3ce8b2SLionel Debieve 623ae3ce8b2SLionel Debieve result = bsec_write_otp(otp_value, otp); 62473680c23SYann Gautier if (result != BSEC_OK) { 62573680c23SYann Gautier return result; 62673680c23SYann Gautier } 62773680c23SYann Gautier 62873680c23SYann Gautier /* Sticky lock OTP_IWDG (read and write) */ 629ae3ce8b2SLionel Debieve if ((bsec_set_sr_lock(otp) != BSEC_OK) || 630ae3ce8b2SLionel Debieve (bsec_set_sw_lock(otp) != BSEC_OK)) { 63173680c23SYann Gautier return BSEC_LOCK_FAIL; 63273680c23SYann Gautier } 63373680c23SYann Gautier 63473680c23SYann Gautier return BSEC_OK; 63573680c23SYann Gautier } 63673680c23SYann Gautier #endif 637e6cc3ccfSYann Gautier 6384584e01dSLionel Debieve #if STM32MP_USE_STM32IMAGE 639e6cc3ccfSYann Gautier /* Get the non-secure DDR size */ 640e6cc3ccfSYann Gautier uint32_t stm32mp_get_ddr_ns_size(void) 641e6cc3ccfSYann Gautier { 642e6cc3ccfSYann Gautier static uint32_t ddr_ns_size; 643e6cc3ccfSYann Gautier uint32_t ddr_size; 644e6cc3ccfSYann Gautier 645e6cc3ccfSYann Gautier if (ddr_ns_size != 0U) { 646e6cc3ccfSYann Gautier return ddr_ns_size; 647e6cc3ccfSYann Gautier } 648e6cc3ccfSYann Gautier 649e6cc3ccfSYann Gautier ddr_size = dt_get_ddr_size(); 650e6cc3ccfSYann Gautier if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) || 651e6cc3ccfSYann Gautier (ddr_size > STM32MP_DDR_MAX_SIZE)) { 652e6cc3ccfSYann Gautier panic(); 653e6cc3ccfSYann Gautier } 654e6cc3ccfSYann Gautier 655e6cc3ccfSYann Gautier ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE); 656e6cc3ccfSYann Gautier 657e6cc3ccfSYann Gautier return ddr_ns_size; 658e6cc3ccfSYann Gautier } 6594584e01dSLionel Debieve #endif /* STM32MP_USE_STM32IMAGE */ 6604dc77a35SYann Gautier 6614dc77a35SYann Gautier void stm32_save_boot_interface(uint32_t interface, uint32_t instance) 6624dc77a35SYann Gautier { 663c870188dSNicolas Toromanoff uintptr_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID); 6644dc77a35SYann Gautier 66533667d29SYann Gautier clk_enable(RTCAPB); 6664dc77a35SYann Gautier 6674dc77a35SYann Gautier mmio_clrsetbits_32(bkpr_itf_idx, 6684dc77a35SYann Gautier TAMP_BOOT_MODE_ITF_MASK, 6694dc77a35SYann Gautier ((interface << 4) | (instance & 0xFU)) << 6704dc77a35SYann Gautier TAMP_BOOT_MODE_ITF_SHIFT); 6714dc77a35SYann Gautier 67233667d29SYann Gautier clk_disable(RTCAPB); 6734dc77a35SYann Gautier } 674a6bfa75cSYann Gautier 675a6bfa75cSYann Gautier void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance) 676a6bfa75cSYann Gautier { 677a6bfa75cSYann Gautier static uint32_t itf; 678a6bfa75cSYann Gautier 679a6bfa75cSYann Gautier if (itf == 0U) { 680c870188dSNicolas Toromanoff uintptr_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID); 681a6bfa75cSYann Gautier 68233667d29SYann Gautier clk_enable(RTCAPB); 683a6bfa75cSYann Gautier 684a6bfa75cSYann Gautier itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >> 685a6bfa75cSYann Gautier TAMP_BOOT_MODE_ITF_SHIFT; 686a6bfa75cSYann Gautier 68733667d29SYann Gautier clk_disable(RTCAPB); 688a6bfa75cSYann Gautier } 689a6bfa75cSYann Gautier 690a6bfa75cSYann Gautier *interface = itf >> 4; 691a6bfa75cSYann Gautier *instance = itf & 0xFU; 692a6bfa75cSYann Gautier } 693ba02add9SSughosh Ganu 694ba02add9SSughosh Ganu #if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT 695ba02add9SSughosh Ganu void stm32mp1_fwu_set_boot_idx(void) 696ba02add9SSughosh Ganu { 697ba02add9SSughosh Ganu clk_enable(RTCAPB); 698ba02add9SSughosh Ganu mmio_write_32(tamp_bkpr(TAMP_BOOT_COUNTER_REG_ID), 699ba02add9SSughosh Ganu plat_fwu_get_boot_idx()); 700ba02add9SSughosh Ganu clk_disable(RTCAPB); 701ba02add9SSughosh Ganu } 702ba02add9SSughosh Ganu #endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */ 703