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