1 /* 2 * Copyright 2021 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 #include <stdint.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 13 #include <caam.h> 14 #include <common/debug.h> 15 #include <drivers/delay_timer.h> 16 #include <sfp.h> 17 #include <sfp_error_codes.h> 18 19 static uintptr_t g_nxp_sfp_addr; 20 static uint32_t srk_hash[SRK_HASH_SIZE/sizeof(uint32_t)] 21 __aligned(CACHE_WRITEBACK_GRANULE); 22 sfp_init(uintptr_t nxp_sfp_addr)23void sfp_init(uintptr_t nxp_sfp_addr) 24 { 25 g_nxp_sfp_addr = nxp_sfp_addr; 26 } 27 get_sfp_addr(void)28uintptr_t get_sfp_addr(void) 29 { 30 return g_nxp_sfp_addr; 31 } 32 get_sfp_srk_hash(void)33uint32_t *get_sfp_srk_hash(void) 34 { 35 struct sfp_ccsr_regs_t *sfp_ccsr_regs = 36 (void *) (g_nxp_sfp_addr + SFP_FUSE_REGS_OFFSET); 37 int i = 0; 38 39 /* Add comparison of hash with SFP hash here */ 40 for (i = 0; i < SRK_HASH_SIZE/sizeof(uint32_t); i++) 41 srk_hash[i] = 42 mmio_read_32((uintptr_t)&sfp_ccsr_regs->srk_hash[i]); 43 44 return srk_hash; 45 } 46 set_sfp_wr_disable(void)47void set_sfp_wr_disable(void) 48 { 49 /* 50 * Mark SFP Write Disable and Write Disable Lock 51 * Bit to prevent write to SFP fuses like 52 * OUID's, Key Revocation fuse etc 53 */ 54 void *sfpcr = (void *)(g_nxp_sfp_addr + SFP_SFPCR_OFFSET); 55 uint32_t sfpcr_val; 56 57 sfpcr_val = sfp_read32(sfpcr); 58 sfpcr_val |= (SFP_SFPCR_WD | SFP_SFPCR_WDL); 59 sfp_write32(sfpcr, sfpcr_val); 60 } 61 sfp_program_fuses(void)62int sfp_program_fuses(void) 63 { 64 uint32_t ingr; 65 uint32_t sfp_cmd_status = 0U; 66 int ret = 0; 67 68 /* Program SFP fuses from mirror registers */ 69 sfp_write32((void *)(g_nxp_sfp_addr + SFP_INGR_OFFSET), 70 SFP_INGR_PROGFB_CMD); 71 72 /* Wait until fuse programming is successful */ 73 do { 74 ingr = sfp_read32(g_nxp_sfp_addr + SFP_INGR_OFFSET); 75 } while (ingr & SFP_INGR_PROGFB_CMD); 76 77 /* Check for SFP fuse programming error */ 78 sfp_cmd_status = sfp_read32(g_nxp_sfp_addr + SFP_INGR_OFFSET) 79 & SFP_INGR_ERROR_MASK; 80 81 if (sfp_cmd_status != 0U) { 82 return ERROR_PROGFB_CMD; 83 } 84 85 return ret; 86 } 87 sfp_read_oem_uid(uint8_t oem_uid)88uint32_t sfp_read_oem_uid(uint8_t oem_uid) 89 { 90 uint32_t val = 0U; 91 struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(g_nxp_sfp_addr 92 + SFP_FUSE_REGS_OFFSET); 93 94 if (oem_uid > MAX_OEM_UID) { 95 ERROR("Invalid OEM UID received.\n"); 96 return ERROR_OEMUID_WRITE; 97 } 98 99 val = sfp_read32(&sfp_ccsr_regs->oem_uid[oem_uid]); 100 101 return val; 102 } 103 104 /* 105 * return val: 0 - No update required. 106 * 1 - successful update done. 107 * ERROR_OEMUID_WRITE - Invalid OEM UID 108 */ sfp_write_oem_uid(uint8_t oem_uid,uint32_t sfp_val)109uint32_t sfp_write_oem_uid(uint8_t oem_uid, uint32_t sfp_val) 110 { 111 uint32_t val = 0U; 112 struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(g_nxp_sfp_addr 113 + SFP_FUSE_REGS_OFFSET); 114 115 val = sfp_read_oem_uid(oem_uid); 116 117 if (val == ERROR_OEMUID_WRITE) { 118 return ERROR_OEMUID_WRITE; 119 } 120 121 /* Counter already set. No need to do anything */ 122 if ((val & sfp_val) != 0U) { 123 return 0U; 124 } 125 126 val |= sfp_val; 127 128 INFO("SFP Value is %x for setting sfp_val = %d\n", val, sfp_val); 129 130 sfp_write32(&sfp_ccsr_regs->oem_uid[oem_uid], val); 131 132 return 1U; 133 } 134 sfp_check_its(void)135int sfp_check_its(void) 136 { 137 struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(g_nxp_sfp_addr 138 + SFP_FUSE_REGS_OFFSET); 139 140 if ((sfp_read32(&sfp_ccsr_regs->ospr) & OSPR_ITS_MASK) != 0) { 141 return 1; 142 } else { 143 return 0; 144 } 145 } 146 sfp_check_oem_wp(void)147int sfp_check_oem_wp(void) 148 { 149 struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(g_nxp_sfp_addr 150 + SFP_FUSE_REGS_OFFSET); 151 152 if ((sfp_read32(&sfp_ccsr_regs->ospr) & OSPR_WP_MASK) != 0) { 153 return 1; 154 } else { 155 return 0; 156 } 157 } 158 159 /* This function returns ospr's key_revoc values.*/ get_key_revoc(void)160uint32_t get_key_revoc(void) 161 { 162 struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(g_nxp_sfp_addr 163 + SFP_FUSE_REGS_OFFSET); 164 165 return (sfp_read32(&sfp_ccsr_regs->ospr) & OSPR_KEY_REVOC_MASK) >> 166 OSPR_KEY_REVOC_SHIFT; 167 } 168