blob: e06c6b996c6a78fe42471ec166a0920085b98c87 [file] [log] [blame]
Pankaj Gupta44392ea2020-12-09 14:02:38 +05301/*
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
19static uintptr_t g_nxp_sfp_addr;
20static uint32_t srk_hash[SRK_HASH_SIZE/sizeof(uint32_t)]
21 __aligned(CACHE_WRITEBACK_GRANULE);
22
23void sfp_init(uintptr_t nxp_sfp_addr)
24{
25 g_nxp_sfp_addr = nxp_sfp_addr;
26}
27
28uintptr_t get_sfp_addr(void)
29{
30 return g_nxp_sfp_addr;
31}
32
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
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
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
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 */
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
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
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.*/
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}