1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <drivers/clk.h> 10*91f16700Schasinglulu #include <drivers/st/stm32_gpio.h> 11*91f16700Schasinglulu #include <drivers/st/stm32_iwdg.h> 12*91f16700Schasinglulu #include <lib/mmio.h> 13*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables_v2.h> 14*91f16700Schasinglulu #include <libfdt.h> 15*91f16700Schasinglulu 16*91f16700Schasinglulu #include <plat/common/platform.h> 17*91f16700Schasinglulu #include <platform_def.h> 18*91f16700Schasinglulu 19*91f16700Schasinglulu #if STM32MP13 20*91f16700Schasinglulu #define TAMP_BOOT_MODE_BACKUP_REG_ID U(30) 21*91f16700Schasinglulu #endif 22*91f16700Schasinglulu #if STM32MP15 23*91f16700Schasinglulu #define TAMP_BOOT_MODE_BACKUP_REG_ID U(20) 24*91f16700Schasinglulu #endif 25*91f16700Schasinglulu 26*91f16700Schasinglulu /* 27*91f16700Schasinglulu * Backup register to store fwu update information. 28*91f16700Schasinglulu * It should be writeable only by secure world, but also readable by non secure 29*91f16700Schasinglulu * (so it should be in Zone 2). 30*91f16700Schasinglulu */ 31*91f16700Schasinglulu #define TAMP_BOOT_FWU_INFO_REG_ID U(10) 32*91f16700Schasinglulu #define TAMP_BOOT_FWU_INFO_IDX_MSK GENMASK(3, 0) 33*91f16700Schasinglulu #define TAMP_BOOT_FWU_INFO_IDX_OFF U(0) 34*91f16700Schasinglulu #define TAMP_BOOT_FWU_INFO_CNT_MSK GENMASK(7, 4) 35*91f16700Schasinglulu #define TAMP_BOOT_FWU_INFO_CNT_OFF U(4) 36*91f16700Schasinglulu 37*91f16700Schasinglulu #if defined(IMAGE_BL2) 38*91f16700Schasinglulu #define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ 39*91f16700Schasinglulu STM32MP_SYSRAM_SIZE, \ 40*91f16700Schasinglulu MT_MEMORY | \ 41*91f16700Schasinglulu MT_RW | \ 42*91f16700Schasinglulu MT_SECURE | \ 43*91f16700Schasinglulu MT_EXECUTE_NEVER) 44*91f16700Schasinglulu #elif defined(IMAGE_BL32) 45*91f16700Schasinglulu #define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \ 46*91f16700Schasinglulu STM32MP_SEC_SYSRAM_SIZE, \ 47*91f16700Schasinglulu MT_MEMORY | \ 48*91f16700Schasinglulu MT_RW | \ 49*91f16700Schasinglulu MT_SECURE | \ 50*91f16700Schasinglulu MT_EXECUTE_NEVER) 51*91f16700Schasinglulu 52*91f16700Schasinglulu /* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */ 53*91f16700Schasinglulu #define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \ 54*91f16700Schasinglulu STM32MP_NS_SYSRAM_SIZE, \ 55*91f16700Schasinglulu MT_DEVICE | \ 56*91f16700Schasinglulu MT_RW | \ 57*91f16700Schasinglulu MT_NS | \ 58*91f16700Schasinglulu MT_EXECUTE_NEVER) 59*91f16700Schasinglulu #endif 60*91f16700Schasinglulu 61*91f16700Schasinglulu #if STM32MP13 62*91f16700Schasinglulu #define MAP_SRAM_ALL MAP_REGION_FLAT(SRAMS_BASE, \ 63*91f16700Schasinglulu SRAMS_SIZE_2MB_ALIGNED, \ 64*91f16700Schasinglulu MT_MEMORY | \ 65*91f16700Schasinglulu MT_RW | \ 66*91f16700Schasinglulu MT_SECURE | \ 67*91f16700Schasinglulu MT_EXECUTE_NEVER) 68*91f16700Schasinglulu #endif 69*91f16700Schasinglulu 70*91f16700Schasinglulu #define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \ 71*91f16700Schasinglulu STM32MP1_DEVICE1_SIZE, \ 72*91f16700Schasinglulu MT_DEVICE | \ 73*91f16700Schasinglulu MT_RW | \ 74*91f16700Schasinglulu MT_SECURE | \ 75*91f16700Schasinglulu MT_EXECUTE_NEVER) 76*91f16700Schasinglulu 77*91f16700Schasinglulu #define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \ 78*91f16700Schasinglulu STM32MP1_DEVICE2_SIZE, \ 79*91f16700Schasinglulu MT_DEVICE | \ 80*91f16700Schasinglulu MT_RW | \ 81*91f16700Schasinglulu MT_SECURE | \ 82*91f16700Schasinglulu MT_EXECUTE_NEVER) 83*91f16700Schasinglulu 84*91f16700Schasinglulu #if defined(IMAGE_BL2) 85*91f16700Schasinglulu static const mmap_region_t stm32mp1_mmap[] = { 86*91f16700Schasinglulu MAP_SEC_SYSRAM, 87*91f16700Schasinglulu #if STM32MP13 88*91f16700Schasinglulu MAP_SRAM_ALL, 89*91f16700Schasinglulu #endif 90*91f16700Schasinglulu MAP_DEVICE1, 91*91f16700Schasinglulu #if STM32MP_RAW_NAND 92*91f16700Schasinglulu MAP_DEVICE2, 93*91f16700Schasinglulu #endif 94*91f16700Schasinglulu {0} 95*91f16700Schasinglulu }; 96*91f16700Schasinglulu #endif 97*91f16700Schasinglulu #if defined(IMAGE_BL32) 98*91f16700Schasinglulu static const mmap_region_t stm32mp1_mmap[] = { 99*91f16700Schasinglulu MAP_SEC_SYSRAM, 100*91f16700Schasinglulu MAP_NS_SYSRAM, 101*91f16700Schasinglulu MAP_DEVICE1, 102*91f16700Schasinglulu MAP_DEVICE2, 103*91f16700Schasinglulu {0} 104*91f16700Schasinglulu }; 105*91f16700Schasinglulu #endif 106*91f16700Schasinglulu 107*91f16700Schasinglulu void configure_mmu(void) 108*91f16700Schasinglulu { 109*91f16700Schasinglulu mmap_add(stm32mp1_mmap); 110*91f16700Schasinglulu init_xlat_tables(); 111*91f16700Schasinglulu 112*91f16700Schasinglulu enable_mmu_svc_mon(0); 113*91f16700Schasinglulu } 114*91f16700Schasinglulu 115*91f16700Schasinglulu uintptr_t stm32_get_gpio_bank_base(unsigned int bank) 116*91f16700Schasinglulu { 117*91f16700Schasinglulu #if STM32MP13 118*91f16700Schasinglulu assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I)); 119*91f16700Schasinglulu #endif 120*91f16700Schasinglulu #if STM32MP15 121*91f16700Schasinglulu if (bank == GPIO_BANK_Z) { 122*91f16700Schasinglulu return GPIOZ_BASE; 123*91f16700Schasinglulu } 124*91f16700Schasinglulu 125*91f16700Schasinglulu assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K)); 126*91f16700Schasinglulu #endif 127*91f16700Schasinglulu 128*91f16700Schasinglulu return GPIOA_BASE + (bank * GPIO_BANK_OFFSET); 129*91f16700Schasinglulu } 130*91f16700Schasinglulu 131*91f16700Schasinglulu uint32_t stm32_get_gpio_bank_offset(unsigned int bank) 132*91f16700Schasinglulu { 133*91f16700Schasinglulu #if STM32MP13 134*91f16700Schasinglulu assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I)); 135*91f16700Schasinglulu #endif 136*91f16700Schasinglulu #if STM32MP15 137*91f16700Schasinglulu if (bank == GPIO_BANK_Z) { 138*91f16700Schasinglulu return 0; 139*91f16700Schasinglulu } 140*91f16700Schasinglulu 141*91f16700Schasinglulu assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K)); 142*91f16700Schasinglulu #endif 143*91f16700Schasinglulu 144*91f16700Schasinglulu return bank * GPIO_BANK_OFFSET; 145*91f16700Schasinglulu } 146*91f16700Schasinglulu 147*91f16700Schasinglulu bool stm32_gpio_is_secure_at_reset(unsigned int bank) 148*91f16700Schasinglulu { 149*91f16700Schasinglulu #if STM32MP13 150*91f16700Schasinglulu return true; 151*91f16700Schasinglulu #endif 152*91f16700Schasinglulu #if STM32MP15 153*91f16700Schasinglulu if (bank == GPIO_BANK_Z) { 154*91f16700Schasinglulu return true; 155*91f16700Schasinglulu } 156*91f16700Schasinglulu 157*91f16700Schasinglulu return false; 158*91f16700Schasinglulu #endif 159*91f16700Schasinglulu } 160*91f16700Schasinglulu 161*91f16700Schasinglulu unsigned long stm32_get_gpio_bank_clock(unsigned int bank) 162*91f16700Schasinglulu { 163*91f16700Schasinglulu #if STM32MP13 164*91f16700Schasinglulu assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I)); 165*91f16700Schasinglulu #endif 166*91f16700Schasinglulu #if STM32MP15 167*91f16700Schasinglulu if (bank == GPIO_BANK_Z) { 168*91f16700Schasinglulu return GPIOZ; 169*91f16700Schasinglulu } 170*91f16700Schasinglulu 171*91f16700Schasinglulu assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K)); 172*91f16700Schasinglulu #endif 173*91f16700Schasinglulu 174*91f16700Schasinglulu return GPIOA + (bank - GPIO_BANK_A); 175*91f16700Schasinglulu } 176*91f16700Schasinglulu 177*91f16700Schasinglulu int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank) 178*91f16700Schasinglulu { 179*91f16700Schasinglulu const char *node_compatible = NULL; 180*91f16700Schasinglulu 181*91f16700Schasinglulu switch (bank) { 182*91f16700Schasinglulu case GPIO_BANK_A: 183*91f16700Schasinglulu case GPIO_BANK_B: 184*91f16700Schasinglulu case GPIO_BANK_C: 185*91f16700Schasinglulu case GPIO_BANK_D: 186*91f16700Schasinglulu case GPIO_BANK_E: 187*91f16700Schasinglulu case GPIO_BANK_F: 188*91f16700Schasinglulu case GPIO_BANK_G: 189*91f16700Schasinglulu case GPIO_BANK_H: 190*91f16700Schasinglulu case GPIO_BANK_I: 191*91f16700Schasinglulu #if STM32MP13 192*91f16700Schasinglulu node_compatible = "st,stm32mp135-pinctrl"; 193*91f16700Schasinglulu break; 194*91f16700Schasinglulu #endif 195*91f16700Schasinglulu #if STM32MP15 196*91f16700Schasinglulu case GPIO_BANK_J: 197*91f16700Schasinglulu case GPIO_BANK_K: 198*91f16700Schasinglulu node_compatible = "st,stm32mp157-pinctrl"; 199*91f16700Schasinglulu break; 200*91f16700Schasinglulu case GPIO_BANK_Z: 201*91f16700Schasinglulu node_compatible = "st,stm32mp157-z-pinctrl"; 202*91f16700Schasinglulu break; 203*91f16700Schasinglulu #endif 204*91f16700Schasinglulu default: 205*91f16700Schasinglulu panic(); 206*91f16700Schasinglulu } 207*91f16700Schasinglulu 208*91f16700Schasinglulu return fdt_node_offset_by_compatible(fdt, -1, node_compatible); 209*91f16700Schasinglulu } 210*91f16700Schasinglulu 211*91f16700Schasinglulu #if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2) 212*91f16700Schasinglulu /* 213*91f16700Schasinglulu * UART Management 214*91f16700Schasinglulu */ 215*91f16700Schasinglulu static const uintptr_t stm32mp1_uart_addresses[8] = { 216*91f16700Schasinglulu USART1_BASE, 217*91f16700Schasinglulu USART2_BASE, 218*91f16700Schasinglulu USART3_BASE, 219*91f16700Schasinglulu UART4_BASE, 220*91f16700Schasinglulu UART5_BASE, 221*91f16700Schasinglulu USART6_BASE, 222*91f16700Schasinglulu UART7_BASE, 223*91f16700Schasinglulu UART8_BASE, 224*91f16700Schasinglulu }; 225*91f16700Schasinglulu 226*91f16700Schasinglulu uintptr_t get_uart_address(uint32_t instance_nb) 227*91f16700Schasinglulu { 228*91f16700Schasinglulu if ((instance_nb == 0U) || 229*91f16700Schasinglulu (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) { 230*91f16700Schasinglulu return 0U; 231*91f16700Schasinglulu } 232*91f16700Schasinglulu 233*91f16700Schasinglulu return stm32mp1_uart_addresses[instance_nb - 1U]; 234*91f16700Schasinglulu } 235*91f16700Schasinglulu #endif 236*91f16700Schasinglulu 237*91f16700Schasinglulu #if STM32MP_USB_PROGRAMMER 238*91f16700Schasinglulu struct gpio_bank_pin_list { 239*91f16700Schasinglulu uint32_t bank; 240*91f16700Schasinglulu uint32_t pin; 241*91f16700Schasinglulu }; 242*91f16700Schasinglulu 243*91f16700Schasinglulu static const struct gpio_bank_pin_list gpio_list[] = { 244*91f16700Schasinglulu { /* USART2_RX: GPIOA3 */ 245*91f16700Schasinglulu .bank = 0U, 246*91f16700Schasinglulu .pin = 3U, 247*91f16700Schasinglulu }, 248*91f16700Schasinglulu { /* USART3_RX: GPIOB12 */ 249*91f16700Schasinglulu .bank = 1U, 250*91f16700Schasinglulu .pin = 12U, 251*91f16700Schasinglulu }, 252*91f16700Schasinglulu { /* UART4_RX: GPIOB2 */ 253*91f16700Schasinglulu .bank = 1U, 254*91f16700Schasinglulu .pin = 2U, 255*91f16700Schasinglulu }, 256*91f16700Schasinglulu { /* UART5_RX: GPIOB4 */ 257*91f16700Schasinglulu .bank = 1U, 258*91f16700Schasinglulu .pin = 5U, 259*91f16700Schasinglulu }, 260*91f16700Schasinglulu { /* USART6_RX: GPIOC7 */ 261*91f16700Schasinglulu .bank = 2U, 262*91f16700Schasinglulu .pin = 7U, 263*91f16700Schasinglulu }, 264*91f16700Schasinglulu { /* UART7_RX: GPIOF6 */ 265*91f16700Schasinglulu .bank = 5U, 266*91f16700Schasinglulu .pin = 6U, 267*91f16700Schasinglulu }, 268*91f16700Schasinglulu { /* UART8_RX: GPIOE0 */ 269*91f16700Schasinglulu .bank = 4U, 270*91f16700Schasinglulu .pin = 0U, 271*91f16700Schasinglulu }, 272*91f16700Schasinglulu }; 273*91f16700Schasinglulu 274*91f16700Schasinglulu void stm32mp1_deconfigure_uart_pins(void) 275*91f16700Schasinglulu { 276*91f16700Schasinglulu size_t i; 277*91f16700Schasinglulu 278*91f16700Schasinglulu for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) { 279*91f16700Schasinglulu set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin); 280*91f16700Schasinglulu } 281*91f16700Schasinglulu } 282*91f16700Schasinglulu #endif 283*91f16700Schasinglulu 284*91f16700Schasinglulu uint32_t stm32mp_get_chip_version(void) 285*91f16700Schasinglulu { 286*91f16700Schasinglulu #if STM32MP13 287*91f16700Schasinglulu return stm32mp1_syscfg_get_chip_version(); 288*91f16700Schasinglulu #endif 289*91f16700Schasinglulu #if STM32MP15 290*91f16700Schasinglulu uint32_t version = 0U; 291*91f16700Schasinglulu 292*91f16700Schasinglulu if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) { 293*91f16700Schasinglulu INFO("Cannot get CPU version, debug disabled\n"); 294*91f16700Schasinglulu return 0U; 295*91f16700Schasinglulu } 296*91f16700Schasinglulu 297*91f16700Schasinglulu return version; 298*91f16700Schasinglulu #endif 299*91f16700Schasinglulu } 300*91f16700Schasinglulu 301*91f16700Schasinglulu uint32_t stm32mp_get_chip_dev_id(void) 302*91f16700Schasinglulu { 303*91f16700Schasinglulu #if STM32MP13 304*91f16700Schasinglulu return stm32mp1_syscfg_get_chip_dev_id(); 305*91f16700Schasinglulu #endif 306*91f16700Schasinglulu #if STM32MP15 307*91f16700Schasinglulu uint32_t dev_id; 308*91f16700Schasinglulu 309*91f16700Schasinglulu if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) { 310*91f16700Schasinglulu INFO("Use default chip ID, debug disabled\n"); 311*91f16700Schasinglulu dev_id = STM32MP1_CHIP_ID; 312*91f16700Schasinglulu } 313*91f16700Schasinglulu 314*91f16700Schasinglulu return dev_id; 315*91f16700Schasinglulu #endif 316*91f16700Schasinglulu } 317*91f16700Schasinglulu 318*91f16700Schasinglulu static uint32_t get_part_number(void) 319*91f16700Schasinglulu { 320*91f16700Schasinglulu static uint32_t part_number; 321*91f16700Schasinglulu 322*91f16700Schasinglulu if (part_number != 0U) { 323*91f16700Schasinglulu return part_number; 324*91f16700Schasinglulu } 325*91f16700Schasinglulu 326*91f16700Schasinglulu if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) { 327*91f16700Schasinglulu panic(); 328*91f16700Schasinglulu } 329*91f16700Schasinglulu 330*91f16700Schasinglulu part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >> 331*91f16700Schasinglulu PART_NUMBER_OTP_PART_SHIFT; 332*91f16700Schasinglulu 333*91f16700Schasinglulu part_number |= stm32mp_get_chip_dev_id() << 16; 334*91f16700Schasinglulu 335*91f16700Schasinglulu return part_number; 336*91f16700Schasinglulu } 337*91f16700Schasinglulu 338*91f16700Schasinglulu #if STM32MP15 339*91f16700Schasinglulu static uint32_t get_cpu_package(void) 340*91f16700Schasinglulu { 341*91f16700Schasinglulu uint32_t package; 342*91f16700Schasinglulu 343*91f16700Schasinglulu if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) { 344*91f16700Schasinglulu panic(); 345*91f16700Schasinglulu } 346*91f16700Schasinglulu 347*91f16700Schasinglulu package = (package & PACKAGE_OTP_PKG_MASK) >> 348*91f16700Schasinglulu PACKAGE_OTP_PKG_SHIFT; 349*91f16700Schasinglulu 350*91f16700Schasinglulu return package; 351*91f16700Schasinglulu } 352*91f16700Schasinglulu #endif 353*91f16700Schasinglulu 354*91f16700Schasinglulu void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE]) 355*91f16700Schasinglulu { 356*91f16700Schasinglulu const char *cpu_s, *cpu_r, *pkg; 357*91f16700Schasinglulu 358*91f16700Schasinglulu /* MPUs Part Numbers */ 359*91f16700Schasinglulu switch (get_part_number()) { 360*91f16700Schasinglulu #if STM32MP13 361*91f16700Schasinglulu case STM32MP135F_PART_NB: 362*91f16700Schasinglulu cpu_s = "135F"; 363*91f16700Schasinglulu break; 364*91f16700Schasinglulu case STM32MP135D_PART_NB: 365*91f16700Schasinglulu cpu_s = "135D"; 366*91f16700Schasinglulu break; 367*91f16700Schasinglulu case STM32MP135C_PART_NB: 368*91f16700Schasinglulu cpu_s = "135C"; 369*91f16700Schasinglulu break; 370*91f16700Schasinglulu case STM32MP135A_PART_NB: 371*91f16700Schasinglulu cpu_s = "135A"; 372*91f16700Schasinglulu break; 373*91f16700Schasinglulu case STM32MP133F_PART_NB: 374*91f16700Schasinglulu cpu_s = "133F"; 375*91f16700Schasinglulu break; 376*91f16700Schasinglulu case STM32MP133D_PART_NB: 377*91f16700Schasinglulu cpu_s = "133D"; 378*91f16700Schasinglulu break; 379*91f16700Schasinglulu case STM32MP133C_PART_NB: 380*91f16700Schasinglulu cpu_s = "133C"; 381*91f16700Schasinglulu break; 382*91f16700Schasinglulu case STM32MP133A_PART_NB: 383*91f16700Schasinglulu cpu_s = "133A"; 384*91f16700Schasinglulu break; 385*91f16700Schasinglulu case STM32MP131F_PART_NB: 386*91f16700Schasinglulu cpu_s = "131F"; 387*91f16700Schasinglulu break; 388*91f16700Schasinglulu case STM32MP131D_PART_NB: 389*91f16700Schasinglulu cpu_s = "131D"; 390*91f16700Schasinglulu break; 391*91f16700Schasinglulu case STM32MP131C_PART_NB: 392*91f16700Schasinglulu cpu_s = "131C"; 393*91f16700Schasinglulu break; 394*91f16700Schasinglulu case STM32MP131A_PART_NB: 395*91f16700Schasinglulu cpu_s = "131A"; 396*91f16700Schasinglulu break; 397*91f16700Schasinglulu #endif 398*91f16700Schasinglulu #if STM32MP15 399*91f16700Schasinglulu case STM32MP157C_PART_NB: 400*91f16700Schasinglulu cpu_s = "157C"; 401*91f16700Schasinglulu break; 402*91f16700Schasinglulu case STM32MP157A_PART_NB: 403*91f16700Schasinglulu cpu_s = "157A"; 404*91f16700Schasinglulu break; 405*91f16700Schasinglulu case STM32MP153C_PART_NB: 406*91f16700Schasinglulu cpu_s = "153C"; 407*91f16700Schasinglulu break; 408*91f16700Schasinglulu case STM32MP153A_PART_NB: 409*91f16700Schasinglulu cpu_s = "153A"; 410*91f16700Schasinglulu break; 411*91f16700Schasinglulu case STM32MP151C_PART_NB: 412*91f16700Schasinglulu cpu_s = "151C"; 413*91f16700Schasinglulu break; 414*91f16700Schasinglulu case STM32MP151A_PART_NB: 415*91f16700Schasinglulu cpu_s = "151A"; 416*91f16700Schasinglulu break; 417*91f16700Schasinglulu case STM32MP157F_PART_NB: 418*91f16700Schasinglulu cpu_s = "157F"; 419*91f16700Schasinglulu break; 420*91f16700Schasinglulu case STM32MP157D_PART_NB: 421*91f16700Schasinglulu cpu_s = "157D"; 422*91f16700Schasinglulu break; 423*91f16700Schasinglulu case STM32MP153F_PART_NB: 424*91f16700Schasinglulu cpu_s = "153F"; 425*91f16700Schasinglulu break; 426*91f16700Schasinglulu case STM32MP153D_PART_NB: 427*91f16700Schasinglulu cpu_s = "153D"; 428*91f16700Schasinglulu break; 429*91f16700Schasinglulu case STM32MP151F_PART_NB: 430*91f16700Schasinglulu cpu_s = "151F"; 431*91f16700Schasinglulu break; 432*91f16700Schasinglulu case STM32MP151D_PART_NB: 433*91f16700Schasinglulu cpu_s = "151D"; 434*91f16700Schasinglulu break; 435*91f16700Schasinglulu #endif 436*91f16700Schasinglulu default: 437*91f16700Schasinglulu cpu_s = "????"; 438*91f16700Schasinglulu break; 439*91f16700Schasinglulu } 440*91f16700Schasinglulu 441*91f16700Schasinglulu /* Package */ 442*91f16700Schasinglulu #if STM32MP13 443*91f16700Schasinglulu /* On STM32MP13, package is not present in OTP */ 444*91f16700Schasinglulu pkg = ""; 445*91f16700Schasinglulu #endif 446*91f16700Schasinglulu #if STM32MP15 447*91f16700Schasinglulu switch (get_cpu_package()) { 448*91f16700Schasinglulu case PKG_AA_LFBGA448: 449*91f16700Schasinglulu pkg = "AA"; 450*91f16700Schasinglulu break; 451*91f16700Schasinglulu case PKG_AB_LFBGA354: 452*91f16700Schasinglulu pkg = "AB"; 453*91f16700Schasinglulu break; 454*91f16700Schasinglulu case PKG_AC_TFBGA361: 455*91f16700Schasinglulu pkg = "AC"; 456*91f16700Schasinglulu break; 457*91f16700Schasinglulu case PKG_AD_TFBGA257: 458*91f16700Schasinglulu pkg = "AD"; 459*91f16700Schasinglulu break; 460*91f16700Schasinglulu default: 461*91f16700Schasinglulu pkg = "??"; 462*91f16700Schasinglulu break; 463*91f16700Schasinglulu } 464*91f16700Schasinglulu #endif 465*91f16700Schasinglulu 466*91f16700Schasinglulu /* REVISION */ 467*91f16700Schasinglulu switch (stm32mp_get_chip_version()) { 468*91f16700Schasinglulu case STM32MP1_REV_B: 469*91f16700Schasinglulu cpu_r = "B"; 470*91f16700Schasinglulu break; 471*91f16700Schasinglulu #if STM32MP13 472*91f16700Schasinglulu case STM32MP1_REV_Y: 473*91f16700Schasinglulu cpu_r = "Y"; 474*91f16700Schasinglulu break; 475*91f16700Schasinglulu #endif 476*91f16700Schasinglulu case STM32MP1_REV_Z: 477*91f16700Schasinglulu cpu_r = "Z"; 478*91f16700Schasinglulu break; 479*91f16700Schasinglulu default: 480*91f16700Schasinglulu cpu_r = "?"; 481*91f16700Schasinglulu break; 482*91f16700Schasinglulu } 483*91f16700Schasinglulu 484*91f16700Schasinglulu snprintf(name, STM32_SOC_NAME_SIZE, 485*91f16700Schasinglulu "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r); 486*91f16700Schasinglulu } 487*91f16700Schasinglulu 488*91f16700Schasinglulu void stm32mp_print_cpuinfo(void) 489*91f16700Schasinglulu { 490*91f16700Schasinglulu char name[STM32_SOC_NAME_SIZE]; 491*91f16700Schasinglulu 492*91f16700Schasinglulu stm32mp_get_soc_name(name); 493*91f16700Schasinglulu NOTICE("CPU: %s\n", name); 494*91f16700Schasinglulu } 495*91f16700Schasinglulu 496*91f16700Schasinglulu void stm32mp_print_boardinfo(void) 497*91f16700Schasinglulu { 498*91f16700Schasinglulu uint32_t board_id = 0U; 499*91f16700Schasinglulu 500*91f16700Schasinglulu if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) { 501*91f16700Schasinglulu return; 502*91f16700Schasinglulu } 503*91f16700Schasinglulu 504*91f16700Schasinglulu if (board_id != 0U) { 505*91f16700Schasinglulu stm32_display_board_info(board_id); 506*91f16700Schasinglulu } 507*91f16700Schasinglulu } 508*91f16700Schasinglulu 509*91f16700Schasinglulu /* Return true when SoC provides a single Cortex-A7 core, and false otherwise */ 510*91f16700Schasinglulu bool stm32mp_is_single_core(void) 511*91f16700Schasinglulu { 512*91f16700Schasinglulu #if STM32MP13 513*91f16700Schasinglulu return true; 514*91f16700Schasinglulu #endif 515*91f16700Schasinglulu #if STM32MP15 516*91f16700Schasinglulu bool single_core = false; 517*91f16700Schasinglulu 518*91f16700Schasinglulu switch (get_part_number()) { 519*91f16700Schasinglulu case STM32MP151A_PART_NB: 520*91f16700Schasinglulu case STM32MP151C_PART_NB: 521*91f16700Schasinglulu case STM32MP151D_PART_NB: 522*91f16700Schasinglulu case STM32MP151F_PART_NB: 523*91f16700Schasinglulu single_core = true; 524*91f16700Schasinglulu break; 525*91f16700Schasinglulu default: 526*91f16700Schasinglulu break; 527*91f16700Schasinglulu } 528*91f16700Schasinglulu 529*91f16700Schasinglulu return single_core; 530*91f16700Schasinglulu #endif 531*91f16700Schasinglulu } 532*91f16700Schasinglulu 533*91f16700Schasinglulu /* Return true when device is in closed state */ 534*91f16700Schasinglulu bool stm32mp_is_closed_device(void) 535*91f16700Schasinglulu { 536*91f16700Schasinglulu uint32_t value; 537*91f16700Schasinglulu 538*91f16700Schasinglulu if (stm32_get_otp_value(CFG0_OTP, &value) != 0) { 539*91f16700Schasinglulu return true; 540*91f16700Schasinglulu } 541*91f16700Schasinglulu 542*91f16700Schasinglulu #if STM32MP13 543*91f16700Schasinglulu value = (value & CFG0_OTP_MODE_MASK) >> CFG0_OTP_MODE_SHIFT; 544*91f16700Schasinglulu 545*91f16700Schasinglulu switch (value) { 546*91f16700Schasinglulu case CFG0_OPEN_DEVICE: 547*91f16700Schasinglulu return false; 548*91f16700Schasinglulu case CFG0_CLOSED_DEVICE: 549*91f16700Schasinglulu case CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN: 550*91f16700Schasinglulu case CFG0_CLOSED_DEVICE_NO_JTAG: 551*91f16700Schasinglulu return true; 552*91f16700Schasinglulu default: 553*91f16700Schasinglulu panic(); 554*91f16700Schasinglulu } 555*91f16700Schasinglulu #endif 556*91f16700Schasinglulu #if STM32MP15 557*91f16700Schasinglulu return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE; 558*91f16700Schasinglulu #endif 559*91f16700Schasinglulu } 560*91f16700Schasinglulu 561*91f16700Schasinglulu /* Return true when device supports secure boot */ 562*91f16700Schasinglulu bool stm32mp_is_auth_supported(void) 563*91f16700Schasinglulu { 564*91f16700Schasinglulu bool supported = false; 565*91f16700Schasinglulu 566*91f16700Schasinglulu switch (get_part_number()) { 567*91f16700Schasinglulu #if STM32MP13 568*91f16700Schasinglulu case STM32MP131C_PART_NB: 569*91f16700Schasinglulu case STM32MP131F_PART_NB: 570*91f16700Schasinglulu case STM32MP133C_PART_NB: 571*91f16700Schasinglulu case STM32MP133F_PART_NB: 572*91f16700Schasinglulu case STM32MP135C_PART_NB: 573*91f16700Schasinglulu case STM32MP135F_PART_NB: 574*91f16700Schasinglulu #endif 575*91f16700Schasinglulu #if STM32MP15 576*91f16700Schasinglulu case STM32MP151C_PART_NB: 577*91f16700Schasinglulu case STM32MP151F_PART_NB: 578*91f16700Schasinglulu case STM32MP153C_PART_NB: 579*91f16700Schasinglulu case STM32MP153F_PART_NB: 580*91f16700Schasinglulu case STM32MP157C_PART_NB: 581*91f16700Schasinglulu case STM32MP157F_PART_NB: 582*91f16700Schasinglulu #endif 583*91f16700Schasinglulu supported = true; 584*91f16700Schasinglulu break; 585*91f16700Schasinglulu default: 586*91f16700Schasinglulu break; 587*91f16700Schasinglulu } 588*91f16700Schasinglulu 589*91f16700Schasinglulu return supported; 590*91f16700Schasinglulu } 591*91f16700Schasinglulu 592*91f16700Schasinglulu uint32_t stm32_iwdg_get_instance(uintptr_t base) 593*91f16700Schasinglulu { 594*91f16700Schasinglulu switch (base) { 595*91f16700Schasinglulu case IWDG1_BASE: 596*91f16700Schasinglulu return IWDG1_INST; 597*91f16700Schasinglulu case IWDG2_BASE: 598*91f16700Schasinglulu return IWDG2_INST; 599*91f16700Schasinglulu default: 600*91f16700Schasinglulu panic(); 601*91f16700Schasinglulu } 602*91f16700Schasinglulu } 603*91f16700Schasinglulu 604*91f16700Schasinglulu uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst) 605*91f16700Schasinglulu { 606*91f16700Schasinglulu uint32_t iwdg_cfg = 0U; 607*91f16700Schasinglulu uint32_t otp_value; 608*91f16700Schasinglulu 609*91f16700Schasinglulu if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) { 610*91f16700Schasinglulu panic(); 611*91f16700Schasinglulu } 612*91f16700Schasinglulu 613*91f16700Schasinglulu if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) { 614*91f16700Schasinglulu iwdg_cfg |= IWDG_HW_ENABLED; 615*91f16700Schasinglulu } 616*91f16700Schasinglulu 617*91f16700Schasinglulu if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) { 618*91f16700Schasinglulu iwdg_cfg |= IWDG_DISABLE_ON_STOP; 619*91f16700Schasinglulu } 620*91f16700Schasinglulu 621*91f16700Schasinglulu if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) { 622*91f16700Schasinglulu iwdg_cfg |= IWDG_DISABLE_ON_STANDBY; 623*91f16700Schasinglulu } 624*91f16700Schasinglulu 625*91f16700Schasinglulu return iwdg_cfg; 626*91f16700Schasinglulu } 627*91f16700Schasinglulu 628*91f16700Schasinglulu #if defined(IMAGE_BL2) 629*91f16700Schasinglulu uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags) 630*91f16700Schasinglulu { 631*91f16700Schasinglulu uint32_t otp_value; 632*91f16700Schasinglulu uint32_t otp; 633*91f16700Schasinglulu uint32_t result; 634*91f16700Schasinglulu 635*91f16700Schasinglulu if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) { 636*91f16700Schasinglulu panic(); 637*91f16700Schasinglulu } 638*91f16700Schasinglulu 639*91f16700Schasinglulu if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) { 640*91f16700Schasinglulu panic(); 641*91f16700Schasinglulu } 642*91f16700Schasinglulu 643*91f16700Schasinglulu if ((flags & IWDG_DISABLE_ON_STOP) != 0) { 644*91f16700Schasinglulu otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS); 645*91f16700Schasinglulu } 646*91f16700Schasinglulu 647*91f16700Schasinglulu if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) { 648*91f16700Schasinglulu otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS); 649*91f16700Schasinglulu } 650*91f16700Schasinglulu 651*91f16700Schasinglulu result = bsec_write_otp(otp_value, otp); 652*91f16700Schasinglulu if (result != BSEC_OK) { 653*91f16700Schasinglulu return result; 654*91f16700Schasinglulu } 655*91f16700Schasinglulu 656*91f16700Schasinglulu /* Sticky lock OTP_IWDG (read and write) */ 657*91f16700Schasinglulu if ((bsec_set_sr_lock(otp) != BSEC_OK) || 658*91f16700Schasinglulu (bsec_set_sw_lock(otp) != BSEC_OK)) { 659*91f16700Schasinglulu return BSEC_LOCK_FAIL; 660*91f16700Schasinglulu } 661*91f16700Schasinglulu 662*91f16700Schasinglulu return BSEC_OK; 663*91f16700Schasinglulu } 664*91f16700Schasinglulu #endif 665*91f16700Schasinglulu 666*91f16700Schasinglulu uintptr_t stm32_get_bkpr_boot_mode_addr(void) 667*91f16700Schasinglulu { 668*91f16700Schasinglulu return tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID); 669*91f16700Schasinglulu } 670*91f16700Schasinglulu 671*91f16700Schasinglulu #if PSA_FWU_SUPPORT 672*91f16700Schasinglulu void stm32mp1_fwu_set_boot_idx(void) 673*91f16700Schasinglulu { 674*91f16700Schasinglulu clk_enable(RTCAPB); 675*91f16700Schasinglulu mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID), 676*91f16700Schasinglulu TAMP_BOOT_FWU_INFO_IDX_MSK, 677*91f16700Schasinglulu (plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) & 678*91f16700Schasinglulu TAMP_BOOT_FWU_INFO_IDX_MSK); 679*91f16700Schasinglulu clk_disable(RTCAPB); 680*91f16700Schasinglulu } 681*91f16700Schasinglulu 682*91f16700Schasinglulu uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void) 683*91f16700Schasinglulu { 684*91f16700Schasinglulu uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID); 685*91f16700Schasinglulu uint32_t try_cnt; 686*91f16700Schasinglulu 687*91f16700Schasinglulu clk_enable(RTCAPB); 688*91f16700Schasinglulu try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >> 689*91f16700Schasinglulu TAMP_BOOT_FWU_INFO_CNT_OFF; 690*91f16700Schasinglulu 691*91f16700Schasinglulu assert(try_cnt <= FWU_MAX_TRIAL_REBOOT); 692*91f16700Schasinglulu 693*91f16700Schasinglulu if (try_cnt != 0U) { 694*91f16700Schasinglulu mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK, 695*91f16700Schasinglulu (try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF); 696*91f16700Schasinglulu } 697*91f16700Schasinglulu clk_disable(RTCAPB); 698*91f16700Schasinglulu 699*91f16700Schasinglulu return try_cnt; 700*91f16700Schasinglulu } 701*91f16700Schasinglulu 702*91f16700Schasinglulu void stm32_set_max_fwu_trial_boot_cnt(void) 703*91f16700Schasinglulu { 704*91f16700Schasinglulu uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID); 705*91f16700Schasinglulu 706*91f16700Schasinglulu clk_enable(RTCAPB); 707*91f16700Schasinglulu mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK, 708*91f16700Schasinglulu (FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) & 709*91f16700Schasinglulu TAMP_BOOT_FWU_INFO_CNT_MSK); 710*91f16700Schasinglulu clk_disable(RTCAPB); 711*91f16700Schasinglulu } 712*91f16700Schasinglulu #endif /* PSA_FWU_SUPPORT */ 713