1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2016-2020, Broadcom 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <string.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <common/debug.h> 10*91f16700Schasinglulu #include <lib/mmio.h> 11*91f16700Schasinglulu #include <sotp.h> 12*91f16700Schasinglulu 13*91f16700Schasinglulu #include <platform_def.h> 14*91f16700Schasinglulu #include <platform_sotp.h> 15*91f16700Schasinglulu 16*91f16700Schasinglulu #ifdef USE_SOFT_SOTP 17*91f16700Schasinglulu extern uint64_t soft_sotp[]; 18*91f16700Schasinglulu #endif 19*91f16700Schasinglulu 20*91f16700Schasinglulu #define SOTP_PROG_CONTROL (SOTP_REGS_OTP_BASE + 0x0000) 21*91f16700Schasinglulu #define SOTP_PROG_CONTROL__OTP_CPU_MODE_EN 15 22*91f16700Schasinglulu #define SOTP_PROG_CONTROL__OTP_DISABLE_ECC 9 23*91f16700Schasinglulu #define SOTP_PROG_CONTROL__OTP_ECC_WREN 8 24*91f16700Schasinglulu 25*91f16700Schasinglulu #define SOTP_WRDATA_0 (SOTP_REGS_OTP_BASE + 0x0004) 26*91f16700Schasinglulu #define SOTP_WRDATA_1 (SOTP_REGS_OTP_BASE + 0x0008) 27*91f16700Schasinglulu 28*91f16700Schasinglulu #define SOTP_ADDR (SOTP_REGS_OTP_BASE + 0x000c) 29*91f16700Schasinglulu #define SOTP_ADDR__OTP_ROW_ADDR_R 6 30*91f16700Schasinglulu #define SOTP_ADDR_MASK 0x3FF 31*91f16700Schasinglulu 32*91f16700Schasinglulu #define SOTP_CTRL_0 (SOTP_REGS_OTP_BASE + 0x0010) 33*91f16700Schasinglulu #define SOTP_CTRL_0__START 0 34*91f16700Schasinglulu #define SOTP_CTRL_0__OTP_CMD 1 35*91f16700Schasinglulu 36*91f16700Schasinglulu #define SOTP_STATUS_0 (SOTP_REGS_OTP_BASE + 0x0018) 37*91f16700Schasinglulu #define SOTP_STATUS__FDONE 3 38*91f16700Schasinglulu 39*91f16700Schasinglulu #define SOTP_STATUS_1 (SOTP_REGS_OTP_BASE + 0x001c) 40*91f16700Schasinglulu #define SOTP_STATUS_1__CMD_DONE 1 41*91f16700Schasinglulu #define SOTP_STATUS_1__ECC_DET 17 42*91f16700Schasinglulu 43*91f16700Schasinglulu #define SOTP_RDDATA_0 (SOTP_REGS_OTP_BASE + 0x0020) 44*91f16700Schasinglulu #define SOTP_RDDATA_1 (SOTP_REGS_OTP_BASE + 0x0024) 45*91f16700Schasinglulu 46*91f16700Schasinglulu #define SOTP_READ 0 47*91f16700Schasinglulu 48*91f16700Schasinglulu #define SOTP_PROG_WORD 10 49*91f16700Schasinglulu #define SOTP_STATUS__PROGOK 2 50*91f16700Schasinglulu #define SOTP_PROG_ENABLE 2 51*91f16700Schasinglulu 52*91f16700Schasinglulu #define SOTP_ROW_DATA_MASK 0xffffffff 53*91f16700Schasinglulu #define SOTP_ECC_ERR_BITS_MASK 0x1ff00000000 54*91f16700Schasinglulu 55*91f16700Schasinglulu #define SOTP_CHIP_CTRL_SW_OVERRIDE_CHIP_STATES 4 56*91f16700Schasinglulu #define SOTP_CHIP_CTRL_SW_MANU_PROG 5 57*91f16700Schasinglulu #define SOTP_CHIP_CTRL_SW_CID_PROG 6 58*91f16700Schasinglulu #define SOTP_CHIP_CTRL_SW_AB_DEVICE 8 59*91f16700Schasinglulu #define SOTP_CHIP_CTRL_SW_AB_DEV_MODE 9 60*91f16700Schasinglulu #define CHIP_STATE_UNPROGRAMMED 0x1 61*91f16700Schasinglulu #define CHIP_STATE_UNASSIGNED 0x2 62*91f16700Schasinglulu 63*91f16700Schasinglulu uint64_t sotp_mem_read(uint32_t offset, uint32_t sotp_add_ecc) 64*91f16700Schasinglulu { 65*91f16700Schasinglulu #ifdef USE_SOFT_SOTP 66*91f16700Schasinglulu (void)sotp_add_ecc; 67*91f16700Schasinglulu 68*91f16700Schasinglulu return soft_sotp[offset]; 69*91f16700Schasinglulu #else 70*91f16700Schasinglulu uint64_t read_data = 0; 71*91f16700Schasinglulu uint64_t read_data1 = 0; 72*91f16700Schasinglulu uint64_t read_data2 = 0; 73*91f16700Schasinglulu 74*91f16700Schasinglulu /* Check for FDONE status */ 75*91f16700Schasinglulu while ((mmio_read_32(SOTP_STATUS_0) & BIT(SOTP_STATUS__FDONE)) != 76*91f16700Schasinglulu BIT(SOTP_STATUS__FDONE)) 77*91f16700Schasinglulu ; 78*91f16700Schasinglulu 79*91f16700Schasinglulu /* Enable OTP access by CPU */ 80*91f16700Schasinglulu mmio_setbits_32(SOTP_PROG_CONTROL, 81*91f16700Schasinglulu BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN)); 82*91f16700Schasinglulu 83*91f16700Schasinglulu if (sotp_add_ecc == 1) { 84*91f16700Schasinglulu mmio_clrbits_32(SOTP_PROG_CONTROL, 85*91f16700Schasinglulu BIT(SOTP_PROG_CONTROL__OTP_DISABLE_ECC)); 86*91f16700Schasinglulu } 87*91f16700Schasinglulu 88*91f16700Schasinglulu if (sotp_add_ecc == 0) { 89*91f16700Schasinglulu mmio_setbits_32(SOTP_PROG_CONTROL, 90*91f16700Schasinglulu BIT(SOTP_PROG_CONTROL__OTP_DISABLE_ECC)); 91*91f16700Schasinglulu } 92*91f16700Schasinglulu 93*91f16700Schasinglulu mmio_write_32(SOTP_ADDR, 94*91f16700Schasinglulu ((offset & SOTP_ADDR_MASK) << SOTP_ADDR__OTP_ROW_ADDR_R)); 95*91f16700Schasinglulu mmio_write_32(SOTP_CTRL_0, (SOTP_READ << SOTP_CTRL_0__OTP_CMD)); 96*91f16700Schasinglulu 97*91f16700Schasinglulu /* Start bit to tell SOTP to send command to the OTP controller */ 98*91f16700Schasinglulu mmio_setbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); 99*91f16700Schasinglulu 100*91f16700Schasinglulu /* Wait for SOTP command done to be set */ 101*91f16700Schasinglulu while ((mmio_read_32(SOTP_STATUS_1) & BIT(SOTP_STATUS_1__CMD_DONE)) != 102*91f16700Schasinglulu BIT(SOTP_STATUS_1__CMD_DONE)) 103*91f16700Schasinglulu ; 104*91f16700Schasinglulu 105*91f16700Schasinglulu /* Clr Start bit after command done */ 106*91f16700Schasinglulu mmio_clrbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); 107*91f16700Schasinglulu 108*91f16700Schasinglulu if ((offset > SOTP_DEVICE_SECURE_CFG3_ROW) && 109*91f16700Schasinglulu (mmio_read_32(SOTP_STATUS_1) & BIT(SOTP_STATUS_1__ECC_DET))) { 110*91f16700Schasinglulu ERROR("SOTP ECC ERROR Detected row offset %d\n", offset); 111*91f16700Schasinglulu read_data = SOTP_ECC_ERR_DETECT; 112*91f16700Schasinglulu } else { 113*91f16700Schasinglulu read_data1 = (uint64_t)mmio_read_32(SOTP_RDDATA_0); 114*91f16700Schasinglulu read_data1 = read_data1 & 0xFFFFFFFF; 115*91f16700Schasinglulu read_data2 = (uint64_t)mmio_read_32(SOTP_RDDATA_1); 116*91f16700Schasinglulu read_data2 = (read_data2 & 0x1ff) << 32; 117*91f16700Schasinglulu read_data = read_data1 | read_data2; 118*91f16700Schasinglulu } 119*91f16700Schasinglulu 120*91f16700Schasinglulu /* Command done is cleared */ 121*91f16700Schasinglulu mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE)); 122*91f16700Schasinglulu 123*91f16700Schasinglulu /* disable OTP access by CPU */ 124*91f16700Schasinglulu mmio_clrbits_32(SOTP_PROG_CONTROL, 125*91f16700Schasinglulu BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN)); 126*91f16700Schasinglulu 127*91f16700Schasinglulu return read_data; 128*91f16700Schasinglulu #endif 129*91f16700Schasinglulu } 130*91f16700Schasinglulu 131*91f16700Schasinglulu void sotp_mem_write(uint32_t addr, uint32_t sotp_add_ecc, uint64_t wdata) 132*91f16700Schasinglulu { 133*91f16700Schasinglulu #ifdef USE_SOFT_SOTP 134*91f16700Schasinglulu (void)sotp_add_ecc; 135*91f16700Schasinglulu 136*91f16700Schasinglulu soft_sotp[addr] = wdata; 137*91f16700Schasinglulu #else 138*91f16700Schasinglulu uint32_t loop; 139*91f16700Schasinglulu uint8_t prog_array[4] = { 0x0F, 0x04, 0x08, 0x0D }; 140*91f16700Schasinglulu 141*91f16700Schasinglulu uint32_t chip_state_default = 142*91f16700Schasinglulu (CHIP_STATE_UNASSIGNED|CHIP_STATE_UNPROGRAMMED); 143*91f16700Schasinglulu uint32_t chip_state = mmio_read_32(SOTP_REGS_SOTP_CHIP_STATES); 144*91f16700Schasinglulu uint32_t chip_ctrl_default = 0; 145*91f16700Schasinglulu 146*91f16700Schasinglulu /* 147*91f16700Schasinglulu * The override settings is required to allow the customer to program 148*91f16700Schasinglulu * the application specific keys into SOTP, before the conversion to 149*91f16700Schasinglulu * one of the AB modes. 150*91f16700Schasinglulu * At the end of write operation, the chip ctrl settings will restored 151*91f16700Schasinglulu * to the state prior to write call 152*91f16700Schasinglulu */ 153*91f16700Schasinglulu if (chip_state & chip_state_default) { 154*91f16700Schasinglulu uint32_t chip_ctrl; 155*91f16700Schasinglulu 156*91f16700Schasinglulu chip_ctrl_default = mmio_read_32(SOTP_CHIP_CTRL); 157*91f16700Schasinglulu INFO("SOTP: enable special prog mode\n"); 158*91f16700Schasinglulu 159*91f16700Schasinglulu chip_ctrl = BIT(SOTP_CHIP_CTRL_SW_OVERRIDE_CHIP_STATES) | 160*91f16700Schasinglulu BIT(SOTP_CHIP_CTRL_SW_MANU_PROG) | 161*91f16700Schasinglulu BIT(SOTP_CHIP_CTRL_SW_CID_PROG) | 162*91f16700Schasinglulu BIT(SOTP_CHIP_CTRL_SW_AB_DEVICE); 163*91f16700Schasinglulu mmio_write_32(SOTP_CHIP_CTRL, chip_ctrl); 164*91f16700Schasinglulu } 165*91f16700Schasinglulu 166*91f16700Schasinglulu /* Check for FDONE status */ 167*91f16700Schasinglulu while ((mmio_read_32(SOTP_STATUS_0) & BIT(SOTP_STATUS__FDONE)) != 168*91f16700Schasinglulu BIT(SOTP_STATUS__FDONE)) 169*91f16700Schasinglulu ; 170*91f16700Schasinglulu 171*91f16700Schasinglulu /* Enable OTP access by CPU */ 172*91f16700Schasinglulu mmio_setbits_32(SOTP_PROG_CONTROL, 173*91f16700Schasinglulu BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN)); 174*91f16700Schasinglulu 175*91f16700Schasinglulu if (addr > SOTP_DEVICE_SECURE_CFG3_ROW) { 176*91f16700Schasinglulu if (sotp_add_ecc == 0) { 177*91f16700Schasinglulu mmio_clrbits_32(SOTP_PROG_CONTROL, 178*91f16700Schasinglulu BIT(SOTP_PROG_CONTROL__OTP_ECC_WREN)); 179*91f16700Schasinglulu } 180*91f16700Schasinglulu if (sotp_add_ecc == 1) { 181*91f16700Schasinglulu mmio_setbits_32(SOTP_PROG_CONTROL, 182*91f16700Schasinglulu BIT(SOTP_PROG_CONTROL__OTP_ECC_WREN)); 183*91f16700Schasinglulu } 184*91f16700Schasinglulu } else { 185*91f16700Schasinglulu mmio_clrbits_32(SOTP_PROG_CONTROL, 186*91f16700Schasinglulu BIT(SOTP_PROG_CONTROL__OTP_ECC_WREN)); 187*91f16700Schasinglulu } 188*91f16700Schasinglulu 189*91f16700Schasinglulu mmio_write_32(SOTP_CTRL_0, (SOTP_PROG_ENABLE << 1)); 190*91f16700Schasinglulu 191*91f16700Schasinglulu /* 192*91f16700Schasinglulu * In order to avoid unintentional writes / programming of the OTP 193*91f16700Schasinglulu * array, the OTP Controller must be put into programming mode before 194*91f16700Schasinglulu * it will accept program commands. This is done by writing 0xF, 0x4, 195*91f16700Schasinglulu * 0x8, 0xD with program commands prior to starting the actual 196*91f16700Schasinglulu * programming sequence 197*91f16700Schasinglulu */ 198*91f16700Schasinglulu for (loop = 0; loop < 4; loop++) { 199*91f16700Schasinglulu mmio_write_32(SOTP_WRDATA_0, prog_array[loop]); 200*91f16700Schasinglulu 201*91f16700Schasinglulu /* 202*91f16700Schasinglulu * Start bit to tell SOTP to send command to the OTP controller 203*91f16700Schasinglulu */ 204*91f16700Schasinglulu mmio_setbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); 205*91f16700Schasinglulu 206*91f16700Schasinglulu /* Wait for SOTP command done to <-- be set */ 207*91f16700Schasinglulu while ((mmio_read_32(SOTP_STATUS_1) & 208*91f16700Schasinglulu BIT(SOTP_STATUS_1__CMD_DONE)) != 209*91f16700Schasinglulu BIT(SOTP_STATUS_1__CMD_DONE)) 210*91f16700Schasinglulu ; 211*91f16700Schasinglulu 212*91f16700Schasinglulu /* Command done is cleared w1c */ 213*91f16700Schasinglulu mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE)); 214*91f16700Schasinglulu 215*91f16700Schasinglulu /* Clr Start bit after command done */ 216*91f16700Schasinglulu mmio_clrbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); 217*91f16700Schasinglulu } 218*91f16700Schasinglulu 219*91f16700Schasinglulu /* Check for PROGOK */ 220*91f16700Schasinglulu while ((mmio_read_32(SOTP_STATUS_0) & 0x4) != BIT(SOTP_STATUS__PROGOK)) 221*91f16700Schasinglulu ; 222*91f16700Schasinglulu 223*91f16700Schasinglulu /* Set 10 bit row address */ 224*91f16700Schasinglulu mmio_write_32(SOTP_ADDR, 225*91f16700Schasinglulu ((addr & SOTP_ADDR_MASK) << SOTP_ADDR__OTP_ROW_ADDR_R)); 226*91f16700Schasinglulu 227*91f16700Schasinglulu /* Set SOTP Row data */ 228*91f16700Schasinglulu mmio_write_32(SOTP_WRDATA_0, (wdata & SOTP_ROW_DATA_MASK)); 229*91f16700Schasinglulu 230*91f16700Schasinglulu /* Set SOTP ECC and error bits */ 231*91f16700Schasinglulu mmio_write_32(SOTP_WRDATA_1, ((wdata & SOTP_ECC_ERR_BITS_MASK) >> 32)); 232*91f16700Schasinglulu 233*91f16700Schasinglulu /* Set prog_word command */ 234*91f16700Schasinglulu mmio_write_32(SOTP_CTRL_0, (SOTP_PROG_WORD << 1)); 235*91f16700Schasinglulu 236*91f16700Schasinglulu /* Start bit to tell SOTP to send command to the OTP controller */ 237*91f16700Schasinglulu mmio_setbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); 238*91f16700Schasinglulu 239*91f16700Schasinglulu /* Wait for SOTP command done to be set */ 240*91f16700Schasinglulu while ((mmio_read_32(SOTP_STATUS_1) & BIT(SOTP_STATUS_1__CMD_DONE)) != 241*91f16700Schasinglulu BIT(SOTP_STATUS_1__CMD_DONE)) 242*91f16700Schasinglulu ; 243*91f16700Schasinglulu 244*91f16700Schasinglulu /* Command done is cleared w1c */ 245*91f16700Schasinglulu mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE)); 246*91f16700Schasinglulu 247*91f16700Schasinglulu /* disable OTP access by CPU */ 248*91f16700Schasinglulu mmio_clrbits_32(SOTP_PROG_CONTROL, 249*91f16700Schasinglulu BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN)); 250*91f16700Schasinglulu 251*91f16700Schasinglulu /* Clr Start bit after command done */ 252*91f16700Schasinglulu mmio_clrbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START)); 253*91f16700Schasinglulu 254*91f16700Schasinglulu if (chip_state & chip_state_default) 255*91f16700Schasinglulu mmio_write_32(SOTP_CHIP_CTRL, chip_ctrl_default); 256*91f16700Schasinglulu 257*91f16700Schasinglulu #endif 258*91f16700Schasinglulu } 259*91f16700Schasinglulu 260*91f16700Schasinglulu int sotp_read_key(uint8_t *key, size_t keysize, int start_row, int end_row) 261*91f16700Schasinglulu { 262*91f16700Schasinglulu int row; 263*91f16700Schasinglulu uint32_t status = 0; 264*91f16700Schasinglulu uint32_t status2 = 0xFFFFFFFF; 265*91f16700Schasinglulu uint64_t row_data; 266*91f16700Schasinglulu uint32_t data; 267*91f16700Schasinglulu uint32_t *temp_key = (uint32_t *)key; 268*91f16700Schasinglulu 269*91f16700Schasinglulu row = start_row; 270*91f16700Schasinglulu while ((keysize > 0) && (row <= end_row)) { 271*91f16700Schasinglulu row_data = sotp_mem_read(row, SOTP_ROW_ECC); 272*91f16700Schasinglulu if (!(row_data & (SOTP_ECC_ERR_DETECT | SOTP_FAIL_BITS))) { 273*91f16700Schasinglulu memcpy(temp_key++, &row_data, sizeof(uint32_t)); 274*91f16700Schasinglulu keysize -= sizeof(uint32_t); 275*91f16700Schasinglulu data = (uint32_t)(row_data & SOTP_ROW_DATA_MASK); 276*91f16700Schasinglulu status |= data; 277*91f16700Schasinglulu status2 &= data; 278*91f16700Schasinglulu } 279*91f16700Schasinglulu row++; 280*91f16700Schasinglulu } 281*91f16700Schasinglulu 282*91f16700Schasinglulu if ((status2 == 0xFFFFFFFF) || (status == 0) || (row > end_row)) 283*91f16700Schasinglulu return -1; 284*91f16700Schasinglulu 285*91f16700Schasinglulu return 0; 286*91f16700Schasinglulu } 287*91f16700Schasinglulu 288*91f16700Schasinglulu int sotp_key_erased(void) 289*91f16700Schasinglulu { 290*91f16700Schasinglulu uint64_t row_data; 291*91f16700Schasinglulu int status = 0; 292*91f16700Schasinglulu 293*91f16700Schasinglulu row_data = sotp_mem_read(SOTP_DEVICE_SECURE_CFG0_ROW, 0); 294*91f16700Schasinglulu if (row_data & SOTP_DEVICE_SECURE_CFG0_OTP_ERASED_MASK) 295*91f16700Schasinglulu status = 1; 296*91f16700Schasinglulu 297*91f16700Schasinglulu else if (mmio_read_32(SOTP_REGS_SOTP_CHIP_STATES) & 298*91f16700Schasinglulu SOTP_REGS_SOTP_CHIP_STATES_OTP_ERASED_MASK) 299*91f16700Schasinglulu status = 1; 300*91f16700Schasinglulu 301*91f16700Schasinglulu return status; 302*91f16700Schasinglulu } 303*91f16700Schasinglulu 304*91f16700Schasinglulu /* 305*91f16700Schasinglulu * This function optimise the SOTP redundancy 306*91f16700Schasinglulu * by considering the 00- zero and 01,10,11 - one 307*91f16700Schasinglulu */ 308*91f16700Schasinglulu uint32_t sotp_redundancy_reduction(uint32_t sotp_row_data) 309*91f16700Schasinglulu { 310*91f16700Schasinglulu uint32_t opt_data; 311*91f16700Schasinglulu uint32_t opt_loop; 312*91f16700Schasinglulu uint32_t temp_data; 313*91f16700Schasinglulu 314*91f16700Schasinglulu opt_data = 0; 315*91f16700Schasinglulu 316*91f16700Schasinglulu for (opt_loop = 0; opt_loop < 16; opt_loop = opt_loop + 1) { 317*91f16700Schasinglulu temp_data = ((sotp_row_data >> (opt_loop * 2)) & 0x3); 318*91f16700Schasinglulu 319*91f16700Schasinglulu if (temp_data != 0x0) 320*91f16700Schasinglulu opt_data = (opt_data | (1 << opt_loop)); 321*91f16700Schasinglulu } 322*91f16700Schasinglulu return opt_data; 323*91f16700Schasinglulu } 324