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