1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu #include <limits.h> 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <arch_helpers.h> 11*91f16700Schasinglulu #include <common/debug.h> 12*91f16700Schasinglulu #include <drivers/st/bsec.h> 13*91f16700Schasinglulu #include <drivers/st/bsec2_reg.h> 14*91f16700Schasinglulu #include <lib/mmio.h> 15*91f16700Schasinglulu #include <lib/spinlock.h> 16*91f16700Schasinglulu #include <libfdt.h> 17*91f16700Schasinglulu 18*91f16700Schasinglulu #include <platform_def.h> 19*91f16700Schasinglulu 20*91f16700Schasinglulu #define BSEC_IP_VERSION_1_1 U(0x11) 21*91f16700Schasinglulu #define BSEC_IP_VERSION_2_0 U(0x20) 22*91f16700Schasinglulu #define BSEC_IP_ID_2 U(0x100032) 23*91f16700Schasinglulu 24*91f16700Schasinglulu #define OTP_ACCESS_SIZE (round_up(OTP_MAX_SIZE, __WORD_BIT) / __WORD_BIT) 25*91f16700Schasinglulu 26*91f16700Schasinglulu static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __unused; 27*91f16700Schasinglulu 28*91f16700Schasinglulu static uint32_t bsec_power_safmem(bool power); 29*91f16700Schasinglulu 30*91f16700Schasinglulu /* BSEC access protection */ 31*91f16700Schasinglulu static spinlock_t bsec_spinlock; 32*91f16700Schasinglulu static uintptr_t bsec_base; 33*91f16700Schasinglulu 34*91f16700Schasinglulu static void bsec_lock(void) 35*91f16700Schasinglulu { 36*91f16700Schasinglulu if (stm32mp_lock_available()) { 37*91f16700Schasinglulu spin_lock(&bsec_spinlock); 38*91f16700Schasinglulu } 39*91f16700Schasinglulu } 40*91f16700Schasinglulu 41*91f16700Schasinglulu static void bsec_unlock(void) 42*91f16700Schasinglulu { 43*91f16700Schasinglulu if (stm32mp_lock_available()) { 44*91f16700Schasinglulu spin_unlock(&bsec_spinlock); 45*91f16700Schasinglulu } 46*91f16700Schasinglulu } 47*91f16700Schasinglulu 48*91f16700Schasinglulu static bool is_otp_invalid_mode(void) 49*91f16700Schasinglulu { 50*91f16700Schasinglulu bool ret = ((bsec_get_status() & BSEC_MODE_INVALID) == BSEC_MODE_INVALID); 51*91f16700Schasinglulu 52*91f16700Schasinglulu if (ret) { 53*91f16700Schasinglulu ERROR("OTP mode is OTP-INVALID\n"); 54*91f16700Schasinglulu } 55*91f16700Schasinglulu 56*91f16700Schasinglulu return ret; 57*91f16700Schasinglulu } 58*91f16700Schasinglulu 59*91f16700Schasinglulu #if defined(IMAGE_BL32) 60*91f16700Schasinglulu static int bsec_get_dt_node(struct dt_node_info *info) 61*91f16700Schasinglulu { 62*91f16700Schasinglulu int node; 63*91f16700Schasinglulu 64*91f16700Schasinglulu node = dt_get_node(info, -1, DT_BSEC_COMPAT); 65*91f16700Schasinglulu if (node < 0) { 66*91f16700Schasinglulu return -FDT_ERR_NOTFOUND; 67*91f16700Schasinglulu } 68*91f16700Schasinglulu 69*91f16700Schasinglulu return node; 70*91f16700Schasinglulu } 71*91f16700Schasinglulu 72*91f16700Schasinglulu static void enable_non_secure_access(uint32_t otp) 73*91f16700Schasinglulu { 74*91f16700Schasinglulu otp_nsec_access[otp / __WORD_BIT] |= BIT(otp % __WORD_BIT); 75*91f16700Schasinglulu 76*91f16700Schasinglulu if (bsec_shadow_register(otp) != BSEC_OK) { 77*91f16700Schasinglulu panic(); 78*91f16700Schasinglulu } 79*91f16700Schasinglulu } 80*91f16700Schasinglulu 81*91f16700Schasinglulu static bool non_secure_can_access(uint32_t otp) 82*91f16700Schasinglulu { 83*91f16700Schasinglulu return (otp_nsec_access[otp / __WORD_BIT] & 84*91f16700Schasinglulu BIT(otp % __WORD_BIT)) != 0U; 85*91f16700Schasinglulu } 86*91f16700Schasinglulu 87*91f16700Schasinglulu static void bsec_dt_otp_nsec_access(void *fdt, int bsec_node) 88*91f16700Schasinglulu { 89*91f16700Schasinglulu int bsec_subnode; 90*91f16700Schasinglulu 91*91f16700Schasinglulu fdt_for_each_subnode(bsec_subnode, fdt, bsec_node) { 92*91f16700Schasinglulu const fdt32_t *cuint; 93*91f16700Schasinglulu uint32_t otp; 94*91f16700Schasinglulu uint32_t i; 95*91f16700Schasinglulu uint32_t size; 96*91f16700Schasinglulu uint32_t offset; 97*91f16700Schasinglulu uint32_t length; 98*91f16700Schasinglulu 99*91f16700Schasinglulu cuint = fdt_getprop(fdt, bsec_subnode, "reg", NULL); 100*91f16700Schasinglulu if (cuint == NULL) { 101*91f16700Schasinglulu panic(); 102*91f16700Schasinglulu } 103*91f16700Schasinglulu 104*91f16700Schasinglulu offset = fdt32_to_cpu(*cuint); 105*91f16700Schasinglulu cuint++; 106*91f16700Schasinglulu length = fdt32_to_cpu(*cuint); 107*91f16700Schasinglulu 108*91f16700Schasinglulu otp = offset / sizeof(uint32_t); 109*91f16700Schasinglulu 110*91f16700Schasinglulu if (otp < STM32MP1_UPPER_OTP_START) { 111*91f16700Schasinglulu unsigned int otp_end = round_up(offset + length, 112*91f16700Schasinglulu sizeof(uint32_t)) / 113*91f16700Schasinglulu sizeof(uint32_t); 114*91f16700Schasinglulu 115*91f16700Schasinglulu if (otp_end > STM32MP1_UPPER_OTP_START) { 116*91f16700Schasinglulu /* 117*91f16700Schasinglulu * OTP crosses Lower/Upper boundary, consider 118*91f16700Schasinglulu * only the upper part. 119*91f16700Schasinglulu */ 120*91f16700Schasinglulu otp = STM32MP1_UPPER_OTP_START; 121*91f16700Schasinglulu length -= (STM32MP1_UPPER_OTP_START * 122*91f16700Schasinglulu sizeof(uint32_t)) - offset; 123*91f16700Schasinglulu offset = STM32MP1_UPPER_OTP_START * 124*91f16700Schasinglulu sizeof(uint32_t); 125*91f16700Schasinglulu 126*91f16700Schasinglulu WARN("OTP crosses Lower/Upper boundary\n"); 127*91f16700Schasinglulu } else { 128*91f16700Schasinglulu continue; 129*91f16700Schasinglulu } 130*91f16700Schasinglulu } 131*91f16700Schasinglulu 132*91f16700Schasinglulu if ((fdt_getprop(fdt, bsec_subnode, 133*91f16700Schasinglulu "st,non-secure-otp", NULL)) == NULL) { 134*91f16700Schasinglulu continue; 135*91f16700Schasinglulu } 136*91f16700Schasinglulu 137*91f16700Schasinglulu if (((offset % sizeof(uint32_t)) != 0U) || 138*91f16700Schasinglulu ((length % sizeof(uint32_t)) != 0U)) { 139*91f16700Schasinglulu ERROR("Unaligned non-secure OTP\n"); 140*91f16700Schasinglulu panic(); 141*91f16700Schasinglulu } 142*91f16700Schasinglulu 143*91f16700Schasinglulu size = length / sizeof(uint32_t); 144*91f16700Schasinglulu 145*91f16700Schasinglulu for (i = otp; i < (otp + size); i++) { 146*91f16700Schasinglulu enable_non_secure_access(i); 147*91f16700Schasinglulu } 148*91f16700Schasinglulu } 149*91f16700Schasinglulu } 150*91f16700Schasinglulu 151*91f16700Schasinglulu static void bsec_late_init(void) 152*91f16700Schasinglulu { 153*91f16700Schasinglulu void *fdt; 154*91f16700Schasinglulu int node; 155*91f16700Schasinglulu struct dt_node_info bsec_info; 156*91f16700Schasinglulu 157*91f16700Schasinglulu if (fdt_get_address(&fdt) == 0) { 158*91f16700Schasinglulu panic(); 159*91f16700Schasinglulu } 160*91f16700Schasinglulu 161*91f16700Schasinglulu node = bsec_get_dt_node(&bsec_info); 162*91f16700Schasinglulu if (node < 0) { 163*91f16700Schasinglulu panic(); 164*91f16700Schasinglulu } 165*91f16700Schasinglulu 166*91f16700Schasinglulu assert(bsec_base == bsec_info.base); 167*91f16700Schasinglulu 168*91f16700Schasinglulu bsec_dt_otp_nsec_access(fdt, node); 169*91f16700Schasinglulu } 170*91f16700Schasinglulu #endif 171*91f16700Schasinglulu 172*91f16700Schasinglulu static uint32_t otp_bank_offset(uint32_t otp) 173*91f16700Schasinglulu { 174*91f16700Schasinglulu assert(otp <= STM32MP1_OTP_MAX_ID); 175*91f16700Schasinglulu 176*91f16700Schasinglulu return ((otp & ~BSEC_OTP_MASK) >> BSEC_OTP_BANK_SHIFT) * 177*91f16700Schasinglulu sizeof(uint32_t); 178*91f16700Schasinglulu } 179*91f16700Schasinglulu 180*91f16700Schasinglulu /* 181*91f16700Schasinglulu * bsec_check_error: check BSEC error status. 182*91f16700Schasinglulu * otp: OTP number. 183*91f16700Schasinglulu * check_disturbed: check only error (false), 184*91f16700Schasinglulu * or error and disturbed status (true). 185*91f16700Schasinglulu * return value: BSEC_OK if no error. 186*91f16700Schasinglulu */ 187*91f16700Schasinglulu static uint32_t bsec_check_error(uint32_t otp, bool check_disturbed) 188*91f16700Schasinglulu { 189*91f16700Schasinglulu uint32_t bit = BIT(otp & BSEC_OTP_MASK); 190*91f16700Schasinglulu uint32_t bank = otp_bank_offset(otp); 191*91f16700Schasinglulu 192*91f16700Schasinglulu if ((mmio_read_32(bsec_base + BSEC_ERROR_OFF + bank) & bit) != 0U) { 193*91f16700Schasinglulu return BSEC_ERROR; 194*91f16700Schasinglulu } 195*91f16700Schasinglulu 196*91f16700Schasinglulu if (!check_disturbed) { 197*91f16700Schasinglulu return BSEC_OK; 198*91f16700Schasinglulu } 199*91f16700Schasinglulu 200*91f16700Schasinglulu if ((mmio_read_32(bsec_base + BSEC_DISTURBED_OFF + bank) & bit) != 0U) { 201*91f16700Schasinglulu return BSEC_DISTURBED; 202*91f16700Schasinglulu } 203*91f16700Schasinglulu 204*91f16700Schasinglulu return BSEC_OK; 205*91f16700Schasinglulu } 206*91f16700Schasinglulu 207*91f16700Schasinglulu /* 208*91f16700Schasinglulu * bsec_probe: initialize BSEC driver. 209*91f16700Schasinglulu * return value: BSEC_OK if no error. 210*91f16700Schasinglulu */ 211*91f16700Schasinglulu uint32_t bsec_probe(void) 212*91f16700Schasinglulu { 213*91f16700Schasinglulu bsec_base = BSEC_BASE; 214*91f16700Schasinglulu 215*91f16700Schasinglulu if (is_otp_invalid_mode()) { 216*91f16700Schasinglulu return BSEC_ERROR; 217*91f16700Schasinglulu } 218*91f16700Schasinglulu 219*91f16700Schasinglulu if ((((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_1_1) && 220*91f16700Schasinglulu ((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_2_0)) || 221*91f16700Schasinglulu (bsec_get_id() != BSEC_IP_ID_2)) { 222*91f16700Schasinglulu panic(); 223*91f16700Schasinglulu } 224*91f16700Schasinglulu 225*91f16700Schasinglulu #if defined(IMAGE_BL32) 226*91f16700Schasinglulu bsec_late_init(); 227*91f16700Schasinglulu #endif 228*91f16700Schasinglulu return BSEC_OK; 229*91f16700Schasinglulu } 230*91f16700Schasinglulu 231*91f16700Schasinglulu /* 232*91f16700Schasinglulu * bsec_get_base: return BSEC base address. 233*91f16700Schasinglulu */ 234*91f16700Schasinglulu uint32_t bsec_get_base(void) 235*91f16700Schasinglulu { 236*91f16700Schasinglulu return bsec_base; 237*91f16700Schasinglulu } 238*91f16700Schasinglulu 239*91f16700Schasinglulu /* 240*91f16700Schasinglulu * bsec_set_config: enable and configure BSEC. 241*91f16700Schasinglulu * cfg: pointer to param structure used to set register. 242*91f16700Schasinglulu * return value: BSEC_OK if no error. 243*91f16700Schasinglulu */ 244*91f16700Schasinglulu uint32_t bsec_set_config(struct bsec_config *cfg) 245*91f16700Schasinglulu { 246*91f16700Schasinglulu uint32_t value; 247*91f16700Schasinglulu uint32_t result; 248*91f16700Schasinglulu 249*91f16700Schasinglulu if (is_otp_invalid_mode()) { 250*91f16700Schasinglulu return BSEC_ERROR; 251*91f16700Schasinglulu } 252*91f16700Schasinglulu 253*91f16700Schasinglulu value = ((((uint32_t)cfg->freq << BSEC_CONF_FRQ_SHIFT) & 254*91f16700Schasinglulu BSEC_CONF_FRQ_MASK) | 255*91f16700Schasinglulu (((uint32_t)cfg->pulse_width << BSEC_CONF_PRG_WIDTH_SHIFT) & 256*91f16700Schasinglulu BSEC_CONF_PRG_WIDTH_MASK) | 257*91f16700Schasinglulu (((uint32_t)cfg->tread << BSEC_CONF_TREAD_SHIFT) & 258*91f16700Schasinglulu BSEC_CONF_TREAD_MASK)); 259*91f16700Schasinglulu 260*91f16700Schasinglulu bsec_lock(); 261*91f16700Schasinglulu 262*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, value); 263*91f16700Schasinglulu 264*91f16700Schasinglulu bsec_unlock(); 265*91f16700Schasinglulu 266*91f16700Schasinglulu result = bsec_power_safmem((bool)cfg->power & 267*91f16700Schasinglulu BSEC_CONF_POWER_UP_MASK); 268*91f16700Schasinglulu if (result != BSEC_OK) { 269*91f16700Schasinglulu return result; 270*91f16700Schasinglulu } 271*91f16700Schasinglulu 272*91f16700Schasinglulu value = ((((uint32_t)cfg->upper_otp_lock << UPPER_OTP_LOCK_SHIFT) & 273*91f16700Schasinglulu UPPER_OTP_LOCK_MASK) | 274*91f16700Schasinglulu (((uint32_t)cfg->den_lock << DENREG_LOCK_SHIFT) & 275*91f16700Schasinglulu DENREG_LOCK_MASK) | 276*91f16700Schasinglulu (((uint32_t)cfg->prog_lock << GPLOCK_LOCK_SHIFT) & 277*91f16700Schasinglulu GPLOCK_LOCK_MASK)); 278*91f16700Schasinglulu 279*91f16700Schasinglulu bsec_lock(); 280*91f16700Schasinglulu 281*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_OTP_LOCK_OFF, value); 282*91f16700Schasinglulu 283*91f16700Schasinglulu bsec_unlock(); 284*91f16700Schasinglulu 285*91f16700Schasinglulu return BSEC_OK; 286*91f16700Schasinglulu } 287*91f16700Schasinglulu 288*91f16700Schasinglulu /* 289*91f16700Schasinglulu * bsec_get_config: return config parameters set in BSEC registers. 290*91f16700Schasinglulu * cfg: config param return. 291*91f16700Schasinglulu * return value: BSEC_OK if no error. 292*91f16700Schasinglulu */ 293*91f16700Schasinglulu uint32_t bsec_get_config(struct bsec_config *cfg) 294*91f16700Schasinglulu { 295*91f16700Schasinglulu uint32_t value; 296*91f16700Schasinglulu 297*91f16700Schasinglulu if (cfg == NULL) { 298*91f16700Schasinglulu return BSEC_INVALID_PARAM; 299*91f16700Schasinglulu } 300*91f16700Schasinglulu 301*91f16700Schasinglulu value = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF); 302*91f16700Schasinglulu cfg->power = (uint8_t)((value & BSEC_CONF_POWER_UP_MASK) >> 303*91f16700Schasinglulu BSEC_CONF_POWER_UP_SHIFT); 304*91f16700Schasinglulu cfg->freq = (uint8_t)((value & BSEC_CONF_FRQ_MASK) >> 305*91f16700Schasinglulu BSEC_CONF_FRQ_SHIFT); 306*91f16700Schasinglulu cfg->pulse_width = (uint8_t)((value & BSEC_CONF_PRG_WIDTH_MASK) >> 307*91f16700Schasinglulu BSEC_CONF_PRG_WIDTH_SHIFT); 308*91f16700Schasinglulu cfg->tread = (uint8_t)((value & BSEC_CONF_TREAD_MASK) >> 309*91f16700Schasinglulu BSEC_CONF_TREAD_SHIFT); 310*91f16700Schasinglulu 311*91f16700Schasinglulu value = mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF); 312*91f16700Schasinglulu cfg->upper_otp_lock = (uint8_t)((value & UPPER_OTP_LOCK_MASK) >> 313*91f16700Schasinglulu UPPER_OTP_LOCK_SHIFT); 314*91f16700Schasinglulu cfg->den_lock = (uint8_t)((value & DENREG_LOCK_MASK) >> 315*91f16700Schasinglulu DENREG_LOCK_SHIFT); 316*91f16700Schasinglulu cfg->prog_lock = (uint8_t)((value & GPLOCK_LOCK_MASK) >> 317*91f16700Schasinglulu GPLOCK_LOCK_SHIFT); 318*91f16700Schasinglulu 319*91f16700Schasinglulu return BSEC_OK; 320*91f16700Schasinglulu } 321*91f16700Schasinglulu 322*91f16700Schasinglulu /* 323*91f16700Schasinglulu * bsec_shadow_register: copy SAFMEM OTP to BSEC data. 324*91f16700Schasinglulu * otp: OTP number. 325*91f16700Schasinglulu * return value: BSEC_OK if no error. 326*91f16700Schasinglulu */ 327*91f16700Schasinglulu uint32_t bsec_shadow_register(uint32_t otp) 328*91f16700Schasinglulu { 329*91f16700Schasinglulu uint32_t result; 330*91f16700Schasinglulu bool value; 331*91f16700Schasinglulu bool power_up = false; 332*91f16700Schasinglulu 333*91f16700Schasinglulu if (is_otp_invalid_mode()) { 334*91f16700Schasinglulu return BSEC_ERROR; 335*91f16700Schasinglulu } 336*91f16700Schasinglulu 337*91f16700Schasinglulu result = bsec_read_sr_lock(otp, &value); 338*91f16700Schasinglulu if (result != BSEC_OK) { 339*91f16700Schasinglulu ERROR("BSEC: %u Sticky-read bit read Error %u\n", otp, result); 340*91f16700Schasinglulu return result; 341*91f16700Schasinglulu } 342*91f16700Schasinglulu 343*91f16700Schasinglulu if (value) { 344*91f16700Schasinglulu VERBOSE("BSEC: OTP %u is locked and will not be refreshed\n", 345*91f16700Schasinglulu otp); 346*91f16700Schasinglulu } 347*91f16700Schasinglulu 348*91f16700Schasinglulu if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) { 349*91f16700Schasinglulu result = bsec_power_safmem(true); 350*91f16700Schasinglulu 351*91f16700Schasinglulu if (result != BSEC_OK) { 352*91f16700Schasinglulu return result; 353*91f16700Schasinglulu } 354*91f16700Schasinglulu 355*91f16700Schasinglulu power_up = true; 356*91f16700Schasinglulu } 357*91f16700Schasinglulu 358*91f16700Schasinglulu bsec_lock(); 359*91f16700Schasinglulu 360*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_READ); 361*91f16700Schasinglulu 362*91f16700Schasinglulu while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) { 363*91f16700Schasinglulu ; 364*91f16700Schasinglulu } 365*91f16700Schasinglulu 366*91f16700Schasinglulu result = bsec_check_error(otp, true); 367*91f16700Schasinglulu 368*91f16700Schasinglulu bsec_unlock(); 369*91f16700Schasinglulu 370*91f16700Schasinglulu if (power_up) { 371*91f16700Schasinglulu if (bsec_power_safmem(false) != BSEC_OK) { 372*91f16700Schasinglulu panic(); 373*91f16700Schasinglulu } 374*91f16700Schasinglulu } 375*91f16700Schasinglulu 376*91f16700Schasinglulu return result; 377*91f16700Schasinglulu } 378*91f16700Schasinglulu 379*91f16700Schasinglulu /* 380*91f16700Schasinglulu * bsec_read_otp: read an OTP data value. 381*91f16700Schasinglulu * val: read value. 382*91f16700Schasinglulu * otp: OTP number. 383*91f16700Schasinglulu * return value: BSEC_OK if no error. 384*91f16700Schasinglulu */ 385*91f16700Schasinglulu uint32_t bsec_read_otp(uint32_t *val, uint32_t otp) 386*91f16700Schasinglulu { 387*91f16700Schasinglulu if (is_otp_invalid_mode()) { 388*91f16700Schasinglulu return BSEC_ERROR; 389*91f16700Schasinglulu } 390*91f16700Schasinglulu 391*91f16700Schasinglulu if (otp > STM32MP1_OTP_MAX_ID) { 392*91f16700Schasinglulu return BSEC_INVALID_PARAM; 393*91f16700Schasinglulu } 394*91f16700Schasinglulu 395*91f16700Schasinglulu *val = mmio_read_32(bsec_base + BSEC_OTP_DATA_OFF + 396*91f16700Schasinglulu (otp * sizeof(uint32_t))); 397*91f16700Schasinglulu 398*91f16700Schasinglulu return BSEC_OK; 399*91f16700Schasinglulu } 400*91f16700Schasinglulu 401*91f16700Schasinglulu /* 402*91f16700Schasinglulu * bsec_write_otp: write value in BSEC data register. 403*91f16700Schasinglulu * val: value to write. 404*91f16700Schasinglulu * otp: OTP number. 405*91f16700Schasinglulu * return value: BSEC_OK if no error. 406*91f16700Schasinglulu */ 407*91f16700Schasinglulu uint32_t bsec_write_otp(uint32_t val, uint32_t otp) 408*91f16700Schasinglulu { 409*91f16700Schasinglulu uint32_t result; 410*91f16700Schasinglulu bool value; 411*91f16700Schasinglulu 412*91f16700Schasinglulu if (is_otp_invalid_mode()) { 413*91f16700Schasinglulu return BSEC_ERROR; 414*91f16700Schasinglulu } 415*91f16700Schasinglulu 416*91f16700Schasinglulu result = bsec_read_sw_lock(otp, &value); 417*91f16700Schasinglulu if (result != BSEC_OK) { 418*91f16700Schasinglulu ERROR("BSEC: %u Sticky-write bit read Error %u\n", otp, result); 419*91f16700Schasinglulu return result; 420*91f16700Schasinglulu } 421*91f16700Schasinglulu 422*91f16700Schasinglulu if (value) { 423*91f16700Schasinglulu VERBOSE("BSEC: OTP %u is locked and write will be ignored\n", 424*91f16700Schasinglulu otp); 425*91f16700Schasinglulu } 426*91f16700Schasinglulu 427*91f16700Schasinglulu /* Ensure integrity of each register access sequence */ 428*91f16700Schasinglulu bsec_lock(); 429*91f16700Schasinglulu 430*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_OTP_DATA_OFF + 431*91f16700Schasinglulu (otp * sizeof(uint32_t)), val); 432*91f16700Schasinglulu 433*91f16700Schasinglulu bsec_unlock(); 434*91f16700Schasinglulu 435*91f16700Schasinglulu return result; 436*91f16700Schasinglulu } 437*91f16700Schasinglulu 438*91f16700Schasinglulu /* 439*91f16700Schasinglulu * bsec_program_otp: program a bit in SAFMEM after the prog. 440*91f16700Schasinglulu * The OTP data is not refreshed. 441*91f16700Schasinglulu * val: value to program. 442*91f16700Schasinglulu * otp: OTP number. 443*91f16700Schasinglulu * return value: BSEC_OK if no error. 444*91f16700Schasinglulu */ 445*91f16700Schasinglulu uint32_t bsec_program_otp(uint32_t val, uint32_t otp) 446*91f16700Schasinglulu { 447*91f16700Schasinglulu uint32_t result; 448*91f16700Schasinglulu bool power_up = false; 449*91f16700Schasinglulu bool sp_lock; 450*91f16700Schasinglulu bool perm_lock; 451*91f16700Schasinglulu 452*91f16700Schasinglulu if (is_otp_invalid_mode()) { 453*91f16700Schasinglulu return BSEC_ERROR; 454*91f16700Schasinglulu } 455*91f16700Schasinglulu 456*91f16700Schasinglulu result = bsec_read_sp_lock(otp, &sp_lock); 457*91f16700Schasinglulu if (result != BSEC_OK) { 458*91f16700Schasinglulu ERROR("BSEC: %u Sticky-prog bit read Error %u\n", otp, result); 459*91f16700Schasinglulu return result; 460*91f16700Schasinglulu } 461*91f16700Schasinglulu 462*91f16700Schasinglulu result = bsec_read_permanent_lock(otp, &perm_lock); 463*91f16700Schasinglulu if (result != BSEC_OK) { 464*91f16700Schasinglulu ERROR("BSEC: %u permanent bit read Error %u\n", otp, result); 465*91f16700Schasinglulu return result; 466*91f16700Schasinglulu } 467*91f16700Schasinglulu 468*91f16700Schasinglulu if (sp_lock || perm_lock) { 469*91f16700Schasinglulu WARN("BSEC: OTP locked, prog will be ignored\n"); 470*91f16700Schasinglulu return BSEC_PROG_FAIL; 471*91f16700Schasinglulu } 472*91f16700Schasinglulu 473*91f16700Schasinglulu if ((mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF) & 474*91f16700Schasinglulu BIT(BSEC_LOCK_PROGRAM)) != 0U) { 475*91f16700Schasinglulu WARN("BSEC: GPLOCK activated, prog will be ignored\n"); 476*91f16700Schasinglulu } 477*91f16700Schasinglulu 478*91f16700Schasinglulu if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) { 479*91f16700Schasinglulu result = bsec_power_safmem(true); 480*91f16700Schasinglulu 481*91f16700Schasinglulu if (result != BSEC_OK) { 482*91f16700Schasinglulu return result; 483*91f16700Schasinglulu } 484*91f16700Schasinglulu 485*91f16700Schasinglulu power_up = true; 486*91f16700Schasinglulu } 487*91f16700Schasinglulu 488*91f16700Schasinglulu bsec_lock(); 489*91f16700Schasinglulu 490*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, val); 491*91f16700Schasinglulu 492*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE); 493*91f16700Schasinglulu 494*91f16700Schasinglulu while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) { 495*91f16700Schasinglulu ; 496*91f16700Schasinglulu } 497*91f16700Schasinglulu 498*91f16700Schasinglulu if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) { 499*91f16700Schasinglulu result = BSEC_PROG_FAIL; 500*91f16700Schasinglulu } else { 501*91f16700Schasinglulu result = bsec_check_error(otp, true); 502*91f16700Schasinglulu } 503*91f16700Schasinglulu 504*91f16700Schasinglulu bsec_unlock(); 505*91f16700Schasinglulu 506*91f16700Schasinglulu if (power_up) { 507*91f16700Schasinglulu if (bsec_power_safmem(false) != BSEC_OK) { 508*91f16700Schasinglulu panic(); 509*91f16700Schasinglulu } 510*91f16700Schasinglulu } 511*91f16700Schasinglulu 512*91f16700Schasinglulu return result; 513*91f16700Schasinglulu } 514*91f16700Schasinglulu 515*91f16700Schasinglulu /* 516*91f16700Schasinglulu * bsec_permanent_lock_otp: permanent lock of OTP in SAFMEM. 517*91f16700Schasinglulu * otp: OTP number. 518*91f16700Schasinglulu * return value: BSEC_OK if no error. 519*91f16700Schasinglulu */ 520*91f16700Schasinglulu uint32_t bsec_permanent_lock_otp(uint32_t otp) 521*91f16700Schasinglulu { 522*91f16700Schasinglulu uint32_t result; 523*91f16700Schasinglulu bool power_up = false; 524*91f16700Schasinglulu uint32_t data; 525*91f16700Schasinglulu uint32_t addr; 526*91f16700Schasinglulu 527*91f16700Schasinglulu if (is_otp_invalid_mode()) { 528*91f16700Schasinglulu return BSEC_ERROR; 529*91f16700Schasinglulu } 530*91f16700Schasinglulu 531*91f16700Schasinglulu if (otp > STM32MP1_OTP_MAX_ID) { 532*91f16700Schasinglulu return BSEC_INVALID_PARAM; 533*91f16700Schasinglulu } 534*91f16700Schasinglulu 535*91f16700Schasinglulu if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) { 536*91f16700Schasinglulu result = bsec_power_safmem(true); 537*91f16700Schasinglulu 538*91f16700Schasinglulu if (result != BSEC_OK) { 539*91f16700Schasinglulu return result; 540*91f16700Schasinglulu } 541*91f16700Schasinglulu 542*91f16700Schasinglulu power_up = true; 543*91f16700Schasinglulu } 544*91f16700Schasinglulu 545*91f16700Schasinglulu if (otp < STM32MP1_UPPER_OTP_START) { 546*91f16700Schasinglulu addr = otp >> ADDR_LOWER_OTP_PERLOCK_SHIFT; 547*91f16700Schasinglulu data = DATA_LOWER_OTP_PERLOCK_BIT << 548*91f16700Schasinglulu ((otp & DATA_LOWER_OTP_PERLOCK_MASK) << 1U); 549*91f16700Schasinglulu } else { 550*91f16700Schasinglulu addr = (otp >> ADDR_UPPER_OTP_PERLOCK_SHIFT) + 2U; 551*91f16700Schasinglulu data = DATA_UPPER_OTP_PERLOCK_BIT << 552*91f16700Schasinglulu (otp & DATA_UPPER_OTP_PERLOCK_MASK); 553*91f16700Schasinglulu } 554*91f16700Schasinglulu 555*91f16700Schasinglulu bsec_lock(); 556*91f16700Schasinglulu 557*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, data); 558*91f16700Schasinglulu 559*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, 560*91f16700Schasinglulu addr | BSEC_WRITE | BSEC_LOCK); 561*91f16700Schasinglulu 562*91f16700Schasinglulu while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) { 563*91f16700Schasinglulu ; 564*91f16700Schasinglulu } 565*91f16700Schasinglulu 566*91f16700Schasinglulu if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) { 567*91f16700Schasinglulu result = BSEC_PROG_FAIL; 568*91f16700Schasinglulu } else { 569*91f16700Schasinglulu result = bsec_check_error(otp, false); 570*91f16700Schasinglulu } 571*91f16700Schasinglulu 572*91f16700Schasinglulu bsec_unlock(); 573*91f16700Schasinglulu 574*91f16700Schasinglulu if (power_up) { 575*91f16700Schasinglulu if (bsec_power_safmem(false) != BSEC_OK) { 576*91f16700Schasinglulu panic(); 577*91f16700Schasinglulu } 578*91f16700Schasinglulu } 579*91f16700Schasinglulu 580*91f16700Schasinglulu return result; 581*91f16700Schasinglulu } 582*91f16700Schasinglulu 583*91f16700Schasinglulu /* 584*91f16700Schasinglulu * bsec_write_debug_conf: write value in debug feature. 585*91f16700Schasinglulu * to enable/disable debug service. 586*91f16700Schasinglulu * val: value to write. 587*91f16700Schasinglulu * return value: none. 588*91f16700Schasinglulu */ 589*91f16700Schasinglulu void bsec_write_debug_conf(uint32_t val) 590*91f16700Schasinglulu { 591*91f16700Schasinglulu if (is_otp_invalid_mode()) { 592*91f16700Schasinglulu return; 593*91f16700Schasinglulu } 594*91f16700Schasinglulu 595*91f16700Schasinglulu bsec_lock(); 596*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_DEN_OFF, val & BSEC_DEN_ALL_MSK); 597*91f16700Schasinglulu bsec_unlock(); 598*91f16700Schasinglulu } 599*91f16700Schasinglulu 600*91f16700Schasinglulu /* 601*91f16700Schasinglulu * bsec_read_debug_conf: return debug configuration register value. 602*91f16700Schasinglulu */ 603*91f16700Schasinglulu uint32_t bsec_read_debug_conf(void) 604*91f16700Schasinglulu { 605*91f16700Schasinglulu return mmio_read_32(bsec_base + BSEC_DEN_OFF); 606*91f16700Schasinglulu } 607*91f16700Schasinglulu 608*91f16700Schasinglulu /* 609*91f16700Schasinglulu * bsec_write_scratch: write value in scratch register. 610*91f16700Schasinglulu * val: value to write. 611*91f16700Schasinglulu * return value: none. 612*91f16700Schasinglulu */ 613*91f16700Schasinglulu void bsec_write_scratch(uint32_t val) 614*91f16700Schasinglulu { 615*91f16700Schasinglulu #if defined(IMAGE_BL32) 616*91f16700Schasinglulu if (is_otp_invalid_mode()) { 617*91f16700Schasinglulu return; 618*91f16700Schasinglulu } 619*91f16700Schasinglulu 620*91f16700Schasinglulu bsec_lock(); 621*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_SCRATCH_OFF, val); 622*91f16700Schasinglulu bsec_unlock(); 623*91f16700Schasinglulu #else 624*91f16700Schasinglulu mmio_write_32(BSEC_BASE + BSEC_SCRATCH_OFF, val); 625*91f16700Schasinglulu #endif 626*91f16700Schasinglulu } 627*91f16700Schasinglulu 628*91f16700Schasinglulu /* 629*91f16700Schasinglulu * bsec_read_scratch: return scratch register value. 630*91f16700Schasinglulu */ 631*91f16700Schasinglulu uint32_t bsec_read_scratch(void) 632*91f16700Schasinglulu { 633*91f16700Schasinglulu return mmio_read_32(bsec_base + BSEC_SCRATCH_OFF); 634*91f16700Schasinglulu } 635*91f16700Schasinglulu 636*91f16700Schasinglulu /* 637*91f16700Schasinglulu * bsec_get_status: return status register value. 638*91f16700Schasinglulu */ 639*91f16700Schasinglulu uint32_t bsec_get_status(void) 640*91f16700Schasinglulu { 641*91f16700Schasinglulu return mmio_read_32(bsec_base + BSEC_OTP_STATUS_OFF); 642*91f16700Schasinglulu } 643*91f16700Schasinglulu 644*91f16700Schasinglulu /* 645*91f16700Schasinglulu * bsec_get_hw_conf: return hardware configuration register value. 646*91f16700Schasinglulu */ 647*91f16700Schasinglulu uint32_t bsec_get_hw_conf(void) 648*91f16700Schasinglulu { 649*91f16700Schasinglulu return mmio_read_32(bsec_base + BSEC_IPHW_CFG_OFF); 650*91f16700Schasinglulu } 651*91f16700Schasinglulu 652*91f16700Schasinglulu /* 653*91f16700Schasinglulu * bsec_get_version: return BSEC version register value. 654*91f16700Schasinglulu */ 655*91f16700Schasinglulu uint32_t bsec_get_version(void) 656*91f16700Schasinglulu { 657*91f16700Schasinglulu return mmio_read_32(bsec_base + BSEC_IPVR_OFF); 658*91f16700Schasinglulu } 659*91f16700Schasinglulu 660*91f16700Schasinglulu /* 661*91f16700Schasinglulu * bsec_get_id: return BSEC ID register value. 662*91f16700Schasinglulu */ 663*91f16700Schasinglulu uint32_t bsec_get_id(void) 664*91f16700Schasinglulu { 665*91f16700Schasinglulu return mmio_read_32(bsec_base + BSEC_IP_ID_OFF); 666*91f16700Schasinglulu } 667*91f16700Schasinglulu 668*91f16700Schasinglulu /* 669*91f16700Schasinglulu * bsec_get_magic_id: return BSEC magic number register value. 670*91f16700Schasinglulu */ 671*91f16700Schasinglulu uint32_t bsec_get_magic_id(void) 672*91f16700Schasinglulu { 673*91f16700Schasinglulu return mmio_read_32(bsec_base + BSEC_IP_MAGIC_ID_OFF); 674*91f16700Schasinglulu } 675*91f16700Schasinglulu 676*91f16700Schasinglulu /* 677*91f16700Schasinglulu * bsec_set_sr_lock: set shadow-read lock. 678*91f16700Schasinglulu * otp: OTP number. 679*91f16700Schasinglulu * return value: BSEC_OK if no error. 680*91f16700Schasinglulu */ 681*91f16700Schasinglulu uint32_t bsec_set_sr_lock(uint32_t otp) 682*91f16700Schasinglulu { 683*91f16700Schasinglulu uint32_t bank = otp_bank_offset(otp); 684*91f16700Schasinglulu uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); 685*91f16700Schasinglulu 686*91f16700Schasinglulu if (is_otp_invalid_mode()) { 687*91f16700Schasinglulu return BSEC_ERROR; 688*91f16700Schasinglulu } 689*91f16700Schasinglulu 690*91f16700Schasinglulu if (otp > STM32MP1_OTP_MAX_ID) { 691*91f16700Schasinglulu return BSEC_INVALID_PARAM; 692*91f16700Schasinglulu } 693*91f16700Schasinglulu 694*91f16700Schasinglulu bsec_lock(); 695*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_SRLOCK_OFF + bank, otp_mask); 696*91f16700Schasinglulu bsec_unlock(); 697*91f16700Schasinglulu 698*91f16700Schasinglulu return BSEC_OK; 699*91f16700Schasinglulu } 700*91f16700Schasinglulu 701*91f16700Schasinglulu /* 702*91f16700Schasinglulu * bsec_read_sr_lock: read shadow-read lock. 703*91f16700Schasinglulu * otp: OTP number. 704*91f16700Schasinglulu * value: read value (true or false). 705*91f16700Schasinglulu * return value: BSEC_OK if no error. 706*91f16700Schasinglulu */ 707*91f16700Schasinglulu uint32_t bsec_read_sr_lock(uint32_t otp, bool *value) 708*91f16700Schasinglulu { 709*91f16700Schasinglulu uint32_t bank = otp_bank_offset(otp); 710*91f16700Schasinglulu uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); 711*91f16700Schasinglulu uint32_t bank_value; 712*91f16700Schasinglulu 713*91f16700Schasinglulu if (otp > STM32MP1_OTP_MAX_ID) { 714*91f16700Schasinglulu return BSEC_INVALID_PARAM; 715*91f16700Schasinglulu } 716*91f16700Schasinglulu 717*91f16700Schasinglulu bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank); 718*91f16700Schasinglulu 719*91f16700Schasinglulu *value = ((bank_value & otp_mask) != 0U); 720*91f16700Schasinglulu 721*91f16700Schasinglulu return BSEC_OK; 722*91f16700Schasinglulu } 723*91f16700Schasinglulu 724*91f16700Schasinglulu /* 725*91f16700Schasinglulu * bsec_set_sw_lock: set shadow-write lock. 726*91f16700Schasinglulu * otp: OTP number. 727*91f16700Schasinglulu * return value: BSEC_OK if no error. 728*91f16700Schasinglulu */ 729*91f16700Schasinglulu uint32_t bsec_set_sw_lock(uint32_t otp) 730*91f16700Schasinglulu { 731*91f16700Schasinglulu uint32_t bank = otp_bank_offset(otp); 732*91f16700Schasinglulu uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); 733*91f16700Schasinglulu 734*91f16700Schasinglulu if (is_otp_invalid_mode()) { 735*91f16700Schasinglulu return BSEC_ERROR; 736*91f16700Schasinglulu } 737*91f16700Schasinglulu 738*91f16700Schasinglulu if (otp > STM32MP1_OTP_MAX_ID) { 739*91f16700Schasinglulu return BSEC_INVALID_PARAM; 740*91f16700Schasinglulu } 741*91f16700Schasinglulu 742*91f16700Schasinglulu bsec_lock(); 743*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_SWLOCK_OFF + bank, otp_mask); 744*91f16700Schasinglulu bsec_unlock(); 745*91f16700Schasinglulu 746*91f16700Schasinglulu return BSEC_OK; 747*91f16700Schasinglulu } 748*91f16700Schasinglulu 749*91f16700Schasinglulu /* 750*91f16700Schasinglulu * bsec_read_sw_lock: read shadow-write lock. 751*91f16700Schasinglulu * otp: OTP number. 752*91f16700Schasinglulu * value: read value (true or false). 753*91f16700Schasinglulu * return value: BSEC_OK if no error. 754*91f16700Schasinglulu */ 755*91f16700Schasinglulu uint32_t bsec_read_sw_lock(uint32_t otp, bool *value) 756*91f16700Schasinglulu { 757*91f16700Schasinglulu uint32_t bank = otp_bank_offset(otp); 758*91f16700Schasinglulu uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); 759*91f16700Schasinglulu uint32_t bank_value; 760*91f16700Schasinglulu 761*91f16700Schasinglulu if (otp > STM32MP1_OTP_MAX_ID) { 762*91f16700Schasinglulu return BSEC_INVALID_PARAM; 763*91f16700Schasinglulu } 764*91f16700Schasinglulu 765*91f16700Schasinglulu bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank); 766*91f16700Schasinglulu 767*91f16700Schasinglulu *value = ((bank_value & otp_mask) != 0U); 768*91f16700Schasinglulu 769*91f16700Schasinglulu return BSEC_OK; 770*91f16700Schasinglulu } 771*91f16700Schasinglulu 772*91f16700Schasinglulu /* 773*91f16700Schasinglulu * bsec_set_sp_lock: set shadow-program lock. 774*91f16700Schasinglulu * otp: OTP number. 775*91f16700Schasinglulu * return value: BSEC_OK if no error. 776*91f16700Schasinglulu */ 777*91f16700Schasinglulu uint32_t bsec_set_sp_lock(uint32_t otp) 778*91f16700Schasinglulu { 779*91f16700Schasinglulu uint32_t bank = otp_bank_offset(otp); 780*91f16700Schasinglulu uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); 781*91f16700Schasinglulu 782*91f16700Schasinglulu if (is_otp_invalid_mode()) { 783*91f16700Schasinglulu return BSEC_ERROR; 784*91f16700Schasinglulu } 785*91f16700Schasinglulu 786*91f16700Schasinglulu if (otp > STM32MP1_OTP_MAX_ID) { 787*91f16700Schasinglulu return BSEC_INVALID_PARAM; 788*91f16700Schasinglulu } 789*91f16700Schasinglulu 790*91f16700Schasinglulu bsec_lock(); 791*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_SPLOCK_OFF + bank, otp_mask); 792*91f16700Schasinglulu bsec_unlock(); 793*91f16700Schasinglulu 794*91f16700Schasinglulu return BSEC_OK; 795*91f16700Schasinglulu } 796*91f16700Schasinglulu 797*91f16700Schasinglulu /* 798*91f16700Schasinglulu * bsec_read_sp_lock: read shadow-program lock. 799*91f16700Schasinglulu * otp: OTP number. 800*91f16700Schasinglulu * value: read value (true or false). 801*91f16700Schasinglulu * return value: BSEC_OK if no error. 802*91f16700Schasinglulu */ 803*91f16700Schasinglulu uint32_t bsec_read_sp_lock(uint32_t otp, bool *value) 804*91f16700Schasinglulu { 805*91f16700Schasinglulu uint32_t bank = otp_bank_offset(otp); 806*91f16700Schasinglulu uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); 807*91f16700Schasinglulu uint32_t bank_value; 808*91f16700Schasinglulu 809*91f16700Schasinglulu if (otp > STM32MP1_OTP_MAX_ID) { 810*91f16700Schasinglulu return BSEC_INVALID_PARAM; 811*91f16700Schasinglulu } 812*91f16700Schasinglulu 813*91f16700Schasinglulu bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank); 814*91f16700Schasinglulu 815*91f16700Schasinglulu *value = ((bank_value & otp_mask) != 0U); 816*91f16700Schasinglulu 817*91f16700Schasinglulu return BSEC_OK; 818*91f16700Schasinglulu } 819*91f16700Schasinglulu 820*91f16700Schasinglulu /* 821*91f16700Schasinglulu * bsec_read_permanent_lock: Read permanent lock status. 822*91f16700Schasinglulu * otp: OTP number. 823*91f16700Schasinglulu * value: read value (true or false). 824*91f16700Schasinglulu * return value: BSEC_OK if no error. 825*91f16700Schasinglulu */ 826*91f16700Schasinglulu uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value) 827*91f16700Schasinglulu { 828*91f16700Schasinglulu uint32_t bank = otp_bank_offset(otp); 829*91f16700Schasinglulu uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK); 830*91f16700Schasinglulu uint32_t bank_value; 831*91f16700Schasinglulu 832*91f16700Schasinglulu if (otp > STM32MP1_OTP_MAX_ID) { 833*91f16700Schasinglulu return BSEC_INVALID_PARAM; 834*91f16700Schasinglulu } 835*91f16700Schasinglulu 836*91f16700Schasinglulu bank_value = mmio_read_32(bsec_base + BSEC_WRLOCK_OFF + bank); 837*91f16700Schasinglulu 838*91f16700Schasinglulu *value = ((bank_value & otp_mask) != 0U); 839*91f16700Schasinglulu 840*91f16700Schasinglulu return BSEC_OK; 841*91f16700Schasinglulu } 842*91f16700Schasinglulu 843*91f16700Schasinglulu /* 844*91f16700Schasinglulu * bsec_otp_lock: Lock Upper OTP or Global Programming or Debug Enable. 845*91f16700Schasinglulu * service: Service to lock, see header file. 846*91f16700Schasinglulu * return value: BSEC_OK if no error. 847*91f16700Schasinglulu */ 848*91f16700Schasinglulu uint32_t bsec_otp_lock(uint32_t service) 849*91f16700Schasinglulu { 850*91f16700Schasinglulu uintptr_t reg = bsec_base + BSEC_OTP_LOCK_OFF; 851*91f16700Schasinglulu 852*91f16700Schasinglulu if (is_otp_invalid_mode()) { 853*91f16700Schasinglulu return BSEC_ERROR; 854*91f16700Schasinglulu } 855*91f16700Schasinglulu 856*91f16700Schasinglulu switch (service) { 857*91f16700Schasinglulu case BSEC_LOCK_UPPER_OTP: 858*91f16700Schasinglulu mmio_write_32(reg, BIT(BSEC_LOCK_UPPER_OTP)); 859*91f16700Schasinglulu break; 860*91f16700Schasinglulu case BSEC_LOCK_DEBUG: 861*91f16700Schasinglulu mmio_write_32(reg, BIT(BSEC_LOCK_DEBUG)); 862*91f16700Schasinglulu break; 863*91f16700Schasinglulu case BSEC_LOCK_PROGRAM: 864*91f16700Schasinglulu mmio_write_32(reg, BIT(BSEC_LOCK_PROGRAM)); 865*91f16700Schasinglulu break; 866*91f16700Schasinglulu default: 867*91f16700Schasinglulu return BSEC_INVALID_PARAM; 868*91f16700Schasinglulu } 869*91f16700Schasinglulu 870*91f16700Schasinglulu return BSEC_OK; 871*91f16700Schasinglulu } 872*91f16700Schasinglulu 873*91f16700Schasinglulu /* 874*91f16700Schasinglulu * bsec_power_safmem: Activate or deactivate SAFMEM power. 875*91f16700Schasinglulu * power: true to power up, false to power down. 876*91f16700Schasinglulu * return value: BSEC_OK if no error. 877*91f16700Schasinglulu */ 878*91f16700Schasinglulu static uint32_t bsec_power_safmem(bool power) 879*91f16700Schasinglulu { 880*91f16700Schasinglulu uint32_t register_val; 881*91f16700Schasinglulu uint32_t timeout = BSEC_TIMEOUT_VALUE; 882*91f16700Schasinglulu 883*91f16700Schasinglulu bsec_lock(); 884*91f16700Schasinglulu 885*91f16700Schasinglulu register_val = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF); 886*91f16700Schasinglulu 887*91f16700Schasinglulu if (power) { 888*91f16700Schasinglulu register_val |= BSEC_CONF_POWER_UP_MASK; 889*91f16700Schasinglulu } else { 890*91f16700Schasinglulu register_val &= ~BSEC_CONF_POWER_UP_MASK; 891*91f16700Schasinglulu } 892*91f16700Schasinglulu 893*91f16700Schasinglulu mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, register_val); 894*91f16700Schasinglulu 895*91f16700Schasinglulu if (power) { 896*91f16700Schasinglulu while (((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) && 897*91f16700Schasinglulu (timeout != 0U)) { 898*91f16700Schasinglulu timeout--; 899*91f16700Schasinglulu } 900*91f16700Schasinglulu } else { 901*91f16700Schasinglulu while (((bsec_get_status() & BSEC_MODE_PWR_MASK) != 0U) && 902*91f16700Schasinglulu (timeout != 0U)) { 903*91f16700Schasinglulu timeout--; 904*91f16700Schasinglulu } 905*91f16700Schasinglulu } 906*91f16700Schasinglulu 907*91f16700Schasinglulu bsec_unlock(); 908*91f16700Schasinglulu 909*91f16700Schasinglulu if (timeout == 0U) { 910*91f16700Schasinglulu return BSEC_TIMEOUT; 911*91f16700Schasinglulu } 912*91f16700Schasinglulu 913*91f16700Schasinglulu return BSEC_OK; 914*91f16700Schasinglulu } 915*91f16700Schasinglulu 916*91f16700Schasinglulu /* 917*91f16700Schasinglulu * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value. 918*91f16700Schasinglulu * otp_value: read value. 919*91f16700Schasinglulu * word: OTP number. 920*91f16700Schasinglulu * return value: BSEC_OK if no error. 921*91f16700Schasinglulu */ 922*91f16700Schasinglulu uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word) 923*91f16700Schasinglulu { 924*91f16700Schasinglulu uint32_t result; 925*91f16700Schasinglulu 926*91f16700Schasinglulu result = bsec_shadow_register(word); 927*91f16700Schasinglulu if (result != BSEC_OK) { 928*91f16700Schasinglulu ERROR("BSEC: %u Shadowing Error %u\n", word, result); 929*91f16700Schasinglulu return result; 930*91f16700Schasinglulu } 931*91f16700Schasinglulu 932*91f16700Schasinglulu result = bsec_read_otp(otp_value, word); 933*91f16700Schasinglulu if (result != BSEC_OK) { 934*91f16700Schasinglulu ERROR("BSEC: %u Read Error %u\n", word, result); 935*91f16700Schasinglulu } 936*91f16700Schasinglulu 937*91f16700Schasinglulu return result; 938*91f16700Schasinglulu } 939*91f16700Schasinglulu 940*91f16700Schasinglulu /* 941*91f16700Schasinglulu * bsec_check_nsec_access_rights: check non-secure access rights to target OTP. 942*91f16700Schasinglulu * otp: OTP number. 943*91f16700Schasinglulu * return value: BSEC_OK if authorized access. 944*91f16700Schasinglulu */ 945*91f16700Schasinglulu uint32_t bsec_check_nsec_access_rights(uint32_t otp) 946*91f16700Schasinglulu { 947*91f16700Schasinglulu #if defined(IMAGE_BL32) 948*91f16700Schasinglulu if (otp > STM32MP1_OTP_MAX_ID) { 949*91f16700Schasinglulu return BSEC_INVALID_PARAM; 950*91f16700Schasinglulu } 951*91f16700Schasinglulu 952*91f16700Schasinglulu if (otp >= STM32MP1_UPPER_OTP_START) { 953*91f16700Schasinglulu if (!non_secure_can_access(otp)) { 954*91f16700Schasinglulu return BSEC_ERROR; 955*91f16700Schasinglulu } 956*91f16700Schasinglulu } 957*91f16700Schasinglulu #endif 958*91f16700Schasinglulu 959*91f16700Schasinglulu return BSEC_OK; 960*91f16700Schasinglulu } 961*91f16700Schasinglulu 962