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