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